Merge remote-tracking branch 'mesa-public/master' into vulkan
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 24 Jun 2015 01:05:25 +0000 (18:05 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 24 Jun 2015 01:05:25 +0000 (18:05 -0700)
812 files changed:
Android.common.mk
Android.mk
CleanSpec.mk
VERSION
configure.ac
docs/GL3.txt
docs/devinfo.html
docs/egl.html
docs/index.html
docs/relnotes.html
docs/relnotes/10.5.5.html [new file with mode: 0644]
docs/relnotes/10.5.6.html [new file with mode: 0644]
docs/relnotes/10.5.7.html [new file with mode: 0644]
docs/relnotes/10.5.8.html [new file with mode: 0644]
docs/relnotes/10.6.0.html
docs/relnotes/10.7.0.html [new file with mode: 0644]
include/EGL/egl.h
include/EGL/eglext.h
include/EGL/eglmesaext.h
include/EGL/eglplatform.h
include/KHR/khrplatform.h
include/pci_ids/radeonsi_pci_ids.h
scons/llvm.py
src/Makefile.am
src/egl/drivers/dri2/Android.mk
src/egl/drivers/dri2/Makefile.am
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/drivers/dri2/egl_dri2_fallbacks.h
src/egl/drivers/dri2/platform_android.c
src/egl/drivers/dri2/platform_drm.c
src/egl/drivers/dri2/platform_surfaceless.c [new file with mode: 0644]
src/egl/drivers/dri2/platform_wayland.c
src/egl/drivers/dri2/platform_x11.c
src/egl/drivers/haiku/SConscript
src/egl/drivers/haiku/egl_haiku.cpp
src/egl/main/Android.mk
src/egl/main/Makefile.am
src/egl/main/Makefile.sources
src/egl/main/README.txt
src/egl/main/eglapi.c
src/egl/main/eglapi.h
src/egl/main/eglarray.h
src/egl/main/eglcompiler.h
src/egl/main/eglconfig.c
src/egl/main/eglconfig.h
src/egl/main/eglcontext.c
src/egl/main/eglcontext.h
src/egl/main/eglcurrent.c
src/egl/main/eglcurrent.h
src/egl/main/egldefines.h
src/egl/main/egldisplay.c
src/egl/main/egldisplay.h
src/egl/main/egldriver.c
src/egl/main/egldriver.h
src/egl/main/eglfallbacks.c
src/egl/main/eglglobals.c
src/egl/main/eglglobals.h
src/egl/main/eglimage.h
src/egl/main/egllog.h
src/egl/main/eglmode.c [deleted file]
src/egl/main/eglmode.h [deleted file]
src/egl/main/eglscreen.c [deleted file]
src/egl/main/eglscreen.h [deleted file]
src/egl/main/eglsurface.c
src/egl/main/eglsurface.h
src/egl/main/eglsync.c
src/egl/main/eglsync.h
src/egl/main/egltypedefs.h
src/gallium/Android.common.mk
src/gallium/Android.mk
src/gallium/auxiliary/Android.mk
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/cso_cache/cso_context.h
src/gallium/auxiliary/draw/draw_gs.c
src/gallium/auxiliary/draw/draw_gs.h
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_pipe_aaline.c
src/gallium/auxiliary/draw/draw_pipe_pstipple.c
src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
src/gallium/auxiliary/gallivm/lp_bld_format_aos.c
src/gallium/auxiliary/gallivm/lp_bld_init.c
src/gallium/auxiliary/gallivm/lp_bld_limits.h
src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/auxiliary/hud/hud_context.c
src/gallium/auxiliary/nir/tgsi_to_nir.c
src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
src/gallium/auxiliary/postprocess/postprocess.h
src/gallium/auxiliary/postprocess/pp_run.c
src/gallium/auxiliary/rtasm/rtasm_execmem.c
src/gallium/auxiliary/tgsi/tgsi_build.c
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_exec.h
src/gallium/auxiliary/tgsi/tgsi_info.c
src/gallium/auxiliary/tgsi/tgsi_lowering.c
src/gallium/auxiliary/tgsi/tgsi_sanity.c
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/auxiliary/tgsi/tgsi_scan.h
src/gallium/auxiliary/tgsi/tgsi_strings.c
src/gallium/auxiliary/tgsi/tgsi_strings.h
src/gallium/auxiliary/tgsi/tgsi_text.c
src/gallium/auxiliary/tgsi/tgsi_transform.h
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_blitter.h
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/auxiliary/util/u_format_etc.c
src/gallium/auxiliary/util/u_math.h
src/gallium/auxiliary/util/u_pstipple.c
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_simple_shaders.h
src/gallium/auxiliary/util/u_tests.c
src/gallium/auxiliary/util/u_tests.h
src/gallium/auxiliary/util/u_vbuf.c
src/gallium/docs/source/context.rst
src/gallium/docs/source/screen.rst
src/gallium/docs/source/tgsi.rst
src/gallium/drivers/freedreno/Makefile.am
src/gallium/drivers/freedreno/Makefile.sources
src/gallium/drivers/freedreno/a2xx/fd2_compiler.c
src/gallium/drivers/freedreno/a3xx/fd3_context.h
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/a3xx/fd3_screen.c
src/gallium/drivers/freedreno/a3xx/fd3_texture.c
src/gallium/drivers/freedreno/a4xx/fd4_context.h
src/gallium/drivers/freedreno/a4xx/fd4_draw.c
src/gallium/drivers/freedreno/a4xx/fd4_screen.c
src/gallium/drivers/freedreno/a4xx/fd4_texture.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_fence.c
src/gallium/drivers/freedreno/freedreno_gmem.c
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_screen.h
src/gallium/drivers/freedreno/freedreno_util.h
src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
src/gallium/drivers/freedreno/ir3/instr-a3xx.h
src/gallium/drivers/freedreno/ir3/ir3.c
src/gallium/drivers/freedreno/ir3/ir3.h
src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
src/gallium/drivers/freedreno/ir3/ir3_compiler.c
src/gallium/drivers/freedreno/ir3/ir3_compiler.h
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
src/gallium/drivers/freedreno/ir3/ir3_cp.c
src/gallium/drivers/freedreno/ir3/ir3_depth.c
src/gallium/drivers/freedreno/ir3/ir3_dump.c [deleted file]
src/gallium/drivers/freedreno/ir3/ir3_flatten.c [deleted file]
src/gallium/drivers/freedreno/ir3/ir3_group.c
src/gallium/drivers/freedreno/ir3/ir3_legalize.c
src/gallium/drivers/freedreno/ir3/ir3_nir_lower_if_else.c
src/gallium/drivers/freedreno/ir3/ir3_print.c [new file with mode: 0644]
src/gallium/drivers/freedreno/ir3/ir3_ra.c
src/gallium/drivers/freedreno/ir3/ir3_sched.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c
src/gallium/drivers/freedreno/ir3/ir3_shader.h
src/gallium/drivers/i915/i915_fpc_optimize.c
src/gallium/drivers/i915/i915_fpc_translate.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/ilo/Makefile.sources
src/gallium/drivers/ilo/core/ilo_buffer.h
src/gallium/drivers/ilo/core/ilo_builder.c
src/gallium/drivers/ilo/core/ilo_builder_3d.h
src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h
src/gallium/drivers/ilo/core/ilo_builder_3d_top.h
src/gallium/drivers/ilo/core/ilo_builder_decode.c
src/gallium/drivers/ilo/core/ilo_builder_media.h
src/gallium/drivers/ilo/core/ilo_core.h
src/gallium/drivers/ilo/core/ilo_debug.h
src/gallium/drivers/ilo/core/ilo_dev.c
src/gallium/drivers/ilo/core/ilo_dev.h
src/gallium/drivers/ilo/core/ilo_fence.h [deleted file]
src/gallium/drivers/ilo/core/ilo_format.c [deleted file]
src/gallium/drivers/ilo/core/ilo_format.h [deleted file]
src/gallium/drivers/ilo/core/ilo_image.c
src/gallium/drivers/ilo/core/ilo_image.h
src/gallium/drivers/ilo/core/ilo_state_3d.h [deleted file]
src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c [deleted file]
src/gallium/drivers/ilo/core/ilo_state_3d_top.c [deleted file]
src/gallium/drivers/ilo/core/ilo_state_cc.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_cc.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_compute.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_compute.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_raster.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_raster.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_sampler.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_sampler.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_sbe.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_sbe.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_shader.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_shader.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_shader_ps.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_sol.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_sol.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_surface.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_surface.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_surface_format.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_urb.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_urb.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_vf.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_vf.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_viewport.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_viewport.h [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_zs.c [new file with mode: 0644]
src/gallium/drivers/ilo/core/ilo_state_zs.h [new file with mode: 0644]
src/gallium/drivers/ilo/genhw/gen_mi.xml.h
src/gallium/drivers/ilo/genhw/gen_regs.xml.h
src/gallium/drivers/ilo/genhw/gen_render_3d.xml.h
src/gallium/drivers/ilo/genhw/gen_render_dynamic.xml.h
src/gallium/drivers/ilo/genhw/gen_render_surface.xml.h
src/gallium/drivers/ilo/genhw/genhw.h
src/gallium/drivers/ilo/ilo_blitter.h
src/gallium/drivers/ilo/ilo_blitter_pipe.c
src/gallium/drivers/ilo/ilo_blitter_rectlist.c
src/gallium/drivers/ilo/ilo_draw.c
src/gallium/drivers/ilo/ilo_format.c [new file with mode: 0644]
src/gallium/drivers/ilo/ilo_format.h [new file with mode: 0644]
src/gallium/drivers/ilo/ilo_render.c
src/gallium/drivers/ilo/ilo_render.h
src/gallium/drivers/ilo/ilo_render_dynamic.c
src/gallium/drivers/ilo/ilo_render_gen.h
src/gallium/drivers/ilo/ilo_render_gen6.c
src/gallium/drivers/ilo/ilo_render_gen7.c
src/gallium/drivers/ilo/ilo_render_gen8.c
src/gallium/drivers/ilo/ilo_render_media.c
src/gallium/drivers/ilo/ilo_render_surface.c
src/gallium/drivers/ilo/ilo_resource.c
src/gallium/drivers/ilo/ilo_screen.c
src/gallium/drivers/ilo/ilo_shader.c
src/gallium/drivers/ilo/ilo_shader.h
src/gallium/drivers/ilo/ilo_state.c
src/gallium/drivers/ilo/ilo_state.h
src/gallium/drivers/ilo/shader/ilo_shader_internal.h
src/gallium/drivers/ilo/shader/toy_tgsi.c
src/gallium/drivers/llvmpipe/lp_bld_depth.c
src/gallium/drivers/llvmpipe/lp_public.h
src/gallium/drivers/llvmpipe/lp_query.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_state_sampler.c
src/gallium/drivers/llvmpipe/lp_surface.c
src/gallium/drivers/nouveau/Android.mk
src/gallium/drivers/nouveau/Makefile.am
src/gallium/drivers/nouveau/codegen/lib/gk110.asm
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
src/gallium/drivers/nouveau/nouveau_buffer.c
src/gallium/drivers/nouveau/nouveau_heap.h
src/gallium/drivers/nouveau/nouveau_screen.c
src/gallium/drivers/nouveau/nouveau_screen.h
src/gallium/drivers/nouveau/nv30/nv30_clear.c
src/gallium/drivers/nouveau/nv30/nv30_context.h
src/gallium/drivers/nouveau/nv30/nv30_draw.c
src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
src/gallium/drivers/nouveau/nv30/nv30_screen.c
src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
src/gallium/drivers/nouveau/nv30/nv30_vbo.c
src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
src/gallium/drivers/nouveau/nv30/nvfx_fragprog.c
src/gallium/drivers/nouveau/nv30/nvfx_vertprog.c
src/gallium/drivers/nouveau/nv50/nv50_context.c
src/gallium/drivers/nouveau/nv50/nv50_context.h
src/gallium/drivers/nouveau/nv50/nv50_miptree.c
src/gallium/drivers/nouveau/nv50/nv50_query.c
src/gallium/drivers/nouveau/nv50/nv50_screen.c
src/gallium/drivers/nouveau/nv50/nv50_screen.h
src/gallium/drivers/nouveau/nv50/nv50_state.c
src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
src/gallium/drivers/nouveau/nv50/nv50_vbo.c
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.h
src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
src/gallium/drivers/nouveau/nvc0/nvc0_program.c
src/gallium/drivers/nouveau/nvc0/nvc0_query.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
src/gallium/drivers/nouveau/nvc0/nvc0_state.c
src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
src/gallium/drivers/nouveau/nvc0/nve4_compute.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_tgsi_to_rc.c
src/gallium/drivers/r600/Android.mk
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/radeon/Android.mk
src/gallium/drivers/radeon/Makefile.sources
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/radeon_llvm.h
src/gallium/drivers/radeon/radeon_llvm_emit.c
src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
src/gallium/drivers/radeon/radeon_vce.c
src/gallium/drivers/radeon/radeon_vce.h
src/gallium/drivers/radeon/radeon_vce_40_2_2.c
src/gallium/drivers/radeon/radeon_vce_50.c [new file with mode: 0644]
src/gallium/drivers/radeonsi/Makefile.sources
src/gallium/drivers/radeonsi/cik_sdma.c [new file with mode: 0644]
src/gallium/drivers/radeonsi/si_dma.c
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_shaders.c
src/gallium/drivers/radeonsi/sid.h
src/gallium/drivers/rbug/rbug_public.h
src/gallium/drivers/softpipe/sp_public.h
src/gallium/drivers/softpipe/sp_query.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_state_sampler.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_sample.h
src/gallium/drivers/softpipe/sp_tex_tile_cache.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.h
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/svga/svga_tgsi_insn.c
src/gallium/drivers/trace/tr_context.c
src/gallium/drivers/trace/tr_dump_state.c
src/gallium/drivers/trace/tr_public.h
src/gallium/drivers/vc4/Android.mk [new file with mode: 0644]
src/gallium/drivers/vc4/Makefile.am
src/gallium/drivers/vc4/Makefile.sources
src/gallium/drivers/vc4/kernel/Makefile.am [deleted file]
src/gallium/drivers/vc4/kernel/Makefile.sources [deleted file]
src/gallium/drivers/vc4/kernel/vc4_drv.h
src/gallium/drivers/vc4/kernel/vc4_gem.c
src/gallium/drivers/vc4/kernel/vc4_packet.h [new file with mode: 0644]
src/gallium/drivers/vc4/kernel/vc4_render_cl.c [new file with mode: 0644]
src/gallium/drivers/vc4/kernel/vc4_validate.c
src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c
src/gallium/drivers/vc4/vc4_blit.c
src/gallium/drivers/vc4/vc4_bufmgr.c
src/gallium/drivers/vc4/vc4_bufmgr.h
src/gallium/drivers/vc4/vc4_cl.h
src/gallium/drivers/vc4/vc4_cl_dump.c
src/gallium/drivers/vc4/vc4_context.c
src/gallium/drivers/vc4/vc4_context.h
src/gallium/drivers/vc4/vc4_draw.c
src/gallium/drivers/vc4/vc4_drm.h
src/gallium/drivers/vc4/vc4_job.c
src/gallium/drivers/vc4/vc4_opt_algebraic.c
src/gallium/drivers/vc4/vc4_opt_constant_folding.c
src/gallium/drivers/vc4/vc4_opt_copy_propagation.c
src/gallium/drivers/vc4/vc4_opt_cse.c
src/gallium/drivers/vc4/vc4_opt_dead_code.c
src/gallium/drivers/vc4/vc4_opt_small_immediates.c
src/gallium/drivers/vc4/vc4_opt_vpm_writes.c
src/gallium/drivers/vc4/vc4_packet.h [deleted file]
src/gallium/drivers/vc4/vc4_program.c
src/gallium/drivers/vc4/vc4_qir.c
src/gallium/drivers/vc4/vc4_qir.h
src/gallium/drivers/vc4/vc4_qir_lower_uniforms.c
src/gallium/drivers/vc4/vc4_qpu_emit.c
src/gallium/drivers/vc4/vc4_qpu_schedule.c
src/gallium/drivers/vc4/vc4_query.c
src/gallium/drivers/vc4/vc4_register_allocate.c
src/gallium/drivers/vc4/vc4_reorder_uniforms.c
src/gallium/drivers/vc4/vc4_resource.c
src/gallium/drivers/vc4/vc4_resource.h
src/gallium/drivers/vc4/vc4_screen.c
src/gallium/drivers/vc4/vc4_screen.h
src/gallium/drivers/vc4/vc4_simulator.c
src/gallium/drivers/vc4/vc4_simulator_validate.h
src/gallium/drivers/vc4/vc4_state.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_shader_tokens.h
src/gallium/include/pipe/p_state.h
src/gallium/include/state_tracker/st_api.h
src/gallium/state_trackers/clover/api/interop.cpp
src/gallium/state_trackers/clover/core/error.hpp
src/gallium/state_trackers/clover/core/event.cpp
src/gallium/state_trackers/clover/core/event.hpp
src/gallium/state_trackers/clover/core/memory.cpp
src/gallium/state_trackers/clover/core/queue.cpp
src/gallium/state_trackers/clover/core/queue.hpp
src/gallium/state_trackers/clover/core/resource.cpp
src/gallium/state_trackers/clover/llvm/invocation.cpp
src/gallium/state_trackers/dri/Android.mk [new file with mode: 0644]
src/gallium/state_trackers/dri/dri2.c
src/gallium/state_trackers/dri/dri_context.c
src/gallium/state_trackers/dri/dri_screen.h
src/gallium/state_trackers/dri/drisw.c
src/gallium/state_trackers/glx/xlib/glx_api.c
src/gallium/state_trackers/hgl/hgl.c
src/gallium/state_trackers/hgl/hgl_context.h
src/gallium/state_trackers/nine/nine_ff.c
src/gallium/state_trackers/nine/nine_shader.c
src/gallium/state_trackers/wgl/Makefile.sources
src/gallium/state_trackers/wgl/stw_context.c
src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
src/gallium/state_trackers/wgl/stw_getprocaddress.c
src/gallium/state_trackers/wgl/stw_nopfuncs.c [new file with mode: 0644]
src/gallium/state_trackers/wgl/stw_nopfuncs.h [new file with mode: 0644]
src/gallium/state_trackers/wgl/stw_pixelformat.c
src/gallium/state_trackers/wgl/stw_st.c
src/gallium/state_trackers/xa/xa_tracker.c
src/gallium/targets/d3dadapter9/Makefile.am
src/gallium/targets/dri/Android.mk [new file with mode: 0644]
src/gallium/targets/dri/Makefile.am
src/gallium/targets/haiku-softpipe/GalliumContext.cpp
src/gallium/targets/haiku-softpipe/GalliumContext.h
src/gallium/targets/libgl-xlib/Makefile.am
src/gallium/targets/osmesa/Makefile.am
src/gallium/targets/pipe-loader/Makefile.am
src/gallium/tests/trivial/quad-tex.c
src/gallium/winsys/sw/android/Android.mk [deleted file]
src/gallium/winsys/sw/android/android_sw_winsys.cpp [deleted file]
src/gallium/winsys/sw/android/android_sw_winsys.h [deleted file]
src/gallium/winsys/sw/dri/Android.mk [new file with mode: 0644]
src/gallium/winsys/sw/hgl/hgl_sw_winsys.h
src/gallium/winsys/sw/kms-dri/Android.mk [new file with mode: 0644]
src/gallium/winsys/vc4/drm/Android.mk [new file with mode: 0644]
src/gbm/Makefile.am
src/gbm/backends/dri/gbm_dri.c
src/glsl/Android.mk
src/glsl/Makefile.am
src/glsl/SConscript
src/glsl/ast_array_index.cpp
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/builtin_functions.cpp
src/glsl/builtin_variables.cpp
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_types.cpp
src/glsl/glsl_types.h
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_function.cpp
src/glsl/ir_hierarchical_visitor.cpp
src/glsl/ir_hierarchical_visitor.h
src/glsl/ir_hv_accept.cpp
src/glsl/ir_print_visitor.cpp
src/glsl/ir_print_visitor.h
src/glsl/ir_reader.cpp
src/glsl/ir_uniform.h
src/glsl/ir_visitor.h
src/glsl/link_atomics.cpp
src/glsl/link_uniform_initializers.cpp
src/glsl/link_uniforms.cpp
src/glsl/link_varyings.cpp
src/glsl/linker.cpp
src/glsl/lower_clip_distance.cpp
src/glsl/main.cpp
src/glsl/nir/glsl_to_nir.cpp
src/glsl/nir/nir_intrinsics.h
src/glsl/nir/nir_lower_atomics.c
src/glsl/nir/nir_lower_io.c
src/glsl/nir/nir_lower_phis_to_scalar.c
src/glsl/nir/nir_lower_samplers.cpp
src/glsl/nir/nir_opt_algebraic.py
src/glsl/nir/nir_opt_peephole_ffma.c
src/glsl/nir/nir_opt_peephole_select.c
src/glsl/standalone_scaffolding.cpp
src/glsl/tests/common.c [deleted file]
src/glsl/tests/set_uniform_initializer_tests.cpp
src/glx/SConscript
src/glx/dri2_glx.c
src/glx/dri3_glx.c
src/hgl/GLDispatcher.cpp
src/hgl/GLDispatcher.h
src/hgl/SConscript
src/loader/Android.mk
src/loader/Makefile.am
src/loader/loader.c
src/loader/loader.h
src/mapi/glapi/gen/AMD_performance_monitor.xml
src/mapi/glapi/gen/APPLE_object_purgeable.xml
src/mapi/glapi/gen/APPLE_vertex_array_object.xml
src/mapi/glapi/gen/ARB_ES2_compatibility.xml
src/mapi/glapi/gen/ARB_base_instance.xml
src/mapi/glapi/gen/ARB_blend_func_extended.xml
src/mapi/glapi/gen/ARB_clear_buffer_object.xml
src/mapi/glapi/gen/ARB_clear_texture.xml
src/mapi/glapi/gen/ARB_clip_control.xml
src/mapi/glapi/gen/ARB_compute_shader.xml
src/mapi/glapi/gen/ARB_copy_buffer.xml
src/mapi/glapi/gen/ARB_copy_image.xml
src/mapi/glapi/gen/ARB_direct_state_access.xml
src/mapi/glapi/gen/ARB_draw_buffers_blend.xml
src/mapi/glapi/gen/ARB_draw_elements_base_vertex.xml
src/mapi/glapi/gen/ARB_draw_indirect.xml
src/mapi/glapi/gen/ARB_draw_instanced.xml
src/mapi/glapi/gen/ARB_framebuffer_no_attachments.xml [new file with mode: 0644]
src/mapi/glapi/gen/ARB_framebuffer_object.xml
src/mapi/glapi/gen/ARB_geometry_shader4.xml
src/mapi/glapi/gen/ARB_get_program_binary.xml
src/mapi/glapi/gen/ARB_gpu_shader_fp64.xml
src/mapi/glapi/gen/ARB_internalformat_query.xml
src/mapi/glapi/gen/ARB_invalidate_subdata.xml
src/mapi/glapi/gen/ARB_map_buffer_range.xml
src/mapi/glapi/gen/ARB_multi_bind.xml
src/mapi/glapi/gen/ARB_program_interface_query.xml
src/mapi/glapi/gen/ARB_robustness.xml
src/mapi/glapi/gen/ARB_sampler_objects.xml
src/mapi/glapi/gen/ARB_separate_shader_objects.xml
src/mapi/glapi/gen/ARB_shader_atomic_counters.xml
src/mapi/glapi/gen/ARB_shader_image_load_store.xml
src/mapi/glapi/gen/ARB_sync.xml
src/mapi/glapi/gen/ARB_texture_buffer_range.xml
src/mapi/glapi/gen/ARB_texture_multisample.xml
src/mapi/glapi/gen/ARB_texture_storage.xml
src/mapi/glapi/gen/ARB_texture_storage_multisample.xml
src/mapi/glapi/gen/ARB_texture_view.xml
src/mapi/glapi/gen/ARB_uniform_buffer_object.xml
src/mapi/glapi/gen/ARB_vertex_array_object.xml
src/mapi/glapi/gen/ARB_vertex_attrib_64bit.xml
src/mapi/glapi/gen/ARB_vertex_attrib_binding.xml
src/mapi/glapi/gen/ARB_vertex_type_2_10_10_10_rev.xml
src/mapi/glapi/gen/ARB_viewport_array.xml
src/mapi/glapi/gen/EXT_framebuffer_object.xml
src/mapi/glapi/gen/EXT_gpu_shader4.xml
src/mapi/glapi/gen/EXT_provoking_vertex.xml
src/mapi/glapi/gen/EXT_separate_shader_objects.xml
src/mapi/glapi/gen/EXT_texture_integer.xml
src/mapi/glapi/gen/EXT_transform_feedback.xml
src/mapi/glapi/gen/GL3x.xml
src/mapi/glapi/gen/GL4x.xml
src/mapi/glapi/gen/INTEL_performance_query.xml
src/mapi/glapi/gen/KHR_debug.xml
src/mapi/glapi/gen/Makefile.am
src/mapi/glapi/gen/NV_primitive_restart.xml
src/mapi/glapi/gen/NV_texture_barrier.xml
src/mapi/glapi/gen/NV_vdpau_interop.xml
src/mapi/glapi/gen/OES_EGL_image.xml
src/mapi/glapi/gen/OES_fixed_point.xml
src/mapi/glapi/gen/OES_single_precision.xml
src/mapi/glapi/gen/apiexec.py [new file with mode: 0644]
src/mapi/glapi/gen/es_EXT.xml
src/mapi/glapi/gen/glX_proto_recv.py
src/mapi/glapi/gen/glX_proto_send.py
src/mapi/glapi/gen/glX_proto_size.py
src/mapi/glapi/gen/glX_server_table.py
src/mapi/glapi/gen/gl_API.dtd
src/mapi/glapi/gen/gl_API.xml
src/mapi/glapi/gen/gl_SPARC_asm.py
src/mapi/glapi/gen/gl_XML.py
src/mapi/glapi/gen/gl_and_es_API.xml
src/mapi/glapi/gen/gl_apitemp.py
src/mapi/glapi/gen/gl_enums.py
src/mapi/glapi/gen/gl_genexec.py
src/mapi/glapi/gen/gl_gentable.py
src/mapi/glapi/gen/gl_procs.py
src/mapi/glapi/gen/gl_table.py
src/mapi/glapi/gen/gl_x86-64_asm.py
src/mapi/glapi/gen/gl_x86_asm.py
src/mapi/glapi/gen/remap_helper.py
src/mapi/glapi/gen/static_data.py [new file with mode: 0644]
src/mapi/glapi/glapi_priv.h
src/mapi/glapi/tests/check_table.cpp
src/mesa/Android.gen.mk
src/mesa/Android.libmesa_glsl_utils.mk
src/mesa/Makefile.am
src/mesa/drivers/SConscript
src/mesa/drivers/common/driverfuncs.c
src/mesa/drivers/common/meta.c
src/mesa/drivers/common/meta_blit.c
src/mesa/drivers/common/meta_tex_subimage.c
src/mesa/drivers/dri/Makefile.am
src/mesa/drivers/dri/common/Android.mk
src/mesa/drivers/dri/common/Makefile.am
src/mesa/drivers/dri/common/Makefile.sources
src/mesa/drivers/dri/common/SConscript
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_fragprog.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i915/intel_fbo.c
src/mesa/drivers/dri/i965/Makefile.am
src/mesa/drivers/dri/i965/Makefile.sources
src/mesa/drivers/dri/i965/brw_blorp_blit_eu.cpp
src/mesa/drivers/dri/i965/brw_cfg.cpp
src/mesa/drivers/dri/i965/brw_cfg.h
src/mesa/drivers/dri/i965/brw_clear.c
src/mesa/drivers/dri/i965/brw_clip_state.c
src/mesa/drivers/dri/i965/brw_compute.c
src/mesa/drivers/dri/i965/brw_conditional_render.c [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_cs.cpp
src/mesa/drivers/dri/i965/brw_dead_control_flow.cpp
src/mesa/drivers/dri/i965/brw_dead_control_flow.h
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_disasm.c
src/mesa/drivers/dri/i965/brw_draw.c
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_compact.c
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_builder.h [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
src/mesa/drivers/dri/i965/brw_fs_cse.cpp
src/mesa/drivers/dri/i965/brw_fs_fp.cpp [deleted file]
src/mesa/drivers/dri/i965/brw_fs_generator.cpp
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp
src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_gs_surface_state.c
src/mesa/drivers/dri/i965/brw_inst.h
src/mesa/drivers/dri/i965/brw_ir_fs.h
src/mesa/drivers/dri/i965/brw_ir_vec4.h
src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
src/mesa/drivers/dri/i965/brw_meta_fast_clear.c
src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c
src/mesa/drivers/dri/i965/brw_misc_state.c
src/mesa/drivers/dri/i965/brw_nir.c
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_queryobj.c
src/mesa/drivers/dri/i965/brw_reg.h
src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
src/mesa/drivers/dri/i965/brw_sf_state.c
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_shader.h
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_batch.c
src/mesa/drivers/dri/i965/brw_state_dump.c
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_surface_formats.c
src/mesa/drivers/dri/i965/brw_tex_layout.c
src/mesa/drivers/dri/i965/brw_util.h
src/mesa/drivers/dri/i965/brw_vec4.cpp
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_cse.cpp
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h
src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_vp.cpp
src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h
src/mesa/drivers/dri/i965/brw_vs_surface_state.c
src/mesa/drivers/dri/i965/brw_vue_map.c [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_clip_state.c
src/mesa/drivers/dri/i965/gen6_gs_visitor.h
src/mesa/drivers/dri/i965/gen6_multisample_state.c
src/mesa/drivers/dri/i965/gen6_queryobj.c
src/mesa/drivers/dri/i965/gen6_scissor_state.c
src/mesa/drivers/dri/i965/gen6_sf_state.c
src/mesa/drivers/dri/i965/gen6_viewport_state.c
src/mesa/drivers/dri/i965/gen6_wm_state.c
src/mesa/drivers/dri/i965/gen7_gs_state.c
src/mesa/drivers/dri/i965/gen7_sf_state.c
src/mesa/drivers/dri/i965/gen7_viewport_state.c
src/mesa/drivers/dri/i965/gen7_vs_state.c
src/mesa/drivers/dri/i965/gen7_wm_state.c
src/mesa/drivers/dri/i965/gen8_depth_state.c
src/mesa/drivers/dri/i965/gen8_gs_state.c
src/mesa/drivers/dri/i965/gen8_ps_state.c
src/mesa/drivers/dri/i965/gen8_sf_state.c
src/mesa/drivers/dri/i965/gen8_surface_state.c
src/mesa/drivers/dri/i965/gen8_viewport_state.c
src/mesa/drivers/dri/i965/gen8_vs_state.c
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_blit.c
src/mesa/drivers/dri/i965/intel_blit.h
src/mesa/drivers/dri/i965/intel_debug.c
src/mesa/drivers/dri/i965/intel_debug.h
src/mesa/drivers/dri/i965/intel_extensions.c
src/mesa/drivers/dri/i965/intel_fbo.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.h
src/mesa/drivers/dri/i965/intel_pixel_draw.c
src/mesa/drivers/dri/i965/intel_pixel_read.c
src/mesa/drivers/dri/i965/intel_reg.h
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/i965/intel_screen.h
src/mesa/drivers/dri/i965/intel_tex.c
src/mesa/drivers/dri/i965/intel_tex.h
src/mesa/drivers/dri/i965/intel_tex_image.c
src/mesa/drivers/dri/i965/intel_tex_validate.c
src/mesa/drivers/dri/i965/test_fs_cmod_propagation.cpp
src/mesa/drivers/dri/i965/test_fs_saturate_propagation.cpp
src/mesa/drivers/dri/i965/test_vec4_copy_propagation.cpp
src/mesa/drivers/dri/i965/test_vec4_register_coalesce.cpp
src/mesa/drivers/dri/nouveau/nouveau_fbo.c
src/mesa/drivers/dri/nouveau/nv10_state_tnl.c
src/mesa/drivers/dri/nouveau/nv20_state_tnl.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/radeon/radeon_common.c
src/mesa/drivers/dri/radeon/radeon_fbo.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/swrast/swrast.c
src/mesa/drivers/haiku/swrast/SConscript [deleted file]
src/mesa/drivers/haiku/swrast/SoftwareRast.cpp [deleted file]
src/mesa/drivers/haiku/swrast/SoftwareRast.h [deleted file]
src/mesa/drivers/haiku/swrast/SoftwareRast.rdef [deleted file]
src/mesa/drivers/osmesa/Makefile.am
src/mesa/drivers/x11/Makefile.am
src/mesa/main/api_exec.h
src/mesa/main/api_loopback.c
src/mesa/main/attrib.c
src/mesa/main/blend.c
src/mesa/main/blend.h
src/mesa/main/blit.c
src/mesa/main/blit.h
src/mesa/main/buffers.c
src/mesa/main/buffers.h
src/mesa/main/clear.c
src/mesa/main/clear.h
src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/copyimage.c
src/mesa/main/depth.c
src/mesa/main/dlist.c
src/mesa/main/errors.c
src/mesa/main/errors.h
src/mesa/main/extensions.c
src/mesa/main/fbobject.c
src/mesa/main/fbobject.h
src/mesa/main/formats.c
src/mesa/main/framebuffer.c
src/mesa/main/framebuffer.h
src/mesa/main/get.c
src/mesa/main/get_hash_params.py
src/mesa/main/getstring.c
src/mesa/main/glformats.c
src/mesa/main/glformats.h
src/mesa/main/glheader.h
src/mesa/main/hash.c
src/mesa/main/hash.h
src/mesa/main/imports.h
src/mesa/main/mtypes.h
src/mesa/main/objectlabel.c
src/mesa/main/pipelineobj.c
src/mesa/main/pipelineobj.h
src/mesa/main/program_resource.c
src/mesa/main/readpix.c
src/mesa/main/readpix.h
src/mesa/main/shader_query.cpp
src/mesa/main/shaderapi.c
src/mesa/main/shaderobj.c
src/mesa/main/shared.c
src/mesa/main/state.c
src/mesa/main/tests/dispatch_sanity.cpp
src/mesa/main/texenv.c
src/mesa/main/teximage.c
src/mesa/main/texparam.c
src/mesa/main/textureview.c
src/mesa/main/textureview.h
src/mesa/main/uniform_query.cpp
src/mesa/main/uniforms.h
src/mesa/main/varray.c
src/mesa/main/version.c
src/mesa/main/version.h
src/mesa/main/vtxfmt.c
src/mesa/program/dummy_errors.c [new file with mode: 0644]
src/mesa/program/ir_to_mesa.cpp
src/mesa/program/prog_execute.c
src/mesa/program/prog_instruction.c
src/mesa/program/prog_instruction.h
src/mesa/program/prog_optimize.c
src/mesa/program/prog_print.c
src/mesa/program/prog_statevars.c
src/mesa/program/prog_to_nir.c
src/mesa/program/program.c
src/mesa/program/program_parse.y
src/mesa/program/program_parse_extra.c
src/mesa/program/programopt.c
src/mesa/state_tracker/st_atom_framebuffer.c
src/mesa/state_tracker/st_atom_shader.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_cb_blit.c
src/mesa/state_tracker/st_cb_clear.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_drawtex.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_flush.c
src/mesa/state_tracker/st_cb_flush.h
src/mesa/state_tracker/st_cb_program.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_draw.c
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.h
src/mesa/state_tracker/st_manager.c
src/mesa/state_tracker/st_mesa_to_tgsi.c
src/mesa/state_tracker/st_program.c
src/mesa/state_tracker/st_program.h
src/mesa/swrast/s_texrender.c
src/mesa/tnl/t_context.c
src/mesa/vbo/vbo_exec_array.c
src/util/list.h
src/vulkan/compiler.cpp

index edf52d6fabbbb4aa6f69034701119fa220aacea6..d662d6018e4f115e75ffdb2ce75114f533d5be06 100644 (file)
@@ -68,7 +68,16 @@ LOCAL_CFLAGS += \
 endif
 endif
 
+ifeq ($(MESA_ENABLE_LLVM),true)
+LOCAL_CFLAGS += \
+       -DHAVE_LLVM=0x0305 -DLLVM_VERSION_PATCH=2 \
+       -D__STDC_CONSTANT_MACROS \
+       -D__STDC_FORMAT_MACROS \
+       -D__STDC_LIMIT_MACROS
+endif
+
 LOCAL_CPPFLAGS += \
+       $(if $(filter true,$(MESA_LOLLIPOP_BUILD)),-D_USING_LIBCXX) \
        -Wno-error=non-virtual-dtor \
        -Wno-non-virtual-dtor
 
index b19419ba7c2af110eeeb72924c9be128c834914e..69e0d33f1aa601df1b8585349d553691d6c6f064 100644 (file)
@@ -24,7 +24,7 @@
 # BOARD_GPU_DRIVERS should be defined.  The valid values are
 #
 #   classic drivers: i915 i965
-#   gallium drivers: swrast freedreno i915g ilo nouveau r300g r600g radeonsi vmwgfx
+#   gallium drivers: swrast freedreno i915g ilo nouveau r300g r600g radeonsi vc4 vmwgfx
 #
 # The main target is libGLES_mesa.  For each classic driver enabled, a DRI
 # module will also be built.  DRI modules will be loaded by libGLES_mesa.
@@ -48,7 +48,7 @@ MESA_PYTHON2 := python
 DRM_GRALLOC_TOP := hardware/drm_gralloc
 
 classic_drivers := i915 i965
-gallium_drivers := swrast freedreno i915g ilo nouveau r300g r600g radeonsi vmwgfx
+gallium_drivers := swrast freedreno i915g ilo nouveau r300g r600g radeonsi vmwgfx vc4
 
 MESA_GPU_DRIVERS := $(strip $(BOARD_GPU_DRIVERS))
 
@@ -80,6 +80,8 @@ else
 MESA_BUILD_GALLIUM := false
 endif
 
+MESA_ENABLE_LLVM := $(if $(filter radeonsi,$(MESA_GPU_DRIVERS)),true,false)
+
 # add subdirectories
 ifneq ($(strip $(MESA_GPU_DRIVERS)),)
 
@@ -89,13 +91,9 @@ SUBDIRS := \
        src/glsl \
        src/mesa \
        src/util \
-       src/egl/main
-
-ifeq ($(strip $(MESA_BUILD_CLASSIC)),true)
-SUBDIRS += \
+       src/egl/main \
        src/egl/drivers/dri2 \
        src/mesa/drivers/dri
-endif
 
 ifeq ($(strip $(MESA_BUILD_GALLIUM)),true)
 SUBDIRS += src/gallium
index 20681638e21bbbca27559f4bef3cbfacc531e4f3..d08b0def7d097fbd013f47eda16c4ad269ab4cce 100644 (file)
@@ -13,3 +13,4 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/*/SHARED_LIBRARIES/libGLES_mesa_int
 $(call add-clean-step, rm -rf $(HOST_OUT_release)/*/EXECUTABLES/mesa_*_intermediates)
 $(call add-clean-step, rm -rf $(HOST_OUT_release)/*/EXECUTABLES/glsl_compiler_intermediates)
 $(call add-clean-step, rm -rf $(HOST_OUT_release)/*/STATIC_LIBRARIES/libmesa_*_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/*/SHARED_LIBRARIES/*_dri_intermediates)
diff --git a/VERSION b/VERSION
index 8d3030650220b7ea9a79a9eefb8b1b42cd91ecaf..1edd8fc00e5d3e1c0f5e51044b81acb551627e47 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-10.6.0-devel
+10.7.0-devel
index 1f23de4d1ce4c360ce2630e8e25cf8e112956d46..33aacd2ec06aae5756661694b4a20f4cf22164ba 100644 (file)
@@ -649,6 +649,7 @@ if test "x$enable_asm" = xyes; then
 fi
 
 AC_CHECK_HEADER([xlocale.h], [DEFINES="$DEFINES -DHAVE_XLOCALE_H"])
+AC_CHECK_HEADER([sys/sysctl.h], [DEFINES="$DEFINES -DHAVE_SYS_SYSCTL_H"])
 AC_CHECK_FUNC([strtof], [DEFINES="$DEFINES -DHAVE_STRTOF"])
 
 dnl Check to see if dlopen is in default libraries (like Solaris, which
@@ -713,15 +714,15 @@ AC_ARG_ENABLE([opengl],
     [enable_opengl="$enableval"],
     [enable_opengl=yes])
 AC_ARG_ENABLE([gles1],
-    [AS_HELP_STRING([--enable-gles1],
-        [enable support for OpenGL ES 1.x API @<:@default=disabled@:>@])],
+    [AS_HELP_STRING([--disable-gles1],
+        [disable support for OpenGL ES 1.x API @<:@default=enabled@:>@])],
     [enable_gles1="$enableval"],
-    [enable_gles1=no])
+    [enable_gles1=yes])
 AC_ARG_ENABLE([gles2],
-    [AS_HELP_STRING([--enable-gles2],
-        [enable support for OpenGL ES 2.x API @<:@default=disabled@:>@])],
+    [AS_HELP_STRING([--disable-gles2],
+        [disable support for OpenGL ES 2.x API @<:@default=enabled@:>@])],
     [enable_gles2="$enableval"],
-    [enable_gles2=no])
+    [enable_gles2=yes])
 
 AC_ARG_ENABLE([dri],
     [AS_HELP_STRING([--enable-dri],
@@ -940,12 +941,6 @@ x*yes*yes*)
     ;;
 esac
 
-# Building Xlib-GLX requires shared glapi to be disabled.
-if test "x$enable_xlib_glx" = xyes; then
-    AC_MSG_NOTICE([Shared GLAPI should not used with Xlib-GLX, disabling])
-    enable_shared_glapi=no
-fi
-
 AM_CONDITIONAL(HAVE_SHARED_GLAPI, test "x$enable_shared_glapi" = xyes)
 
 # Build the pipe-drivers as separate libraries/modules.
@@ -1516,7 +1511,6 @@ if test "x$enable_gbm" = xyes; then
     fi
 
     if test "x$enable_dri" = xyes; then
-        GBM_BACKEND_DIRS="$GBM_BACKEND_DIRS dri"
         if test "x$enable_shared_glapi" = xno; then
             AC_MSG_ERROR([gbm_dri requires --enable-shared-glapi])
         fi
@@ -1553,8 +1547,15 @@ if test "x$enable_egl" = xyes; then
 
     if test "$enable_static" != yes; then
         if test "x$enable_dri" = xyes; then
-           HAVE_EGL_DRIVER_DRI2=1
-       fi
+            HAVE_EGL_DRIVER_DRI2=1
+            if test "x$enable_shared_glapi" = xno; then
+                AC_MSG_ERROR([egl_dri2 requires --enable-shared-glapi])
+            fi
+        else
+            # Avoid building an "empty" libEGL. Drop/update this
+            # when other backends (haiku?) come along.
+            AC_MSG_ERROR([egl requires --enable-dri])
+        fi
 
     fi
 fi
@@ -1782,6 +1783,11 @@ for plat in $egl_platforms; do
                        AC_MSG_ERROR([EGL platform drm requires libdrm >= $LIBDRM_REQUIRED])
                ;;
 
+       surfaceless)
+               test "x$have_libdrm" != xyes &&
+                       AC_MSG_ERROR([EGL platform surfaceless requires libdrm >= $LIBDRM_REQUIRED])
+               ;;
+
        android|gdi|null)
                ;;
 
@@ -1811,6 +1817,7 @@ fi
 AM_CONDITIONAL(HAVE_EGL_PLATFORM_X11, echo "$egl_platforms" | grep -q 'x11')
 AM_CONDITIONAL(HAVE_EGL_PLATFORM_WAYLAND, echo "$egl_platforms" | grep -q 'wayland')
 AM_CONDITIONAL(HAVE_EGL_PLATFORM_DRM, echo "$egl_platforms" | grep -q 'drm')
+AM_CONDITIONAL(HAVE_EGL_PLATFORM_SURFACELESS, echo "$egl_platforms" | grep -q 'surfaceless')
 AM_CONDITIONAL(HAVE_EGL_PLATFORM_NULL, echo "$egl_platforms" | grep -q 'null')
 
 AM_CONDITIONAL(HAVE_EGL_DRIVER_DRI2, test "x$HAVE_EGL_DRIVER_DRI2" != "x")
@@ -1926,10 +1933,7 @@ if test "x$enable_gallium_llvm" = xyes; then
             AC_MSG_ERROR([LLVM $LLVM_REQUIRED_VERSION_MAJOR.$LLVM_REQUIRED_VERSION_MINOR or newer is required])
         fi
 
-        LLVM_COMPONENTS="engine bitwriter"
-        if $LLVM_CONFIG --components | grep -qw 'mcjit'; then
-            LLVM_COMPONENTS="${LLVM_COMPONENTS} mcjit"
-        fi
+        LLVM_COMPONENTS="engine bitwriter mcjit mcdisassembler"
 
         if test "x$enable_opencl" = xyes; then
             llvm_check_version_for "3" "5" "0" "opencl"
@@ -1937,7 +1941,7 @@ if test "x$enable_gallium_llvm" = xyes; then
             LLVM_COMPONENTS="${LLVM_COMPONENTS} all-targets ipo linker instrumentation"
             LLVM_COMPONENTS="${LLVM_COMPONENTS} irreader option objcarcopts profiledata"
         fi
-        DEFINES="${DEFINES} -DHAVE_LLVM=0x0$LLVM_VERSION_INT -DLLVM_VERSION_PATCH=$LLVM_VERSION_PATCH"
+        DEFINES="${DEFINES} -DHAVE_LLVM=0x0$LLVM_VERSION_INT -DMESA_LLVM_VERSION_PATCH=$LLVM_VERSION_PATCH"
         MESA_LLVM=1
 
         dnl Check for Clang internal headers
@@ -2056,16 +2060,19 @@ require_egl_drm() {
 }
 
 radeon_llvm_check() {
+    if test ${LLVM_VERSION_INT} -lt 307; then
+        amdgpu_llvm_target_name='r600'
+    else
+        amdgpu_llvm_target_name='amdgpu'
+    fi
     if test "x$enable_gallium_llvm" != "xyes"; then
         AC_MSG_ERROR([--enable-gallium-llvm is required when building $1])
     fi
     llvm_check_version_for "3" "4" "2" $1 
-    if test true && $LLVM_CONFIG --targets-built | grep -qvw 'R600' ; then
-        AC_MSG_ERROR([LLVM R600 Target not enabled.  You can enable it when building the LLVM
-                      sources with the --enable-experimental-targets=R600
-                      configure flag])
+    if test true && $LLVM_CONFIG --targets-built | grep -iqvw $amdgpu_llvm_target_name ; then
+        AC_MSG_ERROR([LLVM $amdgpu_llvm_target_name not enabled in your LLVM build.])
     fi
-    LLVM_COMPONENTS="${LLVM_COMPONENTS} r600 bitreader ipo"
+    LLVM_COMPONENTS="${LLVM_COMPONENTS} $amdgpu_llvm_target_name bitreader ipo"
     NEED_RADEON_LLVM=yes
     if test "x$have_libelf" != xyes; then
        AC_MSG_ERROR([$1 requires libelf when using llvm])
@@ -2365,7 +2372,6 @@ AC_CONFIG_FILES([Makefile
                src/gallium/drivers/svga/Makefile
                src/gallium/drivers/trace/Makefile
                src/gallium/drivers/vc4/Makefile
-               src/gallium/drivers/vc4/kernel/Makefile
                src/gallium/state_trackers/clover/Makefile
                src/gallium/state_trackers/dri/Makefile
                src/gallium/state_trackers/glx/xlib/Makefile
index 7a7c1bd96897d96412ba98a8c91b02d896a5420b..220bcc8742faa8bbb4260c9bf66a11348758fd33 100644 (file)
@@ -98,13 +98,13 @@ GL 4.0, GLSL 4.00:
   GL_ARB_draw_indirect                                 DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_gpu_shader5                                   DONE (i965, nvc0)
   - 'precise' qualifier                                DONE
-  - Dynamically uniform sampler array indices          DONE (r600)
+  - Dynamically uniform sampler array indices          DONE (r600, softpipe)
   - Dynamically uniform UBO array indices              DONE (r600)
   - Implicit signed -> unsigned conversions            DONE
   - Fused multiply-add                                 DONE ()
-  - Packing/bitfield/conversion functions              DONE (r600, radeonsi)
-  - Enhanced textureGather                             DONE (r600, radeonsi)
-  - Geometry shader instancing                         DONE (r600)
+  - Packing/bitfield/conversion functions              DONE (r600, radeonsi, softpipe)
+  - Enhanced textureGather                             DONE (r600, radeonsi, softpipe)
+  - Geometry shader instancing                         DONE (r600, llvmpipe, softpipe)
   - Geometry shader multiple streams                   DONE ()
   - Enhanced per-sample shading                        DONE (r600, radeonsi)
   - Interpolation functions                            DONE (r600)
@@ -115,10 +115,10 @@ GL 4.0, GLSL 4.00:
   GL_ARB_tessellation_shader                           started (Chris, Ilia)
   GL_ARB_texture_buffer_object_rgb32                   DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_texture_cube_map_array                        DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
-  GL_ARB_texture_gather                                DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe)
+  GL_ARB_texture_gather                                DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_texture_query_lod                             DONE (i965, nv50, nvc0, r600, radeonsi)
-  GL_ARB_transform_feedback2                           DONE (i965, nv50, nvc0, r600, radeonsi)
-  GL_ARB_transform_feedback3                           DONE (i965, nv50, nvc0, r600, radeonsi)
+  GL_ARB_transform_feedback2                           DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
+  GL_ARB_transform_feedback3                           DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
 
 
 GL 4.1, GLSL 4.10:
@@ -137,7 +137,7 @@ GL 4.2, GLSL 4.20:
   GL_ARB_compressed_texture_pixel_storage              DONE (all drivers)
   GL_ARB_shader_atomic_counters                        DONE (i965)
   GL_ARB_texture_storage                               DONE (all drivers)
-  GL_ARB_transform_feedback_instanced                  DONE (i965, nv50, nvc0, r600, radeonsi)
+  GL_ARB_transform_feedback_instanced                  DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_base_instance                                 DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_shader_image_load_store                       in progress (curro)
   GL_ARB_conservative_depth                            DONE (all drivers that support GLSL 1.30)
@@ -153,23 +153,23 @@ GL 4.3, GLSL 4.30:
   GL_ARB_ES3_compatibility                             DONE (all drivers that support GLSL 3.30)
   GL_ARB_clear_buffer_object                           DONE (all drivers)
   GL_ARB_compute_shader                                in progress (jljusten)
-  GL_ARB_copy_image                                    DONE (i965)
+  GL_ARB_copy_image                                    DONE (i965) (gallium - in progress, VMware)
   GL_KHR_debug                                         DONE (all drivers)
   GL_ARB_explicit_uniform_location                     DONE (all drivers that support GLSL)
   GL_ARB_fragment_layer_viewport                       DONE (nv50, nvc0, r600, llvmpipe)
-  GL_ARB_framebuffer_no_attachments                    not started
+  GL_ARB_framebuffer_no_attachments                    DONE (i965)
   GL_ARB_internalformat_query2                         not started
   GL_ARB_invalidate_subdata                            DONE (all drivers)
   GL_ARB_multi_draw_indirect                           DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_program_interface_query                       DONE (all drivers)
   GL_ARB_robust_buffer_access_behavior                 not started
   GL_ARB_shader_image_size                             in progress (Martin Peres)
-  GL_ARB_shader_storage_buffer_object                  not started
+  GL_ARB_shader_storage_buffer_object                  in progress (Iago Toral, Samuel Iglesias)
   GL_ARB_stencil_texturing                             DONE (i965/gen8+, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_texture_buffer_range                          DONE (nv50, nvc0, i965, r600, radeonsi, llvmpipe)
   GL_ARB_texture_query_levels                          DONE (all drivers that support GLSL 1.30)
   GL_ARB_texture_storage_multisample                   DONE (all drivers that support GL_ARB_texture_multisample)
-  GL_ARB_texture_view                                  DONE (i965, nv50, nvc0)
+  GL_ARB_texture_view                                  DONE (i965, nv50, nvc0, llvmpipe, softpipe)
   GL_ARB_vertex_attrib_binding                         DONE (all drivers)
 
 
@@ -177,7 +177,7 @@ GL 4.4, GLSL 4.40:
 
   GL_MAX_VERTEX_ATTRIB_STRIDE                          DONE (all drivers)
   GL_ARB_buffer_storage                                DONE (i965, nv50, nvc0, r600, radeonsi)
-  GL_ARB_clear_texture                                 DONE (i965)
+  GL_ARB_clear_texture                                 DONE (i965) (gallium - in progress, VMware)
   GL_ARB_enhanced_layouts                              not started
   GL_ARB_multi_bind                                    DONE (all drivers)
   GL_ARB_query_buffer_object                           not started
@@ -190,12 +190,12 @@ GL 4.5, GLSL 4.50:
   GL_ARB_ES3_1_compatibility                           not started
   GL_ARB_clip_control                                  DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_conditional_render_inverted                   DONE (i965, nv50, nvc0, llvmpipe, softpipe)
-  GL_ARB_cull_distance                                 not started
+  GL_ARB_cull_distance                                 in progress (Tobias)
   GL_ARB_derivative_control                            DONE (i965, nv50, nvc0, r600)
-  GL_ARB_direct_state_access                           started
+  GL_ARB_direct_state_access                           DONE (all drivers)
   - Transform Feedback object                          DONE
   - Buffer object                                      DONE
-  - Framebuffer object                                 started (Laura Ekstrand)
+  - Framebuffer object                                 DONE
   - Renderbuffer object                                DONE
   - Texture object                                     DONE
   - Vertex array object                                DONE
@@ -216,12 +216,12 @@ GLES3.1, GLSL ES 3.1
   GL_ARB_compute_shader                                in progress (jljusten)
   GL_ARB_draw_indirect                                 DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_explicit_uniform_location                     DONE (all drivers that support GLSL)
-  GL_ARB_framebuffer_no_attachments                    not started
+  GL_ARB_framebuffer_no_attachments                    DONE (i965)
   GL_ARB_program_interface_query                       DONE (all drivers)
   GL_ARB_shader_atomic_counters                        DONE (i965)
   GL_ARB_shader_image_load_store                       in progress (curro)
   GL_ARB_shader_image_size                             in progress (Martin Peres)
-  GL_ARB_shader_storage_buffer_object                  not started
+  GL_ARB_shader_storage_buffer_object                  in progress (Iago Toral, Samuel Iglesias)
   GL_ARB_shading_language_packing                      DONE (all drivers)
   GL_ARB_separate_shader_objects                       DONE (all drivers)
   GL_ARB_stencil_texturing                             DONE (i965/gen8+, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
index 8d20eea3c568fdcf63e29b2b701d2a56a3f5778a..8ebf80f40e8019f85124f7e2ad2a58eab3022cec 100644 (file)
 <h1>Development Notes</h1>
 
 
-<h2>Adding Extensions</h2>
-
-<p>
-To add a new GL extension to Mesa you have to do at least the following.
-
 <ul>
-<li>
-   If glext.h doesn't define the extension, edit include/GL/gl.h and add
-   code like this:
-   <pre>
-     #ifndef GL_EXT_the_extension_name
-     #define GL_EXT_the_extension_name 1
-     /* declare the new enum tokens */
-     /* prototype the new functions */
-     /* TYPEDEFS for the new functions */
-     #endif
-   </pre>
-</li>
-<li>
-   In the src/mapi/glapi/gen/ directory, add the new extension functions and
-   enums to the gl_API.xml file.
-   Then, a bunch of source files must be regenerated by executing the
-   corresponding Python scripts.
-</li>
-<li>
-   Add a new entry to the <code>gl_extensions</code> struct in mtypes.h
-</li>
-<li>
-   Update the <code>extensions.c</code> file.
-</li>
-<li>
-   From this point, the best way to proceed is to find another extension,
-   similar to the new one, that's already implemented in Mesa and use it
-   as an example.
-</li>
-<li>
-   If the new extension adds new GL state, the functions in get.c, enable.c
-   and attrib.c will most likely require new code.
-</li>
-<li>
-   The dispatch tests check_table.cpp and dispatch_sanity.cpp
-   should be updated with details about the new extensions functions. These
-   tests are run using 'make check'
-</li>
+<li><a href="#style">Coding Style</a>
+<li><a href="#submitting">Submitting Patches</a>
+<li><a href="#release">Making a New Mesa Release</a>
+<li><a href="#extensions">Adding Extensions</a>
 </ul>
 
 
-
-<h2>Coding Style</h2>
+<h2 id="style">Coding Style</h2>
 
 <p>
-Mesa's code style has changed over the years.  Here's the latest.
+Mesa is over 20 years old and the coding style has evolved over time.
+Some old parts use a style that's a bit out of date.
+If the guidelines below don't cover something, try following the format of
+existing, neighboring code.
 </p>
 
 <p>
-Comment your code!  It's extremely important that open-source code be
-well documented.  Also, strive to write clean, easily understandable code.
+Basic formatting guidelines
 </p>
 
-<p>
-3-space indentation
-</p>
+<ul>
+<li>3-space indentation, no tabs.
+<li>Limit lines to 78 or fewer characters.  The idea is to prevent line
+wrapping in 80-column editors and terminals.  There are exceptions, such
+as if you're defining a large, static table of information.
+<li>Opening braces go on the same line as the if/for/while statement.
+For example:
+<pre>
+   if (condition) {
+      foo;
+   } else {
+      bar;
+   }
+</pre>
 
-<p>
-If you use tabs, set them to 8 columns
-</p>
+<li>Put a space before/after operators.  For example, <tt>a = b + c;</tt>
+and not <tt>a=b+c;</tt>
 
-<p>
-Line width: the preferred width to fill comments and code in Mesa is 78
-columns.  Exceptions are sometimes made for clarity (e.g. tabular data is
-sometimes filled to a much larger width so that extraneous carriage returns
-don't obscure the table).
-</p>
+<li>This GNU indent command generally does the right thing for formatting:
+<pre>
+   indent -br -i3 -npcs --no-tabs infile.c -o outfile.c
+</pre>
 
-<p>
-Brace example:
-</p>
+<li>Use comments wherever you think it would be helpful for other developers.
+Several specific cases and style examples follow.  Note that we roughly
+follow <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a> conventions.
+<br>
+<br>
+Single-line comments:
 <pre>
-       if (condition) {
-          foo;
-       }
-       else {
-          bar;
-       }
-
-       switch (condition) {
-       case 0:
-          foo();
-          break;
-
-       case 1: {
-          ...
-          break;
-       }
-
-       default:
-          ...
-          break;
-       }
+   /* null-out pointer to prevent dangling reference below */
+   bufferObj = NULL;
+</pre>
+Or,
+<pre>
+   bufferObj = NULL;  /* prevent dangling reference below */
+</pre>
+Multi-line comment:
+<pre>
+   /* If this is a new buffer object id, or one which was generated but
+    * never used before, allocate a buffer object now.
+    */
+</pre>
+We try to quote the OpenGL specification where prudent:
+<pre>
+   /* Page 38 of the PDF of the OpenGL ES 3.0 spec says:
+    *
+    *     "An INVALID_OPERATION error is generated for any of the following
+    *     conditions:
+    *
+    *     * <length> is zero."
+    *
+    * Additionally, page 94 of the PDF of the OpenGL 4.5 core spec
+    * (30.10.2014) also says this, so it's no longer allowed for desktop GL,
+    * either.
+    */
+</pre>
+Function comment example:
+<pre>
+   /**
+    * Create and initialize a new buffer object.  Called via the
+    * ctx->Driver.CreateObject() driver callback function.
+    * \param  name  integer name of the object
+    * \param  type  one of GL_FOO, GL_BAR, etc.
+    * \return  pointer to new object or NULL if error
+    */
+   struct gl_object *
+   _mesa_create_object(GLuint name, GLenum type)
+   {
+      /* function body */
+   }
 </pre>
 
-<p>
-Here's the GNU indent command which will best approximate my preferred style:
-(Note that it won't format switch statements in the preferred way)
-</p>
+<li>Put the function return type and qualifiers on one line and the function
+name and parameters on the next, as seen above.  This makes it easy to use
+<code>grep ^function_name dir/*</code> to find function definitions.  Also,
+the opening brace goes on the next line by itself (see above.)
+
+<li>Function names follow various conventions depending on the type of function:
 <pre>
-       indent -br -i3 -npcs --no-tabs infile.c -o outfile.c
+   glFooBar()       - a public GL entry point (in glapi_dispatch.c)
+   _mesa_FooBar()   - the internal immediate mode function
+   save_FooBar()    - retained mode (display list) function in dlist.c
+   foo_bar()        - a static (private) function
+   _mesa_foo_bar()  - an internal non-static Mesa function
 </pre>
 
+<li>Constants, macros and enumerant names are ALL_UPPERCASE, with _ between
+words.
+<li>Mesa usually uses camel case for local variables (Ex: "localVarname")
+while gallium typically uses underscores (Ex: "local_var_name").
+<li>Global variables are almost never used because Mesa should be thread-safe.
 
-<p>
-Local variable name example:  localVarName (no underscores)
-</p>
+<li>Booleans.  Places that are not directly visible to the GL API
+should prefer the use of <tt>bool</tt>, <tt>true</tt>, and
+<tt>false</tt> over <tt>GLboolean</tt>, <tt>GL_TRUE</tt>, and
+<tt>GL_FALSE</tt>.  In C code, this may mean that
+<tt>#include &lt;stdbool.h&gt;</tt> needs to be added.  The
+<tt>try_emit_</tt>* methods in src/mesa/program/ir_to_mesa.cpp and
+src/mesa/state_tracker/st_glsl_to_tgsi.cpp can serve as examples.
+
+</ul>
 
-<p>
-Constants and macros are ALL_UPPERCASE, with _ between words
-</p>
+
+<h2 id="submitting">Submitting patches</h2>
 
 <p>
-Global variables are not allowed.
+The basic guidelines for submitting patches are:
 </p>
 
+<ul>
+<li>Patches should be sufficiently tested before submitting.
+<li>Code patches should follow Mesa coding conventions.
+<li>Whenever possible, patches should only effect individual Mesa/Gallium
+components.
+<li>Patches should never introduce build breaks and should be bisectable (see
+<code>git bisect</code>.)
+<li>Patches should be properly formatted (see below).
+<li>Patches should be submitted to mesa-dev for review using
+<code>git send-email</code>.
+<li>Patches should not mix code changes with code formatting changes (except,
+perhaps, in very trivial cases.)
+</ul>
+
+<h3>Patch formatting</h3>
+
 <p>
-Function name examples:
+The basic rules for patch formatting are:
 </p>
+
+<ul>
+<li>Lines should be limited to 75 characters or less so that git logs
+displayed in 80-column terminals avoid line wrapping.  Note that git
+log uses 4 spaces of indentation (4 + 75 &lt; 80).
+<li>The first line should be a short, concise summary of the change prefixed
+with a module name.  Examples:
+<pre>
+    mesa: Add support for querying GL_VERTEX_ATTRIB_ARRAY_LONG
+
+    gallium: add PIPE_CAP_DEVICE_RESET_STATUS_QUERY
+
+    i965: Fix missing type in local variable declaration.
+</pre>
+<li>Subsequent patch comments should describe the change in more detail,
+if needed.  For example:
 <pre>
-       glFooBar()       - a public GL entry point (in glapi_dispatch.c)
-       _mesa_FooBar()   - the internal immediate mode function
-       save_FooBar()    - retained mode (display list) function in dlist.c
-       foo_bar()        - a static (private) function
-       _mesa_foo_bar()  - an internal non-static Mesa function
+    i965: Remove end-of-thread SEND alignment code.
+    
+    This was present in Eric's initial implementation of the compaction code
+    for Sandybridge (commit 077d01b6). There is no documentation saying this
+    is necessary, and removing it causes no regressions in piglit on any
+    platform.
 </pre>
+<li>A "Signed-off-by:" line is not required, but not discouraged either.
+<li>If a patch address a bugzilla issue, that should be noted in the
+patch comment.  For example:
+<pre>
+   Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89689
+</pre>
+<li>If there have been several revisions to a patch during the review
+process, they should be noted such as in this example:
+<pre>
+    st/mesa: add ARB_texture_stencil8 support (v4)
+    
+    if we support stencil texturing, enable texture_stencil8
+    there is no requirement to support native S8 for this,
+    the texture can be converted to x24s8 fine.
+    
+    v2: fold fixes from Marek in:
+       a) put S8 last in the list
+       b) fix renderable to always test for d/s renderable
+        fixup the texture case to use a stencil only format
+        for picking the format for the texture view.
+    v3: hit fallback for getteximage
+    v4: put s8 back in front, it shouldn't get picked now (Ilia)
+</pre>
+<li>If someone tested your patch, document it with a line like this:
+<pre>
+    Tested-by: Joe Hacker &lt;jhacker@foo.com&gt;
+</pre>
+<li>If the patch was reviewed (usually the case) or acked by someone,
+that should be documented with:
+<pre>
+    Reviewed-by: Joe Hacker &lt;jhacker@foo.com&gt;
+    Acked-by: Joe Hacker &lt;jhacker@foo.com&gt;
+</pre>
+</ul>
+
+
+
+<h3>Testing Patches</h3>
 
 <p>
-Places that are not directly visible to the GL API should prefer the use
-of <tt>bool</tt>, <tt>true</tt>, and
-<tt>false</tt> over <tt>GLboolean</tt>, <tt>GL_TRUE</tt>, and
-<tt>GL_FALSE</tt>.  In C code, this may mean that
-<tt>#include &lt;stdbool.h&gt;</tt> needs to be added.  The
-<tt>try_emit_</tt>* methods in src/mesa/program/ir_to_mesa.cpp and
-src/mesa/state_tracker/st_glsl_to_tgsi.cpp can serve as examples.
+It should go without saying that patches must be tested.  In general,
+do whatever testing is prudent.
 </p>
 
-<h2>Submitting patches</h2>
-
 <p>
-You should always run the Mesa Testsuite before submitting patches.
-The Testsuite can be run using the 'make check' command. All tests
+You should always run the Mesa test suite before submitting patches.
+The test suite can be run using the 'make check' command. All tests
 must pass before patches will be accepted, this may mean you have
 to update the tests themselves.
 </p>
 
+<p>
+Whenever possible and applicable, test the patch with
+<a href="http://piglit.freedesktop.org">Piglit</a> to
+check for regressions.
+</p>
+
+
+<h3>Mailing Patches</h3>
+
 <p>
 Patches should be sent to the Mesa mailing list for review.
 When submitting a patch make sure to use git send-email rather than attaching
@@ -184,7 +266,38 @@ re-sending the whole series). Using --in-reply-to makes
 it harder for reviewers to accidentally review old patches.
 </p>
 
-<h2>Marking a commit as a candidate for a stable branch</h2>
+<p>
+When submitting follow-up patches you should also login to
+<a href="https://patchwork.freedesktop.org">patchwork</a> and change the
+state of your old patches to Superseded.
+</p>
+
+<h3>Reviewing Patches</h3>
+
+<p>
+When you've reviewed a patch on the mailing list, please be unambiguous
+about your review.  That is, state either
+<pre>
+    Reviewed-by: Joe Hacker &lt;jhacker@foo.com&gt;
+</pre>
+or
+<pre>
+    Acked-by: Joe Hacker &lt;jhacker@foo.com&gt;
+</pre>
+Rather than saying just "LGTM" or "Seems OK".
+</p>
+
+<p>
+If small changes are suggested, it's OK to say something like:
+<pre>
+   With the above fixes, Reviewed-by: Joe Hacker &lt;jhacker@foo.com&gt;
+</pre>
+which tells the patch author that the patch can be committed, as long
+as the issues are resolved first.
+</p>
+
+
+<h3>Marking a commit as a candidate for a stable branch</h3>
 
 <p>
 If you want a commit to be applied to a stable branch,
@@ -221,7 +334,7 @@ the upcoming stable release can always be seen on the
 <a href="http://cworth.org/~cworth/mesa-stable-queue/">Mesa Stable Queue</a>
 page.
 
-<h2>Criteria for accepting patches to the stable branch</h2>
+<h3>Criteria for accepting patches to the stable branch</h3>
 
 Mesa has a designated release manager for each stable branch, and the release
 manager is the only developer that should be pushing changes to these
@@ -306,7 +419,8 @@ be rejected:
   regression that is unaacceptable for the stable branch.</li>
 </ul>
 
-<h2>Making a New Mesa Release</h2>
+
+<h2 id="release">Making a New Mesa Release</h2>
 
 <p>
 These are the instructions for making a new Mesa release.
@@ -456,7 +570,7 @@ Edit docs/relnotes/X.Y.Z.html to add the sha256sums printed as part of "make
 tarballs" in the previous step. Commit this change.
 </p>
 
-<h3>Push all commits and the tag creates above</h3>
+<h3>Push all commits and the tag created above</h3>
 
 <p>
 This is the first step that cannot easily be undone. The release is going
@@ -483,7 +597,7 @@ signatures to the freedesktop.org server:
        mv ~/MesaLib-X.Y.Z* .
 </pre>
 
-<h3>Back on mesa master, andd the new release notes into the tree</h3>
+<h3>Back on mesa master, add the new release notes into the tree</h3>
 
 <p>
 Something like the following steps will do the trick:
@@ -543,6 +657,56 @@ release announcement:
 </pre>
 </p>
 
+
+<h2 id="extensions">Adding Extensions</h2>
+
+<p>
+To add a new GL extension to Mesa you have to do at least the following.
+
+<ul>
+<li>
+   If glext.h doesn't define the extension, edit include/GL/gl.h and add
+   code like this:
+   <pre>
+     #ifndef GL_EXT_the_extension_name
+     #define GL_EXT_the_extension_name 1
+     /* declare the new enum tokens */
+     /* prototype the new functions */
+     /* TYPEDEFS for the new functions */
+     #endif
+   </pre>
+</li>
+<li>
+   In the src/mapi/glapi/gen/ directory, add the new extension functions and
+   enums to the gl_API.xml file.
+   Then, a bunch of source files must be regenerated by executing the
+   corresponding Python scripts.
+</li>
+<li>
+   Add a new entry to the <code>gl_extensions</code> struct in mtypes.h
+</li>
+<li>
+   Update the <code>extensions.c</code> file.
+</li>
+<li>
+   From this point, the best way to proceed is to find another extension,
+   similar to the new one, that's already implemented in Mesa and use it
+   as an example.
+</li>
+<li>
+   If the new extension adds new GL state, the functions in get.c, enable.c
+   and attrib.c will most likely require new code.
+</li>
+<li>
+   The dispatch tests check_table.cpp and dispatch_sanity.cpp
+   should be updated with details about the new extensions functions. These
+   tests are run using 'make check'
+</li>
+</ul>
+
+
+
+
 </div>
 </body>
 </html>
index d946bb0ae38d87b0e78b9e141a0446d0f7f8c0d4..3ab1a6018fd6b9d13ac6f07f0d340c136daac0d2 100644 (file)
@@ -183,14 +183,6 @@ probably required only for some of the demos found in mesa/demo repository.</p>
 values are: <code>debug</code>, <code>info</code>, <code>warning</code>, and
 <code>fatal</code>.</p>
 
-</dd>
-
-<dt><code>EGL_SOFTWARE</code></dt>
-<dd>
-
-<p>For drivers that support both hardware and software rendering, setting this
-variable to true forces the use of software rendering.</p>
-
 </dd>
 </dl>
 
index e01790cd79d446ee451c09783fdbeb179ef290c5..80c6e03e3f12cbdc434de98e11522a5b83d1bbc8 100644 (file)
 
 <h1>News</h1>
 
+<h2>June 20, 2015</h2>
+<p>
+<a href="relnotes/10.5.8.html">Mesa 10.5.8</a> is released.
+This is a bug-fix release.
+</p>
+
+<h2>June 14, 2015</h2>
+<p>
+<a href="relnotes/10.6.0.html">Mesa 10.6.0</a> is released.  This is a new
+development release.  See the release notes for more information about
+the release.
+</p>
+
+<h2>June 07, 2015</h2>
+<p>
+<a href="relnotes/10.5.7.html">Mesa 10.5.7</a> is released.
+This is a bug-fix release.
+</p>
+
+<h2>May 23, 2015</h2>
+<p>
+<a href="relnotes/10.5.6.html">Mesa 10.5.6</a> is released.
+This is a bug-fix release.
+</p>
+
+<h2>May 11, 2015</h2>
+<p>
+<a href="relnotes/10.5.5.html">Mesa 10.5.5</a> is released.
+This is a bug-fix release.
+</p>
+
 <h2>April 24, 2015</h2>
 <p>
 <a href="relnotes/10.5.4.html">Mesa 10.5.4</a> is released.
index 7f2e1d851b9522baaf46d28285b1d42afff814c9..5fd80025a39f8125dea074402f1f79f2fb5ac3aa 100644 (file)
@@ -21,6 +21,11 @@ The release notes summarize what's new or changed in each Mesa release.
 </p>
 
 <ul>
+<li><a href="relnotes/10.5.8.html">10.5.8 release notes</a>
+<li><a href="relnotes/10.6.0.html">10.6.0 release notes</a>
+<li><a href="relnotes/10.5.7.html">10.5.7 release notes</a>
+<li><a href="relnotes/10.5.6.html">10.5.6 release notes</a>
+<li><a href="relnotes/10.5.5.html">10.5.5 release notes</a>
 <li><a href="relnotes/10.5.4.html">10.5.4 release notes</a>
 <li><a href="relnotes/10.5.3.html">10.5.3 release notes</a>
 <li><a href="relnotes/10.5.2.html">10.5.2 release notes</a>
diff --git a/docs/relnotes/10.5.5.html b/docs/relnotes/10.5.5.html
new file mode 100644 (file)
index 0000000..fc8247c
--- /dev/null
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Mesa Release Notes</title>
+  <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+  <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.5.5 Release Notes / May 11, 2015</h1>
+
+<p>
+Mesa 10.5.5 is a bug fix release which fixes bugs found since the 10.5.4 release.
+</p>
+<p>
+Mesa 10.5.5 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3.  OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+c10f00fd792b8290dd51ebcc48a9016c4cafab19ec205423c6fcadfd7f3a59f2  mesa-10.5.5.tar.gz
+4ac4e4ea3414f1cadb1467f2f173f9e56170d31e8674f7953a46f0549d319f28  mesa-10.5.5.tar.xz
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88521">Bug 88521</a> - GLBenchmark 2.7 TRex renders with artifacts on Gen8 with !UXA</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89455">Bug 89455</a> - [NVC0/Gallium] Unigine Heaven black and white boxes</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89689">Bug 89689</a> - [Regression] Weston on DRM backend won't start with new version of mesa</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90130">Bug 90130</a> - gl_PrimitiveId seems to reset at 340</li>
+
+</ul>
+
+
+<h2>Changes</h2>
+
+<p>Boyan Ding (1):</p>
+<ul>
+  <li>i965: Add XRGB8888 format to intel_screen_make_configs</li>
+</ul>
+
+<p>Emil Velikov (3):</p>
+<ul>
+  <li>docs: Add sha256 sums for the 10.5.4 release</li>
+  <li>r300: do not link against libdrm_intel</li>
+  <li>Update version to 10.5.5</li>
+</ul>
+
+<p>Ilia Mirkin (4):</p>
+<ul>
+  <li>nvc0/ir: flush denorms to zero in non-compute shaders</li>
+  <li>gk110/ir: fix set with a register dest to not auto-set the abs flag</li>
+  <li>nvc0/ir: fix predicated PFETCH emission</li>
+  <li>nv50/ir: fix asFlow() const helper for OP_JOIN</li>
+</ul>
+
+<p>Kenneth Graunke (2):</p>
+<ul>
+  <li>i965: Make intel_emit_linear_blit handle Gen8+ alignment restrictions.</li>
+  <li>i965: Disallow linear blits that are not cacheline aligned.</li>
+</ul>
+
+<p>Roland Scheidegger (1):</p>
+<ul>
+  <li>draw: fix prim ids when there's no gs</li>
+</ul>
+
+
+</div>
+</body>
+</html>
diff --git a/docs/relnotes/10.5.6.html b/docs/relnotes/10.5.6.html
new file mode 100644 (file)
index 0000000..0046b8f
--- /dev/null
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Mesa Release Notes</title>
+  <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+  <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.5.6 Release Notes / May 23, 2015</h1>
+
+<p>
+Mesa 10.5.6 is a bug fix release which fixes bugs found since the 10.5.5 release.
+</p>
+<p>
+Mesa 10.5.6 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3.  OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+89ff9cb08d0f6e3f34154864c3071253057cd21020759457c8ae27e0f70985d3  mesa-10.5.6.tar.gz
+66017853bde5f7a6647db3eede30512a091a3491daa1708e0ad8027c328ba595  mesa-10.5.6.tar.xz
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86792">Bug 86792</a> - [NVC0] Portal 2 Crashes in Wine</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90147">Bug 90147</a> - swrast: build error undeclared _SC_PHYS_PAGES on osx</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90350">Bug 90350</a> - [G96] Portal's portal are incorrectly rendered</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90363">Bug 90363</a> - [nv50] HW state is not reset correctly when using a new GL context</li>
+
+</ul>
+
+
+<h2>Changes</h2>
+
+<p>Alex Deucher (1):</p>
+<ul>
+  <li>radeonsi: add new bonaire pci id</li>
+</ul>
+
+<p>Axel Davy (2):</p>
+<ul>
+  <li>egl/wayland: properly destroy wayland objects</li>
+  <li>glx/dri3: Add additional check for gpu offloading case</li>
+</ul>
+
+<p>Emil Velikov (4):</p>
+<ul>
+  <li>docs: Add sha256 sums for the 10.5.5 release</li>
+  <li>egl/main: fix EGL_KHR_get_all_proc_addresses</li>
+  <li>targets/osmesa: drop the -module tag from LDFLAGS</li>
+  <li>Update version to 10.5.6</li>
+</ul>
+
+<p>Francisco Jerez (4):</p>
+<ul>
+  <li>clover: Refactor event::trigger and ::abort to prevent deadlock and reentrancy issues.</li>
+  <li>clover: Wrap event::_status in a method to prevent unlocked access.</li>
+  <li>clover: Implement locking of the wait_count, _chain and _status members of event.</li>
+  <li>i965: Fix PBO cache coherency issue after _mesa_meta_pbo_GetTexSubImage().</li>
+</ul>
+
+<p>Fredrik Höglund (2):</p>
+<ul>
+  <li>main: Require that the texture exists in framebuffer_texture</li>
+  <li>mesa: Generate GL_INVALID_VALUE in framebuffer_texture when layer &lt; 0</li>
+</ul>
+
+<p>Ilia Mirkin (7):</p>
+<ul>
+  <li>nv50/ir: only propagate saturate up if some actual folding took place</li>
+  <li>nv50: keep track of PGRAPH state in nv50_screen</li>
+  <li>nvc0: keep track of PGRAPH state in nvc0_screen</li>
+  <li>nvc0: reset the instanced elements state when doing blit using 3d engine</li>
+  <li>nv50/ir: only enable mul saturate on G200+</li>
+  <li>st/mesa: make sure to create a "clean" bool when doing i2b</li>
+  <li>nvc0: switch mechanism for shader eviction to be a while loop</li>
+</ul>
+
+<p>Jeremy Huddleston Sequoia (2):</p>
+<ul>
+  <li>swrast: Build fix for darwin</li>
+  <li>darwin: Fix install name of libOSMesa</li>
+</ul>
+
+<p>Laura Ekstrand (2):</p>
+<ul>
+  <li>main: Fix an error generated by FramebufferTexture</li>
+  <li>main: Complete error conditions for glInvalidate*Framebuffer.</li>
+</ul>
+
+<p>Marta Lofstedt (1):</p>
+<ul>
+  <li>main: glGetIntegeri_v fails for GL_VERTEX_BINDING_STRIDE</li>
+</ul>
+
+<p>Rob Clark (2):</p>
+<ul>
+  <li>freedreno: enable a306</li>
+  <li>freedreno: fix bug in tile/slot calculation</li>
+</ul>
+
+<p>Roland Scheidegger (1):</p>
+<ul>
+  <li>draw: (trivial) fix out-of-bounds vector initialization</li>
+</ul>
+
+<p>Tim Rowley (1):</p>
+<ul>
+  <li>mesa: fix shininess check for ffvertex_prog v2</li>
+</ul>
+
+<p>Tom Stellard (2):</p>
+<ul>
+  <li>clover: Add a mutex to guard queue::queued_events</li>
+  <li>clover: Fix a bug with multi-threaded events v2</li>
+</ul>
+
+
+</div>
+</body>
+</html>
diff --git a/docs/relnotes/10.5.7.html b/docs/relnotes/10.5.7.html
new file mode 100644 (file)
index 0000000..68c8385
--- /dev/null
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Mesa Release Notes</title>
+  <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+  <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.5.7 Release Notes / June 07, 2015</h1>
+
+<p>
+Mesa 10.5.7 is a bug fix release which fixes bugs found since the 10.5.6 release.
+</p>
+<p>
+Mesa 10.5.7 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3.  OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+8f865ce497435fdf25d4e35f3b5551b2bcd5f9bc6570561183be82af20d18b82  mesa-10.5.7.tar.gz
+04d06890cd69af8089d6ca76f40e46dcf9cacfe4a9788b32be620574d4638818  mesa-10.5.7.tar.xz
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89131">Bug 89131</a> - [Bisected] Graphical corruption in Weston,  shows old framebuffer pieces</li>
+
+</ul>
+
+
+<h2>Changes</h2>
+
+<p>Ben Widawsky (1):</p>
+<ul>
+  <li>i965: Emit 3DSTATE_MULTISAMPLE before WM_HZ_OP (gen8+)</li>
+</ul>
+
+<p>Emil Velikov (4):</p>
+<ul>
+  <li>docs: Add sha256sums for the 10.5.6 release</li>
+  <li>get-pick-list.sh: Require explicit "10.5" for nominating stable patches</li>
+  <li>cherry-ignore: add clover build fix not applicable for 10.5</li>
+  <li>Update version to 10.5.7</li>
+</ul>
+
+<p>Ilia Mirkin (18):</p>
+<ul>
+  <li>nvc0/ir: set ftz when sources are floats, not just destinations</li>
+  <li>nv50/ir: guess that the constant offset is the starting slot of array</li>
+  <li>nvc0/ir: LOAD's can't be used for shader inputs</li>
+  <li>nvc0: a geometry shader can have up to 1024 vertices output</li>
+  <li>nv50/ir: avoid messing up arg1 of PFETCH</li>
+  <li>nv30: don't leak fragprog consts</li>
+  <li>nv30: avoid leaking render state and draw shaders</li>
+  <li>nv30: fix clip plane uploads and enable changes</li>
+  <li>nv30/draw: avoid leaving stale pointers in draw state</li>
+  <li>nv30/draw: draw expects constbuf size in bytes, not vec4 units</li>
+  <li>st/mesa: don't leak glsl_to_tgsi object on link failure</li>
+  <li>glsl: avoid leaking linked gl_shader when there's a late linker error</li>
+  <li>nv30/draw: fix indexed draws with swtnl path and a resource index buffer</li>
+  <li>nv30/draw: only use the DMA1 object (GART) if the bo is not in VRAM</li>
+  <li>nv30/draw: allocate vertex buffers in gart</li>
+  <li>nv30/draw: switch varying hookup logic to know about texcoords</li>
+  <li>nv30: falling back to draw path for edgeflag does no good</li>
+  <li>nv30: avoid doing extra work on clear and hitting unexpected states</li>
+</ul>
+
+<p>Jason Ekstrand (1):</p>
+<ul>
+  <li>i965/fs: Fix implied_mrf_writes for scratch writes</li>
+</ul>
+
+<p>Marek Olšák (1):</p>
+<ul>
+  <li>st/dri: fix postprocessing crash when there's no depth buffer</li>
+</ul>
+
+
+</div>
+</body>
+</html>
diff --git a/docs/relnotes/10.5.8.html b/docs/relnotes/10.5.8.html
new file mode 100644 (file)
index 0000000..6239400
--- /dev/null
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Mesa Release Notes</title>
+  <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+  <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.5.8 Release Notes / June 20, 2015</h1>
+
+<p>
+Mesa 10.5.8 is a bug fix release which fixes bugs found since the 10.5.7 release.
+</p>
+<p>
+Mesa 10.5.8 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3.  OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+611ddcfa3c1bf13f7e6ccac785c8749c3b74c9a78452bac70f8372cf6b209aa0  mesa-10.5.8.tar.gz
+2866b855c5299a4aed066338c77ff6467c389b2c30ada7647be8758663da2b54  mesa-10.5.8.tar.xz
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90310">Bug 90310</a> - Fails to build gallium_dri.so at linking stage with clang because of multiple redefinitions</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90347">Bug 90347</a> - [NVE0+] Failure to insert texbar under some circumstances (causing bad colors in Terasology)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90520">Bug 90520</a> - Register spilling clobbers registers used elsewhere in the shader</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90905">Bug 90905</a> - mesa: Finish subdir-objects transition</li>
+
+</ul>
+
+
+<h2>Changes</h2>
+
+<p>Ben Widawsky (1):</p>
+<ul>
+  <li>i965: Disable compaction for EOT send messages</li>
+</ul>
+
+<p>Boyan Ding (1):</p>
+<ul>
+  <li>egl/x11: Set version of swrastLoader to 2</li>
+</ul>
+
+<p>Emil Velikov (2):</p>
+<ul>
+  <li>docs: Add sha256sums for the 10.5.7 release</li>
+  <li>Update version to 10.5.8</li>
+</ul>
+
+<p>Erik Faye-Lund (1):</p>
+<ul>
+  <li>mesa: build xmlconfig to a separate static library</li>
+</ul>
+
+<p>Francisco Jerez (1):</p>
+<ul>
+  <li>i965: Don't compact instructions with unmapped bits.</li>
+</ul>
+
+<p>Ilia Mirkin (3):</p>
+<ul>
+  <li>nvc0/ir: fix collection of first uses for texture barrier insertion</li>
+  <li>nv50,nvc0: clamp uniform size to 64k</li>
+  <li>nvc0/ir: can't have a join on a load with an indirect source</li>
+</ul>
+
+<p>Jason Ekstrand (1):</p>
+<ul>
+  <li>i965/fs: Don't let the EOT send message interfere with the MRF hack</li>
+</ul>
+
+<p>Marek Olšák (1):</p>
+<ul>
+  <li>egl: fix setting context flags</li>
+</ul>
+
+<p>Roland Scheidegger (1):</p>
+<ul>
+  <li>draw: (trivial) fix NULL pointer dereference</li>
+</ul>
+
+
+</div>
+</body>
+</html>
index b7cd486f529fa731b5d5cf17df89511c717f1b81..ebd1f104d6f411e6f726a40355555c01cfca0ff7 100644 (file)
@@ -14,7 +14,7 @@
 <iframe src="../contents.html"></iframe>
 <div class="content">
 
-<h1>Mesa 10.6.0 Release Notes / TBD</h1>
+<h1>Mesa 10.6.0 Release Notes / June 14, 2015</h1>
 
 <p>
 Mesa 10.6.0 is a new development release.
@@ -31,9 +31,10 @@ because compatibility contexts are not supported.
 </p>
 
 
-<h2>MD5 checksums</h2>
+<h2>SHA256 checksums</h2>
 <pre>
-TBD.
+9bc659abdba26202509304f259723aaa4343dba6aac4bd87d5baea11d23c8c63  mesa-10.6.0.tar.gz
+f37e2633978deed02ff0522abc36c709586e2b555fd439a82ab71dce2c866c76  mesa-10.6.0.tar.xz
 </pre>
 
 
@@ -48,6 +49,7 @@ Note: some of the new features are only available with certain drivers.
 <li>GL_ARB_clip_control on i965</li>
 <li>GL_ARB_depth_buffer_float on freedreno</li>
 <li>GL_ARB_depth_clamp on freedreno</li>
+<li>GL_ARB_direct_state_access on all drivers that support GL 2.0+</li>
 <li>GL_ARB_draw_indirect, GL_ARB_multi_draw_indirect on r600</li>
 <li>GL_ARB_draw_instanced on freedreno</li>
 <li>GL_ARB_gpu_shader_fp64 on nvc0, softpipe</li>
@@ -56,6 +58,7 @@ Note: some of the new features are only available with certain drivers.
 <li>GL_ARB_pipeline_statistics_query on i965, nv50, nvc0, r600, radeonsi, softpipe</li>
 <li>GL_ARB_program_interface_query (all drivers)</li>
 <li>GL_ARB_texture_stencil8 on nv50, nvc0, r600, radeonsi, softpipe</li>
+<li>GL_ARB_texture_view on llvmpipe, softpipe</li>
 <li>GL_ARB_uniform_buffer_object on freedreno</li>
 <li>GL_ARB_vertex_attrib_64bit on nvc0, softpipe</li>
 <li>GL_ARB_viewport_array, GL_AMD_vertex_shader_viewport_index on i965/gen6</li>
@@ -69,7 +72,246 @@ Note: some of the new features are only available with certain drivers.
 
 <h2>Bug fixes</h2>
 
-TBD.
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=15006">Bug 15006</a> - translate &amp; rotate the line cause Aliasing</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=27007">Bug 27007</a> - Lines disappear with GL_LINE_SMOOTH</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=28832">Bug 28832</a> - piglit/general/line-aa-width fail</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=45348">Bug 45348</a> - [swrast] piglit fbo-drawbuffers-arbfp regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=60797">Bug 60797</a> - 1px lines in octave plot aliased to 0</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=67564">Bug 67564</a> - HiZ buffers are much larger than necessary</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=69226">Bug 69226</a> - Cannot enable basic shaders with Second Life aborts attempt</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=71591">Bug 71591</a> - Second Life shaders fail to compile (extension declared in middle of shader)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79202">Bug 79202</a> - valgrind errors in glsl-fs-uniform-array-loop-unroll.shader_test; random code generation</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81025">Bug 81025</a> - [IVB/BYT Bisected]Piglit spec_ARB_draw_indirect_arb_draw_indirect-draw-elements-prim-restart-ugly fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82477">Bug 82477</a> - [softpipe] piglit fp-long-alu regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82668">Bug 82668</a> - Can't set int attributes to certain values on 32-bit</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82831">Bug 82831</a> - i965: Support GL_ARB_blend_func_extended in SIMD16</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83962">Bug 83962</a> - [HSW/BYT]Piglit spec_ARB_gpu_shader5_arb_gpu_shader5-emitstreamvertex_nodraw fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84613">Bug 84613</a> - [G965, bisected] piglit regressions : glslparsertest.glsl2</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86747">Bug 86747</a> - Noise in Football Manager 2014 textures</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86792">Bug 86792</a> - [NVC0] Portal 2 Crashes in Wine</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86811">Bug 86811</a> - [BDW/BSW Bisected]Piglit spec_arb_shading_language_packing_execution_built-in-functions_vs-unpackSnorm4x8 fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86837">Bug 86837</a> - kodi segfault since auxiliary/vl: rework the build of the VL code</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86944">Bug 86944</a> - glsl_parser_extras.cpp&quot;, line 1455: Error: Badly formed expression. (Oracle Studio)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86974">Bug 86974</a> - INTEL_DEBUG=shader_time always asserts in fs_generator::generate_code() when Mesa is built with --enable-debug (= with asserts)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=86980">Bug 86980</a> - [swrast] piglit fp-rfl regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=87258">Bug 87258</a> - [BDW/BSW Bisected]Piglit spec_ARB_shader_atomic_counters_array-indexing fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88246">Bug 88246</a> - Commit 2881b12 causes 43 DrawElements test regressions</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88248">Bug 88248</a> - Calling glClear while there is an occlusion query in progress messes up the results</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88521">Bug 88521</a> - GLBenchmark 2.7 TRex renders with artifacts on Gen8 with !UXA</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88534">Bug 88534</a> - include/c11/threads_posix.h PTHREAD_MUTEX_RECURSIVE_NP not defined</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88561">Bug 88561</a> - [radeonsi][regression,bisected] Depth test/buffer issues in Portal</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88793">Bug 88793</a> - [BDW/BSW Bisected]Piglit/shaders_glsl-max-varyings fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88815">Bug 88815</a> - Incorrect handling of GLSL #line directive</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88883">Bug 88883</a> - ir-a2xx.c: variable changed in assert statement</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88885">Bug 88885</a> - Transform feedback uses incorrect interleaving if a previous draw did not write gl_Position</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88905">Bug 88905</a> - [SNB+ Bisected]Ogles3conform ES3-CTS.gtf.GL3Tests.packed_pixels.packed_pixels fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88999">Bug 88999</a> - [SKL] Compiz crashes after opening unity dash</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89014">Bug 89014</a> - PIPE_QUERY_GPU_FINISHED is not acting as expected on SI</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89026">Bug 89026</a> - Renderbuffer layered state used for framebuffer completeness test</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89032">Bug 89032</a> - [BDW/BSW/SKL Bisected]Piglit spec_OpenGL_1.1_infinite-spot-light fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89037">Bug 89037</a> - [SKL]Piglit spec_EXT_texture_array_copyteximage_1D_ARRAY_samples=2 sporadically causes GPU hang</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89039">Bug 89039</a> - [SKL]etqw system hang</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89058">Bug 89058</a> - [SKL]Render error in some games (etqw-demo, nexuiz, portal)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89068">Bug 89068</a> - glTexImage2D regression by texstore_rgba switch to _mesa_format_convert</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89069">Bug 89069</a> - Lack of grass in The Talos Principle on radeonsi (native\wine\nine)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89094">Bug 89094</a> - [SNB/IVB/HSW/BYT Bisected]Ogles3conform ES3-CTS.gtf.GL3Tests.shadow.shadow_execution_vert fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89095">Bug 89095</a> - [SNB/IVB/BYT Bisected]Webglc conformance/glsl/functions/glsl-function-mix-float.html fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89112">Bug 89112</a> - u_atomic_test: u_atomic_test.c:124: test_atomic_8bits_bool: Assertion `r == 65 &amp;&amp; &quot;p_atomic_add&quot;' failed.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89118">Bug 89118</a> - [SKL Bisected]many Ogles3conform cases core dumped</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89131">Bug 89131</a> - [Bisected] Graphical corruption in Weston,  shows old framebuffer pieces</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89156">Bug 89156</a> - r300g: GL_COMPRESSED_RED_RGTC1 / ATI1N support broken</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89180">Bug 89180</a> - [IVB regression] Rendering issues in Mass Effect through VMware Workstation</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89210">Bug 89210</a> - GS statistics fail on SNB</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89218">Bug 89218</a> - lower_instructions.cpp:648:48: error: invalid suffix 'd' on floating constant</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89224">Bug 89224</a> - Incorrect rendering of Unigine Valley running in VM on VMware Workstation</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89260">Bug 89260</a> - macros.h:34:25: fatal error: util/u_math.h: No such file or directory</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89292">Bug 89292</a> - [regression,bisected] incomplete screenshots in some cases</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89311">Bug 89311</a> - [regression, bisected] dEQP: Added entry points for glCompressedTextureSubImage*D.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89312">Bug 89312</a> - [regression, bisected] main: Added entry points for CopyTextureSubImage*D. (d6b7c40cecfe01)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89315">Bug 89315</a> - [HSW, regression, bisected] i965/fs: Emit MAD instructions when possible.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89317">Bug 89317</a> - [HSW, regression, bisected] i965: Add LINTERP/CINTERP to can_do_cmod() (d91390634)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89328">Bug 89328</a> - python required to build Mesa release tarballs</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89342">Bug 89342</a> - main/light.c:159:62: error: 'M_PI' undeclared (first use in this function)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89343">Bug 89343</a> - compiler/tests/radeon_compiler_optimize_tests.c:43:3: error: implicit declaration of function â€˜fprintf’ [-Werror=implicit-function-declaration]</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89345">Bug 89345</a> - imports.h:452:58: error: expected declaration specifiers or '...' before 'va_list'</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89364">Bug 89364</a> - c99_alloca.h:40:22: fatal error: alloca.h: No such file or directory</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89372">Bug 89372</a> - [softpipe] piglit glsl-1.50 generate-zero-primitives regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89387">Bug 89387</a> - Double delete in lp_bld_misc.cpp</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89416">Bug 89416</a> - UE4Editor crash after load project</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89430">Bug 89430</a> - [g965][bisected] arb_copy_image-targets gl_texture* tests fail</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89433">Bug 89433</a> - GCC 4.2 does not support -Wvla</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89455">Bug 89455</a> - [NVC0/Gallium] Unigine Heaven black and white boxes</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89457">Bug 89457</a> - [BSW Bisected]ogles3conform ES3-CTS.gtf.GL3Tests.shadow.shadow_execution_vert fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89477">Bug 89477</a> - include/no_extern_c.h:47:1: error: template with C linkage</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89508">Bug 89508</a> - Bad int(floatBitsToInt(vec4))</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89530">Bug 89530</a> - FTBFS in loader: missing fstat</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89569">Bug 89569</a> - Papo &amp; Yo crash on startup [HSW]</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89590">Bug 89590</a> - Crash in glLinkProgram with shaders with multiple constant arrays</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89662">Bug 89662</a> - context.c:943: undefined reference to `_glapi_new_nop_table'</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89670">Bug 89670</a> - cmod_propagation_test.andnz_one regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89679">Bug 89679</a> - [NV50] Portal/Half-Life 2 will not start (native Steam)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89689">Bug 89689</a> - [Regression] Weston on DRM backend won't start with new version of mesa</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89722">Bug 89722</a> - [ILK Bisected]Ogles2conform/ES2-CTS.gtf.GL.equal.equal_vec2_frag fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89726">Bug 89726</a> - [Bisected] dEQP-GLES3: uniform linking logic in the presence of structs</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89746">Bug 89746</a> - Mesa and LLVM 3.6+ break opengl for genymotion</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89754">Bug 89754</a> - vertexAttrib fails WebGL Conformance test with mesa drivers</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89758">Bug 89758</a> - pow WebGL Conformance test with mesa drivers</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89759">Bug 89759</a> - WebGL OGL ES GLSL conformance test with mesa drivers fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89831">Bug 89831</a> - [r600] r600_asm.c:310:assign_alu_units: Assertion `0' failed.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89899">Bug 89899</a> - nir/nir_lower_tex_projector.c:112: error: unknown field â€˜ssa’ specified in initializer</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89957">Bug 89957</a> - vm protection faults in piglit lest: texsubimage cube_map_array pbo</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89960">Bug 89960</a> - [softpipe] piglit copy-pixels regreession</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89961">Bug 89961</a> - [BDW/BSW Bisected]Synmark2_v6 OglDrvRes/OglDrvShComp/OglDrvState/OglPSPom Image Validation fail</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89963">Bug 89963</a> - lp_bld_debug.cpp:100:31: error: no matching function for call to â€˜llvm::raw_ostream::raw_ostream()’</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90000">Bug 90000</a> - [i965 Bisected NIR] Piglit/gglean_fragprog1-z-write_test fail</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90109">Bug 90109</a> - [SNB+ Bisected]Ogles3conform ES3-CTS.shaders.uniform_block.random.basic_arrays.3 fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90114">Bug 90114</a> - [SNB+ Bisected]Ogles3conform ES3-CTS.shaders.struct.uniform.sampler_array_fragment fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90130">Bug 90130</a> - gl_PrimitiveId seems to reset at 340</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90147">Bug 90147</a> - swrast: build error undeclared _SC_PHYS_PAGES on osx</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90149">Bug 90149</a> - [SNB+ Bisected]ES3-CTS.gtf.GL3Tests.uniform_buffer_object.uniform_buffer_object_getactiveuniformsiv_for_nonexistent_uniform_indices fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90153">Bug 90153</a> - [SKL Bisected]ES3-CTS.gtf.GL3Tests.uniform_buffer_object.uniform_buffer_object_all_valid_basic_types fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90167">Bug 90167</a> - [softpipe] piglit depthstencil-default_fb-drawpixels-32f_24_8_rev regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90207">Bug 90207</a> - [r600g, bisected] regression: NI/Turks crash on WebGL Water (most WebGL stuff)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90213">Bug 90213</a> - glDrawPixels with GL_COLOR_INDEX never returns.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90243">Bug 90243</a> - [bisected] regression: spec.!opengl 3_2.get-active-attrib-returns-all-inputs</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90258">Bug 90258</a> - [IVB] spec.glsl-1_10.execution.fs-dfdy-accuracy fails intermittently</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90310">Bug 90310</a> - Fails to build gallium_dri.so at linking stage with clang because of multiple redefinitions</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90350">Bug 90350</a> - [G96] Portal's portal are incorrectly rendered</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90363">Bug 90363</a> - [nv50] HW state is not reset correctly when using a new GL context</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90397">Bug 90397</a> - ARB_program_interface_query: glGetProgramResourceiv() returns wrong value for GL_REFERENCED_BY_*_SHADER prop for GL_UNIFORM for members of an interface block with an instance name</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90466">Bug 90466</a> - arm: linker error ndefined reference to `nir_metadata_preserve'</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90520">Bug 90520</a> - Register spilling clobbers registers used elsewhere in the shader</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90547">Bug 90547</a> - [BDW/BSW/SKL Bisected]Piglit/glean&#64;vertprog1-rsq_test_2_(reciprocal_square_root_of_negative_value) fais</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90580">Bug 90580</a> - [HSW bisected] integer multiplication bug</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90629">Bug 90629</a> - [i965] SIMD16 dual_source_blend assertion `src[i].file != GRF || src[i].width == dst.width' failed</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90749">Bug 90749</a> - [BDW Bisected]dEQP-GLES3.functional.rasterization.fbo.rbo_multisample_max.primitives.lines_wide fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90830">Bug 90830</a> - [bsw bisected regression] GPU hang for spec.arb_gpu_shader5.execution.sampler_array_indexing.vs-nonzero-base</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90839">Bug 90839</a> - [10.5.5/10.6 regression, bisected] PBO glDrawPixels no longer using blit fastpath</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90905">Bug 90905</a> - mesa: Finish subdir-objects transition</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=9951">Bug 9951</a> - GL_LINE_SMOOTH and GL_POLYGON_SMOOTH with i965 driver</li>
+
+</ul>
+
 
 <h2>Changes</h2>
 
diff --git a/docs/relnotes/10.7.0.html b/docs/relnotes/10.7.0.html
new file mode 100644 (file)
index 0000000..e089889
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Mesa Release Notes</title>
+  <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+  <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.7.0 Release Notes / TBD</h1>
+
+<p>
+Mesa 10.7.0 is a new development release.
+People who are concerned with stability and reliability should stick
+with a previous release or wait for Mesa 10.7.1.
+</p>
+<p>
+Mesa 10.7.0 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3.  OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+TBD.
+</pre>
+
+
+<h2>New features</h2>
+
+<p>
+Note: some of the new features are only available with certain drivers.
+</p>
+
+<ul>
+<li>GL_ARB_framebuffer_no_attachments on i965</li>
+<li>GL_ARB_shader_stencil_export on llvmpipe</li>
+</ul>
+
+<h2>Bug fixes</h2>
+
+TBD.
+
+<h2>Changes</h2>
+
+TBD.
+
+</div>
+</body>
+</html>
index 99ea342a47738e45bed10578a9671a7cbe6709c2..0d514e4defb4e91727e202e20542851722b60365 100644 (file)
@@ -1,11 +1,12 @@
-/* -*- mode: c; tab-width: 8; -*- */
-/* vi: set sw=4 ts=8: */
-/* Reference version of egl.h for EGL 1.4.
- * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
- */
+#ifndef __egl_h_
+#define __egl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2013-2014 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
 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+**   http://www.opengl.org/registry/
+**
+** Khronos $Revision: 31039 $ on $Date: 2015-05-04 17:01:57 -0700 (Mon, 04 May 2015) $
+*/
 
-#ifndef __egl_h_
-#define __egl_h_
-
-/* All platform-dependent types and macro boilerplate (such as EGLAPI
- * and EGLAPIENTRY) should go in eglplatform.h.
- */
 #include <EGL/eglplatform.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* Generated on date 20150504 */
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
 
-/* EGL Types */
-/* EGLint is defined in eglplatform.h */
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
 typedef unsigned int EGLBoolean;
-typedef unsigned int EGLenum;
-typedef void *EGLConfig;
-typedef void *EGLContext;
 typedef void *EGLDisplay;
+#include <KHR/khrplatform.h>
+#include <EGL/eglplatform.h>
+typedef void *EGLConfig;
 typedef void *EGLSurface;
-typedef void *EGLClientBuffer;
-
-/* EGL Versioning */
-#define EGL_VERSION_1_0                        1
-#define EGL_VERSION_1_1                        1
-#define EGL_VERSION_1_2                        1
-#define EGL_VERSION_1_3                        1
-#define EGL_VERSION_1_4                        1
-
-/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
- * enums are assigned unique values starting at 0x3000.
- */
-
-/* EGL aliases */
-#define EGL_FALSE                      0
-#define EGL_TRUE                       1
-
-/* Out-of-band handle values */
-#define EGL_DEFAULT_DISPLAY            ((EGLNativeDisplayType)0)
-#define EGL_NO_CONTEXT                 ((EGLContext)0)
-#define EGL_NO_DISPLAY                 ((EGLDisplay)0)
-#define EGL_NO_SURFACE                 ((EGLSurface)0)
-
-/* Out-of-band attribute value */
-#define EGL_DONT_CARE                  ((EGLint)-1)
-
-/* Errors / GetError return values */
-#define EGL_SUCCESS                    0x3000
-#define EGL_NOT_INITIALIZED            0x3001
-#define EGL_BAD_ACCESS                 0x3002
-#define EGL_BAD_ALLOC                  0x3003
-#define EGL_BAD_ATTRIBUTE              0x3004
-#define EGL_BAD_CONFIG                 0x3005
-#define EGL_BAD_CONTEXT                        0x3006
-#define EGL_BAD_CURRENT_SURFACE                0x3007
-#define EGL_BAD_DISPLAY                        0x3008
-#define EGL_BAD_MATCH                  0x3009
-#define EGL_BAD_NATIVE_PIXMAP          0x300A
-#define EGL_BAD_NATIVE_WINDOW          0x300B
-#define EGL_BAD_PARAMETER              0x300C
-#define EGL_BAD_SURFACE                        0x300D
-#define EGL_CONTEXT_LOST               0x300E  /* EGL 1.1 - IMG_power_management */
-
-/* Reserved 0x300F-0x301F for additional errors */
-
-/* Config attributes */
-#define EGL_BUFFER_SIZE                        0x3020
-#define EGL_ALPHA_SIZE                 0x3021
-#define EGL_BLUE_SIZE                  0x3022
-#define EGL_GREEN_SIZE                 0x3023
-#define EGL_RED_SIZE                   0x3024
-#define EGL_DEPTH_SIZE                 0x3025
-#define EGL_STENCIL_SIZE               0x3026
-#define EGL_CONFIG_CAVEAT              0x3027
-#define EGL_CONFIG_ID                  0x3028
-#define EGL_LEVEL                      0x3029
-#define EGL_MAX_PBUFFER_HEIGHT         0x302A
-#define EGL_MAX_PBUFFER_PIXELS         0x302B
-#define EGL_MAX_PBUFFER_WIDTH          0x302C
-#define EGL_NATIVE_RENDERABLE          0x302D
-#define EGL_NATIVE_VISUAL_ID           0x302E
-#define EGL_NATIVE_VISUAL_TYPE         0x302F
-#define EGL_SAMPLES                    0x3031
-#define EGL_SAMPLE_BUFFERS             0x3032
-#define EGL_SURFACE_TYPE               0x3033
-#define EGL_TRANSPARENT_TYPE           0x3034
-#define EGL_TRANSPARENT_BLUE_VALUE     0x3035
-#define EGL_TRANSPARENT_GREEN_VALUE    0x3036
-#define EGL_TRANSPARENT_RED_VALUE      0x3037
-#define EGL_NONE                       0x3038  /* Attrib list terminator */
-#define EGL_BIND_TO_TEXTURE_RGB                0x3039
-#define EGL_BIND_TO_TEXTURE_RGBA       0x303A
-#define EGL_MIN_SWAP_INTERVAL          0x303B
-#define EGL_MAX_SWAP_INTERVAL          0x303C
-#define EGL_LUMINANCE_SIZE             0x303D
-#define EGL_ALPHA_MASK_SIZE            0x303E
-#define EGL_COLOR_BUFFER_TYPE          0x303F
-#define EGL_RENDERABLE_TYPE            0x3040
-#define EGL_MATCH_NATIVE_PIXMAP                0x3041  /* Pseudo-attribute (not queryable) */
-#define EGL_CONFORMANT                 0x3042
-
-/* Reserved 0x3041-0x304F for additional config attributes */
-
-/* Config attribute values */
-#define EGL_SLOW_CONFIG                        0x3050  /* EGL_CONFIG_CAVEAT value */
-#define EGL_NON_CONFORMANT_CONFIG      0x3051  /* EGL_CONFIG_CAVEAT value */
-#define EGL_TRANSPARENT_RGB            0x3052  /* EGL_TRANSPARENT_TYPE value */
-#define EGL_RGB_BUFFER                 0x308E  /* EGL_COLOR_BUFFER_TYPE value */
-#define EGL_LUMINANCE_BUFFER           0x308F  /* EGL_COLOR_BUFFER_TYPE value */
-
-/* More config attribute values, for EGL_TEXTURE_FORMAT */
-#define EGL_NO_TEXTURE                 0x305C
-#define EGL_TEXTURE_RGB                        0x305D
-#define EGL_TEXTURE_RGBA               0x305E
-#define EGL_TEXTURE_2D                 0x305F
-
-/* Config attribute mask bits */
-#define EGL_PBUFFER_BIT                        0x0001  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_PIXMAP_BIT                 0x0002  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_WINDOW_BIT                 0x0004  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_VG_COLORSPACE_LINEAR_BIT   0x0020  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_VG_ALPHA_FORMAT_PRE_BIT    0x0040  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */
-#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */
-
-#define EGL_OPENGL_ES_BIT              0x0001  /* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENVG_BIT                 0x0002  /* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_ES2_BIT             0x0004  /* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_BIT                 0x0008  /* EGL_RENDERABLE_TYPE mask bits */
-
-/* QueryString targets */
-#define EGL_VENDOR                     0x3053
-#define EGL_VERSION                    0x3054
-#define EGL_EXTENSIONS                 0x3055
-#define EGL_CLIENT_APIS                        0x308D
-
-/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
-#define EGL_HEIGHT                     0x3056
-#define EGL_WIDTH                      0x3057
-#define EGL_LARGEST_PBUFFER            0x3058
-#define EGL_TEXTURE_FORMAT             0x3080
-#define EGL_TEXTURE_TARGET             0x3081
-#define EGL_MIPMAP_TEXTURE             0x3082
-#define EGL_MIPMAP_LEVEL               0x3083
-#define EGL_RENDER_BUFFER              0x3086
-#define EGL_VG_COLORSPACE              0x3087
-#define EGL_VG_ALPHA_FORMAT            0x3088
-#define EGL_HORIZONTAL_RESOLUTION      0x3090
-#define EGL_VERTICAL_RESOLUTION                0x3091
-#define EGL_PIXEL_ASPECT_RATIO         0x3092
-#define EGL_SWAP_BEHAVIOR              0x3093
-#define EGL_MULTISAMPLE_RESOLVE                0x3099
-
-/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
-#define EGL_BACK_BUFFER                        0x3084
-#define EGL_SINGLE_BUFFER              0x3085
-
-/* OpenVG color spaces */
-#define EGL_VG_COLORSPACE_sRGB         0x3089  /* EGL_VG_COLORSPACE value */
-#define EGL_VG_COLORSPACE_LINEAR       0x308A  /* EGL_VG_COLORSPACE value */
-
-/* OpenVG alpha formats */
-#define EGL_VG_ALPHA_FORMAT_NONPRE     0x308B  /* EGL_ALPHA_FORMAT value */
-#define EGL_VG_ALPHA_FORMAT_PRE                0x308C  /* EGL_ALPHA_FORMAT value */
-
-/* Constant scale factor by which fractional display resolutions &
- * aspect ratio are scaled when queried as integer values.
- */
-#define EGL_DISPLAY_SCALING            10000
-
-/* Unknown display resolution/aspect ratio */
-#define EGL_UNKNOWN                    ((EGLint)-1)
-
-/* Back buffer swap behaviors */
-#define EGL_BUFFER_PRESERVED           0x3094  /* EGL_SWAP_BEHAVIOR value */
-#define EGL_BUFFER_DESTROYED           0x3095  /* EGL_SWAP_BEHAVIOR value */
-
-/* CreatePbufferFromClientBuffer buffer types */
-#define EGL_OPENVG_IMAGE               0x3096
-
-/* QueryContext targets */
-#define EGL_CONTEXT_CLIENT_TYPE                0x3097
-
-/* CreateContext attributes */
-#define EGL_CONTEXT_CLIENT_VERSION     0x3098
-
-/* Multisample resolution behaviors */
-#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
-#define EGL_MULTISAMPLE_RESOLVE_BOX    0x309B  /* EGL_MULTISAMPLE_RESOLVE value */
-
-/* BindAPI/QueryAPI targets */
-#define EGL_OPENGL_ES_API              0x30A0
-#define EGL_OPENVG_API                 0x30A1
-#define EGL_OPENGL_API                 0x30A2
-
-/* GetCurrentSurface targets */
-#define EGL_DRAW                       0x3059
-#define EGL_READ                       0x305A
-
-/* WaitNative engines */
-#define EGL_CORE_NATIVE_ENGINE         0x305B
-
-/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
-#define EGL_COLORSPACE                 EGL_VG_COLORSPACE
-#define EGL_ALPHA_FORMAT               EGL_VG_ALPHA_FORMAT
-#define EGL_COLORSPACE_sRGB            EGL_VG_COLORSPACE_sRGB
-#define EGL_COLORSPACE_LINEAR          EGL_VG_COLORSPACE_LINEAR
-#define EGL_ALPHA_FORMAT_NONPRE                EGL_VG_ALPHA_FORMAT_NONPRE
-#define EGL_ALPHA_FORMAT_PRE           EGL_VG_ALPHA_FORMAT_PRE
-
-/* EGL extensions must request enum blocks from the Khronos
- * API Registrar, who maintains the enumerant registry. Submit
- * a bug in Khronos Bugzilla against task "Registry".
- */
-
-
-
-/* EGL Functions */
-
-EGLAPI EGLint EGLAPIENTRY eglGetError(void);
-
-EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
-EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
-EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
-
-EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
-                        EGLint config_size, EGLint *num_config);
-EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
-                          EGLConfig *configs, EGLint config_size,
-                          EGLint *num_config);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
-                             EGLint attribute, EGLint *value);
-
-EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
-                                 EGLNativeWindowType win,
-                                 const EGLint *attrib_list);
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
-                                  const EGLint *attrib_list);
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
-                                 EGLNativePixmapType pixmap,
-                                 const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
-EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
-                          EGLint attribute, EGLint *value);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
-EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
-
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
-             EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
-             EGLConfig config, const EGLint *attrib_list);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
-                           EGLint attribute, EGLint value);
-EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
-
-
-EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
-                           EGLContext share_context,
-                           const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
-EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
-                         EGLSurface read, EGLContext ctx);
-
-EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
-EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
-EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
-                          EGLint attribute, EGLint *value);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
-EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
-                         EGLNativePixmapType target);
-
-/* This is a generic function pointer type, whose name indicates it must
- * be cast to the proper type *and calling convention* before use.
- */
+typedef void *EGLContext;
 typedef void (*__eglMustCastToProperFunctionPointerType)(void);
-
-/* Now, define eglGetProcAddress using the generic function ptr. type */
-EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
-       eglGetProcAddress(const char *procname);
+#define EGL_ALPHA_SIZE                    0x3021
+#define EGL_BAD_ACCESS                    0x3002
+#define EGL_BAD_ALLOC                     0x3003
+#define EGL_BAD_ATTRIBUTE                 0x3004
+#define EGL_BAD_CONFIG                    0x3005
+#define EGL_BAD_CONTEXT                   0x3006
+#define EGL_BAD_CURRENT_SURFACE           0x3007
+#define EGL_BAD_DISPLAY                   0x3008
+#define EGL_BAD_MATCH                     0x3009
+#define EGL_BAD_NATIVE_PIXMAP             0x300A
+#define EGL_BAD_NATIVE_WINDOW             0x300B
+#define EGL_BAD_PARAMETER                 0x300C
+#define EGL_BAD_SURFACE                   0x300D
+#define EGL_BLUE_SIZE                     0x3022
+#define EGL_BUFFER_SIZE                   0x3020
+#define EGL_CONFIG_CAVEAT                 0x3027
+#define EGL_CONFIG_ID                     0x3028
+#define EGL_CORE_NATIVE_ENGINE            0x305B
+#define EGL_DEPTH_SIZE                    0x3025
+#define EGL_DONT_CARE                     ((EGLint)-1)
+#define EGL_DRAW                          0x3059
+#define EGL_EXTENSIONS                    0x3055
+#define EGL_FALSE                         0
+#define EGL_GREEN_SIZE                    0x3023
+#define EGL_HEIGHT                        0x3056
+#define EGL_LARGEST_PBUFFER               0x3058
+#define EGL_LEVEL                         0x3029
+#define EGL_MAX_PBUFFER_HEIGHT            0x302A
+#define EGL_MAX_PBUFFER_PIXELS            0x302B
+#define EGL_MAX_PBUFFER_WIDTH             0x302C
+#define EGL_NATIVE_RENDERABLE             0x302D
+#define EGL_NATIVE_VISUAL_ID              0x302E
+#define EGL_NATIVE_VISUAL_TYPE            0x302F
+#define EGL_NONE                          0x3038
+#define EGL_NON_CONFORMANT_CONFIG         0x3051
+#define EGL_NOT_INITIALIZED               0x3001
+#define EGL_NO_CONTEXT                    ((EGLContext)0)
+#define EGL_NO_DISPLAY                    ((EGLDisplay)0)
+#define EGL_NO_SURFACE                    ((EGLSurface)0)
+#define EGL_PBUFFER_BIT                   0x0001
+#define EGL_PIXMAP_BIT                    0x0002
+#define EGL_READ                          0x305A
+#define EGL_RED_SIZE                      0x3024
+#define EGL_SAMPLES                       0x3031
+#define EGL_SAMPLE_BUFFERS                0x3032
+#define EGL_SLOW_CONFIG                   0x3050
+#define EGL_STENCIL_SIZE                  0x3026
+#define EGL_SUCCESS                       0x3000
+#define EGL_SURFACE_TYPE                  0x3033
+#define EGL_TRANSPARENT_BLUE_VALUE        0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE       0x3036
+#define EGL_TRANSPARENT_RED_VALUE         0x3037
+#define EGL_TRANSPARENT_RGB               0x3052
+#define EGL_TRANSPARENT_TYPE              0x3034
+#define EGL_TRUE                          1
+#define EGL_VENDOR                        0x3053
+#define EGL_VERSION                       0x3054
+#define EGL_WIDTH                         0x3057
+#define EGL_WINDOW_BIT                    0x0004
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
+EGLAPI EGLint EGLAPIENTRY eglGetError (void);
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
+#endif /* EGL_VERSION_1_0 */
+
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+#define EGL_BACK_BUFFER                   0x3084
+#define EGL_BIND_TO_TEXTURE_RGB           0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA          0x303A
+#define EGL_CONTEXT_LOST                  0x300E
+#define EGL_MIN_SWAP_INTERVAL             0x303B
+#define EGL_MAX_SWAP_INTERVAL             0x303C
+#define EGL_MIPMAP_TEXTURE                0x3082
+#define EGL_MIPMAP_LEVEL                  0x3083
+#define EGL_NO_TEXTURE                    0x305C
+#define EGL_TEXTURE_2D                    0x305F
+#define EGL_TEXTURE_FORMAT                0x3080
+#define EGL_TEXTURE_RGB                   0x305D
+#define EGL_TEXTURE_RGBA                  0x305E
+#define EGL_TEXTURE_TARGET                0x3081
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
+#endif /* EGL_VERSION_1_1 */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+#define EGL_ALPHA_FORMAT                  0x3088
+#define EGL_ALPHA_FORMAT_NONPRE           0x308B
+#define EGL_ALPHA_FORMAT_PRE              0x308C
+#define EGL_ALPHA_MASK_SIZE               0x303E
+#define EGL_BUFFER_PRESERVED              0x3094
+#define EGL_BUFFER_DESTROYED              0x3095
+#define EGL_CLIENT_APIS                   0x308D
+#define EGL_COLORSPACE                    0x3087
+#define EGL_COLORSPACE_sRGB               0x3089
+#define EGL_COLORSPACE_LINEAR             0x308A
+#define EGL_COLOR_BUFFER_TYPE             0x303F
+#define EGL_CONTEXT_CLIENT_TYPE           0x3097
+#define EGL_DISPLAY_SCALING               10000
+#define EGL_HORIZONTAL_RESOLUTION         0x3090
+#define EGL_LUMINANCE_BUFFER              0x308F
+#define EGL_LUMINANCE_SIZE                0x303D
+#define EGL_OPENGL_ES_BIT                 0x0001
+#define EGL_OPENVG_BIT                    0x0002
+#define EGL_OPENGL_ES_API                 0x30A0
+#define EGL_OPENVG_API                    0x30A1
+#define EGL_OPENVG_IMAGE                  0x3096
+#define EGL_PIXEL_ASPECT_RATIO            0x3092
+#define EGL_RENDERABLE_TYPE               0x3040
+#define EGL_RENDER_BUFFER                 0x3086
+#define EGL_RGB_BUFFER                    0x308E
+#define EGL_SINGLE_BUFFER                 0x3085
+#define EGL_SWAP_BEHAVIOR                 0x3093
+#define EGL_UNKNOWN                       ((EGLint)-1)
+#define EGL_VERTICAL_RESOLUTION           0x3091
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
+#endif /* EGL_VERSION_1_2 */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+#define EGL_CONFORMANT                    0x3042
+#define EGL_CONTEXT_CLIENT_VERSION        0x3098
+#define EGL_MATCH_NATIVE_PIXMAP           0x3041
+#define EGL_OPENGL_ES2_BIT                0x0004
+#define EGL_VG_ALPHA_FORMAT               0x3088
+#define EGL_VG_ALPHA_FORMAT_NONPRE        0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE           0x308C
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT       0x0040
+#define EGL_VG_COLORSPACE                 0x3087
+#define EGL_VG_COLORSPACE_sRGB            0x3089
+#define EGL_VG_COLORSPACE_LINEAR          0x308A
+#define EGL_VG_COLORSPACE_LINEAR_BIT      0x0020
+#endif /* EGL_VERSION_1_3 */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+#define EGL_DEFAULT_DISPLAY               ((EGLNativeDisplayType)0)
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT   0x0200
+#define EGL_MULTISAMPLE_RESOLVE           0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT   0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX       0x309B
+#define EGL_OPENGL_API                    0x30A2
+#define EGL_OPENGL_BIT                    0x0008
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT   0x0400
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
+#endif /* EGL_VERSION_1_4 */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+typedef void *EGLImage;
+#define EGL_CONTEXT_MAJOR_VERSION         0x3098
+#define EGL_CONTEXT_MINOR_VERSION         0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK   0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION         0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET         0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG          0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS  0x31B2
+#define EGL_OPENGL_ES3_BIT                0x00000040
+#define EGL_CL_EVENT_HANDLE               0x309C
+#define EGL_SYNC_CL_EVENT                 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE        0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE  0x30F0
+#define EGL_SYNC_TYPE                     0x30F7
+#define EGL_SYNC_STATUS                   0x30F1
+#define EGL_SYNC_CONDITION                0x30F8
+#define EGL_SIGNALED                      0x30F2
+#define EGL_UNSIGNALED                    0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT       0x0001
+#define EGL_FOREVER                       0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED               0x30F5
+#define EGL_CONDITION_SATISFIED           0x30F6
+#define EGL_NO_SYNC                       ((EGLSync)0)
+#define EGL_SYNC_FENCE                    0x30F9
+#define EGL_GL_COLORSPACE                 0x309D
+#define EGL_GL_COLORSPACE_SRGB            0x3089
+#define EGL_GL_COLORSPACE_LINEAR          0x308A
+#define EGL_GL_RENDERBUFFER               0x30B9
+#define EGL_GL_TEXTURE_2D                 0x30B1
+#define EGL_GL_TEXTURE_LEVEL              0x30BC
+#define EGL_GL_TEXTURE_3D                 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET            0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_IMAGE_PRESERVED               0x30D2
+#define EGL_NO_IMAGE                      ((EGLImage)0)
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#endif /* EGL_VERSION_1_5 */
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __egl_h_ */
+#endif
index 88b39dbc4f7a9860b38fce51a2a36c03e837057d..6043b374fd27e5bd71f6a77ffb01d300cd223f94 100644 (file)
@@ -6,7 +6,7 @@ extern "C" {
 #endif
 
 /*
-** Copyright (c) 2013 The Khronos Group Inc.
+** Copyright (c) 2013-2014 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
@@ -33,12 +33,12 @@ extern "C" {
 ** used to make the header, and the header can be found at
 **   http://www.opengl.org/registry/
 **
-** Khronos $Revision: 24567 $ on $Date: 2013-12-18 09:50:17 -0800 (Wed, 18 Dec 2013) $
+** Khronos $Revision$ on $Date$
 */
 
 #include <EGL/eglplatform.h>
 
-#define EGL_EGLEXT_VERSION 20131218
+#define EGL_EGLEXT_VERSION 20150508
 
 /* Generated C header for:
  * API: egl
@@ -94,12 +94,28 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type,
 #define EGL_OPENGL_ES3_BIT_KHR            0x00000040
 #endif /* EGL_KHR_create_context */
 
+#ifndef EGL_KHR_create_context_no_error
+#define EGL_KHR_create_context_no_error 1
+#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR   0x31B3
+#endif /* EGL_KHR_create_context_no_error */
+
 #ifndef EGL_KHR_fence_sync
 #define EGL_KHR_fence_sync 1
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
 #ifdef KHRONOS_SUPPORT_INT64
 #define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
 #define EGL_SYNC_CONDITION_KHR            0x30F8
 #define EGL_SYNC_FENCE_KHR                0x30F9
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
 #endif /* KHRONOS_SUPPORT_INT64 */
 #endif /* EGL_KHR_fence_sync */
 
@@ -207,9 +223,38 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s
 #endif
 #endif /* EGL_KHR_lock_surface3 */
 
+#ifndef EGL_KHR_partial_update
+#define EGL_KHR_partial_update 1
+#define EGL_BUFFER_AGE_KHR                0x313D
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_partial_update */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+#define EGL_PLATFORM_ANDROID_KHR          0x3141
+#endif /* EGL_KHR_platform_android */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+#define EGL_PLATFORM_GBM_KHR              0x31D7
+#endif /* EGL_KHR_platform_gbm */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_KHR          0x31D8
+#endif /* EGL_KHR_platform_wayland */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+#define EGL_PLATFORM_X11_KHR              0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR       0x31D6
+#endif /* EGL_KHR_platform_x11 */
+
 #ifndef EGL_KHR_reusable_sync
 #define EGL_KHR_reusable_sync 1
-typedef khronos_utime_nanoseconds_t EGLTimeKHR;
 #ifdef KHRONOS_SUPPORT_INT64
 #define EGL_SYNC_STATUS_KHR               0x30F1
 #define EGL_SIGNALED_KHR                  0x30F2
@@ -221,17 +266,9 @@ typedef khronos_utime_nanoseconds_t EGLTimeKHR;
 #define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR   0x0001
 #define EGL_FOREVER_KHR                   0xFFFFFFFFFFFFFFFFull
 #define EGL_NO_SYNC_KHR                   ((EGLSyncKHR)0)
-typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
-typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
 #ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
-EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
 EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
 #endif
 #endif /* KHRONOS_SUPPORT_INT64 */
 #endif /* EGL_KHR_reusable_sync */
@@ -333,6 +370,14 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy,
 #define EGL_KHR_surfaceless_context 1
 #endif /* EGL_KHR_surfaceless_context */
 
+#ifndef EGL_KHR_swap_buffers_with_damage
+#define EGL_KHR_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
 #ifndef EGL_KHR_vg_parent_image
 #define EGL_KHR_vg_parent_image 1
 #define EGL_VG_PARENT_IMAGE_KHR           0x30BA
@@ -389,6 +434,12 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR
 #define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
 #endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
 
+#ifndef EGL_ANGLE_device_d3d
+#define EGL_ANGLE_device_d3d 1
+#define EGL_D3D9_DEVICE_ANGLE             0x33A0
+#define EGL_D3D11_DEVICE_ANGLE            0x33A1
+#endif /* EGL_ANGLE_device_d3d */
+
 #ifndef EGL_ANGLE_query_surface_pointer
 #define EGL_ANGLE_query_surface_pointer 1
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
@@ -401,6 +452,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
 #define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
 #endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
 
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+#define EGL_FIXED_SIZE_ANGLE              0x3201
+#endif /* EGL_ANGLE_window_fixed_size */
+
 #ifndef EGL_ARM_pixmap_multisample_discard
 #define EGL_ARM_pixmap_multisample_discard 1
 #define EGL_DISCARD_SAMPLES_ARM           0x3286
@@ -423,6 +479,42 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
 #define EGL_LOSE_CONTEXT_ON_RESET_EXT     0x31BF
 #endif /* EGL_EXT_create_context_robustness */
 
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT                 ((EGLDeviceEXT)(0))
+#define EGL_BAD_DEVICE_EXT                0x322B
+#define EGL_DEVICE_EXT                    0x322C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_EXT_device_base */
+
+#ifndef EGL_EXT_device_drm
+#define EGL_EXT_device_drm 1
+#define EGL_DRM_DEVICE_FILE_EXT           0x3233
+#endif /* EGL_EXT_device_drm */
+
+#ifndef EGL_EXT_device_enumeration
+#define EGL_EXT_device_enumeration 1
+#endif /* EGL_EXT_device_enumeration */
+
+#ifndef EGL_EXT_device_openwf
+#define EGL_EXT_device_openwf 1
+#define EGL_OPENWF_DEVICE_ID_EXT          0x3237
+#endif /* EGL_EXT_device_openwf */
+
+#ifndef EGL_EXT_device_query
+#define EGL_EXT_device_query 1
+#endif /* EGL_EXT_device_query */
+
 #ifndef EGL_EXT_image_dma_buf_import
 #define EGL_EXT_image_dma_buf_import 1
 #define EGL_LINUX_DMA_BUF_EXT             0x3270
@@ -454,6 +546,48 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
 #define EGL_MULTIVIEW_VIEW_COUNT_EXT      0x3134
 #endif /* EGL_EXT_multiview_window */
 
+#ifndef EGL_EXT_output_base
+#define EGL_EXT_output_base 1
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+#define EGL_NO_OUTPUT_LAYER_EXT           ((EGLOutputLayerEXT)0)
+#define EGL_NO_OUTPUT_PORT_EXT            ((EGLOutputPortEXT)0)
+#define EGL_BAD_OUTPUT_LAYER_EXT          0x322D
+#define EGL_BAD_OUTPUT_PORT_EXT           0x322E
+#define EGL_SWAP_INTERVAL_EXT             0x322F
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#endif
+#endif /* EGL_EXT_output_base */
+
+#ifndef EGL_EXT_output_drm
+#define EGL_EXT_output_drm 1
+#define EGL_DRM_CRTC_EXT                  0x3234
+#define EGL_DRM_PLANE_EXT                 0x3235
+#define EGL_DRM_CONNECTOR_EXT             0x3236
+#endif /* EGL_EXT_output_drm */
+
+#ifndef EGL_EXT_output_openwf
+#define EGL_EXT_output_openwf 1
+#define EGL_OPENWF_PIPELINE_ID_EXT        0x3238
+#define EGL_OPENWF_PORT_ID_EXT            0x3239
+#endif /* EGL_EXT_output_openwf */
+
 #ifndef EGL_EXT_platform_base
 #define EGL_EXT_platform_base 1
 typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
@@ -466,6 +600,11 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy,
 #endif
 #endif /* EGL_EXT_platform_base */
 
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+#define EGL_PLATFORM_DEVICE_EXT           0x313F
+#endif /* EGL_EXT_platform_device */
+
 #ifndef EGL_EXT_platform_wayland
 #define EGL_EXT_platform_wayland 1
 #define EGL_PLATFORM_WAYLAND_EXT          0x31D8
@@ -477,6 +616,19 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy,
 #define EGL_PLATFORM_X11_SCREEN_EXT       0x31D6
 #endif /* EGL_EXT_platform_x11 */
 
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+#define EGL_PROTECTED_CONTENT_EXT         0x32C0
+#endif /* EGL_EXT_protected_surface */
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+#define EGL_EXT_stream_consumer_egloutput 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#endif
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
 #ifndef EGL_EXT_swap_buffers_with_damage
 #define EGL_EXT_swap_buffers_with_damage 1
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
@@ -485,6 +637,35 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSu
 #endif
 #endif /* EGL_EXT_swap_buffers_with_damage */
 
+#ifndef EGL_EXT_yuv_surface
+#define EGL_EXT_yuv_surface 1
+#define EGL_YUV_ORDER_EXT                 0x3301
+#define EGL_YUV_NUMBER_OF_PLANES_EXT      0x3311
+#define EGL_YUV_SUBSAMPLE_EXT             0x3312
+#define EGL_YUV_DEPTH_RANGE_EXT           0x3317
+#define EGL_YUV_CSC_STANDARD_EXT          0x330A
+#define EGL_YUV_PLANE_BPP_EXT             0x331A
+#define EGL_YUV_BUFFER_EXT                0x3300
+#define EGL_YUV_ORDER_YUV_EXT             0x3302
+#define EGL_YUV_ORDER_YVU_EXT             0x3303
+#define EGL_YUV_ORDER_YUYV_EXT            0x3304
+#define EGL_YUV_ORDER_UYVY_EXT            0x3305
+#define EGL_YUV_ORDER_YVYU_EXT            0x3306
+#define EGL_YUV_ORDER_VYUY_EXT            0x3307
+#define EGL_YUV_ORDER_AYUV_EXT            0x3308
+#define EGL_YUV_SUBSAMPLE_4_2_0_EXT       0x3313
+#define EGL_YUV_SUBSAMPLE_4_2_2_EXT       0x3314
+#define EGL_YUV_SUBSAMPLE_4_4_4_EXT       0x3315
+#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT   0x3318
+#define EGL_YUV_DEPTH_RANGE_FULL_EXT      0x3319
+#define EGL_YUV_CSC_STANDARD_601_EXT      0x330B
+#define EGL_YUV_CSC_STANDARD_709_EXT      0x330C
+#define EGL_YUV_CSC_STANDARD_2020_EXT     0x330D
+#define EGL_YUV_PLANE_BPP_0_EXT           0x331B
+#define EGL_YUV_PLANE_BPP_8_EXT           0x331C
+#define EGL_YUV_PLANE_BPP_10_EXT          0x331D
+#endif /* EGL_EXT_yuv_surface */
+
 #ifndef EGL_HI_clientpixmap
 #define EGL_HI_clientpixmap 1
 struct EGLClientPixmapHI {
@@ -533,11 +714,42 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR
 #endif
 #endif /* EGL_MESA_drm_image */
 
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#endif
+#endif /* EGL_MESA_image_dma_buf_export */
+
 #ifndef EGL_MESA_platform_gbm
 #define EGL_MESA_platform_gbm 1
 #define EGL_PLATFORM_GBM_MESA             0x31D7
 #endif /* EGL_MESA_platform_gbm */
 
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region2 */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+#define EGL_Y_INVERTED_NOK                0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
 #ifndef EGL_NV_3dvision_surface
 #define EGL_NV_3dvision_surface 1
 #define EGL_AUTO_STEREO_NV                0x3136
@@ -556,6 +768,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR
 #define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
 #endif /* EGL_NV_coverage_sample_resolve */
 
+#ifndef EGL_NV_cuda_event
+#define EGL_NV_cuda_event 1
+#define EGL_CUDA_EVENT_HANDLE_NV          0x323B
+#define EGL_SYNC_CUDA_EVENT_NV            0x323C
+#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV   0x323D
+#endif /* EGL_NV_cuda_event */
+
 #ifndef EGL_NV_depth_nonlinear
 #define EGL_NV_depth_nonlinear 1
 #define EGL_DEPTH_ENCODING_NV             0x30E2
@@ -563,6 +782,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR
 #define EGL_DEPTH_ENCODING_NONLINEAR_NV   0x30E3
 #endif /* EGL_NV_depth_nonlinear */
 
+#ifndef EGL_NV_device_cuda
+#define EGL_NV_device_cuda 1
+#define EGL_CUDA_DEVICE_NV                0x323A
+#endif /* EGL_NV_device_cuda */
+
 #ifndef EGL_NV_native_query
 #define EGL_NV_native_query 1
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
@@ -645,6 +869,16 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
 #endif /* KHRONOS_SUPPORT_INT64 */
 #endif /* EGL_NV_system_time */
 
+#ifndef EGL_TIZEN_image_native_buffer
+#define EGL_TIZEN_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_TIZEN           0x32A0
+#endif /* EGL_TIZEN_image_native_buffer */
+
+#ifndef EGL_TIZEN_image_native_surface
+#define EGL_TIZEN_image_native_surface 1
+#define EGL_NATIVE_SURFACE_TIZEN          0x32A1
+#endif /* EGL_TIZEN_image_native_surface */
+
 #include <EGL/eglmesaext.h>
 #include <EGL/eglextchromium.h>
 
index 7ce8346c2c63b0da84e62b288e579bd66c88b17a..917a2043c777547dcab9c52c540b59e5382b0481 100644 (file)
@@ -34,63 +34,6 @@ extern "C" {
 
 #include <EGL/eglplatform.h>
 
-/* EGL_MESA_screen extension  >>> PRELIMINARY <<< */
-#ifndef EGL_MESA_screen_surface
-#define EGL_MESA_screen_surface 1
-
-#define EGL_BAD_SCREEN_MESA                    0x4000
-#define EGL_BAD_MODE_MESA                      0x4001
-#define EGL_SCREEN_COUNT_MESA                  0x4002
-#define EGL_SCREEN_POSITION_MESA               0x4003
-#define EGL_SCREEN_POSITION_GRANULARITY_MESA   0x4004
-#define EGL_MODE_ID_MESA                       0x4005
-#define EGL_REFRESH_RATE_MESA                  0x4006
-#define EGL_OPTIMAL_MESA                       0x4007
-#define EGL_INTERLACED_MESA                    0x4008
-#define EGL_SCREEN_BIT_MESA                    0x08
-
-typedef khronos_uint32_t EGLScreenMESA;
-typedef khronos_uint32_t EGLModeMESA;
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
-EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode);
-
-#endif /* EGL_MESA_screen_surface */
-
-#ifndef EGL_MESA_copy_context
-#define EGL_MESA_copy_context 1
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-
-#endif /* EGL_MESA_copy_context */
-
 #ifndef EGL_MESA_drm_display
 #define EGL_MESA_drm_display 1
 
@@ -144,39 +87,14 @@ typedef struct wl_buffer * (EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL) (
 
 #endif
 
-#ifndef EGL_NOK_swap_region
-#define EGL_NOK_swap_region 1
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
-#endif
-
+/* remnant of EGL_NOK_swap_region kept for compatibility because of a non-standard type name */
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
-#endif
-
-#ifndef EGL_NOK_texture_from_pixmap
-#define EGL_NOK_texture_from_pixmap 1
-
-#define EGL_Y_INVERTED_NOK                     0x307F
-#endif /* EGL_NOK_texture_from_pixmap */
-
-#ifndef EGL_ANDROID_image_native_buffer
-#define EGL_ANDROID_image_native_buffer 1
-#define EGL_NATIVE_BUFFER_ANDROID       0x3140  /* eglCreateImageKHR target */
-#endif
 
 #ifndef EGL_MESA_configless_context
 #define EGL_MESA_configless_context 1
 #define EGL_NO_CONFIG_MESA                     ((EGLConfig)0)
 #endif
 
-#if KHRONOS_SUPPORT_INT64
-#ifndef EGL_MESA_image_dma_buf_export
-#define EGL_MESA_image_dma_buf_export 1
-EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *fourcc, EGLint *nplanes, EGLuint64KHR *modifiers);
-EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
-#endif
-#endif
 #ifdef __cplusplus
 }
 #endif
index 2eb6865905c34e379d7685e1e3fab35298618976..7802542ad0f546c0e9989ed89a2b83995cd2ded2 100644 (file)
@@ -2,7 +2,7 @@
 #define __eglplatform_h_
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2007-2013 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
@@ -25,7 +25,7 @@
 */
 
 /* Platform-specific types and definitions for egl.h
- * $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $
+ * $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
@@ -77,7 +77,7 @@ typedef HDC     EGLNativeDisplayType;
 typedef HBITMAP EGLNativePixmapType;
 typedef HWND    EGLNativeWindowType;
 
-#elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */
+#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */
 
 typedef int   EGLNativeDisplayType;
 typedef void *EGLNativeWindowType;
@@ -95,14 +95,15 @@ typedef struct gbm_device  *EGLNativeDisplayType;
 typedef struct gbm_bo      *EGLNativePixmapType;
 typedef void               *EGLNativeWindowType;
 
-#elif defined(ANDROID) /* Android */
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+#include <android/native_window.h>
 
-struct ANativeWindow;
 struct egl_native_pixmap_t;
 
-typedef struct ANativeWindow        *EGLNativeWindowType;
-typedef struct egl_native_pixmap_t  *EGLNativePixmapType;
-typedef void                        *EGLNativeDisplayType;
+typedef struct ANativeWindow*           EGLNativeWindowType;
+typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
+typedef void*                           EGLNativeDisplayType;
 
 #elif defined(__unix__)
 
@@ -131,9 +132,7 @@ typedef khronos_uintptr_t    EGLNativePixmapType;
 typedef khronos_uintptr_t       EGLNativeWindowType;
 
 #else
-
 #error "Platform not recognized"
-
 #endif
 
 /* EGL 1.2 types, renamed for consistency in EGL 1.3 */
index 447953940e64ccfb6adab9d25ce5857e3ace1931..790de44b8f683512f1d1d1f3f36fd73f1a90b13e 100644 (file)
@@ -26,7 +26,7 @@
 
 /* Khronos platform-specific types and definitions.
  *
- * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
+ * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
  *
  * Adopters may modify this file to suit their platform. Adopters are
  * encouraged to submit platform specific modifications to the Khronos
 #elif defined (__SYMBIAN32__)
 #   define KHRONOS_APICALL IMPORT_C
 #elif (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \
-       || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+       || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
 /* KHRONOS_APIATTRIBUTES is not used by the client API headers yet */
-#  define KHRONOS_APICALL __attribute__((visibility("default")))
+#   define KHRONOS_APICALL __attribute__((visibility("default")))
 #else
 #   define KHRONOS_APICALL
 #endif
@@ -229,10 +229,23 @@ typedef signed   char          khronos_int8_t;
 typedef unsigned char          khronos_uint8_t;
 typedef signed   short int     khronos_int16_t;
 typedef unsigned short int     khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64, 
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef _WIN64
+typedef signed   long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed   long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
 typedef signed   long  int     khronos_intptr_t;
 typedef unsigned long  int     khronos_uintptr_t;
 typedef signed   long  int     khronos_ssize_t;
 typedef unsigned long  int     khronos_usize_t;
+#endif
 
 #if KHRONOS_SUPPORT_FLOAT
 /*
index 571e8633ffbd4fa3c60e4008de60a03c90ec8c01..cd5da99a6a620bfdae47e8b2c5697832b533fd13 100644 (file)
@@ -85,6 +85,7 @@ CHIPSET(0x6651, BONAIRE_6651, BONAIRE)
 CHIPSET(0x6658, BONAIRE_6658, BONAIRE)
 CHIPSET(0x665C, BONAIRE_665C, BONAIRE)
 CHIPSET(0x665D, BONAIRE_665D, BONAIRE)
+CHIPSET(0x665F, BONAIRE_665F, BONAIRE)
 
 CHIPSET(0x9830, KABINI_9830, KABINI)
 CHIPSET(0x9831, KABINI_9831, KABINI)
index 17278df88be911fce48f8ed76b0eae3c3592d954..c59b8cb9317f0f384dd7d6686c04bcdd4569d497 100644 (file)
@@ -120,6 +120,7 @@ def generate(env):
             ])
         elif llvm_version >= distutils.version.LooseVersion('3.5'):
             env.Prepend(LIBS = [
+                'LLVMMCDisassembler',
                 'LLVMBitWriter', 'LLVMMCJIT', 'LLVMRuntimeDyld',
                 'LLVMX86Disassembler', 'LLVMX86AsmParser', 'LLVMX86CodeGen',
                 'LLVMSelectionDAG', 'LLVMAsmPrinter', 'LLVMX86Desc',
@@ -132,6 +133,7 @@ def generate(env):
             ])
         else:
             env.Prepend(LIBS = [
+                'LLVMMCDisassembler',
                 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser',
                 'LLVMX86CodeGen', 'LLVMX86Desc', 'LLVMSelectionDAG',
                 'LLVMAsmPrinter', 'LLVMMCParser', 'LLVMX86AsmPrinter',
@@ -189,7 +191,7 @@ def generate(env):
             if '-fno-rtti' in cxxflags:
                 env.Append(CXXFLAGS = ['-fno-rtti'])
 
-            components = ['engine', 'mcjit', 'bitwriter', 'x86asmprinter']
+            components = ['engine', 'mcjit', 'bitwriter', 'x86asmprinter', 'mcdisassembler']
 
             env.ParseConfig('llvm-config --libs ' + ' '.join(components))
             env.ParseConfig('llvm-config --ldflags')
index bf76e35f144b7f0d7d6975629933c266be187ab5..d41a087ae1c1cafc3f4a807a992fdd53180581e7 100644 (file)
@@ -76,4 +76,5 @@ noinst_LTLIBRARIES = libglsl_util.la
 libglsl_util_la_SOURCES = \
        mesa/main/imports.c \
        mesa/program/prog_hash_table.c \
-       mesa/program/symbol_table.c
+       mesa/program/symbol_table.c \
+       mesa/program/dummy_errors.c
index 5931ce8f2f04fafa1682cf09a4c96af8fb116dd0..109e4d4a0d84855b4ebb5f9b6a2966e50de3fc59 100644 (file)
@@ -36,6 +36,7 @@ LOCAL_CFLAGS := \
        -DHAVE_ANDROID_PLATFORM
 
 ifeq ($(MESA_LOLLIPOP_BUILD),true)
+LOCAL_CFLAGS_arm := -DDEFAULT_DRIVER_DIR=\"/system/lib/dri\"
 LOCAL_CFLAGS_x86 := -DDEFAULT_DRIVER_DIR=\"/system/lib/dri\"
 LOCAL_CFLAGS_x86_64 := -DDEFAULT_DRIVER_DIR=\"/system/lib64/dri\"
 else
@@ -45,7 +46,6 @@ endif
 LOCAL_C_INCLUDES := \
        $(MESA_TOP)/src/mapi \
        $(MESA_TOP)/src/egl/main \
-       $(MESA_TOP)/src/loader \
        $(DRM_GRALLOC_TOP)
 
 LOCAL_STATIC_LIBRARIES := \
index f589600be0f7ccaecc2871409c8dae87719ab310..55be4a75ba5af07dd6eeae787a5557c5b7ea8207 100644 (file)
@@ -65,4 +65,9 @@ libegl_dri2_la_SOURCES += platform_drm.c
 AM_CFLAGS += -DHAVE_DRM_PLATFORM
 endif
 
+if HAVE_EGL_PLATFORM_SURFACELESS
+libegl_dri2_la_SOURCES += platform_surfaceless.c
+AM_CFLAGS += -DHAVE_SURFACELESS_PLATFORM
+endif
+
 EXTRA_DIST = SConscript
index f4c29da61cfb1a98564d9efdee4bd6287a499cda..a1cbd437f535b93454577da4349ccb1d5434ff3d 100644 (file)
@@ -397,7 +397,7 @@ dri2_open_driver(_EGLDisplay *disp)
 
    dri2_dpy->driver = NULL;
    end = search_paths + strlen(search_paths);
-   for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) {
+   for (p = search_paths; p < end; p = next + 1) {
       int len;
       next = strchr(p, ':');
       if (next == NULL)
@@ -419,6 +419,15 @@ dri2_open_driver(_EGLDisplay *disp)
       /* not need continue to loop all paths once the driver is found */
       if (dri2_dpy->driver != NULL)
          break;
+
+#ifdef ANDROID
+      snprintf(path, sizeof path, "%.*s/gallium_dri.so", len, p);
+      dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+      if (dri2_dpy->driver == NULL)
+         _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
+      else
+         break;
+#endif
    }
 
    if (dri2_dpy->driver == NULL) {
@@ -576,6 +585,7 @@ dri2_create_screen(_EGLDisplay *disp)
 {
    const __DRIextension **extensions;
    struct dri2_egl_display *dri2_dpy;
+   unsigned i;
 
    dri2_dpy = disp->DriverData;
 
@@ -616,28 +626,26 @@ dri2_create_screen(_EGLDisplay *disp)
    extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
    
    if (dri2_dpy->dri2) {
-      unsigned i;
-
       if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
          goto cleanup_dri_screen;
-
-      for (i = 0; extensions[i]; i++) {
-        if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) {
-            dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i];
-        }
-        if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) {
-           dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i];
-        }
-         if (strcmp(extensions[i]->name, __DRI2_FENCE) == 0) {
-            dri2_dpy->fence = (__DRI2fenceExtension *) extensions[i];
-         }
-      }
    } else {
       assert(dri2_dpy->swrast);
       if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions))
          goto cleanup_dri_screen;
    }
 
+   for (i = 0; extensions[i]; i++) {
+      if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) {
+         dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i];
+      }
+      if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) {
+         dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i];
+      }
+      if (strcmp(extensions[i]->name, __DRI2_FENCE) == 0) {
+         dri2_dpy->fence = (__DRI2fenceExtension *) extensions[i];
+      }
+   }
+
    dri2_setup_screen(disp);
 
    return EGL_TRUE;
@@ -659,6 +667,13 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp)
       return EGL_FALSE;
 
    switch (disp->Platform) {
+#ifdef HAVE_SURFACELESS_PLATFORM
+   case _EGL_PLATFORM_SURFACELESS:
+      if (disp->Options.TestOnly)
+         return EGL_TRUE;
+      return dri2_initialize_surfaceless(drv, disp);
+#endif
+
 #ifdef HAVE_X11_PLATFORM
    case _EGL_PLATFORM_X11:
       if (disp->Options.TestOnly)
@@ -729,7 +744,12 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
 #endif
 #ifdef HAVE_WAYLAND_PLATFORM
    case _EGL_PLATFORM_WAYLAND:
-      wl_drm_destroy(dri2_dpy->wl_drm);
+      if (dri2_dpy->wl_drm)
+          wl_drm_destroy(dri2_dpy->wl_drm);
+      if (dri2_dpy->wl_shm)
+          wl_shm_destroy(dri2_dpy->wl_shm);
+      wl_registry_destroy(dri2_dpy->wl_registry);
+      wl_event_queue_destroy(dri2_dpy->wl_queue);
       if (dri2_dpy->own_device) {
          wl_display_disconnect(dri2_dpy->wl_dpy);
       }
@@ -1252,7 +1272,8 @@ dri2_bind_tex_image(_EGLDriver *drv,
       format = __DRI_TEXTURE_FORMAT_RGBA;
       break;
    default:
-      assert(0);
+      assert(!"Unexpected texture format in dri2_bind_tex_image()");
+      format = __DRI_TEXTURE_FORMAT_RGBA;
    }
 
    switch (dri2_surf->base.TextureTarget) {
@@ -1260,7 +1281,8 @@ dri2_bind_tex_image(_EGLDriver *drv,
       target = GL_TEXTURE_2D;
       break;
    default:
-      assert(0);
+      target = GL_TEXTURE_2D;
+      assert(!"Unexpected texture target in dri2_bind_tex_image()");
    }
 
    (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context,
@@ -2210,7 +2232,7 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy,
 static _EGLSync *
 dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
                  EGLenum type, const EGLint *attrib_list,
-                 const EGLAttribKHR *attrib_list64)
+                 const EGLAttrib *attrib_list64)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
@@ -2276,7 +2298,7 @@ dri2_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
 
 static EGLint
 dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
-                      EGLint flags, EGLTimeKHR timeout)
+                      EGLint flags, EGLTime timeout)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
index 371fb4aee4ac41cc0d3a86a8982813ee4319d7e9..9985c49f98494502774f39d286cfdc8a7a7ce85f 100644 (file)
@@ -196,10 +196,13 @@ struct dri2_egl_display
    struct wl_registry       *wl_registry;
    struct wl_drm            *wl_server_drm;
    struct wl_drm            *wl_drm;
+   struct wl_shm            *wl_shm;
    struct wl_event_queue    *wl_queue;
    int                      authenticated;
    int                      formats;
    uint32_t                  capabilities;
+   int                      is_render_node;
+   int                      is_different_gpu;
 #endif
 };
 
@@ -253,6 +256,11 @@ struct dri2_egl_surface
 #ifdef HAVE_WAYLAND_PLATFORM
       struct wl_buffer   *wl_buffer;
       __DRIimage         *dri_image;
+      /* for is_different_gpu case. NULL else */
+      __DRIimage         *linear_copy;
+      /* for swrast */
+      void *data;
+      int data_size;
 #endif
 #ifdef HAVE_DRM_PLATFORM
       struct gbm_bo       *bo;
@@ -343,6 +351,9 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp);
 EGLBoolean
 dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp);
 
+EGLBoolean
+dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp);
+
 void
 dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw);
 
index 9cba0010ba79f2975acd36e0851965bcccfbc79d..e769af36e60a8889953903d3aca985eb260b4f1a 100644 (file)
@@ -45,6 +45,15 @@ dri2_fallback_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
    return NULL;
 }
 
+static inline _EGLImage*
+dri2_fallback_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+                               _EGLContext *ctx, EGLenum target,
+                               EGLClientBuffer buffer,
+                               const EGLint *attr_list)
+{
+   return NULL;
+}
+
 static inline EGLBoolean
 dri2_fallback_swap_interval(_EGLDriver *drv, _EGLDisplay *dpy,
                             _EGLSurface *surf, EGLint interval)
index f4825261badc502fe4ce85812f2aa2a437b28389..fed3073088acc6d72f9bb1865365b69cc935809e 100644 (file)
@@ -707,10 +707,6 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
    dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
    dpy->Extensions.KHR_image_base = EGL_TRUE;
 
-   /* we're supporting EGL 1.4 */
-   dpy->VersionMajor = 1;
-   dpy->VersionMinor = 4;
-
    /* Fill vtbl last to prevent accidentally calling virtual function during
     * initialization.
     */
index 486b0030dcd80def5be4478d2fe594754af142e3..a62da4121fed304860d10b32cd2e330c4f436aac 100644 (file)
@@ -611,9 +611,9 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
       char buf[64];
       int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
       if (n != -1 && n < sizeof(buf))
-         fd = open(buf, O_RDWR);
+         fd = loader_open_device(buf);
       if (fd < 0)
-         fd = open("/dev/dri/card0", O_RDWR);
+         fd = loader_open_device("/dev/dri/card0");
       dri2_dpy->own_device = 1;
       gbm = gbm_create_device(fd);
       if (gbm == NULL)
@@ -632,7 +632,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
    }
 
    if (fd < 0) {
-      fd = dup(gbm_device_get_fd(gbm));
+      fd = fcntl(gbm_device_get_fd(gbm), F_DUPFD_CLOEXEC, 3);
       if (fd < 0) {
          free(dri2_dpy);
          return EGL_FALSE;
@@ -715,10 +715,6 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
    }
 #endif
 
-   /* we're supporting EGL 1.4 */
-   disp->VersionMajor = 1;
-   disp->VersionMinor = 4;
-
    /* Fill vtbl last to prevent accidentally calling virtual function during
     * initialization.
     */
diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c
new file mode 100644 (file)
index 0000000..48f15df
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (c) 2014 The Chromium OS Authors.
+ * Copyright Â© 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <xf86drm.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "egl_dri2.h"
+#include "egl_dri2_fallbacks.h"
+#include "loader.h"
+
+static struct dri2_egl_display_vtbl dri2_surfaceless_display_vtbl = {
+   .create_pixmap_surface = dri2_fallback_create_pixmap_surface,
+   .create_image = dri2_create_image_khr,
+   .swap_interval = dri2_fallback_swap_interval,
+   .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
+   .swap_buffers_region = dri2_fallback_swap_buffers_region,
+   .post_sub_buffer = dri2_fallback_post_sub_buffer,
+   .copy_buffers = dri2_fallback_copy_buffers,
+   .query_buffer_age = dri2_fallback_query_buffer_age,
+   .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
+   .get_sync_values = dri2_fallback_get_sync_values,
+};
+
+static void
+surfaceless_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
+{
+}
+
+static __DRIbuffer *
+surfaceless_get_buffers_with_format(__DRIdrawable * driDrawable,
+                             int *width, int *height,
+                             unsigned int *attachments, int count,
+                             int *out_count, void *loaderPrivate)
+{
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+
+   dri2_surf->buffer_count = 1;
+   if (width)
+      *width = dri2_surf->base.Width;
+   if (height)
+      *height = dri2_surf->base.Height;
+   *out_count = dri2_surf->buffer_count;;
+   return dri2_surf->buffers;
+}
+
+#define DRM_RENDER_DEV_NAME  "%s/renderD%d"
+
+EGLBoolean
+dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp)
+{
+   struct dri2_egl_display *dri2_dpy;
+   const char* err;
+   int i;
+   int driver_loaded = 0;
+
+   loader_set_logger(_eglLog);
+
+   dri2_dpy = calloc(1, sizeof *dri2_dpy);
+   if (!dri2_dpy)
+      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+   disp->DriverData = (void *) dri2_dpy;
+
+   const int limit = 64;
+   const int base = 128;
+   for (i = 0; i < limit; ++i) {
+      char *card_path;
+      if (asprintf(&card_path, DRM_RENDER_DEV_NAME, DRM_DIR_NAME, base + i) < 0)
+         continue;
+
+      dri2_dpy->fd = loader_open_device(card_path);
+
+      free(card_path);
+      if (dri2_dpy->fd < 0)
+         continue;
+
+      dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
+      if (dri2_dpy->driver_name) {
+         if (dri2_load_driver(disp)) {
+            driver_loaded = 1;
+            break;
+         }
+         free(dri2_dpy->driver_name);
+      }
+      close(dri2_dpy->fd);
+   }
+
+   if (!driver_loaded) {
+      err = "DRI2: failed to load driver";
+      goto cleanup_display;
+   }
+
+   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
+   dri2_dpy->dri2_loader_extension.base.version = 3;
+   dri2_dpy->dri2_loader_extension.getBuffers = NULL;
+   dri2_dpy->dri2_loader_extension.flushFrontBuffer =
+      surfaceless_flush_front_buffer;
+   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
+      surfaceless_get_buffers_with_format;
+
+   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
+   dri2_dpy->extensions[1] = &image_lookup_extension.base;
+   dri2_dpy->extensions[2] = &use_invalidate.base;
+   dri2_dpy->extensions[3] = NULL;
+
+   if (!dri2_create_screen(disp)) {
+      err = "DRI2: failed to create screen";
+      goto cleanup_driver;
+   }
+
+   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
+      dri2_add_config(disp, dri2_dpy->driver_configs[i],
+                      i + 1, EGL_WINDOW_BIT, NULL, NULL);
+   }
+
+   disp->Extensions.KHR_image_base = EGL_TRUE;
+
+   /* Fill vtbl last to prevent accidentally calling virtual function during
+    * initialization.
+    */
+   dri2_dpy->vtbl = &dri2_surfaceless_display_vtbl;
+
+   return EGL_TRUE;
+
+cleanup_driver:
+   dlclose(dri2_dpy->driver);
+   free(dri2_dpy->driver_name);
+   close(dri2_dpy->fd);
+cleanup_display:
+   free(dri2_dpy);
+
+   return _eglError(EGL_NOT_INITIALIZED, err);
+}
index e2260053917e152b5ead81ff738a885796d4367c..1c985523862a8d9a8b2cbd8082e1fda8fe9e610e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright Â© 2011-2012 Intel Corporation
+ * Copyright Â© 2012 Collabora, Ltd.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -35,6 +36,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <xf86drm.h>
+#include <sys/mman.h>
 
 #include "egl_dri2.h"
 #include "egl_dri2_fallbacks.h"
@@ -120,7 +122,7 @@ resize_callback(struct wl_egl_window *wl_win, void *data)
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
  */
 static _EGLSurface *
-dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
+dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp,
                        _EGLConfig *conf, void *native_window,
                        const EGLint *attrib_list)
 {
@@ -137,7 +139,7 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
       return NULL;
    }
    
-   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
+   if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
       goto cleanup_surf;
 
    if (conf->RedSize == 5)
@@ -147,25 +149,17 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
    else
       dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
 
-   switch (type) {
-   case EGL_WINDOW_BIT:
-      dri2_surf->wl_win = window;
+   dri2_surf->wl_win = window;
 
-      dri2_surf->wl_win->private = dri2_surf;
-      dri2_surf->wl_win->resize_callback = resize_callback;
+   dri2_surf->wl_win->private = dri2_surf;
+   dri2_surf->wl_win->resize_callback = resize_callback;
 
-      dri2_surf->base.Width =  -1;
-      dri2_surf->base.Height = -1;
-      break;
-   default: 
-      goto cleanup_surf;
-   }
+   dri2_surf->base.Width =  -1;
+   dri2_surf->base.Height = -1;
 
    dri2_surf->dri_drawable = 
       (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
-                                           type == EGL_WINDOW_BIT ?
-                                           dri2_conf->dri_double_config : 
-                                           dri2_conf->dri_single_config,
+                                           dri2_conf->dri_double_config,
                                            dri2_surf);
    if (dri2_surf->dri_drawable == NULL) {
       _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
@@ -193,8 +187,7 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    _EGLSurface *surf;
 
-   surf = dri2_wl_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
-                                 native_window, attrib_list);
+   surf = dri2_wl_create_surface(drv, disp, conf, native_window, attrib_list);
 
    if (surf != NULL)
       dri2_wl_swap_interval(drv, disp, surf, dri2_dpy->default_swap_interval);
@@ -240,21 +233,26 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
       if (dri2_surf->color_buffers[i].dri_image)
          dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
+      if (dri2_surf->color_buffers[i].linear_copy)
+         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
+      if (dri2_surf->color_buffers[i].data)
+         munmap(dri2_surf->color_buffers[i].data,
+                dri2_surf->color_buffers[i].data_size);
    }
 
-   for (i = 0; i < __DRI_BUFFER_COUNT; i++)
-      if (dri2_surf->dri_buffers[i] &&
-          dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
-         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
-                                       dri2_surf->dri_buffers[i]);
+   if (dri2_dpy->dri2) {
+      for (i = 0; i < __DRI_BUFFER_COUNT; i++)
+         if (dri2_surf->dri_buffers[i] &&
+             dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
+            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
+                                          dri2_surf->dri_buffers[i]);
+   }
 
    if (dri2_surf->throttle_callback)
       wl_callback_destroy(dri2_surf->throttle_callback);
 
-   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
-      dri2_surf->wl_win->private = NULL;
-      dri2_surf->wl_win->resize_callback = NULL;
-   }
+   dri2_surf->wl_win->private = NULL;
+   dri2_surf->wl_win->resize_callback = NULL;
 
    free(surf);
 
@@ -274,17 +272,26 @@ dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
       if (dri2_surf->color_buffers[i].dri_image)
          dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
+      if (dri2_surf->color_buffers[i].linear_copy)
+         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
+      if (dri2_surf->color_buffers[i].data)
+         munmap(dri2_surf->color_buffers[i].data,
+                dri2_surf->color_buffers[i].data_size);
 
       dri2_surf->color_buffers[i].wl_buffer = NULL;
       dri2_surf->color_buffers[i].dri_image = NULL;
+      dri2_surf->color_buffers[i].linear_copy = NULL;
+      dri2_surf->color_buffers[i].data = NULL;
       dri2_surf->color_buffers[i].locked = 0;
    }
 
-   for (i = 0; i < __DRI_BUFFER_COUNT; i++)
-      if (dri2_surf->dri_buffers[i] &&
-          dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
-         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
-                                       dri2_surf->dri_buffers[i]);
+   if (dri2_dpy->dri2) {
+      for (i = 0; i < __DRI_BUFFER_COUNT; i++)
+         if (dri2_surf->dri_buffers[i] &&
+             dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
+            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
+                                          dri2_surf->dri_buffers[i]);
+   }
 }
 
 static int
@@ -338,13 +345,29 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
 
    if (dri2_surf->back == NULL)
       return -1;
+
+   if (dri2_dpy->is_different_gpu &&
+       dri2_surf->back->linear_copy == NULL) {
+       dri2_surf->back->linear_copy =
+          dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+                                      dri2_surf->base.Width,
+                                      dri2_surf->base.Height,
+                                      dri_image_format,
+                                      __DRI_IMAGE_USE_SHARE |
+                                      __DRI_IMAGE_USE_LINEAR,
+                                      NULL);
+      if (dri2_surf->back->linear_copy == NULL)
+          return -1;
+   }
+
    if (dri2_surf->back->dri_image == NULL) {
       dri2_surf->back->dri_image = 
          dri2_dpy->image->createImage(dri2_dpy->dri_screen,
                                       dri2_surf->base.Width,
                                       dri2_surf->base.Height,
                                       dri_image_format,
-                                      __DRI_IMAGE_USE_SHARE,
+                                      dri2_dpy->is_different_gpu ?
+                                         0 : __DRI_IMAGE_USE_SHARE,
                                       NULL);
       dri2_surf->back->age = 0;
    }
@@ -407,9 +430,8 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
       dri2_egl_display(dri2_surf->base.Resource.Display);
    int i;
 
-   if (dri2_surf->base.Type == EGL_WINDOW_BIT &&
-       (dri2_surf->base.Width != dri2_surf->wl_win->width || 
-        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
+   if (dri2_surf->base.Width != dri2_surf->wl_win->width ||
+       dri2_surf->base.Height != dri2_surf->wl_win->height) {
 
       dri2_wl_release_buffers(dri2_surf);
 
@@ -432,8 +454,11 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
           dri2_surf->color_buffers[i].wl_buffer) {
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
          dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
+         if (dri2_dpy->is_different_gpu)
+            dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
          dri2_surf->color_buffers[i].wl_buffer = NULL;
          dri2_surf->color_buffers[i].dri_image = NULL;
+         dri2_surf->color_buffers[i].linear_copy = NULL;
       }
    }
 
@@ -578,16 +603,20 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
 {
    struct dri2_egl_display *dri2_dpy =
       dri2_egl_display(dri2_surf->base.Resource.Display);
+   __DRIimage *image;
    int fd, stride, name;
 
    if (dri2_surf->current->wl_buffer != NULL)
       return;
 
+   if (dri2_dpy->is_different_gpu) {
+      image = dri2_surf->current->linear_copy;
+   } else {
+      image = dri2_surf->current->dri_image;
+   }
    if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
-                                  __DRI_IMAGE_ATTRIB_FD, &fd);
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
-                                  __DRI_IMAGE_ATTRIB_STRIDE, &stride);
+      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd);
+      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
 
       dri2_surf->current->wl_buffer =
          wl_drm_create_prime_buffer(dri2_dpy->wl_drm,
@@ -600,10 +629,8 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
                                     0, 0);
       close(fd);
    } else {
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
-                                  __DRI_IMAGE_ATTRIB_NAME, &name);
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
-                                  __DRI_IMAGE_ATTRIB_STRIDE, &stride);
+      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
+      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
 
       dri2_surf->current->wl_buffer =
          wl_drm_create_buffer(dri2_dpy->wl_drm,
@@ -683,6 +710,18 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv,
       }
    }
 
+   if (dri2_dpy->is_different_gpu) {
+      _EGLContext *ctx = _eglGetCurrentContext();
+      struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+      dri2_dpy->image->blitImage(dri2_ctx->dri_context,
+                                 dri2_surf->current->linear_copy,
+                                 dri2_surf->current->dri_image,
+                                 0, 0, dri2_surf->base.Width,
+                                 dri2_surf->base.Height,
+                                 0, 0, dri2_surf->base.Width,
+                                 dri2_surf->base.Height, 0);
+   }
+
    dri2_flush_drawable_for_swapbuffers(disp, draw);
    (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
 
@@ -800,12 +839,33 @@ bad_format:
    return NULL;
 }
 
+static char
+is_fd_render_node(int fd)
+{
+   struct stat render;
+
+   if (fstat(fd, &render))
+      return 0;
+
+   if (!S_ISCHR(render.st_mode))
+      return 0;
+
+   if (render.st_rdev & 0x80)
+      return 1;
+   return 0;
+}
+
 static int
 dri2_wl_authenticate(_EGLDisplay *disp, uint32_t id)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    int ret = 0;
 
+   if (dri2_dpy->is_render_node) {
+      _eglLog(_EGL_WARNING, "wayland-egl: client asks server to "
+                            "authenticate for render-nodes");
+      return 0;
+   }
    dri2_dpy->authenticated = 0;
 
    wl_drm_authenticate(dri2_dpy->wl_drm, id);
@@ -831,24 +891,19 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *device)
    if (!dri2_dpy->device_name)
       return;
 
-#ifdef O_CLOEXEC
-   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
-   if (dri2_dpy->fd == -1 && errno == EINVAL)
-#endif
-   {
-      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
-      if (dri2_dpy->fd != -1)
-         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
-            FD_CLOEXEC);
-   }
+   dri2_dpy->fd = loader_open_device(dri2_dpy->device_name);
    if (dri2_dpy->fd == -1) {
       _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
              dri2_dpy->device_name, strerror(errno));
       return;
    }
 
-   drmGetMagic(dri2_dpy->fd, &magic);
-   wl_drm_authenticate(dri2_dpy->wl_drm, magic);
+   if (is_fd_render_node(dri2_dpy->fd)) {
+      dri2_dpy->authenticated = 1;
+   } else {
+      drmGetMagic(dri2_dpy->fd, &magic);
+      wl_drm_authenticate(dri2_dpy->wl_drm, magic);
+   }
 }
 
 static void
@@ -893,7 +948,7 @@ static const struct wl_drm_listener drm_listener = {
 };
 
 static void
-registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
+registry_handle_global_drm(void *data, struct wl_registry *registry, uint32_t name,
                       const char *interface, uint32_t version)
 {
    struct dri2_egl_display *dri2_dpy = data;
@@ -913,8 +968,8 @@ registry_handle_global_remove(void *data, struct wl_registry *registry,
 {
 }
 
-static const struct wl_registry_listener registry_listener = {
-   registry_handle_global,
+static const struct wl_registry_listener registry_listener_drm = {
+   registry_handle_global_drm,
    registry_handle_global_remove
 };
 
@@ -990,8 +1045,8 @@ static struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
    .get_sync_values = dri2_fallback_get_sync_values,
 };
 
-EGLBoolean
-dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
+static EGLBoolean
+dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
 {
    struct dri2_egl_display *dri2_dpy;
    const __DRIconfig *config;
@@ -1027,9 +1082,9 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
    wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry,
                       dri2_dpy->wl_queue);
    wl_registry_add_listener(dri2_dpy->wl_registry,
-                            &registry_listener, dri2_dpy);
+                            &registry_listener_drm, dri2_dpy);
    if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL)
-      goto cleanup_dpy;
+      goto cleanup_registry;
 
    if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1)
       goto cleanup_drm;
@@ -1037,6 +1092,24 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
    if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated)
       goto cleanup_fd;
 
+   dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
+                                               &dri2_dpy->is_different_gpu);
+   if (dri2_dpy->is_different_gpu) {
+      free(dri2_dpy->device_name);
+      dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
+      if (!dri2_dpy->device_name) {
+         _eglError(EGL_BAD_ALLOC, "wayland-egl: failed to get device name "
+                                  "for requested GPU");
+         goto cleanup_fd;
+      }
+   }
+
+   /* we have to do the check now, because loader_get_user_preferred_fd
+    * will return a render-node when the requested gpu is different
+    * to the server, but also if the client asks for the same gpu than
+    * the server by requesting its pci-id */
+   dri2_dpy->is_render_node = is_fd_render_node(dri2_dpy->fd);
+
    dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
    if (dri2_dpy->driver_name == NULL) {
       _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
@@ -1046,18 +1119,23 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
    if (!dri2_load_driver(disp))
       goto cleanup_driver_name;
 
-   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
-   dri2_dpy->dri2_loader_extension.base.version = 3;
-   dri2_dpy->dri2_loader_extension.getBuffers = dri2_wl_get_buffers;
-   dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_wl_flush_front_buffer;
-   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
-      dri2_wl_get_buffers_with_format;
-
-   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
-   dri2_dpy->extensions[1] = &image_loader_extension.base;
-   dri2_dpy->extensions[2] = &image_lookup_extension.base;
-   dri2_dpy->extensions[3] = &use_invalidate.base;
-   dri2_dpy->extensions[4] = NULL;
+   dri2_dpy->extensions[0] = &image_loader_extension.base;
+   dri2_dpy->extensions[1] = &image_lookup_extension.base;
+   dri2_dpy->extensions[2] = &use_invalidate.base;
+
+   /* render nodes cannot use Gem names, and thus do not support
+    * the __DRI_DRI2_LOADER extension */
+   if (!dri2_dpy->is_render_node) {
+      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
+      dri2_dpy->dri2_loader_extension.base.version = 3;
+      dri2_dpy->dri2_loader_extension.getBuffers = dri2_wl_get_buffers;
+      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_wl_flush_front_buffer;
+      dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
+         dri2_wl_get_buffers_with_format;
+      dri2_dpy->extensions[3] = &dri2_dpy->dri2_loader_extension.base;
+      dri2_dpy->extensions[4] = NULL;
+   } else
+      dri2_dpy->extensions[3] = NULL;
 
    dri2_dpy->swap_available = EGL_TRUE;
 
@@ -1066,15 +1144,33 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
 
    dri2_wl_setup_swap_interval(dri2_dpy);
 
-   /* The server shouldn't advertise WL_DRM_CAPABILITY_PRIME if the driver
-    * doesn't have createImageFromFds, since we're using the same driver on
-    * both sides.  We don't want crash if that happens anyway, so fall back to
-    * gem names if we don't have prime support. */
+   /* To use Prime, we must have _DRI_IMAGE v7 at least.
+    * createImageFromFds support indicates that Prime export/import
+    * is supported by the driver. Fall back to
+    * gem names if we don't have Prime support. */
 
    if (dri2_dpy->image->base.version < 7 ||
        dri2_dpy->image->createImageFromFds == NULL)
       dri2_dpy->capabilities &= ~WL_DRM_CAPABILITY_PRIME;
 
+   /* We cannot use Gem names with render-nodes, only prime fds (dma-buf).
+    * The server needs to accept them */
+   if (dri2_dpy->is_render_node &&
+       !(dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME)) {
+      _eglLog(_EGL_WARNING, "wayland-egl: display is not render-node capable");
+      goto cleanup_screen;
+   }
+
+   if (dri2_dpy->is_different_gpu &&
+       (dri2_dpy->image->base.version < 9 ||
+        dri2_dpy->image->blitImage == NULL)) {
+      _eglLog(_EGL_WARNING, "wayland-egl: Different GPU selected, but the "
+                            "Image extension in the driver is not "
+                            "compatible. Version 9 or later and blitImage() "
+                            "are required");
+      goto cleanup_screen;
+   }
+
    types = EGL_WINDOW_BIT;
    for (i = 0; dri2_dpy->driver_configs[i]; i++) {
       config = dri2_dpy->driver_configs[i];
@@ -1087,15 +1183,20 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
    }
 
    disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
-   disp->Extensions.WL_create_wayland_buffer_from_image = EGL_TRUE;
+   /* When cannot convert EGLImage to wl_buffer when on a different gpu,
+    * because the buffer of the EGLImage has likely a tiling mode the server
+    * gpu won't support. These is no way to check for now. Thus do not support the
+    * extension */
+   if (!dri2_dpy->is_different_gpu) {
+      disp->Extensions.WL_create_wayland_buffer_from_image = EGL_TRUE;
+   } else {
+      dri2_wl_display_vtbl.create_wayland_buffer_from_image =
+         dri2_fallback_create_wayland_buffer_from_image;
+   }
    disp->Extensions.EXT_buffer_age = EGL_TRUE;
 
    disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
 
-   /* we're supporting EGL 1.4 */
-   disp->VersionMajor = 1;
-   disp->VersionMinor = 4;
-
    /* Fill vtbl last to prevent accidentally calling virtual function during
     * initialization.
     */
@@ -1103,6 +1204,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
 
    return EGL_TRUE;
 
+ cleanup_screen:
+   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
  cleanup_driver:
    dlclose(dri2_dpy->driver);
  cleanup_driver_name:
@@ -1112,8 +1215,666 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
  cleanup_drm:
    free(dri2_dpy->device_name);
    wl_drm_destroy(dri2_dpy->wl_drm);
+ cleanup_registry:
+   wl_registry_destroy(dri2_dpy->wl_registry);
+   wl_event_queue_destroy(dri2_dpy->wl_queue);
  cleanup_dpy:
    free(dri2_dpy);
    
    return EGL_FALSE;
 }
+
+static int
+dri2_wl_swrast_get_stride_for_format(int format, int w)
+{
+   if (format == WL_SHM_FORMAT_RGB565)
+      return 2 * w;
+   else /* ARGB8888 || XRGB8888 */
+      return 4 * w;
+}
+
+/*
+ * Taken from weston shared/os-compatibility.c
+ */
+
+static int
+set_cloexec_or_close(int fd)
+{
+   long flags;
+
+   if (fd == -1)
+      return -1;
+
+   flags = fcntl(fd, F_GETFD);
+   if (flags == -1)
+      goto err;
+
+   if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+      goto err;
+
+   return fd;
+
+err:
+   close(fd);
+   return -1;
+}
+
+/*
+ * Taken from weston shared/os-compatibility.c
+ */
+
+static int
+create_tmpfile_cloexec(char *tmpname)
+{
+   int fd;
+
+#ifdef HAVE_MKOSTEMP
+   fd = mkostemp(tmpname, O_CLOEXEC);
+   if (fd >= 0)
+      unlink(tmpname);
+#else
+   fd = mkstemp(tmpname);
+   if (fd >= 0) {
+      fd = set_cloexec_or_close(fd);
+      unlink(tmpname);
+   }
+#endif
+
+   return fd;
+}
+
+/*
+ * Taken from weston shared/os-compatibility.c
+ *
+ * Create a new, unique, anonymous file of the given size, and
+ * return the file descriptor for it. The file descriptor is set
+ * CLOEXEC. The file is immediately suitable for mmap()'ing
+ * the given size at offset zero.
+ *
+ * The file should not have a permanent backing store like a disk,
+ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
+ *
+ * The file name is deleted from the file system.
+ *
+ * The file is suitable for buffer sharing between processes by
+ * transmitting the file descriptor over Unix sockets using the
+ * SCM_RIGHTS methods.
+ *
+ * If the C library implements posix_fallocate(), it is used to
+ * guarantee that disk space is available for the file at the
+ * given size. If disk space is insufficent, errno is set to ENOSPC.
+ * If posix_fallocate() is not supported, program may receive
+ * SIGBUS on accessing mmap()'ed file contents instead.
+ */
+static int
+os_create_anonymous_file(off_t size)
+{
+   static const char template[] = "/mesa-shared-XXXXXX";
+   const char *path;
+   char *name;
+   int fd;
+   int ret;
+
+   path = getenv("XDG_RUNTIME_DIR");
+   if (!path) {
+      errno = ENOENT;
+      return -1;
+   }
+
+   name = malloc(strlen(path) + sizeof(template));
+   if (!name)
+      return -1;
+
+   strcpy(name, path);
+   strcat(name, template);
+
+   fd = create_tmpfile_cloexec(name);
+
+   free(name);
+
+   if (fd < 0)
+      return -1;
+
+   ret = ftruncate(fd, size);
+   if (ret < 0) {
+      close(fd);
+      return -1;
+   }
+
+   return fd;
+}
+
+
+static EGLBoolean
+dri2_wl_swrast_allocate_buffer(struct dri2_egl_display *dri2_dpy,
+                               int format, int w, int h,
+                               void **data, int *size,
+                               struct wl_buffer **buffer)
+{
+   struct wl_shm_pool *pool;
+   int fd, stride, size_map;
+   void *data_map;
+
+   stride = dri2_wl_swrast_get_stride_for_format(format, w);
+   size_map = h * stride;
+
+   /* Create a sharable buffer */
+   fd = os_create_anonymous_file(size_map);
+   if (fd < 0)
+      return EGL_FALSE;
+
+   data_map = mmap(NULL, size_map, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+   if (data_map == MAP_FAILED) {
+      close(fd);
+      return EGL_FALSE;
+   }
+
+   /* Share it in a wl_buffer */
+   pool = wl_shm_create_pool(dri2_dpy->wl_shm, fd, size_map);
+   *buffer = wl_shm_pool_create_buffer(pool, 0, w, h, stride, format);
+   wl_shm_pool_destroy(pool);
+   close(fd);
+
+   *data = data_map;
+   *size = size_map;
+   return EGL_TRUE;
+}
+
+static int
+swrast_update_buffers(struct dri2_egl_surface *dri2_surf)
+{
+   struct dri2_egl_display *dri2_dpy =
+      dri2_egl_display(dri2_surf->base.Resource.Display);
+   int i;
+
+   /* we need to do the following operations only once per frame */
+   if (dri2_surf->back)
+      return 0;
+
+   if (dri2_surf->base.Width != dri2_surf->wl_win->width ||
+       dri2_surf->base.Height != dri2_surf->wl_win->height) {
+
+      dri2_wl_release_buffers(dri2_surf);
+
+      dri2_surf->base.Width  = dri2_surf->wl_win->width;
+      dri2_surf->base.Height = dri2_surf->wl_win->height;
+      dri2_surf->dx = dri2_surf->wl_win->dx;
+      dri2_surf->dy = dri2_surf->wl_win->dy;
+      dri2_surf->current = NULL;
+   }
+
+   /* find back buffer */
+
+   /* We always want to throttle to some event (either a frame callback or
+    * a sync request) after the commit so that we can be sure the
+    * compositor has had a chance to handle it and send us a release event
+    * before we look for a free buffer */
+   while (dri2_surf->throttle_callback != NULL)
+      if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
+                                    dri2_dpy->wl_queue) == -1)
+         return -1;
+
+   /* try get free buffer already created */
+   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
+      if (!dri2_surf->color_buffers[i].locked &&
+          dri2_surf->color_buffers[i].wl_buffer) {
+          dri2_surf->back = &dri2_surf->color_buffers[i];
+          break;
+      }
+   }
+
+   /* else choose any another free location */
+   if (!dri2_surf->back) {
+      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
+         if (!dri2_surf->color_buffers[i].locked) {
+             dri2_surf->back = &dri2_surf->color_buffers[i];
+             if (!dri2_wl_swrast_allocate_buffer(dri2_dpy,
+                                                 dri2_surf->format,
+                                                 dri2_surf->base.Width,
+                                                 dri2_surf->base.Height,
+                                                 &dri2_surf->back->data,
+                                                 &dri2_surf->back->data_size,
+                                                 &dri2_surf->back->wl_buffer)) {
+                _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
+                 return -1;
+             }
+             wl_proxy_set_queue((struct wl_proxy *) dri2_surf->back->wl_buffer,
+                                dri2_dpy->wl_queue);
+             wl_buffer_add_listener(dri2_surf->back->wl_buffer,
+                                    &wl_buffer_listener, dri2_surf);
+             break;
+         }
+      }
+   }
+
+   if (!dri2_surf->back) {
+      _eglError(EGL_BAD_ALLOC, "failed to find free buffer");
+      return -1;
+   }
+
+   dri2_surf->back->locked = 1;
+
+   /* If we have an extra unlocked buffer at this point, we had to do triple
+    * buffering for a while, but now can go back to just double buffering.
+    * That means we can free any unlocked buffer now. */
+   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
+      if (!dri2_surf->color_buffers[i].locked &&
+          dri2_surf->color_buffers[i].wl_buffer) {
+         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
+         munmap(dri2_surf->color_buffers[i].data,
+                dri2_surf->color_buffers[i].data_size);
+         dri2_surf->color_buffers[i].wl_buffer = NULL;
+         dri2_surf->color_buffers[i].data = NULL;
+      }
+   }
+
+   return 0;
+}
+
+static void*
+dri2_wl_swrast_get_frontbuffer_data(struct dri2_egl_surface *dri2_surf)
+{
+   /* if there has been a resize: */
+   if (!dri2_surf->current)
+      return NULL;
+
+   return dri2_surf->current->data;
+}
+
+static void*
+dri2_wl_swrast_get_backbuffer_data(struct dri2_egl_surface *dri2_surf)
+{
+   assert(dri2_surf->back);
+   return dri2_surf->back->data;
+}
+
+static void
+dri2_wl_swrast_commit_backbuffer(struct dri2_egl_surface *dri2_surf)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
+
+   if (dri2_surf->base.SwapInterval > 0) {
+      dri2_surf->throttle_callback =
+         wl_surface_frame(dri2_surf->wl_win->surface);
+      wl_callback_add_listener(dri2_surf->throttle_callback,
+                               &throttle_listener, dri2_surf);
+      wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback,
+                         dri2_dpy->wl_queue);
+   }
+
+   dri2_surf->current = dri2_surf->back;
+   dri2_surf->back = NULL;
+
+   wl_surface_attach(dri2_surf->wl_win->surface,
+                     dri2_surf->current->wl_buffer,
+                     dri2_surf->dx, dri2_surf->dy);
+
+   dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
+   dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
+   /* reset resize growing parameters */
+   dri2_surf->dx = 0;
+   dri2_surf->dy = 0;
+
+   wl_surface_damage(dri2_surf->wl_win->surface,
+                     0, 0, INT32_MAX, INT32_MAX);
+   wl_surface_commit(dri2_surf->wl_win->surface);
+
+   /* If we're not waiting for a frame callback then we'll at least throttle
+    * to a sync callback so that we always give a chance for the compositor to
+    * handle the commit and send a release event before checking for a free
+    * buffer */
+   if (dri2_surf->throttle_callback == NULL) {
+      dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy);
+      wl_callback_add_listener(dri2_surf->throttle_callback,
+                               &throttle_listener, dri2_surf);
+      wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback,
+                         dri2_dpy->wl_queue);
+   }
+
+   wl_display_flush(dri2_dpy->wl_dpy);
+}
+
+static void
+dri2_wl_swrast_get_drawable_info(__DRIdrawable * draw,
+                                 int *x, int *y, int *w, int *h,
+                                 void *loaderPrivate)
+{
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+
+   (void) swrast_update_buffers(dri2_surf);
+   *x = 0;
+   *y = 0;
+   *w = dri2_surf->base.Width;
+   *h = dri2_surf->base.Height;
+}
+
+static void
+dri2_wl_swrast_get_image(__DRIdrawable * read,
+                         int x, int y, int w, int h,
+                         char *data, void *loaderPrivate)
+{
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+   int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
+   int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x);
+   int src_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width);
+   int dst_stride = copy_width;
+   char *src, *dst;
+
+   src = dri2_wl_swrast_get_frontbuffer_data(dri2_surf);
+   if (!src) {
+      memset(data, 0, copy_width * h);
+      return;
+   }
+
+   assert(data != src);
+   assert(copy_width <= src_stride);
+
+   src += x_offset;
+   src += y * src_stride;
+   dst = data;
+
+   if (copy_width > src_stride-x_offset)
+      copy_width = src_stride-x_offset;
+   if (h > dri2_surf->base.Height-y)
+      h = dri2_surf->base.Height-y;
+
+   for (; h>0; h--) {
+      memcpy(dst, src, copy_width);
+      src += src_stride;
+      dst += dst_stride;
+   }
+}
+
+static void
+dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
+                         int x, int y, int w, int h, int stride,
+                         char *data, void *loaderPrivate)
+{
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+   int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
+   int dst_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width);
+   int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x);
+   char *src, *dst;
+
+   assert(copy_width <= stride);
+
+   (void) swrast_update_buffers(dri2_surf);
+   dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
+
+   /* partial copy, copy old content */
+   if (copy_width < dst_stride)
+      dri2_wl_swrast_get_image(draw, 0, 0,
+                               dri2_surf->base.Width, dri2_surf->base.Height,
+                               dst, loaderPrivate);
+
+   dst += x_offset;
+   dst += y * dst_stride;
+
+   src = data;
+
+   /* drivers expect we do these checks (and some rely on it) */
+   if (copy_width > dst_stride-x_offset)
+      copy_width = dst_stride-x_offset;
+   if (h > dri2_surf->base.Height-y)
+      h = dri2_surf->base.Height-y;
+
+   for (; h>0; h--) {
+      memcpy(dst, src, copy_width);
+      src += stride;
+      dst += dst_stride;
+   }
+   dri2_wl_swrast_commit_backbuffer(dri2_surf);
+}
+
+static void
+dri2_wl_swrast_put_image(__DRIdrawable * draw, int op,
+                         int x, int y, int w, int h,
+                         char *data, void *loaderPrivate)
+{
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+   int stride;
+
+   stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
+   dri2_wl_swrast_put_image2(draw, op, x, y, w, h,
+                             stride, data, loaderPrivate);
+}
+
+/**
+ * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
+ */
+static _EGLSurface *
+dri2_wl_swrast_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
+                                     _EGLConfig *conf, void *native_window,
+                                     const EGLint *attrib_list)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
+   struct wl_egl_window *window = native_window;
+   struct dri2_egl_surface *dri2_surf;
+
+   (void) drv;
+
+   dri2_surf = calloc(1, sizeof *dri2_surf);
+   if (!dri2_surf) {
+      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
+      return NULL;
+   }
+
+   if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
+      goto cleanup_surf;
+
+   if (conf->RedSize == 5)
+      dri2_surf->format = WL_SHM_FORMAT_RGB565;
+   else if (conf->AlphaSize == 0)
+      dri2_surf->format = WL_SHM_FORMAT_XRGB8888;
+   else
+      dri2_surf->format = WL_SHM_FORMAT_ARGB8888;
+
+   dri2_surf->wl_win = window;
+
+   dri2_surf->base.Width = -1;
+   dri2_surf->base.Height = -1;
+
+   dri2_surf->dri_drawable =
+      (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
+                                              dri2_conf->dri_double_config,
+                                              dri2_surf);
+   if (dri2_surf->dri_drawable == NULL) {
+      _eglError(EGL_BAD_ALLOC, "swrast->createNewDrawable");
+      goto cleanup_dri_drawable;
+   }
+
+   dri2_wl_swap_interval(drv, disp, &dri2_surf->base,
+                         dri2_dpy->default_swap_interval);
+
+   return &dri2_surf->base;
+
+ cleanup_dri_drawable:
+   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
+ cleanup_surf:
+   free(dri2_surf);
+
+   return NULL;
+}
+
+static EGLBoolean
+dri2_wl_swrast_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+   dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
+   return EGL_TRUE;
+}
+
+static void
+shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
+{
+   struct dri2_egl_display *dri2_dpy = data;
+
+   switch (format) {
+   case WL_SHM_FORMAT_ARGB8888:
+      dri2_dpy->formats |= HAS_ARGB8888;
+      break;
+   case WL_SHM_FORMAT_XRGB8888:
+      dri2_dpy->formats |= HAS_XRGB8888;
+      break;
+   case WL_SHM_FORMAT_RGB565:
+      dri2_dpy->formats |= HAS_RGB565;
+      break;
+   }
+}
+
+static const struct wl_shm_listener shm_listener = {
+   shm_handle_format
+};
+
+static void
+registry_handle_global_swrast(void *data, struct wl_registry *registry, uint32_t name,
+                              const char *interface, uint32_t version)
+{
+   struct dri2_egl_display *dri2_dpy = data;
+
+   if (strcmp(interface, "wl_shm") == 0) {
+      dri2_dpy->wl_shm =
+         wl_registry_bind(registry, name, &wl_shm_interface, 1);
+      wl_shm_add_listener(dri2_dpy->wl_shm, &shm_listener, dri2_dpy);
+   }
+}
+
+static const struct wl_registry_listener registry_listener_swrast = {
+   registry_handle_global_swrast,
+   registry_handle_global_remove
+};
+
+static struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
+   .authenticate = NULL,
+   .create_window_surface = dri2_wl_swrast_create_window_surface,
+   .create_pixmap_surface = dri2_wl_create_pixmap_surface,
+   .create_pbuffer_surface = dri2_fallback_create_pbuffer_surface,
+   .destroy_surface = dri2_wl_destroy_surface,
+   .create_image = dri2_fallback_create_image_khr,
+   .swap_interval = dri2_wl_swap_interval,
+   .swap_buffers = dri2_wl_swrast_swap_buffers,
+   .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
+   .swap_buffers_region = dri2_fallback_swap_buffers_region,
+   .post_sub_buffer = dri2_fallback_post_sub_buffer,
+   .copy_buffers = dri2_fallback_copy_buffers,
+   .query_buffer_age = dri2_fallback_query_buffer_age,
+   .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
+   .get_sync_values = dri2_fallback_get_sync_values,
+};
+
+static EGLBoolean
+dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
+{
+   struct dri2_egl_display *dri2_dpy;
+   const __DRIconfig *config;
+   uint32_t types;
+   int i;
+   static const unsigned int argb_masks[4] =
+      { 0xff0000, 0xff00, 0xff, 0xff000000 };
+   static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 };
+   static const unsigned int rgb565_masks[4] = { 0xf800, 0x07e0, 0x001f, 0 };
+
+   loader_set_logger(_eglLog);
+
+   dri2_dpy = calloc(1, sizeof *dri2_dpy);
+   if (!dri2_dpy)
+      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+   disp->DriverData = (void *) dri2_dpy;
+   if (disp->PlatformDisplay == NULL) {
+      dri2_dpy->wl_dpy = wl_display_connect(NULL);
+      if (dri2_dpy->wl_dpy == NULL)
+         goto cleanup_dpy;
+      dri2_dpy->own_device = 1;
+   } else {
+      dri2_dpy->wl_dpy = disp->PlatformDisplay;
+   }
+
+   dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
+
+   if (dri2_dpy->own_device)
+      wl_display_dispatch_pending(dri2_dpy->wl_dpy);
+
+   dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy);
+   wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry,
+                      dri2_dpy->wl_queue);
+   wl_registry_add_listener(dri2_dpy->wl_registry,
+                            &registry_listener_swrast, dri2_dpy);
+
+   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_shm == NULL)
+      goto cleanup_registry;
+
+   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->formats == 0)
+      goto cleanup_shm;
+
+   dri2_dpy->driver_name = strdup("swrast");
+   if (!dri2_load_driver_swrast(disp))
+      goto cleanup_shm;
+
+   dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
+   dri2_dpy->swrast_loader_extension.base.version = 2;
+   dri2_dpy->swrast_loader_extension.getDrawableInfo = dri2_wl_swrast_get_drawable_info;
+   dri2_dpy->swrast_loader_extension.putImage = dri2_wl_swrast_put_image;
+   dri2_dpy->swrast_loader_extension.getImage = dri2_wl_swrast_get_image;
+   dri2_dpy->swrast_loader_extension.putImage2 = dri2_wl_swrast_put_image2;
+
+   dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
+   dri2_dpy->extensions[1] = NULL;
+
+   if (!dri2_create_screen(disp))
+      goto cleanup_driver;
+
+   dri2_wl_setup_swap_interval(dri2_dpy);
+
+   types = EGL_WINDOW_BIT;
+   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
+      config = dri2_dpy->driver_configs[i];
+      if (dri2_dpy->formats & HAS_XRGB8888)
+        dri2_add_config(disp, config, i + 1, types, NULL, rgb_masks);
+      if (dri2_dpy->formats & HAS_ARGB8888)
+        dri2_add_config(disp, config, i + 1, types, NULL, argb_masks);
+      if (dri2_dpy->formats & HAS_RGB565)
+        dri2_add_config(disp, config, i + 1, types, NULL, rgb565_masks);
+   }
+
+   /* Fill vtbl last to prevent accidentally calling virtual function during
+    * initialization.
+    */
+   dri2_dpy->vtbl = &dri2_wl_swrast_display_vtbl;
+
+   return EGL_TRUE;
+
+ cleanup_driver:
+   dlclose(dri2_dpy->driver);
+ cleanup_shm:
+   wl_shm_destroy(dri2_dpy->wl_shm);
+ cleanup_registry:
+   wl_registry_destroy(dri2_dpy->wl_registry);
+   wl_event_queue_destroy(dri2_dpy->wl_queue);
+ cleanup_dpy:
+   free(dri2_dpy);
+
+   return EGL_FALSE;
+}
+
+EGLBoolean
+dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
+{
+   EGLBoolean initialized = EGL_TRUE;
+
+   int hw_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
+
+   if (hw_accel) {
+      if (!dri2_initialize_wayland_drm(drv, disp)) {
+         initialized = dri2_initialize_wayland_swrast(drv, disp);
+      }
+   } else {
+      initialized = dri2_initialize_wayland_swrast(drv, disp);
+   }
+
+   return initialized;
+
+}
index ddb3b54e8430a3dc554bbf2628b215438f4ee0b2..56c14288204503610e48c5f0626da7ab8c8114c6 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "egl_dri2.h"
 #include "egl_dri2_fallbacks.h"
+#include "loader.h"
 
 static EGLBoolean
 dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
@@ -1017,15 +1018,6 @@ dri2_x11_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    }
 }
 
-static _EGLImage*
-dri2_x11_swrast_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
-                                 _EGLContext *ctx, EGLenum target,
-                                 EGLClientBuffer buffer,
-                                 const EGLint *attr_list)
-{
-   return NULL;
-}
-
 static EGLBoolean
 dri2_x11_get_sync_values(_EGLDisplay *display, _EGLSurface *surface,
                          EGLuint64KHR *ust, EGLuint64KHR *msc,
@@ -1058,7 +1050,7 @@ static struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = {
    .create_pixmap_surface = dri2_x11_create_pixmap_surface,
    .create_pbuffer_surface = dri2_x11_create_pbuffer_surface,
    .destroy_surface = dri2_x11_destroy_surface,
-   .create_image = dri2_x11_swrast_create_image_khr,
+   .create_image = dri2_fallback_create_image_khr,
    .swap_interval = dri2_fallback_swap_interval,
    .swap_buffers = dri2_x11_swap_buffers,
    .swap_buffers_region = dri2_fallback_swap_buffers_region,
@@ -1121,7 +1113,7 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
       goto cleanup_conn;
 
    dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
-   dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
+   dri2_dpy->swrast_loader_extension.base.version = 2;
    dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
    dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
    dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
@@ -1138,10 +1130,6 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
          goto cleanup_configs;
    }
 
-   /* we're supporting EGL 1.4 */
-   disp->VersionMajor = 1;
-   disp->VersionMinor = 4;
-
    /* Fill vtbl last to prevent accidentally calling virtual function during
     * initialization.
     */
@@ -1243,16 +1231,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
    if (!dri2_load_driver(disp))
       goto cleanup_conn;
 
-#ifdef O_CLOEXEC
-   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
-   if (dri2_dpy->fd == -1 && errno == EINVAL)
-#endif
-   {
-      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
-      if (dri2_dpy->fd != -1)
-         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
-            FD_CLOEXEC);
-   }
+   dri2_dpy->fd = loader_open_device(dri2_dpy->device_name);
    if (dri2_dpy->fd == -1) {
       _eglLog(_EGL_WARNING,
              "DRI2: could not open %s (%s)", dri2_dpy->device_name,
@@ -1292,11 +1271,6 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
 
    dri2_x11_setup_swap_interval(dri2_dpy);
 
-   if (dri2_dpy->conn) {
-      if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp))
-        goto cleanup_configs;
-   }
-
    disp->Extensions.KHR_image_pixmap = EGL_TRUE;
    disp->Extensions.NOK_swap_region = EGL_TRUE;
    disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
@@ -1312,10 +1286,6 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
         goto cleanup_configs;
    }
 
-   /* we're supporting EGL 1.4 */
-   disp->VersionMajor = 1;
-   disp->VersionMinor = 4;
-
    /* Fill vtbl last to prevent accidentally calling virtual function during
     * initialization.
     */
index 9dd2f70f4ac40f54cab67e29119c508c165a5932..ec6020ece77481f233fa68883d08447773b8ce37 100644 (file)
@@ -9,7 +9,6 @@ env.Append(CPPDEFINES = [
 env.Append(CPPPATH = [
        '#/include',
        '#/src/egl/main',
-       '#/src/loader',
 ])
 
 sources = [
@@ -22,10 +21,6 @@ if env['platform'] == 'haiku':
                '_EGL_NATIVE_PLATFORM=haiku',
        ])
 
-env.Prepend(LIBS = [
-       libloader,
-])
-
 egl_haiku = env.ConvenienceLibrary(
        target = 'egl_haiku',
        source = sources,
index 4cf2ccb9db85a9d02b326596098d8c27e82972ca..3d00e47c8e63f06b1faffc11325f5e9c9cbe8559 100644 (file)
@@ -27,8 +27,6 @@
 #include <stdint.h>
 #include <stdio.h>
 
-extern "C" {
-#include "loader.h"
 #include "eglconfig.h"
 #include "eglcontext.h"
 #include "egldisplay.h"
@@ -38,13 +36,19 @@ extern "C" {
 #include "eglsurface.h"
 #include "eglimage.h"
 #include "egltypedefs.h"
-}
 
 #include <InterfaceKit.h>
 #include <OpenGLKit.h>
 
 
-#define CALLOC_STRUCT(T)   (struct T *) calloc(1, sizeof(struct T))
+#ifdef DEBUG
+#      define TRACE(x...) printf("egl_haiku: " x)
+#      define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
+#else
+#      define TRACE(x...)
+#      define CALLED()
+#endif
+#define ERROR(x...) printf("egl_haiku: " x)
 
 
 _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl)
@@ -53,10 +57,6 @@ _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl)
 struct haiku_egl_driver
 {
        _EGLDriver base;
-
-       void *handle;
-       _EGLProc (*get_proc_address)(const char *procname);
-       void (*glFlush)(void);
 };
 
 struct haiku_egl_config
@@ -76,81 +76,6 @@ struct haiku_egl_surface
 };
 
 
-/*
-static void
-swrastCreateDrawable(struct dri2_egl_display * dri2_dpy,
-       struct dri2_egl_surface * dri2_surf, int depth)
-{
-
-}
-
-
-static void
-swrastDestroyDrawable(struct dri2_egl_display * dri2_dpy,
-       struct dri2_egl_surface * dri2_surf)
-{
-
-}
-
-
-static void
-swrastGetDrawableInfo(__DRIdrawable * draw, int *x, int *y,
-       int *w, int *h, void *loaderPrivate)
-{
-
-}
-
-
-static void
-swrastPutImage(__DRIdrawable * draw, int op, int x, int y,
-       int w, int h, char *data, void *loaderPrivate)
-{
-
-}
-
-
-static void
-swrastGetImage(__DRIdrawable * read, int x, int y,
-       int w, int h, char *data, void *loaderPrivate)
-{
-
-}
-*/
-
-
-static void
-haiku_log(EGLint level, const char *msg)
-{
-       switch (level) {
-               case _EGL_DEBUG:
-                       fprintf(stderr,"%s", msg);
-                       break;
-               case _EGL_INFO:
-                       fprintf(stderr,"%s", msg);
-                       break;
-               case _EGL_WARNING:
-                       fprintf(stderr,"%s", msg);
-                       break;
-               case _EGL_FATAL:
-                       fprintf(stderr,"%s", msg);
-                       break;
-               default:
-                       break;
-       }
-}
-
-
-/**
- * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
- */
-static _EGLSurface *
-haiku_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
-       _EGLConfig *conf, void *native_surface, const EGLint *attrib_list)
-{
-       return NULL;
-}
-
-
 /**
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
  */
@@ -158,25 +83,37 @@ static _EGLSurface *
 haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
        _EGLConfig *conf, void *native_window, const EGLint *attrib_list)
 {
+       CALLED();
+
        struct haiku_egl_surface* surface;
-       surface = (struct haiku_egl_surface*)calloc(1,sizeof (*surface));
+       surface = (struct haiku_egl_surface*) calloc(1, sizeof (*surface));
+       if (!surface) {
+               _eglError(EGL_BAD_ALLOC, "haiku_create_window_surface");
+               return NULL;
+       }
+
+       if (!_eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list))
+               goto cleanup_surface;
 
-       _eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list);
        (&surface->surf)->SwapInterval = 1;
 
-       _eglLog(_EGL_DEBUG, "Creating window");
+       TRACE("Creating window\n");
        BWindow* win = (BWindow*)native_window;
 
-       _eglLog(_EGL_DEBUG, "Creating GL view");
+       TRACE("Creating GL view\n");
        surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0,
                BGL_RGB | BGL_DOUBLE | BGL_ALPHA);
 
-       _eglLog(_EGL_DEBUG, "Adding GL");
+       TRACE("Adding GL\n");
        win->AddChild(surface->gl);
 
-       _eglLog(_EGL_DEBUG, "Showing window");
+       TRACE("Showing window\n");
        win->Show();
        return &surface->surf;
+
+cleanup_surface:
+       free(surface);
+       return NULL;
 }
 
 
@@ -199,6 +136,10 @@ haiku_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
 static EGLBoolean
 haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
 {
+       if (_eglPutSurface(surf)) {
+               // XXX: detach haiku_egl_surface::gl from the native window and destroy it
+               free(surf);
+        }
        return EGL_TRUE;
 }
 
@@ -206,13 +147,18 @@ haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
 static EGLBoolean
 haiku_add_configs_for_visuals(_EGLDisplay *dpy)
 {
-       printf("Adding configs\n");
+       CALLED();
 
        struct haiku_egl_config* conf;
-       conf = CALLOC_STRUCT(haiku_egl_config);
+       conf = (struct haiku_egl_config*) calloc(1, sizeof (*conf));
+       if (!conf) {
+               _eglError(EGL_BAD_ALLOC, "haiku_add_configs_for_visuals");
+               return NULL;
+       }
 
        _eglInitConfig(&conf->base, dpy, 1);
-       _eglLog(_EGL_DEBUG,"Config inited\n");
+       TRACE("Config inited\n");
+
        _eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8);
        _eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8);
        _eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8);
@@ -243,76 +189,40 @@ haiku_add_configs_for_visuals(_EGLDisplay *dpy)
        _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ?
        _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);
 
-       printf("Config configuated\n");
+       TRACE("Config configuated\n");
        if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
-               _eglLog(_EGL_DEBUG, "Haiku failed to validate config");
-               return EGL_FALSE;
+               _eglLog(_EGL_DEBUG, "Haiku: failed to validate config");
+               goto cleanup;
        }
-       printf("Validated config\n");
+       TRACE("Validated config\n");
    
        _eglLinkConfig(&conf->base);
        if (!_eglGetArraySize(dpy->Configs)) {
                _eglLog(_EGL_WARNING, "Haiku: failed to create any config");
-               return EGL_FALSE;
+               goto cleanup;
        }
-       printf("Config successful!\n");
-   
+       TRACE("Config successfull\n");
+
        return EGL_TRUE;
+
+cleanup:
+       free(conf);
+       return EGL_FALSE;
 }
 
 extern "C"
 EGLBoolean
 init_haiku(_EGLDriver *drv, _EGLDisplay *dpy)
 {
-       _eglLog(_EGL_DEBUG,"\nInitializing Haiku EGL\n");
-       //_EGLDisplay* egl_dpy;
-
-       printf("Initializing Haiku EGL\n");
-       _eglSetLogProc(haiku_log);
-
-       loader_set_logger(_eglLog);
-
-       /*egl_dpy = (_EGLDisplay*) calloc(1, sizeof(_EGLDisplay));
-       if (!egl_dpy)
-               return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
-       dpy->DriverData=(void*) egl_dpy;
-       if (!dpy->PlatformDisplay) {
-               // OPEN DEVICE 
-               //dri2_dpy->bwindow = (void*)haiku_create_window();
-               //dri2_dpy->own_device = true;
-       } else {
-               //dri2_dpy->bwindow = (BWindow*)dpy->PlatformDisplay;
-       }*/
-       
-       //dri2_dpy->driver_name = strdup("swrast");
-       //if (!dri2_load_driver_swrast(dpy))
-       //   goto cleanup_conn;
-
-       /*dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
-       dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
-       dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
-       dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
-       dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
-
-       dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
-       dri2_dpy->extensions[1] = NULL;
-       dri2_dpy->extensions[2] = NULL;*/
-
-       /*if (dri2_dpy->bwindow) {
-               if (!dri2_haiku_add_configs_for_visuals(dri2_dpy, dpy))
-                       goto cleanup_configs;
-       }*/
-       _eglLog(_EGL_DEBUG,"Add configs");
-    haiku_add_configs_for_visuals(dpy);
-
-       dpy->VersionMajor=1;
-       dpy->VersionMinor=4;
-   
-   //dpy->Extensions.KHR_create_context = true;
+       CALLED();
+
+       TRACE("Add configs\n");
+       if (!haiku_add_configs_for_visuals(dpy))
+               return EGL_FALSE;
 
-       //dri2_dpy->vtbl = &dri2_haiku_display_vtbl;
-       _eglLog(_EGL_DEBUG, "Initialization finished");
+       dpy->Version = 14;
+   
+       TRACE("Initialization finished\n");
 
        return EGL_TRUE;
 }
@@ -331,13 +241,24 @@ _EGLContext*
 haiku_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
        _EGLContext *share_list, const EGLint *attrib_list)
 {
-       _eglLog(_EGL_DEBUG,"Creating context");
+       CALLED();
+
        struct haiku_egl_context* context;
-       context=(struct haiku_egl_context*)calloc(1,sizeof (*context));
-       if(!_eglInitContext(&context->ctx, disp, conf, attrib_list))
-               printf("ERROR creating context");
-       _eglLog(_EGL_DEBUG, "Context created");
+       context = (struct haiku_egl_context*) calloc(1, sizeof (*context));
+       if (!context) {
+               _eglError(EGL_BAD_ALLOC, "haiku_create_context");
+               return NULL;
+       }
+
+       if (!_eglInitContext(&context->ctx, disp, conf, attrib_list))
+               goto cleanup;
+
+       TRACE("Context created\n");
        return &context->ctx;
+
+cleanup:
+       free(context);
+       return NULL;
 }
 
 
@@ -345,7 +266,13 @@ extern "C"
 EGLBoolean
 haiku_destroy_context(_EGLDriver* drv, _EGLDisplay *disp, _EGLContext* ctx)
 {
-       ctx=NULL;
+       struct haiku_egl_context* context = haiku_egl_context(ctx);
+
+       if (_eglPutContext(ctx)) {
+               // XXX: teardown the context ?
+               free(context);
+               ctx = NULL
+       }
        return EGL_TRUE;
 }
 
@@ -355,11 +282,16 @@ EGLBoolean
 haiku_make_current(_EGLDriver* drv, _EGLDisplay* dpy, _EGLSurface *dsurf,
                  _EGLSurface *rsurf, _EGLContext *ctx)
 {
-       struct haiku_egl_context* cont=haiku_egl_context(ctx);
-       struct haiku_egl_surface* surf=haiku_egl_surface(dsurf);
+       CALLED();
+
+       struct haiku_egl_context* cont = haiku_egl_context(ctx);
+       struct haiku_egl_surface* surf = haiku_egl_surface(dsurf);
        _EGLContext *old_ctx;
-    _EGLSurface *old_dsurf, *old_rsurf;
-       _eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf);
+       _EGLSurface *old_dsurf, *old_rsurf;
+
+       if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf))
+               return EGL_FALSE;
+
        //cont->ctx.DrawSurface=&surf->surf;
        surf->gl->LockGL();
        return EGL_TRUE;
@@ -370,7 +302,8 @@ extern "C"
 EGLBoolean
 haiku_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
 {
-       struct haiku_egl_surface* surface=haiku_egl_surface(surf);
+       struct haiku_egl_surface* surface = haiku_egl_surface(surf);
+
        surface->gl->SwapBuffers();
        //gl->Render();
        return EGL_TRUE;
@@ -393,9 +326,15 @@ extern "C"
 _EGLDriver*
 _eglBuiltInDriverHaiku(const char *args)
 {
-       _eglLog(_EGL_DEBUG,"Driver loaded");
+       CALLED();
+
        struct haiku_egl_driver* driver;
-       driver=(struct haiku_egl_driver*)calloc(1,sizeof(*driver));
+       driver = (struct haiku_egl_driver*) calloc(1, sizeof(*driver));
+       if (!driver) {
+               _eglError(EGL_BAD_ALLOC, "_eglBuiltInDriverHaiku");
+               return NULL;
+       }
+
        _eglInitDriverFallbacks(&driver->base);
        driver->base.API.Initialize = init_haiku;
        driver->base.API.Terminate = haiku_terminate;
@@ -406,32 +345,13 @@ _eglBuiltInDriverHaiku(const char *args)
        driver->base.API.CreatePixmapSurface = haiku_create_pixmap_surface;
        driver->base.API.CreatePbufferSurface = haiku_create_pbuffer_surface;
        driver->base.API.DestroySurface = haiku_destroy_surface;
-       /*
-       driver->API.GetProcAddress = dri2_get_proc_address;
-       driver->API.WaitClient = dri2_wait_client;
-       driver->API.WaitNative = dri2_wait_native;
-       driver->API.BindTexImage = dri2_bind_tex_image;
-       driver->API.ReleaseTexImage = dri2_release_tex_image;
-       driver->API.SwapInterval = dri2_swap_interval;
-       */
 
        driver->base.API.SwapBuffers = haiku_swap_buffers;
-       /*
-       driver->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage;
-       driver->API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
-       driver->API.PostSubBufferNV = dri2_post_sub_buffer;
-       driver->API.CopyBuffers = dri2_copy_buffers,
-       driver->API.QueryBufferAge = dri2_query_buffer_age;
-       driver->API.CreateImageKHR = dri2_create_image;
-       driver->API.DestroyImageKHR = dri2_destroy_image_khr;
-       driver->API.CreateWaylandBufferFromImageWL = dri2_create_wayland_buffer_from_image;
-       driver->API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
-       */
 
        driver->base.Name = "Haiku";
        driver->base.Unload = haiku_unload;
 
-       _eglLog(_EGL_DEBUG, "API Calls defined");
-       
+       TRACE("API Calls defined\n");
+
        return &driver->base;
 }
index 12b66d053fc26b502dbcdcdc758fb3a181c4f59e..0ba7295396073955e00703f2a83fdd64c26b1ded 100644 (file)
@@ -43,10 +43,7 @@ LOCAL_CFLAGS := \
        -D_EGL_DRIVER_SEARCH_DIR=\"/system/lib/egl\" \
        -D_EGL_OS_UNIX=1
 
-LOCAL_STATIC_LIBRARIES :=
-
 LOCAL_SHARED_LIBRARIES := \
-       libglapi \
        libdl \
        libhardware \
        liblog \
@@ -62,95 +59,20 @@ ifneq ($(MESA_GPU_DRIVERS),swrast)
 LOCAL_SHARED_LIBRARIES += libdrm
 endif
 
-ifeq ($(strip $(MESA_BUILD_CLASSIC)),true)
 LOCAL_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
-LOCAL_STATIC_LIBRARIES += libmesa_egl_dri2
 
+ifeq ($(strip $(MESA_BUILD_CLASSIC)),true)
 # require i915_dri and/or i965_dri
 LOCAL_REQUIRED_MODULES += \
        $(addsuffix _dri, $(filter i915 i965, $(MESA_GPU_DRIVERS)))
 endif # MESA_BUILD_CLASSIC
 
 ifeq ($(strip $(MESA_BUILD_GALLIUM)),true)
-
-gallium_DRIVERS :=
-
-# swrast
-gallium_DRIVERS += libmesa_pipe_softpipe libmesa_winsys_sw_android
-
-# freedreno
-ifneq ($(filter freedreno, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_winsys_freedreno libmesa_pipe_freedreno
-LOCAL_SHARED_LIBRARIES += libdrm_freedreno
-endif
-
-# i915g
-ifneq ($(filter i915g, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_winsys_i915 libmesa_pipe_i915
-LOCAL_SHARED_LIBRARIES += libdrm_intel
-endif
-
-# ilo
-ifneq ($(filter ilo, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_winsys_intel libmesa_pipe_ilo
-LOCAL_SHARED_LIBRARIES += libdrm_intel
-endif
-
-# nouveau
-ifneq ($(filter nouveau, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS +=  libmesa_winsys_nouveau libmesa_pipe_nouveau
-LOCAL_SHARED_LIBRARIES += libdrm_nouveau
-LOCAL_SHARED_LIBRARIES += libstlport
-endif
-
-# r300g/r600g/radeonsi
-ifneq ($(filter r300g r600g radeonsi, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_winsys_radeon
-LOCAL_SHARED_LIBRARIES += libdrm_radeon
-ifneq ($(filter r300g, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_pipe_r300
-endif # r300g
-ifneq ($(filter r600g radeonsi, $(MESA_GPU_DRIVERS)),)
-ifneq ($(filter r600g, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_pipe_r600
-LOCAL_SHARED_LIBRARIES += libstlport
-endif # r600g
-ifneq ($(filter radeonsi, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_pipe_radeonsi
-endif # radeonsi
-gallium_DRIVERS += libmesa_pipe_radeon
-endif # r600g || radeonsi
-endif # r300g || r600g || radeonsi
-
-# vmwgfx
-ifneq ($(filter vmwgfx, $(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_winsys_svga libmesa_pipe_svga
-endif
-
-#
-# Notes about the order here:
-#
-#  * libmesa_st_egl depends on libmesa_winsys_sw_android in $(gallium_DRIVERS)
-#  * libmesa_pipe_r300 in $(gallium_DRIVERS) depends on libmesa_st_mesa and
-#    libmesa_glsl
-#  * libmesa_st_mesa depends on libmesa_glsl
-#  * libmesa_glsl depends on libmesa_glsl_utils
-#
-LOCAL_STATIC_LIBRARIES := \
-       libmesa_egl_gallium \
-       libmesa_st_egl \
-       $(gallium_DRIVERS) \
-       libmesa_st_mesa \
-       libmesa_util \
-       libmesa_glsl \
-       libmesa_glsl_utils \
-       libmesa_gallium \
-       $(LOCAL_STATIC_LIBRARIES)
-
+LOCAL_REQUIRED_MODULES += gallium_dri
 endif # MESA_BUILD_GALLIUM
 
 LOCAL_STATIC_LIBRARIES := \
-       $(LOCAL_STATIC_LIBRARIES) \
+       libmesa_egl_dri2 \
        libmesa_loader
 
 LOCAL_MODULE := libGLES_mesa
index b6617366c7ed92e7fe3aa0d67571e8644a3d596a..9030d272b538c76f0d7f33f69930a1274b7cb9a2 100644 (file)
@@ -68,6 +68,10 @@ if HAVE_EGL_PLATFORM_NULL
 AM_CFLAGS += -DHAVE_NULL_PLATFORM
 endif
 
+if HAVE_EGL_PLATFORM_SURFACELESS
+AM_CFLAGS += -DHAVE_SURFACELESS_PLATFORM
+endif
+
 if HAVE_EGL_DRIVER_DRI2
 AM_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
 AM_CFLAGS += -DHAVE_XCB_DRI2
index 304c7731c8c3475fd75da7bd53c30c03deefa649..e39a80f14a60ebeaf7003b6e4f3ca610866ee2fc 100644 (file)
@@ -22,10 +22,6 @@ LIBEGL_C_FILES := \
        eglimage.h \
        egllog.c \
        egllog.h \
-       eglmode.c \
-       eglmode.h \
-       eglscreen.c \
-       eglscreen.h \
        eglstring.c \
        eglstring.h \
        eglsurface.c \
index b3d253dd1330d18836205f49f1fabd098dbc4c59..1af995997291e301677c388d4b4b4a8d38b715e4 100644 (file)
@@ -16,10 +16,10 @@ The EGL code here basically consists of two things:
 
 Bootstrapping:
 
-When the apps calls eglOpenDisplay() a device driver is selected and loaded
-(look for dlsym() or LoadLibrary() in egldriver.c).
+When the apps calls eglInitialize() a device driver is selected and loaded
+(look for _eglAddDrivers() and _eglLoadModule() in egldriver.c).
 
-The driver's _eglMain() function is then called.  This driver function
+The built-in driver's entry point function is then called.  This driver function
 allocates, initializes and returns a new _EGLDriver object (usually a
 subclass of that type).
 
@@ -30,10 +30,9 @@ driver->API.Initialize and driver->API.Terminate _must_ be implemented
 with driver-specific code (no default/fallback function is possible).
 
 
-A bit later, the app will call eglInitialize().  This will get routed
-to the driver->API.Initialize() function.  Any additional driver
-initialization that wasn't done in _eglMain() should be done at this
-point.  Typically, this will involve setting up visual configs, etc.
+Shortly after, the driver->API.Initialize() function is executed.  Any additional
+driver initialization that wasn't done in the driver entry point should be
+done at this point.  Typically, this will involve setting up visual configs, etc.
 
 
 
index ba1d0ddc97525488019b5e81b7b70433c0beb40d..105e919683a15e865bfbd9c19287743b1cc8604c 100644 (file)
@@ -98,8 +98,6 @@
 #include "egldriver.h"
 #include "eglsurface.h"
 #include "eglconfig.h"
-#include "eglscreen.h"
-#include "eglmode.h"
 #include "eglimage.h"
 #include "eglsync.h"
 #include "eglstring.h"
 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
    _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
 
-#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
-   _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
-
-#define _EGL_CHECK_MODE(disp, m, ret, drv) \
-   _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
-
 #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
    _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
 
@@ -236,40 +228,6 @@ _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
 }
 
 
-#ifdef EGL_MESA_screen_surface
-
-
-static inline _EGLDriver *
-_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
-{
-   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
-   if (!drv)
-      return NULL;
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, msg);
-      return NULL;
-   }
-   return drv;
-}
-
-
-static inline _EGLDriver *
-_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
-{
-   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
-   if (!drv)
-      return NULL;
-   if (!m) {
-      _eglError(EGL_BAD_MODE_MESA, msg);
-      return NULL;
-   }
-   return drv;
-}
-
-
-#endif /* EGL_MESA_screen_surface */
-
-
 /**
  * Lookup and lock a display.
  */
@@ -293,6 +251,31 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
 }
 
 
+static EGLint *
+_eglConvertAttribsToInt(const EGLAttrib *attr_list)
+{
+   EGLint *int_attribs = NULL;
+
+   /* Convert attributes from EGLAttrib[] to EGLint[] */
+   if (attr_list) {
+      int i, size = 0;
+
+      while (attr_list[size] != EGL_NONE)
+         size += 2;
+
+      size += 1; /* add space for EGL_NONE */
+
+      int_attribs = calloc(size, sizeof(int_attribs[0]));
+      if (!int_attribs)
+         return NULL;
+
+      for (i = 0; i < size; i++)
+         int_attribs[i] = attr_list[i];
+   }
+   return int_attribs;
+}
+
+
 /**
  * This is typically the first EGL function that an application calls.
  * It associates a private _EGLDisplay object to the native display.
@@ -312,7 +295,7 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
    return _eglGetDisplayHandle(dpy);
 }
 
-EGLDisplay EGLAPIENTRY
+static EGLDisplay EGLAPIENTRY
 eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
                          const EGLint *attrib_list)
 {
@@ -343,6 +326,21 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
    return _eglGetDisplayHandle(dpy);
 }
 
+EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplay(EGLenum platform, void *native_display,
+                      const EGLAttrib *attrib_list)
+{
+   EGLDisplay display;
+   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+
+   if (attrib_list && !int_attribs)
+      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
+
+   display = eglGetPlatformDisplayEXT(platform, native_display, int_attribs);
+   free(int_attribs);
+   return display;
+}
+
 /**
  * Copy the extension into the string and update the string pointer.
  */
@@ -383,8 +381,6 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
 
    char *exts = dpy->ExtensionsString;
 
-   _EGL_CHECK_EXTENSION(MESA_screen_surface);
-   _EGL_CHECK_EXTENSION(MESA_copy_context);
    _EGL_CHECK_EXTENSION(MESA_drm_display);
    _EGL_CHECK_EXTENSION(MESA_drm_image);
    _EGL_CHECK_EXTENSION(MESA_configless_context);
@@ -451,6 +447,26 @@ _eglCreateAPIsString(_EGLDisplay *dpy)
    assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
 }
 
+static void
+_eglComputeVersion(_EGLDisplay *disp)
+{
+   disp->Version = 14;
+
+   if (disp->Extensions.KHR_fence_sync &&
+       disp->Extensions.KHR_cl_event2 &&
+       disp->Extensions.KHR_wait_sync &&
+       disp->Extensions.KHR_image_base &&
+       disp->Extensions.KHR_gl_texture_2D_image &&
+       disp->Extensions.KHR_gl_texture_3D_image &&
+       disp->Extensions.KHR_gl_texture_cubemap_image &&
+       disp->Extensions.KHR_gl_renderbuffer_image &&
+       disp->Extensions.KHR_create_context &&
+       disp->Extensions.EXT_create_context_robustness &&
+       disp->Extensions.KHR_get_all_proc_addresses &&
+       disp->Extensions.KHR_gl_colorspace &&
+       disp->Extensions.KHR_surfaceless_context)
+      disp->Version = 15;
+}
 
 /**
  * This is typically the second EGL function that an application calls.
@@ -488,17 +504,18 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
        */
       disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
 
+      _eglComputeVersion(disp);
       _eglCreateExtensionsString(disp);
       _eglCreateAPIsString(disp);
       _eglsnprintf(disp->VersionString, sizeof(disp->VersionString),
-              "%d.%d (%s)", disp->VersionMajor, disp->VersionMinor,
+              "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
               disp->Driver->Name);
    }
 
    /* Update applications version of major and minor if not NULL */
    if ((major != NULL) && (minor != NULL)) {
-      *major = disp->VersionMajor;
-      *minor = disp->VersionMinor;
+      *major = disp->Version / 10;
+      *minor = disp->Version % 10;
    }
 
    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
@@ -740,7 +757,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
 }
 
 
-EGLSurface EGLAPIENTRY
+static EGLSurface EGLAPIENTRY
 eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
                                   void *native_window,
                                   const EGLint *attrib_list)
@@ -765,6 +782,24 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
 }
 
 
+EGLSurface EGLAPIENTRY
+eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
+                               void *native_window,
+                               const EGLAttrib *attrib_list)
+{
+   EGLSurface surface;
+   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+
+   if (attrib_list && !int_attribs)
+      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+   surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window,
+                                               int_attribs);
+   free(int_attribs);
+   return surface;
+}
+
+
 static EGLSurface
 _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
                               void *native_pixmap, const EGLint *attrib_list)
@@ -793,7 +828,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
                                          attrib_list);
 }
 
-EGLSurface EGLAPIENTRY
+static EGLSurface EGLAPIENTRY
 eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
                                    void *native_pixmap,
                                    const EGLint *attrib_list)
@@ -818,6 +853,24 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
 }
 
 
+EGLSurface EGLAPIENTRY
+eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
+                               void *native_pixmap,
+                               const EGLAttrib *attrib_list)
+{
+   EGLSurface surface;
+   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+
+   if (attrib_list && !int_attribs)
+      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+   surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap,
+                                               int_attribs);
+   free(int_attribs);
+   return surface;
+}
+
+
 EGLSurface EGLAPIENTRY
 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
                         const EGLint *attrib_list)
@@ -964,7 +1017,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 
 #ifdef EGL_EXT_swap_buffers_with_damage
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
                             EGLint *rects, EGLint n_rects)
 {
@@ -1151,352 +1204,9 @@ eglGetError(void)
 }
 
 
-__eglMustCastToProperFunctionPointerType EGLAPIENTRY
-eglGetProcAddress(const char *procname)
-{
-   static const struct {
-      const char *name;
-      _EGLProc function;
-   } egl_functions[] = {
-      /* core functions should not be queryable, but, well... */
-#ifdef _EGL_GET_CORE_ADDRESSES
-      /* alphabetical order */
-      { "eglBindAPI", (_EGLProc) eglBindAPI },
-      { "eglBindTexImage", (_EGLProc) eglBindTexImage },
-      { "eglChooseConfig", (_EGLProc) eglChooseConfig },
-      { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
-      { "eglCreateContext", (_EGLProc) eglCreateContext },
-      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
-      { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
-      { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
-      { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
-      { "eglDestroyContext", (_EGLProc) eglDestroyContext },
-      { "eglDestroySurface", (_EGLProc) eglDestroySurface },
-      { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
-      { "eglGetConfigs", (_EGLProc) eglGetConfigs },
-      { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
-      { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
-      { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
-      { "eglGetDisplay", (_EGLProc) eglGetDisplay },
-      { "eglGetError", (_EGLProc) eglGetError },
-      { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
-      { "eglInitialize", (_EGLProc) eglInitialize },
-      { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
-      { "eglQueryAPI", (_EGLProc) eglQueryAPI },
-      { "eglQueryContext", (_EGLProc) eglQueryContext },
-      { "eglQueryString", (_EGLProc) eglQueryString },
-      { "eglQuerySurface", (_EGLProc) eglQuerySurface },
-      { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
-      { "eglReleaseThread", (_EGLProc) eglReleaseThread },
-      { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
-      { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
-      { "eglSwapInterval", (_EGLProc) eglSwapInterval },
-      { "eglTerminate", (_EGLProc) eglTerminate },
-      { "eglWaitClient", (_EGLProc) eglWaitClient },
-      { "eglWaitGL", (_EGLProc) eglWaitGL },
-      { "eglWaitNative", (_EGLProc) eglWaitNative },
-#endif /* _EGL_GET_CORE_ADDRESSES */
-#ifdef EGL_MESA_screen_surface
-      { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
-      { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
-      { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
-      { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
-      { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
-      { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
-      { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
-      { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
-      { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
-      { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
-      { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
-      { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
-#endif /* EGL_MESA_screen_surface */
 #ifdef EGL_MESA_drm_display
-      { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
-#endif
-      { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
-      { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
-      { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
-      { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
-      { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
-      { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
-      { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
-      { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
-      { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
-#ifdef EGL_NOK_swap_region
-      { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
-#endif
-#ifdef EGL_MESA_drm_image
-      { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
-      { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
-#endif
-#ifdef EGL_WL_bind_wayland_display
-      { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
-      { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
-      { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
-#endif
-#ifdef EGL_WL_create_wayland_buffer_from_image
-      { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
-#endif
-      { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
-#ifdef EGL_EXT_swap_buffers_with_damage
-      { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
-#endif
-      { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
-      { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
-      { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
-      { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
-#ifdef EGL_MESA_dma_buf_image_export
-      { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
-      { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
-#endif
-      { NULL, NULL }
-   };
-   EGLint i;
-   _EGLProc ret;
-
-   if (!procname)
-      RETURN_EGL_SUCCESS(NULL, NULL);
-
-   ret = NULL;
-   if (strncmp(procname, "egl", 3) == 0) {
-      for (i = 0; egl_functions[i].name; i++) {
-         if (strcmp(egl_functions[i].name, procname) == 0) {
-            ret = egl_functions[i].function;
-            break;
-         }
-      }
-   }
-   if (!ret)
-      ret = _eglGetDriverProc(procname);
-
-   RETURN_EGL_SUCCESS(NULL, ret);
-}
-
-
-#ifdef EGL_MESA_screen_surface
-
-
-/*
- * EGL_MESA_screen extension
- */
-
-EGLBoolean EGLAPIENTRY
-eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
-                  const EGLint *attrib_list, EGLModeMESA *modes,
-                  EGLint modes_size, EGLint *num_modes)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
-         modes, modes_size, num_modes);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
-                EGLint mode_size, EGLint *num_mode)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
-                     EGLint attribute, EGLint *value)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLMode *m = _eglLookupMode(mode, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
-   ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
-                   EGLint mask)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLContext *source_context = _eglLookupContext(source, disp);
-   _EGLContext *dest_context = _eglLookupContext(dest, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
-   if (!dest_context)
-      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
-
-   ret = drv->API.CopyContextMESA(drv, disp,
-         source_context, dest_context, mask);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
-                  EGLint max_screens, EGLint *num_screens)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
-   ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
 
-EGLSurface EGLAPIENTRY
-eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
-                           const EGLint *attrib_list)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLConfig *conf = _eglLookupConfig(config, disp);
-   _EGLDriver *drv;
-   _EGLSurface *surf;
-   EGLSurface ret;
-
-   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
-
-   surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
-   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
-                         EGLSurface surface, EGLModeMESA mode)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
-   _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _EGLMode *m = _eglLookupMode(mode, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   if (!surf && surface != EGL_NO_SURFACE)
-      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
-   if (!m && mode != EGL_NO_MODE_MESA)
-      RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
-
-   ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
-                   EGLint attribute, EGLint *value)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
-   _EGLDriver *drv;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
-                          EGLSurface *surface)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
-   _EGLDriver *drv;
-   _EGLSurface *surf;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
-   if (ret && surface)
-      *surface = _eglGetSurfaceHandle(surf);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-EGLBoolean EGLAPIENTRY
-eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
-   _EGLDriver *drv;
-   _EGLMode *m;
-   EGLBoolean ret;
-
-   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
-   ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
-   if (ret && mode)
-      *mode = m->Handle;
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-const char * EGLAPIENTRY
-eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
-{
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLMode *m = _eglLookupMode(mode, disp);
-   _EGLDriver *drv;
-   const char *ret;
-
-   _EGL_CHECK_MODE(disp, m, NULL, drv);
-   ret = drv->API.QueryModeStringMESA(drv, disp, m);
-
-   RETURN_EGL_EVAL(disp, ret);
-}
-
-
-#endif /* EGL_MESA_screen_surface */
-
-
-#ifdef EGL_MESA_drm_display
-
-EGLDisplay EGLAPIENTRY
+static EGLDisplay EGLAPIENTRY
 eglGetDRMDisplayMESA(int fd)
 {
    _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
@@ -1607,7 +1317,7 @@ eglReleaseThread(void)
 }
 
 
-EGLImageKHR EGLAPIENTRY
+static EGLImage EGLAPIENTRY
 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                   EGLClientBuffer buffer, const EGLint *attr_list)
 {
@@ -1615,7 +1325,7 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLDriver *drv;
    _EGLImage *img;
-   EGLImageKHR ret;
+   EGLImage ret;
 
    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
    if (!disp->Extensions.KHR_image_base)
@@ -1636,8 +1346,24 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
 }
 
 
+EGLImage EGLAPIENTRY
+eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+               EGLClientBuffer buffer, const EGLAttrib *attr_list)
+{
+   EGLImage image;
+   EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
+
+   if (attr_list && !int_attribs)
+      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE);
+
+   image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs);
+   free(int_attribs);
+   return image;
+}
+
+
 EGLBoolean EGLAPIENTRY
-eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+eglDestroyImage(EGLDisplay dpy, EGLImage image)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
@@ -1657,15 +1383,16 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 }
 
 
-static EGLSyncKHR
+static EGLSync
 _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
-               const EGLAttribKHR *attrib_list64, EGLBoolean is64)
+               const EGLAttrib *attrib_list64, EGLBoolean is64,
+               EGLenum invalid_type_error)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDriver *drv;
    _EGLSync *sync;
-   EGLSyncKHR ret;
+   EGLSync ret;
 
    _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
 
@@ -1680,18 +1407,18 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
    switch (type) {
    case EGL_SYNC_FENCE_KHR:
       if (!disp->Extensions.KHR_fence_sync)
-         RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
       break;
    case EGL_SYNC_REUSABLE_KHR:
       if (!disp->Extensions.KHR_reusable_sync)
-         RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
       break;
    case EGL_SYNC_CL_EVENT_KHR:
       if (!disp->Extensions.KHR_cl_event2)
-         RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
       break;
    default:
-      RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+      RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
    }
 
    sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
@@ -1701,22 +1428,32 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
 }
 
 
-EGLSyncKHR EGLAPIENTRY
+static EGLSync EGLAPIENTRY
 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
 {
-   return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE);
+   return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE,
+                         EGL_BAD_ATTRIBUTE);
+}
+
+
+static EGLSync EGLAPIENTRY
+eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+   return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+                         EGL_BAD_ATTRIBUTE);
 }
 
 
-EGLSyncKHR EGLAPIENTRY
-eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list)
+EGLSync EGLAPIENTRY
+eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 {
-   return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE);
+   return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+                         EGL_BAD_PARAMETER);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+eglDestroySync(EGLDisplay dpy, EGLSync sync)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
@@ -1735,7 +1472,7 @@ eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
 
 
 EGLint EGLAPIENTRY
-eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
@@ -1755,8 +1492,8 @@ eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR t
 }
 
 
-EGLint EGLAPIENTRY
-eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
+static EGLint EGLAPIENTRY
+eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
@@ -1782,7 +1519,18 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
 
 
 EGLBoolean EGLAPIENTRY
-eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+   /* The KHR version returns EGLint, while the core version returns
+    * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
+    * EGL_TRUE.
+    */
+   return eglWaitSyncKHR(dpy, sync, flags);
+}
+
+
+static EGLBoolean EGLAPIENTRY
+eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
@@ -1798,7 +1546,7 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
 
 
 EGLBoolean EGLAPIENTRY
-eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
@@ -1808,15 +1556,33 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *v
    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync);
-   ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
+   ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
 
    RETURN_EGL_EVAL(disp, ret);
 }
 
 
+static EGLBoolean EGLAPIENTRY
+eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
+{
+   EGLAttrib attrib = *value;
+   EGLBoolean result = eglGetSyncAttrib(dpy, sync, attribute, &attrib);
+
+   /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
+    *
+    *    If any error occurs, <*value> is not modified.
+    */
+   if (result == EGL_FALSE)
+      return result;
+
+   *value = attrib;
+   return result;
+}
+
+
 #ifdef EGL_NOK_swap_region
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
                        EGLint numRects, const EGLint *rects)
 {
@@ -1846,13 +1612,13 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
 
 #ifdef EGL_MESA_drm_image
 
-EGLImageKHR EGLAPIENTRY
+static EGLImage EGLAPIENTRY
 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLDriver *drv;
    _EGLImage *img;
-   EGLImageKHR ret;
+   EGLImage ret;
 
    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
    if (!disp->Extensions.MESA_drm_image)
@@ -1864,8 +1630,8 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
    RETURN_EGL_EVAL(disp, ret);
 }
 
-EGLBoolean EGLAPIENTRY
-eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
+static EGLBoolean EGLAPIENTRY
+eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
                      EGLint *name, EGLint *handle, EGLint *stride)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1889,7 +1655,7 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
 #ifdef EGL_WL_bind_wayland_display
 struct wl_display;
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1907,7 +1673,7 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
    RETURN_EGL_EVAL(disp, ret);
 }
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1925,7 +1691,7 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
    RETURN_EGL_EVAL(disp, ret);
 }
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
                         EGLint attribute, EGLint *value)
 {
@@ -1946,8 +1712,8 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
 #endif
 
 #ifdef EGL_WL_create_wayland_buffer_from_image
-struct wl_buffer * EGLAPIENTRY
-eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
+static struct wl_buffer * EGLAPIENTRY
+eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img;
@@ -1968,7 +1734,7 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
 }
 #endif
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
                    EGLint x, EGLint y, EGLint width, EGLint height)
 {
@@ -1987,7 +1753,7 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
    RETURN_EGL_EVAL(disp, ret);
 }
 
-EGLBoolean EGLAPIENTRY
+static EGLBoolean EGLAPIENTRY
 eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
                          EGLuint64KHR *ust, EGLuint64KHR *msc,
                          EGLuint64KHR *sbc)
@@ -2010,8 +1776,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
 }
 
 #ifdef EGL_MESA_image_dma_buf_export
-EGLBoolean EGLAPIENTRY
-eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
+static EGLBoolean EGLAPIENTRY
+eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
                               EGLint *fourcc, EGLint *nplanes,
                               EGLuint64KHR *modifiers)
 {
@@ -2032,8 +1798,8 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
    RETURN_EGL_EVAL(disp, ret);
 }
 
-EGLBoolean EGLAPIENTRY
-eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image,
+static EGLBoolean EGLAPIENTRY
+eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
                          int *fds, EGLint *strides, EGLint *offsets)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -2052,3 +1818,120 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image,
    RETURN_EGL_EVAL(disp, ret);
 }
 #endif
+
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY
+eglGetProcAddress(const char *procname)
+{
+   static const struct {
+      const char *name;
+      _EGLProc function;
+   } egl_functions[] = {
+      /* core functions queryable in the presence of
+       * EGL_KHR_get_all_proc_addresses or EGL 1.5
+       */
+      /* alphabetical order */
+      { "eglBindAPI", (_EGLProc) eglBindAPI },
+      { "eglBindTexImage", (_EGLProc) eglBindTexImage },
+      { "eglChooseConfig", (_EGLProc) eglChooseConfig },
+      { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
+      { "eglCreateContext", (_EGLProc) eglCreateContext },
+      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
+      { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
+      { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
+      { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
+      { "eglDestroyContext", (_EGLProc) eglDestroyContext },
+      { "eglDestroySurface", (_EGLProc) eglDestroySurface },
+      { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
+      { "eglGetConfigs", (_EGLProc) eglGetConfigs },
+      { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
+      { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
+      { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
+      { "eglGetDisplay", (_EGLProc) eglGetDisplay },
+      { "eglGetError", (_EGLProc) eglGetError },
+      { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
+      { "eglInitialize", (_EGLProc) eglInitialize },
+      { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
+      { "eglQueryAPI", (_EGLProc) eglQueryAPI },
+      { "eglQueryContext", (_EGLProc) eglQueryContext },
+      { "eglQueryString", (_EGLProc) eglQueryString },
+      { "eglQuerySurface", (_EGLProc) eglQuerySurface },
+      { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
+      { "eglReleaseThread", (_EGLProc) eglReleaseThread },
+      { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
+      { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
+      { "eglSwapInterval", (_EGLProc) eglSwapInterval },
+      { "eglTerminate", (_EGLProc) eglTerminate },
+      { "eglWaitClient", (_EGLProc) eglWaitClient },
+      { "eglWaitGL", (_EGLProc) eglWaitGL },
+      { "eglWaitNative", (_EGLProc) eglWaitNative },
+      { "eglCreateSync", (_EGLProc) eglCreateSync },
+      { "eglDestroySync", (_EGLProc) eglDestroySync },
+      { "eglClientWaitSync", (_EGLProc) eglClientWaitSync },
+      { "eglGetSyncAttrib", (_EGLProc) eglGetSyncAttrib },
+      { "eglWaitSync", (_EGLProc) eglWaitSync },
+      { "eglCreateImage", (_EGLProc) eglCreateImage },
+      { "eglDestroyImage", (_EGLProc) eglDestroyImage },
+      { "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay },
+      { "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface },
+      { "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface },
+#ifdef EGL_MESA_drm_display
+      { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
+#endif
+      { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
+      { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage },
+      { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
+      { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
+      { "eglDestroySyncKHR", (_EGLProc) eglDestroySync },
+      { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync },
+      { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
+      { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
+      { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
+#ifdef EGL_NOK_swap_region
+      { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
+#endif
+#ifdef EGL_MESA_drm_image
+      { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
+      { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
+#endif
+#ifdef EGL_WL_bind_wayland_display
+      { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
+      { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
+      { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
+#endif
+#ifdef EGL_WL_create_wayland_buffer_from_image
+      { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
+#endif
+      { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
+#ifdef EGL_EXT_swap_buffers_with_damage
+      { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
+#endif
+      { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
+      { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
+      { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
+      { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
+#ifdef EGL_MESA_image_dma_buf_export
+      { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
+      { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
+#endif
+      { NULL, NULL }
+   };
+   EGLint i;
+   _EGLProc ret;
+
+   if (!procname)
+      RETURN_EGL_SUCCESS(NULL, NULL);
+
+   ret = NULL;
+   if (strncmp(procname, "egl", 3) == 0) {
+      for (i = 0; egl_functions[i].name; i++) {
+         if (strcmp(egl_functions[i].name, procname) == 0) {
+            ret = egl_functions[i].function;
+            break;
+         }
+      }
+   }
+   if (!ret)
+      ret = _eglGetDriverProc(procname);
+
+   RETURN_EGL_SUCCESS(NULL, ret);
+}
index 068d4ef5c1e5ed7dcbae0cfe50316d55d0774986..4e0378d0d5fe50ce51f110a366c08d43d7fead20 100644 (file)
 #ifndef EGLAPI_INCLUDED
 #define EGLAPI_INCLUDED
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * A generic function ptr type
  */
@@ -79,22 +84,6 @@ typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname);
 
 
 
-#ifdef EGL_MESA_screen_surface
-typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
-typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *source, _EGLContext *dest, EGLint mask);
-typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-typedef _EGLSurface *(*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
-typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
-typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint x, EGLint y);
-typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface **surface);
-typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLMode **mode);
-typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode);
-#endif /* EGL_MESA_screen_surface */
-
-
 typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list);
 
 
@@ -102,12 +91,12 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo
 typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
 
 
-typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list, const EGLAttribKHR *attrib_list64);
+typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list, const EGLAttrib *attrib_list64);
 typedef EGLBoolean (*DestroySyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
-typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTime timeout);
 typedef EGLint (*WaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
 typedef EGLBoolean (*SignalSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLenum mode);
-typedef EGLBoolean (*GetSyncAttribKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*GetSyncAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLAttrib *value);
 
 
 #ifdef EGL_NOK_swap_region
@@ -179,21 +168,6 @@ struct _egl_api
    WaitNative_t WaitNative;
    GetProcAddress_t GetProcAddress;
 
-#ifdef EGL_MESA_screen_surface
-   ChooseModeMESA_t ChooseModeMESA;
-   GetModesMESA_t GetModesMESA;
-   GetModeAttribMESA_t GetModeAttribMESA;
-   CopyContextMESA_t CopyContextMESA;
-   GetScreensMESA_t GetScreensMESA;
-   CreateScreenSurfaceMESA_t CreateScreenSurfaceMESA;
-   ShowScreenSurfaceMESA_t ShowScreenSurfaceMESA;
-   ScreenPositionMESA_t ScreenPositionMESA;
-   QueryScreenMESA_t QueryScreenMESA;
-   QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA;
-   QueryScreenModeMESA_t QueryScreenModeMESA;
-   QueryModeStringMESA_t QueryModeStringMESA;
-#endif /* EGL_MESA_screen_surface */
-
    CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer;
 
    CreateImageKHR_t CreateImageKHR;
@@ -204,7 +178,7 @@ struct _egl_api
    ClientWaitSyncKHR_t ClientWaitSyncKHR;
    WaitSyncKHR_t WaitSyncKHR;
    SignalSyncKHR_t SignalSyncKHR;
-   GetSyncAttribKHR_t GetSyncAttribKHR;
+   GetSyncAttrib_t GetSyncAttrib;
 
 #ifdef EGL_NOK_swap_region
    SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
@@ -240,4 +214,9 @@ struct _egl_api
 #endif
 };
 
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLAPI_INCLUDED */
index 228f6c3d2cab4383c25d4768d1f5eac94307cf4e..29b7128b68d5a838f6ae4e68225cee2933638dfd 100644 (file)
 #include "egltypedefs.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef EGLBoolean (*_EGLArrayForEach)(void *elem, void *foreach_data);
 
 
@@ -83,4 +87,8 @@ _eglGetArraySize(_EGLArray *array)
 }
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLARRAY_INCLUDED */
index b457a40a32a82f964f7057d5c337aece54f55385..9804ca4f281b229a6a3a26b5d68f274eb07ec502 100644 (file)
 #ifndef EGLCOMPILER_INCLUDED
 #define EGLCOMPILER_INCLUDED
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define STATIC_ASSERT(COND) \
    do { \
       (void) sizeof(char [1 - 2*!(COND)]); \
    } while (0)
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLCOMPILER_INCLUDED */
index db42e95f88db9a53d3f9f00a5451402511b6c090..cf65c69b7b4333fb2cab1e36d8eaf88c043146cb 100644 (file)
@@ -323,10 +323,6 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
                    EGL_VG_ALPHA_FORMAT_PRE_BIT |
                    EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
                    EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
-#ifdef EGL_MESA_screen_surface
-            if (conf->Display->Extensions.MESA_screen_surface)
-               mask |= EGL_SCREEN_BIT_MESA;
-#endif
             break;
          case EGL_RENDERABLE_TYPE:
          case EGL_CONFORMANT:
index dc59ea3f72f864a0e0f000a1b26566c250f4e44c..84cb2276b707e60bc14c5914301bf7fda54b153a 100644 (file)
 #include "egltypedefs.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* update _eglValidationTable and _eglOffsetOfConfig before updating this
  * struct */
 struct _egl_config
@@ -225,4 +229,8 @@ extern EGLBoolean
 _eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLCONFIG_INCLUDED */
index 514b91aeef24e7d10d916262086a63db258b8457..e767f4b1abe303577fea0b25d396691e1af87fd7 100644 (file)
@@ -131,7 +131,7 @@ _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy,
             break;
          }
 
-         ctx->Flags = val;
+         ctx->Flags |= val;
          break;
 
       case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
@@ -194,7 +194,38 @@ _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy,
             break;
          }
 
-         ctx->Flags = EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+         if (val == EGL_TRUE)
+            ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+         break;
+
+      case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
+         if (dpy->Version < 15) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+
+         if (val == EGL_TRUE)
+            ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+         break;
+
+      case EGL_CONTEXT_OPENGL_DEBUG:
+         if (dpy->Version < 15) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+
+         if (val == EGL_TRUE)
+            ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+         break;
+
+      case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE:
+         if (dpy->Version < 15) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+
+         if (val == EGL_TRUE)
+            ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
          break;
 
       default:
index 241917f3bead6df77675da829bb62d6c9448a3da..69bf77d8aff7702c6af787fa5ee6b350d21de929 100644 (file)
 #include "egldisplay.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * "Base" class for device driver contexts.
  */
@@ -150,4 +154,8 @@ _eglGetContextHandle(_EGLContext *ctx)
 }
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLCONTEXT_INCLUDED */
index 6ffc799d3dead3757166612d6d01868eb12f18bf..835631d3ba3ea372ef8417a723d6f58df08f8343 100644 (file)
@@ -282,14 +282,6 @@ _eglError(EGLint errCode, const char *msg)
       case EGL_NOT_INITIALIZED:
          s = "EGL_NOT_INITIALIZED";
          break;
-#ifdef EGL_MESA_screen_surface
-      case EGL_BAD_SCREEN_MESA:
-         s = "EGL_BAD_SCREEN_MESA";
-         break;
-      case EGL_BAD_MODE_MESA:
-         s = "EGL_BAD_MODE_MESA";
-         break;
-#endif
       default:
          s = "other EGL error";
       }
index 3343755c9854642246c4002007f035882b0ca8e6..1e386acdafb9c0550801536da02e2af85f56bcb6 100644 (file)
 #include "egltypedefs.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define _EGL_API_ALL_BITS \
    (EGL_OPENGL_ES_BIT   | \
     EGL_OPENVG_BIT      | \
@@ -115,4 +119,8 @@ extern EGLBoolean
 _eglError(EGLint errCode, const char *msg);
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLCURRENT_INCLUDED */
index 4c9e014fcea911f5062843690cc2f48bf0180d50..a32cab2640802fa9eb3d36c5e2c22824b361a84b 100644 (file)
@@ -34,6 +34,9 @@
 #ifndef EGLDEFINES_INCLUDED
 #define EGLDEFINES_INCLUDED
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #define _EGL_MAX_EXTENSIONS_LEN 1000
 
@@ -41,5 +44,8 @@
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* EGLDEFINES_INCLUDED */
index a3ecba8c41ebe76277d1721ebd0d8d070a3866e7..24a0c7e61a7aa22cc0dd33cff2c78c24525b3124 100644 (file)
@@ -71,7 +71,8 @@ static const struct {
    { _EGL_PLATFORM_DRM, "drm" },
    { _EGL_PLATFORM_NULL, "null" },
    { _EGL_PLATFORM_ANDROID, "android" },
-   { _EGL_PLATFORM_HAIKU, "haiku" }
+   { _EGL_PLATFORM_HAIKU, "haiku" },
+   { _EGL_PLATFORM_SURFACELESS, "surfaceless" },
 };
 
 
index b6b9ed8e2787c3475d8438082d61556116cb1868..0b50a36a09824552fb98625dd4c414c2fa24a7fc 100644 (file)
 #include "eglarray.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 enum _egl_platform_type {
    _EGL_PLATFORM_WINDOWS,
    _EGL_PLATFORM_X11,
@@ -47,6 +51,7 @@ enum _egl_platform_type {
    _EGL_PLATFORM_NULL,
    _EGL_PLATFORM_ANDROID,
    _EGL_PLATFORM_HAIKU,
+   _EGL_PLATFORM_SURFACELESS,
 
    _EGL_NUM_PLATFORMS,
    _EGL_INVALID_PLATFORM = -1
@@ -86,8 +91,6 @@ struct _egl_resource
  */
 struct _egl_extensions
 {
-   EGLBoolean MESA_screen_surface;
-   EGLBoolean MESA_copy_context;
    EGLBoolean MESA_drm_display;
    EGLBoolean MESA_drm_image;
    EGLBoolean MESA_configless_context;
@@ -99,6 +102,7 @@ struct _egl_extensions
    EGLBoolean KHR_image_pixmap;
    EGLBoolean KHR_vg_parent_image;
    EGLBoolean KHR_get_all_proc_addresses;
+   EGLBoolean KHR_gl_colorspace;
    EGLBoolean KHR_gl_texture_2D_image;
    EGLBoolean KHR_gl_texture_cubemap_image;
    EGLBoolean KHR_gl_texture_3D_image;
@@ -151,8 +155,7 @@ struct _egl_display
 
    /* these fields are set by the driver during init */
    void *DriverData;          /**< Driver private data */
-   EGLint VersionMajor;       /**< EGL major version */
-   EGLint VersionMinor;       /**< EGL minor version */
+   EGLint Version;            /**< EGL version major*10+minor */
    EGLint ClientAPIs;         /**< Bitmask of APIs supported (EGL_xxx_BIT) */
    _EGLExtensions Extensions; /**< Extensions supported */
 
@@ -271,4 +274,9 @@ _eglGetWaylandDisplay(struct wl_display *native_display,
                       const EGLint *attrib_list);
 #endif
 
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLDISPLAY_INCLUDED */
index 6983af966b652ec12e1f40c857616fb772c9a534..6ef79d96502e85f31675289bf75abc946aca85d4 100644 (file)
 #include "egldriver.h"
 #include "egllog.h"
 
-#if defined(_EGL_OS_UNIX)
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <unistd.h>
-#endif
-
-#ifdef _EGL_BUILT_IN_DRIVER_HAIKU
-_EGLDriver* _eglBuiltInDriverHaiku(const char* args);
-#endif
-
 typedef struct _egl_module {
-   char *Path;
+   char *Name;
    _EGLMain_t BuiltIn;
-   void *Handle;
    _EGLDriver *Driver;
 } _EGLModule;
 
@@ -79,153 +67,24 @@ const struct {
    { NULL, NULL }
 };
 
-/**
- * Wrappers for dlopen/dlclose()
- */
-#if defined(_EGL_OS_WINDOWS)
-
-
-typedef HMODULE lib_handle;
-
-static HMODULE
-open_library(const char *filename)
-{
-   return LoadLibrary(filename);
-}
-
-static void
-close_library(HMODULE lib)
-{
-   FreeLibrary(lib);
-}
-
-
-static const char *
-library_suffix(void)
-{
-   return ".dll";
-}
-
-
-#elif defined(_EGL_OS_UNIX)
-
-
-typedef void * lib_handle;
-
-static void *
-open_library(const char *filename)
-{
-   return dlopen(filename, RTLD_LAZY);
-}
-
-static void
-close_library(void *lib)
-{
-   dlclose(lib);
-}
-
-
-static const char *
-library_suffix(void)
-{
-   return ".so";
-}
-
-
-#endif
-
-
-/**
- * Open the named driver and find its bootstrap function: _eglMain().
- */
-static _EGLMain_t
-_eglOpenLibrary(const char *driverPath, lib_handle *handle)
-{
-   lib_handle lib;
-   _EGLMain_t mainFunc = NULL;
-   const char *error = "unknown error";
-
-   assert(driverPath);
-
-   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
-   lib = open_library(driverPath);
-
-#if defined(_EGL_OS_WINDOWS)
-   /* XXX untested */
-   if (lib)
-      mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
-#elif defined(_EGL_OS_UNIX)
-   if (lib) {
-      union {
-         _EGLMain_t func;
-         void *ptr;
-      } tmp = { NULL };
-      /* direct cast gives a warning when compiled with -pedantic */
-      tmp.ptr = dlsym(lib, "_eglMain");
-      mainFunc = tmp.func;
-      if (!mainFunc)
-         error = dlerror();
-   }
-   else {
-      error = dlerror();
-   }
-#endif
-
-   if (!lib) {
-      _eglLog(_EGL_WARNING, "Could not open driver %s (%s)",
-              driverPath, error);
-      return NULL;
-   }
-
-   if (!mainFunc) {
-      _eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)",
-              driverPath, error);
-      if (lib)
-         close_library(lib);
-      return NULL;
-   }
-
-   *handle = lib;
-   return mainFunc;
-}
-
-
 /**
  * Load a module and create the driver object.
  */
 static EGLBoolean
 _eglLoadModule(_EGLModule *mod)
 {
-   _EGLMain_t mainFunc;
-   lib_handle lib;
    _EGLDriver *drv;
 
    if (mod->Driver)
       return EGL_TRUE;
 
-   if (mod->BuiltIn) {
-      lib = (lib_handle) NULL;
-      mainFunc = mod->BuiltIn;
-   }
-   else {
-      mainFunc = _eglOpenLibrary(mod->Path, &lib);
-      if (!mainFunc)
+   if (!mod->BuiltIn)
          return EGL_FALSE;
-   }
 
-   drv = mainFunc(NULL);
-   if (!drv) {
-      if (lib)
-         close_library(lib);
+   drv = mod->BuiltIn(NULL);
+   if (!drv || !drv->Name)
       return EGL_FALSE;
-   }
 
-   if (!drv->Name) {
-      _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path);
-      drv->Name = "UNNAMED";
-   }
-
-   mod->Handle = (void *) lib;
    mod->Driver = drv;
 
    return EGL_TRUE;
@@ -243,20 +102,11 @@ _eglUnloadModule(_EGLModule *mod)
    if (mod->Driver && mod->Driver->Unload)
       mod->Driver->Unload(mod->Driver);
 
-   /*
-    * XXX At this point (atexit), the module might be the last reference to
-    * libEGL.  Closing the module might unmap libEGL and give problems.
-    */
-#if 0
-   if (mod->Handle)
-      close_library(mod->Handle);
-#endif
 #elif defined(_EGL_OS_WINDOWS)
    /* XXX Windows unloads DLLs before atexit */
 #endif
 
    mod->Driver = NULL;
-   mod->Handle = NULL;
 }
 
 
@@ -264,7 +114,7 @@ _eglUnloadModule(_EGLModule *mod)
  * Add a module to the module array.
  */
 static _EGLModule *
-_eglAddModule(const char *path)
+_eglAddModule(const char *name)
 {
    _EGLModule *mod;
    EGLint i;
@@ -278,22 +128,22 @@ _eglAddModule(const char *path)
    /* find duplicates */
    for (i = 0; i < _eglModules->Size; i++) {
       mod = _eglModules->Elements[i];
-      if (strcmp(mod->Path, path) == 0)
+      if (strcmp(mod->Name, name) == 0)
          return mod;
    }
 
    /* allocate a new one */
    mod = calloc(1, sizeof(*mod));
    if (mod) {
-      mod->Path = _eglstrdup(path);
-      if (!mod->Path) {
+      mod->Name = _eglstrdup(name);
+      if (!mod->Name) {
          free(mod);
          mod = NULL;
       }
    }
    if (mod) {
       _eglAppendArray(_eglModules, (void *) mod);
-      _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path);
+      _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name);
    }
 
    return mod;
@@ -309,154 +159,11 @@ _eglFreeModule(void *module)
    _EGLModule *mod = (_EGLModule *) module;
 
    _eglUnloadModule(mod);
-   free(mod->Path);
+   free(mod->Name);
    free(mod);
 }
 
 
-/**
- * A loader function for use with _eglPreloadForEach.  The loader data is the
- * filename of the driver.   This function stops on the first valid driver.
- */
-static EGLBoolean
-_eglLoaderFile(const char *dir, size_t len, void *loader_data)
-{
-   char path[1024];
-   const char *filename = (const char *) loader_data;
-   size_t flen = strlen(filename);
-
-   /* make a full path */
-   if (len + flen + 2 > sizeof(path))
-      return EGL_TRUE;
-   if (len) {
-      memcpy(path, dir, len);
-      path[len++] = '/';
-   }
-   memcpy(path + len, filename, flen);
-   len += flen;
-   path[len] = '\0';
-
-   if (library_suffix()) {
-      const char *suffix = library_suffix();
-      size_t slen = strlen(suffix);
-      const char *p;
-      EGLBoolean need_suffix;
-
-      p = filename + flen - slen;
-      need_suffix = (p < filename || strcmp(p, suffix) != 0);
-      if (need_suffix) {
-         /* overflow */
-         if (len + slen + 1 > sizeof(path))
-            return EGL_TRUE;
-         strcpy(path + len, suffix);
-      }
-   }
-
-#if defined(_EGL_OS_UNIX)
-   /* check if the file exists */
-   if (access(path, F_OK))
-      return EGL_TRUE;
-#endif
-
-   _eglAddModule(path);
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Run the callback function on each driver directory.
- *
- * The process may end prematurely if the callback function returns false.
- */
-static void
-_eglPreloadForEach(const char *search_path,
-                   EGLBoolean (*loader)(const char *, size_t, void *),
-                   void *loader_data)
-{
-   const char *cur, *next;
-   size_t len;
-
-   cur = search_path;
-   while (cur) {
-      next = strchr(cur, ':');
-      len = (next) ? next - cur : strlen(cur);
-
-      if (!loader(cur, len, loader_data))
-         break;
-
-      cur = (next) ? next + 1 : NULL;
-   }
-}
-
-
-/**
- * Return a list of colon-separated driver directories.
- */
-static const char *
-_eglGetSearchPath(void)
-{
-   static char search_path[1024];
-
-#if defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS)
-   if (search_path[0] == '\0') {
-      char *buf = search_path;
-      size_t len = sizeof(search_path);
-      EGLBoolean use_env;
-      char dir_sep;
-      int ret;
-
-#if defined(_EGL_OS_UNIX)
-      use_env = (geteuid() == getuid() && getegid() == getgid());
-      dir_sep = '/';
-#else
-      use_env = EGL_TRUE;
-      dir_sep = '\\';
-#endif
-
-      if (use_env) {
-         char *p;
-
-         /* extract the dirname from EGL_DRIVER */
-         p = getenv("EGL_DRIVER");
-         if (p && strchr(p, dir_sep)) {
-            ret = _eglsnprintf(buf, len, "%s", p);
-            if (ret > 0 && ret < len) {
-               p = strrchr(buf, dir_sep);
-               *p++ = ':';
-
-               len -= p - buf;
-               buf = p;
-            }
-         }
-
-         /* append EGL_DRIVERS_PATH */
-         p = getenv("EGL_DRIVERS_PATH");
-         if (p) {
-            ret = _eglsnprintf(buf, len, "%s:", p);
-            if (ret > 0 && ret < len) {
-               buf += ret;
-               len -= ret;
-            }
-         }
-      }
-      else {
-         _eglLog(_EGL_DEBUG,
-               "ignore EGL_DRIVERS_PATH for setuid/setgid binaries");
-      }
-
-      ret = _eglsnprintf(buf, len, "%s", _EGL_DRIVER_SEARCH_DIR);
-      if (ret < 0 || ret >= len)
-         search_path[0] = '\0';
-
-      _eglLog(_EGL_DEBUG, "EGL search path is %s", search_path);
-   }
-#endif /* defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) */
-
-   return search_path;
-}
-
-
 /**
  * Add the user driver to the module array.
  *
@@ -465,42 +172,15 @@ _eglGetSearchPath(void)
 static EGLBoolean
 _eglAddUserDriver(void)
 {
-   const char *search_path = _eglGetSearchPath();
    char *env;
-   size_t name_len = 0;
 
    env = getenv("EGL_DRIVER");
-#if defined(_EGL_OS_UNIX)
-   if (env && strchr(env, '/')) {
-      search_path = "";
-      if ((geteuid() != getuid() || getegid() != getgid())) {
-         _eglLog(_EGL_DEBUG,
-               "ignore EGL_DRIVER for setuid/setgid binaries");
-         env = NULL;
-      }
-   }
-   else if (env) {
-      char *suffix = strchr(env, '.');
-      name_len = (suffix) ? suffix - env : strlen(env);
-   }
-#else
-   if (env)
-      name_len = strlen(env);
-#endif /* _EGL_OS_UNIX */
-
-   /*
-    * Try built-in drivers first if we know the driver name.  This makes sure
-    * we do not load the outdated external driver that is still on the
-    * filesystem.
-    */
-   if (name_len) {
-      _EGLModule *mod;
+   if (env) {
       EGLint i;
 
       for (i = 0; _eglBuiltInDrivers[i].name; i++) {
-         if (strlen(_eglBuiltInDrivers[i].name) == name_len &&
-             !strncmp(_eglBuiltInDrivers[i].name, env, name_len)) {
-            mod = _eglAddModule(env);
+         if (!strcmp(_eglBuiltInDrivers[i].name, env)) {
+            _EGLModule *mod = _eglAddModule(env);
             if (mod)
                mod->BuiltIn = _eglBuiltInDrivers[i].main;
 
@@ -509,13 +189,6 @@ _eglAddUserDriver(void)
       }
    }
 
-   /* otherwise, treat env as a path */
-   if (env) {
-      _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env);
-
-      return EGL_TRUE;
-   }
-
    return EGL_FALSE;
 }
 
@@ -683,18 +356,3 @@ _eglUnloadDrivers(void)
       _eglModules = NULL;
    }
 }
-
-
-/**
- * Invoke a callback function on each EGL search path.
- *
- * The first argument of the callback function is the name of the search path.
- * The second argument is the length of the name.
- */
-void
-_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
-                      void *callback_data)
-{
-   const char *search_path = _eglGetSearchPath();
-   _eglPreloadForEach(search_path, callback, callback_data);
-}
index 11300ce1ee2c21a17626f2a20cf78af4c92ded89..1cf6628446bdaa2b4b9b9240cb3555cfd1984980 100644 (file)
 #include "eglapi.h"
 #include <stddef.h>
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * Define an inline driver typecast function.
  *
@@ -86,20 +91,12 @@ struct _egl_driver
 };
 
 
-extern _EGLDriver *
-_eglBuiltInDriverGALLIUM(const char *args);
-
-
 extern _EGLDriver *
 _eglBuiltInDriverDRI2(const char *args);
 
 
-extern _EGLDriver *
-_eglBuiltInDriverGLX(const char *args);
-
-
-extern _EGLDriver *
-_eglMain(const char *args);
+extern _EGLDriver*
+_eglBuiltInDriverHaiku(const char* args);
 
 
 extern _EGLDriver *
@@ -124,4 +121,9 @@ _eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
                       void *callback_data);
 
 
+#ifdef __cplusplus
+}
+#endif
+
+
 #endif /* EGLDRIVER_INCLUDED */
index 83d775610c52f369322222618d059d4fb384966d..3c3701f4ae96e932c712798caffe1b57109f55a0 100644 (file)
@@ -32,8 +32,6 @@
 #include "eglconfig.h"
 #include "eglcontext.h"
 #include "eglsurface.h"
-#include "eglscreen.h"
-#include "eglmode.h"
 #include "eglsync.h"
 
 
@@ -85,22 +83,6 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    drv->API.WaitNative = (WaitNative_t) _eglReturnFalse;
    drv->API.GetProcAddress = (GetProcAddress_t) _eglReturnFalse;
 
-#ifdef EGL_MESA_screen_surface
-   drv->API.CopyContextMESA = (CopyContextMESA_t) _eglReturnFalse;
-   drv->API.CreateScreenSurfaceMESA =
-      (CreateScreenSurfaceMESA_t) _eglReturnFalse;
-   drv->API.ShowScreenSurfaceMESA = (ShowScreenSurfaceMESA_t) _eglReturnFalse;
-   drv->API.ChooseModeMESA = _eglChooseModeMESA;
-   drv->API.GetModesMESA = _eglGetModesMESA;
-   drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
-   drv->API.GetScreensMESA = _eglGetScreensMESA;
-   drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
-   drv->API.QueryScreenMESA = _eglQueryScreenMESA;
-   drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
-   drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
-   drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
-#endif /* EGL_MESA_screen_surface */
-
    drv->API.CreateImageKHR = NULL;
    drv->API.DestroyImageKHR = NULL;
 
@@ -109,7 +91,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    drv->API.ClientWaitSyncKHR = NULL;
    drv->API.WaitSyncKHR = NULL;
    drv->API.SignalSyncKHR = NULL;
-   drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR;
+   drv->API.GetSyncAttrib = _eglGetSyncAttrib;
 
 #ifdef EGL_MESA_drm_image
    drv->API.CreateDRMImageMESA = NULL;
@@ -120,7 +102,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    drv->API.SwapBuffersRegionNOK = NULL;
 #endif
 
-#ifdef EGL_MESA_dma_buf_image_export
+#ifdef EGL_MESA_image_dma_buf_export
    drv->API.ExportDMABUFImageQueryMESA = NULL;
    drv->API.ExportDMABUFImageMESA = NULL;
 #endif
index 129bf29f1e95bb65d3d1d94403dcc9a11fac9ccc..884cff0c36b8bb5bda3fbe21e6797635dfa3392d 100644 (file)
@@ -50,16 +50,6 @@ struct _egl_global _eglGlobal =
       _eglFiniDisplay
    },
 
-   /* ClientExtensions */
-   {
-      true, /* EGL_EXT_client_extensions */
-      true, /* EGL_EXT_platform_base */
-      true, /* EGL_EXT_platform_x11 */
-      true, /* EGL_EXT_platform_wayland */
-      true, /* EGL_MESA_platform_gbm */
-      true, /* EGL_KHR_client_get_all_proc_addresses */
-   },
-
    /* ClientExtensionsString */
    "EGL_EXT_client_extensions"
    " EGL_EXT_platform_base"
index 04b96099a3b8a451d48e9dca3a8375adc7c0e78d..ae1b75b4545555e204de60f2bf908f43e2f47695 100644 (file)
@@ -50,15 +50,6 @@ struct _egl_global
    EGLint NumAtExitCalls;
    void (*AtExitCalls[10])(void);
 
-   struct _egl_client_extensions {
-      bool EXT_client_extensions;
-      bool EXT_platform_base;
-      bool EXT_platform_x11;
-      bool EXT_platform_wayland;
-      bool MESA_platform_gbm;
-      bool KHR_get_all_proc_addresses;
-   } ClientExtensions;
-
    const char *ClientExtensionString;
 };
 
index 50a87a1889079d27c1c034785ad39fdadb2e46e5..0dd5e120ad7c0bf2ce2a2a75eb712c24f6179c29 100644 (file)
 #include "egltypedefs.h"
 #include "egldisplay.h"
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct _egl_image_attrib_int
 {
    EGLint Value;
@@ -116,11 +121,11 @@ _eglPutImage(_EGLImage *img)
  * Link an image to its display and return the handle of the link.
  * The handle can be passed to client directly.
  */
-static inline EGLImageKHR
+static inline EGLImage
 _eglLinkImage(_EGLImage *img)
 {
    _eglLinkResource(&img->Resource, _EGL_RESOURCE_IMAGE);
-   return (EGLImageKHR) img;
+   return (EGLImage) img;
 }
 
 
@@ -140,7 +145,7 @@ _eglUnlinkImage(_EGLImage *img)
  * Return NULL if the handle has no corresponding linked image.
  */
 static inline _EGLImage *
-_eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy)
+_eglLookupImage(EGLImage image, _EGLDisplay *dpy)
 {
    _EGLImage *img = (_EGLImage *) image;
    if (!dpy || !_eglCheckResource((void *) img, _EGL_RESOURCE_IMAGE, dpy))
@@ -152,13 +157,17 @@ _eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy)
 /**
  * Return the handle of a linked image, or EGL_NO_IMAGE_KHR.
  */
-static inline EGLImageKHR
+static inline EGLImage
 _eglGetImageHandle(_EGLImage *img)
 {
    _EGLResource *res = (_EGLResource *) img;
    return (res && _eglIsResourceLinked(res)) ?
-      (EGLImageKHR) img : EGL_NO_IMAGE_KHR;
+      (EGLImage) img : EGL_NO_IMAGE_KHR;
 }
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLIMAGE_INCLUDED */
index 12a477ee05434403802e8377d922df3f2be90b43..cf58525005eed872826f9761b340cdbbbd956b97 100644 (file)
 #include "egltypedefs.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define _EGL_FATAL   0   /* unrecoverable error */
 #define _EGL_WARNING 1   /* recoverable error/problem */
 #define _EGL_INFO    2   /* just useful info */
@@ -55,4 +59,8 @@ extern void
 _eglLog(EGLint level, const char *fmtStr, ...);
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLLOG_INCLUDED */
diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c
deleted file mode 100644 (file)
index d248ea4..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 VMware, Inc.
- * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
- * Copyright 2010 LunarG, 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "egldisplay.h"
-#include "eglmode.h"
-#include "eglcurrent.h"
-#include "eglscreen.h"
-
-
-#ifdef EGL_MESA_screen_surface
-
-
-#define MIN2(A, B)  (((A) < (B)) ? (A) : (B))
-
-
-/**
- * Given an EGLModeMESA handle, return the corresponding _EGLMode object
- * or null if non-existant.
- */
-_EGLMode *
-_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
-{
-   EGLint scrnum;
-
-   if (!disp || !disp->Screens)
-      return NULL;
-
-   /* loop over all screens on the display */
-   for (scrnum = 0; scrnum < disp->Screens->Size; scrnum++) {
-      const _EGLScreen *scrn = disp->Screens->Elements[scrnum];
-      EGLint idx;
-
-      /*
-       * the mode ids of a screen ranges from scrn->Handle to scrn->Handle +
-       * scrn->NumModes
-       */
-      if (mode >= scrn->Handle &&
-          mode < scrn->Handle + _EGL_SCREEN_MAX_MODES) {
-         idx = mode - scrn->Handle;
-
-         assert(idx < scrn->NumModes && scrn->Modes[idx].Handle == mode);
-
-         return &scrn->Modes[idx];
-      }
-   }
-
-   return NULL;
-}
-
-
-/**
- * Parse the attrib_list to fill in the fields of the given _eglMode
- * Return EGL_FALSE if any errors, EGL_TRUE otherwise.
- */
-static EGLBoolean
-_eglParseModeAttribs(_EGLMode *mode, const EGLint *attrib_list)
-{
-   EGLint i;
-
-   /* init all attribs to EGL_DONT_CARE */
-   mode->Handle = EGL_DONT_CARE;
-   mode->Width = EGL_DONT_CARE;
-   mode->Height = EGL_DONT_CARE;
-   mode->RefreshRate = EGL_DONT_CARE;
-   mode->Optimal = EGL_DONT_CARE;
-   mode->Interlaced = EGL_DONT_CARE;
-   mode->Name = NULL;
-
-   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
-      switch (attrib_list[i]) {
-      case EGL_MODE_ID_MESA:
-         mode->Handle = attrib_list[++i];
-         if (mode->Handle <= 0) {
-            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(handle)");
-            return EGL_FALSE;
-         }
-         break;
-      case EGL_WIDTH:
-         mode->Width = attrib_list[++i];
-         if (mode->Width <= 0) {
-            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(width)");
-            return EGL_FALSE;
-         }
-         break;
-      case EGL_HEIGHT:
-         mode->Height = attrib_list[++i];
-         if (mode->Height <= 0) {
-            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(height)");
-            return EGL_FALSE;
-         }
-         break;
-      case EGL_REFRESH_RATE_MESA:
-         mode->RefreshRate = attrib_list[++i];
-         if (mode->RefreshRate <= 0) {
-            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(refresh rate)");
-            return EGL_FALSE;
-         }
-         break;
-      case EGL_INTERLACED_MESA:
-         mode->Interlaced = attrib_list[++i];
-         if (mode->Interlaced != EGL_TRUE && mode->Interlaced != EGL_FALSE) {
-            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(interlaced)");
-            return EGL_FALSE;
-         }
-         break;
-      case EGL_OPTIMAL_MESA:
-         mode->Optimal = attrib_list[++i];
-         if (mode->Optimal != EGL_TRUE && mode->Optimal != EGL_FALSE) {
-            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(optimal)");
-            return EGL_FALSE;
-         }
-         break;
-      default:
-         _eglError(EGL_BAD_ATTRIBUTE, "eglChooseModeMESA");
-         return EGL_FALSE;
-      }
-   }
-   return EGL_TRUE;
-}
-
-
-/**
- * Determine if the candidate mode's attributes are at least as good
- * as the minimal mode's.
- * \return EGL_TRUE if qualifies, EGL_FALSE otherwise
- */
-static EGLBoolean
-_eglModeQualifies(const _EGLMode *c, const _EGLMode *min)
-{
-   if (min->Handle != EGL_DONT_CARE && c->Handle != min->Handle)
-      return EGL_FALSE;
-   if (min->Width != EGL_DONT_CARE && c->Width < min->Width)
-      return EGL_FALSE;
-   if (min->Height != EGL_DONT_CARE && c->Height < min->Height)
-      return EGL_FALSE;
-   if (min->RefreshRate != EGL_DONT_CARE && c->RefreshRate < min->RefreshRate)
-      return EGL_FALSE;
-   if (min->Optimal != EGL_DONT_CARE && c->Optimal != min->Optimal)
-      return EGL_FALSE;
-   if (min->Interlaced != EGL_DONT_CARE && c->Interlaced != min->Interlaced)
-      return EGL_FALSE;
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Return value of given mode attribute, or -1 if bad attrib.
- */
-static EGLint
-getModeAttrib(const _EGLMode *m, EGLint attrib)
-{
-   switch (attrib) {
-   case EGL_MODE_ID_MESA:
-      return m->Handle;
-   case EGL_WIDTH:
-      return m->Width;
-   case EGL_HEIGHT:
-      return m->Height;
-   case EGL_REFRESH_RATE_MESA:
-      return m->RefreshRate;
-   case EGL_OPTIMAL_MESA:
-      return m->Optimal;
-   case EGL_INTERLACED_MESA:
-      return m->Interlaced;
-   default:
-      return -1;
-   }
-}
-
-
-#define SMALLER 1
-#define LARGER  2
-
-struct sort_info {
-   EGLint Attrib;
-   EGLint Order; /* SMALLER or LARGER */
-};
-
-/* the order of these entries is the priority */
-static struct sort_info SortInfo[] = {
-   { EGL_OPTIMAL_MESA, LARGER },
-   { EGL_INTERLACED_MESA, SMALLER },
-   { EGL_WIDTH, LARGER },
-   { EGL_HEIGHT, LARGER },
-   { EGL_REFRESH_RATE_MESA, LARGER },
-   { EGL_MODE_ID_MESA, SMALLER },
-   { 0, 0 }
-};
-
-
-/**
- * Compare modes 'a' and 'b' and return -1 if a belongs before b, or 1 if a
- * belongs after b, or 0 if they're equal.
- * Used by qsort().
- */
-static int
-_eglCompareModes(const void *a, const void *b)
-{
-   const _EGLMode *aMode = *((const _EGLMode **) a);
-   const _EGLMode *bMode = *((const _EGLMode **) b);
-   EGLint i;
-
-   for (i = 0; SortInfo[i].Attrib; i++) {
-      const EGLint aVal = getModeAttrib(aMode, SortInfo[i].Attrib);
-      const EGLint bVal = getModeAttrib(bMode, SortInfo[i].Attrib);
-      if (aVal == bVal) {
-         /* a tie */
-         continue;
-      }
-      else if (SortInfo[i].Order == SMALLER) {
-         return (aVal < bVal) ? -1 : 1;
-      }
-      else if (SortInfo[i].Order == LARGER) {
-         return (aVal > bVal) ? -1 : 1;
-      }
-   }
-
-   /* all attributes identical */
-   return 0;
-}
-
-
-/**
- * Search for EGLModes which match the given attribute list.
- * Called via eglChooseModeMESA API function.
- */
-EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                   const EGLint *attrib_list, EGLModeMESA *modes,
-                   EGLint modes_size, EGLint *num_modes)
-{
-   _EGLMode **modeList, min;
-   EGLint i, count;
-
-   if (!_eglParseModeAttribs(&min, attrib_list)) {
-      /* error code will have been recorded */
-      return EGL_FALSE;
-   }
-
-   /* allocate array of mode pointers */
-   modeList = malloc(modes_size * sizeof(_EGLMode *));
-   if (!modeList) {
-      _eglError(EGL_BAD_MODE_MESA, "eglChooseModeMESA(out of memory)");
-      return EGL_FALSE;
-   }
-
-   /* make array of pointers to qualifying modes */
-   for (i = count = 0; i < scrn->NumModes && count < modes_size; i++) {
-      if (_eglModeQualifies(scrn->Modes + i, &min)) {
-         modeList[count++] = scrn->Modes + i;
-      }
-   }
-
-   /* sort array of pointers */
-   qsort(modeList, count, sizeof(_EGLMode *), _eglCompareModes);
-
-   /* copy mode handles to output array */
-   for (i = 0; i < count; i++) {
-      modes[i] = modeList[i]->Handle;
-   }
-
-   free(modeList);
-
-   *num_modes = count;
-
-   return EGL_TRUE;
-}
-
-
-
-/**
- * Return all possible modes for the given screen.  No sorting of results.
- * Called via eglGetModesMESA() API function.
- */
-EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                 EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
-{
-   if (modes) {
-      EGLint i;
-      *num_modes = MIN2(scrn->NumModes, modes_size);
-      for (i = 0; i < *num_modes; i++) {
-         modes[i] = scrn->Modes[i].Handle;
-      }
-   }
-   else {
-      /* just return total number of supported modes */
-      *num_modes = scrn->NumModes;
-   }
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Query an attribute of a mode.
- */
-EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy,
-                      _EGLMode *m, EGLint attribute, EGLint *value)
-{
-   EGLint v;
-
-   v = getModeAttrib(m, attribute);
-   if (v < 0) {
-      _eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA");
-      return EGL_FALSE;
-   }
-   *value = v;
-   return EGL_TRUE;
-}
-
-
-/**
- * Return human-readable string for given mode.
- * This is the default function called by eglQueryModeStringMESA().
- */
-const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m)
-{
-   return m->Name;
-}
-
-
-#endif /* EGL_MESA_screen_surface */
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
deleted file mode 100644 (file)
index 664074f..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 VMware, Inc.
- * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
- * Copyright 2010 LunarG, 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef EGLMODE_INCLUDED
-#define EGLMODE_INCLUDED
-
-#include "egltypedefs.h"
-
-
-#ifdef EGL_MESA_screen_surface
-
-
-#define EGL_NO_MODE_MESA 0
-
-
-/**
- * Data structure which corresponds to an EGLModeMESA.
- */
-struct _egl_mode
-{
-   EGLModeMESA Handle;     /* the public/opaque handle which names this mode */
-   EGLint Width, Height;   /* size in pixels */
-   EGLint RefreshRate;     /* rate * 1000.0 */
-   EGLint Optimal;
-   EGLint Interlaced;
-   const char *Name;
-
-   /* Other possible attributes */
-   /* interlaced */
-   /* external sync */
-};
-
-
-extern _EGLMode *
-_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
-
-
-extern EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                   const EGLint *attrib_list, EGLModeMESA *modes,
-                   EGLint modes_size, EGLint *num_modes);
-
-
-extern EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                 EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-
-
-extern EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m,
-                      EGLint attribute, EGLint *value);
-
-
-extern const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m);
-
-
-#endif /* EGL_MESA_screen_surface */
-
-
-#endif /* EGLMODE_INCLUDED */
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
deleted file mode 100644 (file)
index 42ac621..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 VMware, Inc.
- * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
- * Copyright 2010 LunarG, 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/*
- * Ideas for screen management extension to EGL.
- *
- * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
- * The screens' handles can be obtained with eglGetScreensMESA().
- *
- * A new kind of EGLSurface is possible- one which can be directly scanned
- * out on a screen.  Such a surface is created with eglCreateScreenSurface().
- *
- * To actually display a screen surface on a screen, the eglShowSurface()
- * function is called.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "c11/threads.h"
-
-#include "egldisplay.h"
-#include "eglcurrent.h"
-#include "eglmode.h"
-#include "eglsurface.h"
-#include "eglscreen.h"
-
-
-#ifdef EGL_MESA_screen_surface
-
-
-/* ugh, no atomic op? */
-static mtx_t _eglNextScreenHandleMutex = _MTX_INITIALIZER_NP;
-static EGLScreenMESA _eglNextScreenHandle = 1;
-
-
-/**
- * Return a new screen handle/ID.
- * NOTE: we never reuse these!
- */
-static EGLScreenMESA
-_eglAllocScreenHandle(void)
-{
-   EGLScreenMESA s;
-
-   mtx_lock(&_eglNextScreenHandleMutex);
-   s = _eglNextScreenHandle;
-   _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
-   mtx_unlock(&_eglNextScreenHandleMutex);
-
-   return s;
-}
-
-
-/**
- * Initialize an _EGLScreen object to default values.
- */
-void
-_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes)
-{
-   memset(screen, 0, sizeof(_EGLScreen));
-
-   screen->Display = dpy;
-   screen->NumModes = num_modes;
-   screen->StepX = 1;
-   screen->StepY = 1;
-
-   if (num_modes > _EGL_SCREEN_MAX_MODES)
-      num_modes = _EGL_SCREEN_MAX_MODES;
-   screen->Modes = calloc(num_modes, sizeof(*screen->Modes));
-   screen->NumModes = (screen->Modes) ? num_modes : 0;
-}
-
-
-/**
- * Link a screen to its display and return the handle of the link.
- * The handle can be passed to client directly.
- */
-EGLScreenMESA
-_eglLinkScreen(_EGLScreen *screen)
-{
-   _EGLDisplay *display;
-   EGLint i;
-
-   assert(screen && screen->Display);
-   display = screen->Display;
-
-   if (!display->Screens) {
-      display->Screens = _eglCreateArray("Screen", 4);
-      if (!display->Screens)
-         return (EGLScreenMESA) 0;
-   }
-
-   screen->Handle = _eglAllocScreenHandle();
-   for (i = 0; i < screen->NumModes; i++)
-      screen->Modes[i].Handle = screen->Handle + i;
-
-   _eglAppendArray(display->Screens, (void *) screen);
-
-   return screen->Handle;
-}
-
-
-/**
- * Lookup a handle to find the linked config.
- * Return NULL if the handle has no corresponding linked config.
- */
-_EGLScreen *
-_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
-{
-   EGLint i;
-
-   if (!display || !display->Screens)
-      return NULL;
-
-   for (i = 0; i < display->Screens->Size; i++) {
-      _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
-      if (scr->Handle == screen) {
-         assert(scr->Display == display);
-         return scr;
-      }
-   }
-   return NULL;
-}
-
-
-static EGLBoolean
-_eglFlattenScreen(void *elem, void *buffer)
-{
-   _EGLScreen *scr = (_EGLScreen *) elem;
-   EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
-   *handle = _eglGetScreenHandle(scr);
-   return EGL_TRUE;
-}
-
-
-EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
-                   EGLint max_screens, EGLint *num_screens)
-{
-   *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
-         sizeof(screens[0]), max_screens, _eglFlattenScreen);
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Set a screen's surface origin.
- */
-EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
-                       _EGLScreen *scrn, EGLint x, EGLint y)
-{
-   scrn->OriginX = x;
-   scrn->OriginY = y;
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Query a screen's current surface.
- */
-EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
-                           _EGLScreen *scrn, _EGLSurface **surf)
-{
-   *surf = scrn->CurrentSurface;
-   return EGL_TRUE;
-}
-
-
-/**
- * Query a screen's current mode.
- */
-EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                        _EGLMode **m)
-{
-   *m = scrn->CurrentMode;
-   return EGL_TRUE;
-}
-
-
-EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                    EGLint attribute, EGLint *value)
-{
-   switch (attribute) {
-   case EGL_SCREEN_POSITION_MESA:
-      value[0] = scrn->OriginX;
-      value[1] = scrn->OriginY;
-      break;
-   case EGL_SCREEN_POSITION_GRANULARITY_MESA:
-      value[0] = scrn->StepX;
-      value[1] = scrn->StepY;
-      break;
-   default:
-      _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
-      return EGL_FALSE;
-   }
-
-   return EGL_TRUE;
-}
-
-
-#endif /* EGL_MESA_screen_surface */
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
deleted file mode 100644 (file)
index c554e1d..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 VMware, Inc.
- * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
- * Copyright 2010 LunarG, 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef EGLSCREEN_INCLUDED
-#define EGLSCREEN_INCLUDED
-
-#include "c99_compat.h"
-
-#include "egltypedefs.h"
-
-
-#ifdef EGL_MESA_screen_surface
-
-
-#define _EGL_SCREEN_MAX_MODES 16
-
-
-/**
- * Per-screen information.
- * Note that an EGL screen doesn't have a size.  A screen may be set to
- * one of several display modes (width/height/scanrate).  The screen
- * then displays a drawing surface.  The drawing surface must be at least
- * as large as the display mode's resolution.  If it's larger, the
- * OriginX and OriginY fields control what part of the surface is visible
- * on the screen.
- */
-struct _egl_screen
-{
-   _EGLDisplay *Display;
-
-   EGLScreenMESA Handle; /* The public/opaque handle which names this object */
-
-   _EGLMode *CurrentMode;
-   _EGLSurface *CurrentSurface;
-
-   EGLint OriginX, OriginY; /**< Origin of scan-out region w.r.t. surface */
-   EGLint StepX, StepY;     /**< Screen position/origin granularity */
-
-   EGLint NumModes;
-   _EGLMode *Modes;  /**< array [NumModes] */
-};
-
-
-extern void
-_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes);
-
-
-extern EGLScreenMESA
-_eglLinkScreen(_EGLScreen *screen);
-
-
-extern _EGLScreen *
-_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy);
-
-
-/**
- * Return the handle of a linked screen.
- */
-static inline EGLScreenMESA
-_eglGetScreenHandle(_EGLScreen *screen)
-{
-   return (screen) ? screen->Handle : (EGLScreenMESA) 0;
-}
-
-
-extern EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-
-
-extern EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y);
-
-
-extern EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
-                           _EGLScreen *scrn, _EGLSurface **surface);
-
-
-extern EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode **m);
-
-
-extern EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value);
-
-
-#endif /* EGL_MESA_screen_surface */
-
-
-#endif /* EGLSCREEN_INCLUDED */
index e2cb73b7e9123a44b38917dc9807b1e412e6b3fd..76c60e940dc46723596ed45722433179dadf7e26 100644 (file)
@@ -61,50 +61,6 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
 }
 
 
-#ifdef EGL_MESA_screen_surface
-static EGLint
-_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
-{
-   EGLint i, err = EGL_SUCCESS;
-
-   if (!attrib_list)
-      return EGL_SUCCESS;
-
-   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
-      EGLint attr = attrib_list[i++];
-      EGLint val = attrib_list[i];
-
-      switch (attr) {
-      case EGL_WIDTH:
-         if (val < 0) {
-            err = EGL_BAD_PARAMETER;
-            break;
-         }
-         surf->Width = val;
-         break;
-      case EGL_HEIGHT:
-         if (val < 0) {
-            err = EGL_BAD_PARAMETER;
-            break;
-         }
-         surf->Height = val;
-         break;
-      default:
-         err = EGL_BAD_ATTRIBUTE;
-         break;
-      }
-
-      if (err != EGL_SUCCESS) {
-         _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
-         break;
-      }
-   }
-
-   return err;
-}
-#endif /* EGL_MESA_screen_surface */
-
-
 /**
  * Parse the list of surface attributes and return the proper error code.
  */
@@ -119,11 +75,6 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
    if (!attrib_list)
       return EGL_SUCCESS;
 
-#ifdef EGL_MESA_screen_surface
-   if (type == EGL_SCREEN_BIT_MESA)
-      return _eglParseScreenSurfaceAttribList(surf, attrib_list);
-#endif
-
    if (dpy->Extensions.NOK_texture_from_pixmap)
       texture_type |= EGL_PIXMAP_BIT;
 
@@ -297,12 +248,6 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
    case EGL_PBUFFER_BIT:
       func = "eglCreatePBufferSurface";
       break;
-#ifdef EGL_MESA_screen_surface
-   case EGL_SCREEN_BIT_MESA:
-      func = "eglCreateScreenSurface";
-      renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
-      break;
-#endif
    default:
       _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
       return EGL_FALSE;
index 438e27cebc844d8f4c68f24526cb4ab67b8093f9..74c429a9628b50fab751ef15c9aab0d97d7e800e 100644 (file)
 #include "egldisplay.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * "Base" class for device driver surfaces.
  */
@@ -174,4 +178,8 @@ _eglGetSurfaceHandle(_EGLSurface *surf)
 }
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLSURFACE_INCLUDED */
index 8b8ab16b0d268ec3d7d0c0f3d3dae2009b2be663..3019e6e9333bf608344f053c54812fd701e6f5fc 100644 (file)
@@ -67,7 +67,7 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
 
 
 static EGLint
-_eglParseSyncAttribList64(_EGLSync *sync, const EGLAttribKHR *attrib_list)
+_eglParseSyncAttribList64(_EGLSync *sync, const EGLAttrib *attrib_list)
 {
    EGLint i, err = EGL_SUCCESS;
 
@@ -103,7 +103,7 @@ _eglParseSyncAttribList64(_EGLSync *sync, const EGLAttribKHR *attrib_list)
 
 EGLBoolean
 _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
-             const EGLint *attrib_list, const EGLAttribKHR *attrib_list64)
+             const EGLint *attrib_list, const EGLAttrib *attrib_list64)
 {
    EGLint err;
 
@@ -141,8 +141,8 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
 
 
 EGLBoolean
-_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
-                     EGLint attribute, EGLint *value)
+_eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                  EGLint attribute, EGLAttrib *value)
 {
    if (!value)
       return _eglError(EGL_BAD_PARAMETER, "eglGetSyncAttribKHR");
index 1d2eb11a7a06891e5e00d435b327be1e49c747a0..9b2aac8828b90a3f65b6215e5ffcff0843973556 100644 (file)
@@ -47,18 +47,18 @@ struct _egl_sync
    EGLenum Type;
    EGLenum SyncStatus;
    EGLenum SyncCondition;
-   EGLAttribKHR CLEvent;
+   EGLAttrib CLEvent;
 };
 
 
 extern EGLBoolean
 _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
-             const EGLint *attrib_list, const EGLAttribKHR *attrib_list64);
+             const EGLint *attrib_list, const EGLAttrib *attrib_list64);
 
 
 extern EGLBoolean
-_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
-                     EGLint attribute, EGLint *value);
+_eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                  EGLint attribute, EGLAttrib *value);
 
 
 /**
@@ -87,11 +87,11 @@ _eglPutSync(_EGLSync *sync)
  * Link a sync to its display and return the handle of the link.
  * The handle can be passed to client directly.
  */
-static inline EGLSyncKHR
+static inline EGLSync
 _eglLinkSync(_EGLSync *sync)
 {
    _eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC);
-   return (EGLSyncKHR) sync;
+   return (EGLSync) sync;
 }
 
 
@@ -110,7 +110,7 @@ _eglUnlinkSync(_EGLSync *sync)
  * Return NULL if the handle has no corresponding linked sync.
  */
 static inline _EGLSync *
-_eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy)
+_eglLookupSync(EGLSync handle, _EGLDisplay *dpy)
 {
    _EGLSync *sync = (_EGLSync *) handle;
    if (!dpy || !_eglCheckResource((void *) sync, _EGL_RESOURCE_SYNC, dpy))
@@ -122,12 +122,12 @@ _eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy)
 /**
  * Return the handle of a linked sync, or EGL_NO_SYNC_KHR.
  */
-static inline EGLSyncKHR
+static inline EGLSync
 _eglGetSyncHandle(_EGLSync *sync)
 {
    _EGLResource *res = (_EGLResource *) sync;
    return (res && _eglIsResourceLinked(res)) ?
-      (EGLSyncKHR) sync : EGL_NO_SYNC_KHR;
+      (EGLSync) sync : EGL_NO_SYNC_KHR;
 }
 
 
index e90959affae1fc7035d75f33a7c0e5946f409f38..7facdb47f860e4a3b846d3e9c90ed7c879bca893 100644 (file)
 #ifndef EGLTYPEDEFS_INCLUDED
 #define EGLTYPEDEFS_INCLUDED
 
-#define EGL_EGLEXT_PROTOTYPES
-
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
 #include "eglcompiler.h"
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct _egl_api _EGLAPI;
 
 typedef struct _egl_array _EGLArray;
@@ -68,4 +71,9 @@ typedef struct _egl_sync _EGLSync;
 
 typedef struct _egl_thread_info _EGLThreadInfo;
 
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* EGLTYPEDEFS_INCLUDED */
index 782510ff0f47dc0d2fa7b34cd8b5c3811948c8a6..7c6c7ac68202e2704b51883735d16a7978a0b3d7 100644 (file)
@@ -29,4 +29,12 @@ LOCAL_C_INCLUDES += \
        $(GALLIUM_TOP)/winsys \
        $(GALLIUM_TOP)/drivers
 
+ifeq ($(MESA_ENABLE_LLVM),true)
+LOCAL_C_INCLUDES += \
+       external/llvm/include \
+       external/llvm/device/include \
+       external/libcxx/include \
+       external/elfutils/$(if $(filter true,$(MESA_LOLLIPOP_BUILD)),0.153/)libelf
+endif
+
 include $(MESA_COMMON_MK)
index b2662ffca8c3e3b7f7538ca4238930217b50eb56..b946681840cef0026e023be611ac2aee83c31b3d 100644 (file)
@@ -33,7 +33,9 @@ SUBDIRS := auxiliary
 #
 
 # swrast
-SUBDIRS += winsys/sw/android drivers/softpipe
+ifneq ($(filter swrast,$(MESA_GPU_DRIVERS)),)
+SUBDIRS += winsys/sw/dri winsys/sw/kms-dri drivers/softpipe
+endif
 
 # freedreno
 ifneq ($(filter freedreno, $(MESA_GPU_DRIVERS)),)
@@ -74,10 +76,17 @@ endif
 endif
 endif
 
+# vc4
+ifneq ($(filter vc4, $(MESA_GPU_DRIVERS)),)
+SUBDIRS += winsys/vc4/drm drivers/vc4
+endif
+
 # vmwgfx
 ifneq ($(filter vmwgfx, $(MESA_GPU_DRIVERS)),)
 SUBDIRS += winsys/svga/drm drivers/svga
 endif
 
-mkfiles := $(patsubst %,$(GALLIUM_TOP)/%/Android.mk,$(SUBDIRS))
-include $(mkfiles)
+# Gallium state trackers and target for dri
+SUBDIRS += state_trackers/dri targets/dri
+
+include $(call all-named-subdir-makefiles,$(SUBDIRS))
index 96a2125defba90236059ee19cf1b6ba7d34d8ac5..86430eb6a21dd1b3ff67d375dc1a09e9d15dccfc 100644 (file)
@@ -30,12 +30,23 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
        $(C_SOURCES) \
+       $(NIR_SOURCES) \
        $(VL_STUB_SOURCES)
 
 LOCAL_C_INCLUDES := \
        $(GALLIUM_TOP)/auxiliary/util
 
+ifeq ($(MESA_ENABLE_LLVM),true)
+LOCAL_SRC_FILES += \
+       $(GALLIVM_SOURCES) \
+       $(GALLIVM_CPP_SOURCES)
+
+LOCAL_CPPFLAGS := -std=c++11
+endif
+
+# We need libmesa_glsl to get NIR's generated include directories.
 LOCAL_MODULE := libmesa_gallium
+LOCAL_STATIC_LIBRARIES += libmesa_glsl
 
 # generate sources
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
index 31ffa7d9c0bfa754a7e96b1df1b5cdb9f7417bea..744b00cbd92df48dcbb6ffdba3b682e226e61283 100644 (file)
@@ -82,6 +82,7 @@ struct cso_context {
    struct u_vbuf *vbuf;
 
    boolean has_geometry_shader;
+   boolean has_tessellation;
    boolean has_streamout;
 
    struct sampler_info samplers[PIPE_SHADER_TYPES];
@@ -108,6 +109,8 @@ struct cso_context {
    void *fragment_shader, *fragment_shader_saved;
    void *vertex_shader, *vertex_shader_saved;
    void *geometry_shader, *geometry_shader_saved;
+   void *tessctrl_shader, *tessctrl_shader_saved;
+   void *tesseval_shader, *tesseval_shader_saved;
    void *velements, *velements_saved;
    struct pipe_query *render_condition, *render_condition_saved;
    uint render_condition_mode, render_condition_mode_saved;
@@ -273,6 +276,10 @@ struct cso_context *cso_create_context( struct pipe_context *pipe )
                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
       ctx->has_geometry_shader = TRUE;
    }
+   if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
+                                PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
+      ctx->has_tessellation = TRUE;
+   }
    if (pipe->screen->get_param(pipe->screen,
                                PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
       ctx->has_streamout = TRUE;
@@ -293,6 +300,8 @@ void cso_destroy_context( struct cso_context *ctx )
    unsigned i, shader;
 
    if (ctx->pipe) {
+      ctx->pipe->set_index_buffer(ctx->pipe, NULL);
+
       ctx->pipe->bind_blend_state( ctx->pipe, NULL );
       ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL );
 
@@ -319,7 +328,19 @@ void cso_destroy_context( struct cso_context *ctx )
 
       ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
       ctx->pipe->bind_fs_state( ctx->pipe, NULL );
+      ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, NULL);
       ctx->pipe->bind_vs_state( ctx->pipe, NULL );
+      ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, NULL);
+      if (ctx->has_geometry_shader) {
+         ctx->pipe->bind_gs_state(ctx->pipe, NULL);
+         ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_GEOMETRY, 0, NULL);
+      }
+      if (ctx->has_tessellation) {
+         ctx->pipe->bind_tcs_state(ctx->pipe, NULL);
+         ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_TESS_CTRL, 0, NULL);
+         ctx->pipe->bind_tes_state(ctx->pipe, NULL);
+         ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_TESS_EVAL, 0, NULL);
+      }
       ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
 
       if (ctx->has_streamout)
@@ -812,6 +833,92 @@ void cso_restore_geometry_shader(struct cso_context *ctx)
    ctx->geometry_shader_saved = NULL;
 }
 
+void cso_set_tessctrl_shader_handle(struct cso_context *ctx, void *handle)
+{
+   assert(ctx->has_tessellation || !handle);
+
+   if (ctx->has_tessellation && ctx->tessctrl_shader != handle) {
+      ctx->tessctrl_shader = handle;
+      ctx->pipe->bind_tcs_state(ctx->pipe, handle);
+   }
+}
+
+void cso_delete_tessctrl_shader(struct cso_context *ctx, void *handle)
+{
+    if (handle == ctx->tessctrl_shader) {
+      /* unbind before deleting */
+      ctx->pipe->bind_tcs_state(ctx->pipe, NULL);
+      ctx->tessctrl_shader = NULL;
+   }
+   ctx->pipe->delete_tcs_state(ctx->pipe, handle);
+}
+
+void cso_save_tessctrl_shader(struct cso_context *ctx)
+{
+   if (!ctx->has_tessellation) {
+      return;
+   }
+
+   assert(!ctx->tessctrl_shader_saved);
+   ctx->tessctrl_shader_saved = ctx->tessctrl_shader;
+}
+
+void cso_restore_tessctrl_shader(struct cso_context *ctx)
+{
+   if (!ctx->has_tessellation) {
+      return;
+   }
+
+   if (ctx->tessctrl_shader_saved != ctx->tessctrl_shader) {
+      ctx->pipe->bind_tcs_state(ctx->pipe, ctx->tessctrl_shader_saved);
+      ctx->tessctrl_shader = ctx->tessctrl_shader_saved;
+   }
+   ctx->tessctrl_shader_saved = NULL;
+}
+
+void cso_set_tesseval_shader_handle(struct cso_context *ctx, void *handle)
+{
+   assert(ctx->has_tessellation || !handle);
+
+   if (ctx->has_tessellation && ctx->tesseval_shader != handle) {
+      ctx->tesseval_shader = handle;
+      ctx->pipe->bind_tes_state(ctx->pipe, handle);
+   }
+}
+
+void cso_delete_tesseval_shader(struct cso_context *ctx, void *handle)
+{
+    if (handle == ctx->tesseval_shader) {
+      /* unbind before deleting */
+      ctx->pipe->bind_tes_state(ctx->pipe, NULL);
+      ctx->tesseval_shader = NULL;
+   }
+   ctx->pipe->delete_tes_state(ctx->pipe, handle);
+}
+
+void cso_save_tesseval_shader(struct cso_context *ctx)
+{
+   if (!ctx->has_tessellation) {
+      return;
+   }
+
+   assert(!ctx->tesseval_shader_saved);
+   ctx->tesseval_shader_saved = ctx->tesseval_shader;
+}
+
+void cso_restore_tesseval_shader(struct cso_context *ctx)
+{
+   if (!ctx->has_tessellation) {
+      return;
+   }
+
+   if (ctx->tesseval_shader_saved != ctx->tesseval_shader) {
+      ctx->pipe->bind_tes_state(ctx->pipe, ctx->tesseval_shader_saved);
+      ctx->tesseval_shader = ctx->tesseval_shader_saved;
+   }
+   ctx->tesseval_shader_saved = NULL;
+}
+
 /* clip state */
 
 static INLINE void
index aa56c589dade4a894ce7ee102f18080c548773f8..cc50b60c6cd179c0a670af41519d859d8b496e15 100644 (file)
@@ -141,6 +141,18 @@ void cso_save_geometry_shader(struct cso_context *cso);
 void cso_restore_geometry_shader(struct cso_context *cso);
 
 
+void cso_set_tessctrl_shader_handle(struct cso_context *ctx, void *handle);
+void cso_delete_tessctrl_shader(struct cso_context *ctx, void *handle);
+void cso_save_tessctrl_shader(struct cso_context *cso);
+void cso_restore_tessctrl_shader(struct cso_context *cso);
+
+
+void cso_set_tesseval_shader_handle(struct cso_context *ctx, void *handle);
+void cso_delete_tesseval_shader(struct cso_context *ctx, void *handle);
+void cso_save_tesseval_shader(struct cso_context *cso);
+void cso_restore_tesseval_shader(struct cso_context *cso);
+
+
 void cso_set_framebuffer(struct cso_context *cso,
                          const struct pipe_framebuffer_state *fb);
 void cso_save_framebuffer(struct cso_context *cso);
index 6375d41295c24c88b1bce42c257b47f6485e8e5a..a1564f93292bce9d402d8a2bd1349510588da366 100644 (file)
@@ -190,9 +190,15 @@ static void tgsi_gs_prepare(struct draw_geometry_shader *shader,
                             const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
 {
    struct tgsi_exec_machine *machine = shader->machine;
-
+   int j;
    tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
                                   constants, constants_size);
+
+   if (shader->info.uses_invocationid) {
+      unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
+      for (j = 0; j < TGSI_QUAD_SIZE; j++)
+         machine->SystemValue[i].i[j] = shader->invocation_id;
+   }
 }
 
 static unsigned tgsi_gs_run(struct draw_geometry_shader *shader,
@@ -385,7 +391,8 @@ llvm_gs_run(struct draw_geometry_shader *shader,
       (struct vertex_header*)input,
       input_primitives,
       shader->draw->instance_id,
-      shader->llvm_prim_ids);
+      shader->llvm_prim_ids,
+      shader->invocation_id);
 
    return ret;
 }
@@ -555,7 +562,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
     * overflown vertices into some area where they won't harm anyone */
    unsigned total_verts_per_buffer = shader->primitive_boundary *
       num_in_primitives;
-
+   unsigned invocation;
    //Assume at least one primitive
    max_out_prims = MAX2(max_out_prims, 1);
 
@@ -564,7 +571,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
    output_verts->stride = output_verts->vertex_size;
    output_verts->verts =
       (struct vertex_header *)MALLOC(output_verts->vertex_size *
-                                     total_verts_per_buffer);
+                                     total_verts_per_buffer * shader->num_invocations);
    debug_assert(output_verts->verts);
 
 #if 0
@@ -592,7 +599,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
    shader->input = input;
    shader->input_info = input_info;
    FREE(shader->primitive_lengths);
-   shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
+   shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned) * shader->num_invocations);
 
 
 #ifdef HAVE_LLVM
@@ -622,23 +629,26 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
    }
 #endif
 
-   shader->prepare(shader, constants, constants_size);
+   for (invocation = 0; invocation < shader->num_invocations; invocation++) {
+      shader->invocation_id = invocation;
 
-   if (input_prim->linear)
-      gs_run(shader, input_prim, input_verts,
-             output_prims, output_verts);
-   else
-      gs_run_elts(shader, input_prim, input_verts,
-                  output_prims, output_verts);
+      shader->prepare(shader, constants, constants_size);
 
-   /* Flush the remaining primitives. Will happen if
-    * num_input_primitives % 4 != 0
-    */
-   if (shader->fetched_prim_count > 0) {
-      gs_flush(shader);
-   }
+      if (input_prim->linear)
+         gs_run(shader, input_prim, input_verts,
+                output_prims, output_verts);
+      else
+         gs_run_elts(shader, input_prim, input_verts,
+                     output_prims, output_verts);
 
-   debug_assert(shader->fetched_prim_count == 0);
+      /* Flush the remaining primitives. Will happen if
+       * num_input_primitives % 4 != 0
+       */
+      if (shader->fetched_prim_count > 0) {
+         gs_flush(shader);
+      }
+      debug_assert(shader->fetched_prim_count == 0);
+   }
 
    /* Update prim_info:
     */
@@ -771,6 +781,8 @@ draw_create_geometry_shader(struct draw_context *draw,
          gs->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
    gs->max_output_vertices =
          gs->info.properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES];
+   gs->num_invocations =
+      gs->info.properties[TGSI_PROPERTY_GS_INVOCATIONS];
    if (!gs->max_output_vertices)
       gs->max_output_vertices = 32;
 
index 49e93d55a51eea082a391bd3f8385e8670612bc1..663ba847cfe7ad9eb84a19c83db65ed9b3ef6537 100644 (file)
@@ -90,6 +90,8 @@ struct draw_geometry_shader {
    unsigned vector_length;
    unsigned max_out_prims;
 
+   unsigned num_invocations;
+   unsigned invocation_id;
 #ifdef HAVE_LLVM
    struct draw_gs_inputs *gs_input;
    struct draw_gs_jit_context *jit_context;
index b9e55af42c76c77ff6946b1c4cf91f1441f8daa6..90a31bc6ac0a9dc8baff8ea08302e5619621a878 100644 (file)
@@ -97,6 +97,7 @@ create_jit_dvbuffer_type(struct gallivm_state *gallivm,
    dvbuffer_type = LLVMStructTypeInContext(gallivm->context, elem_types,
                                            Elements(elem_types), 0);
 
+   (void) target; /* silence unused var warning for non-debug build */
    LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, map,
                           target, dvbuffer_type,
                           DRAW_JIT_DVBUFFER_MAP);
@@ -133,6 +134,7 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name)
    texture_type = LLVMStructTypeInContext(gallivm->context, elem_types,
                                           Elements(elem_types), 0);
 
+   (void) target; /* silence unused var warning for non-debug build */
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, width,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_WIDTH);
@@ -290,6 +292,7 @@ create_gs_jit_context_type(struct gallivm_state *gallivm,
    context_type = LLVMStructTypeInContext(gallivm->context, elem_types,
                                           Elements(elem_types), 0);
 
+   (void) target; /* silence unused var warning for non-debug build */
    LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, constants,
                           target, context_type, DRAW_GS_JIT_CTX_CONSTANTS);
    LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, num_constants,
@@ -353,6 +356,7 @@ create_jit_vertex_buffer_type(struct gallivm_state *gallivm,
    vb_type = LLVMStructTypeInContext(gallivm->context, elem_types,
                                      Elements(elem_types), 0);
 
+   (void) target; /* silence unused var warning for non-debug build */
    LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride,
                           target, vb_type, 0);
    LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer_offset,
@@ -1965,7 +1969,7 @@ draw_llvm_set_sampler_state(struct draw_context *draw,
       for (i = 0; i < draw->num_samplers[PIPE_SHADER_VERTEX]; i++) {
          struct draw_jit_sampler *jit_sam = &draw->llvm->jit_context.samplers[i];
 
-         if (draw->samplers[i]) {
+         if (draw->samplers[PIPE_SHADER_VERTEX][i]) {
             const struct pipe_sampler_state *s
                = draw->samplers[PIPE_SHADER_VERTEX][i];
             jit_sam->min_lod = s->min_lod;
@@ -1978,7 +1982,7 @@ draw_llvm_set_sampler_state(struct draw_context *draw,
       for (i = 0; i < draw->num_samplers[PIPE_SHADER_GEOMETRY]; i++) {
          struct draw_jit_sampler *jit_sam = &draw->llvm->gs_jit_context.samplers[i];
 
-         if (draw->samplers[i]) {
+         if (draw->samplers[PIPE_SHADER_GEOMETRY][i]) {
             const struct pipe_sampler_state *s
                = draw->samplers[PIPE_SHADER_GEOMETRY][i];
             jit_sam->min_lod = s->min_lod;
@@ -2065,7 +2069,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    struct gallivm_state *gallivm = variant->gallivm;
    LLVMContextRef context = gallivm->context;
    LLVMTypeRef int32_type = LLVMInt32TypeInContext(context);
-   LLVMTypeRef arg_types[6];
+   LLVMTypeRef arg_types[7];
    LLVMTypeRef func_type;
    LLVMValueRef variant_func;
    LLVMValueRef context_ptr;
@@ -2101,6 +2105,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    arg_types[4] = int32_type;                          /* instance_id */
    arg_types[5] = LLVMPointerType(
       LLVMVectorType(int32_type, vector_length), 0);   /* prim_id_ptr */
+   arg_types[6] = int32_type;
 
    func_type = LLVMFunctionType(int32_type, arg_types, Elements(arg_types), 0);
 
@@ -2121,6 +2126,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    num_prims                 = LLVMGetParam(variant_func, 3);
    system_values.instance_id = LLVMGetParam(variant_func, 4);
    prim_id_ptr               = LLVMGetParam(variant_func, 5);
+   system_values.invocation_id = LLVMGetParam(variant_func, 6);
 
    lp_build_name(context_ptr, "context");
    lp_build_name(input_array, "input");
@@ -2128,6 +2134,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    lp_build_name(num_prims, "num_prims");
    lp_build_name(system_values.instance_id, "instance_id");
    lp_build_name(prim_id_ptr, "prim_id_ptr");
+   lp_build_name(system_values.invocation_id, "invocation_id");
 
    variant->context_ptr = context_ptr;
    variant->io_ptr = io_ptr;
index 9565fc68af9a468ef2f6392202d6d94ffd939cfa..d48ed72159301521e633ad00f543beabdaed86ea 100644 (file)
@@ -298,7 +298,8 @@ typedef int
                     struct vertex_header *output,
                     unsigned num_prims,
                     unsigned instance_id,
-                    int *prim_ids);
+                    int *prim_ids,
+                    unsigned invocation_id);
 
 struct draw_llvm_variant_key
 {
index 2f14efea96f67f2cfea9388f92a10a4b65fe3946..936046ea5f552d07060376a895cb6ab5d0b3049a 100644 (file)
@@ -51,7 +51,7 @@
 
 
 /** Approx number of new tokens for instructions in aa_transform_inst() */
-#define NUM_NEW_TOKENS 50
+#define NUM_NEW_TOKENS 53
 
 
 /**
@@ -137,6 +137,7 @@ struct aa_transform_context {
    uint tempsUsed;  /**< bitmask */
    int colorOutput; /**< which output is the primary color */
    uint samplersUsed;  /**< bitfield of samplers used */
+   bool hasSview;
    int freeSampler;  /** an available sampler for the pstipple */
    int maxInput, maxGeneric;  /**< max input index found */
    int colorTemp, texTemp;  /**< temp registers */
@@ -165,6 +166,9 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
          aactx->samplersUsed |= 1 << i;
       }
    }
+   else if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
+      aactx->hasSview = true;
+   }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
       if ((int) decl->Range.Last > aactx->maxInput)
          aactx->maxInput = decl->Range.Last;
@@ -232,6 +236,17 @@ aa_transform_prolog(struct tgsi_transform_context *ctx)
    /* declare new sampler */
    tgsi_transform_sampler_decl(ctx, aactx->freeSampler);
 
+   /* if the src shader has SVIEW decl's for each SAMP decl, we
+    * need to continue the trend and ensure there is a matching
+    * SVIEW for the new SAMP we just created
+    */
+   if (aactx->hasSview) {
+      tgsi_transform_sampler_view_decl(ctx,
+                                       aactx->freeSampler,
+                                       TGSI_TEXTURE_2D,
+                                       TGSI_RETURN_TYPE_FLOAT);
+   }
+
    /* declare new temp regs */
    tgsi_transform_temp_decl(ctx, aactx->texTemp);
    tgsi_transform_temp_decl(ctx, aactx->colorTemp);
index 8f21c46a43a676dc7c5a5ec16ad80ac9a6e64f0c..445f195e59c9e98caccc2d774fa58273c61a07ab 100644 (file)
@@ -53,7 +53,7 @@
 
 
 /** Approx number of new tokens for instructions in pstip_transform_inst() */
-#define NUM_NEW_TOKENS 50
+#define NUM_NEW_TOKENS 53
 
 
 /**
@@ -126,6 +126,7 @@ struct pstip_transform_context {
    int wincoordInput;
    int maxInput;
    uint samplersUsed;  /**< bitfield of samplers used */
+   bool hasSview;
    int freeSampler;  /** an available sampler for the pstipple */
    int texTemp;  /**< temp registers */
    int numImmed;
@@ -149,6 +150,9 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
          pctx->samplersUsed |= 1 << i;
       }
    }
+   else if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
+      pctx->hasSview = true;
+   }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
       pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last);
       if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION)
@@ -232,6 +236,17 @@ pstip_transform_prolog(struct tgsi_transform_context *ctx)
    /* declare new sampler */
    tgsi_transform_sampler_decl(ctx, pctx->freeSampler);
 
+   /* if the src shader has SVIEW decl's for each SAMP decl, we
+    * need to continue the trend and ensure there is a matching
+    * SVIEW for the new SAMP we just created
+    */
+   if (pctx->hasSview) {
+      tgsi_transform_sampler_view_decl(ctx,
+                                       pctx->freeSampler,
+                                       TGSI_TEXTURE_2D,
+                                       TGSI_RETURN_TYPE_FLOAT);
+   }
+
    /* declare new temp regs */
    tgsi_transform_temp_decl(ctx, pctx->texTemp);
 
index be3e834b774877d35fa2f35b32876c0fdf722208..405e6486f7abad84670622ab7ba2d3f97ac97996 100644 (file)
 #include <stddef.h>
 
 #include <llvm-c/Core.h>
-#include <llvm/Target/TargetMachine.h>
-#include <llvm/Target/TargetInstrInfo.h>
+#include <llvm-c/Disassembler.h>
 #include <llvm/Support/raw_ostream.h>
 #include <llvm/Support/Format.h>
-
-#if HAVE_LLVM >= 0x0306
-#include <llvm/Target/TargetSubtargetInfo.h>
-#else
-#include <llvm/Support/MemoryObject.h>
-#endif
-
-#include <llvm/Support/TargetRegistry.h>
-#include <llvm/MC/MCSubtargetInfo.h>
-
 #include <llvm/Support/Host.h>
-
 #include <llvm/IR/Module.h>
 
-#include <llvm/MC/MCDisassembler.h>
-#include <llvm/MC/MCAsmInfo.h>
-#include <llvm/MC/MCInst.h>
-#include <llvm/MC/MCInstPrinter.h>
-#include <llvm/MC/MCRegisterInfo.h>
-
-#if HAVE_LLVM >= 0x0305
-#define OwningPtr std::unique_ptr
-#else
-#include <llvm/ADT/OwningPtr.h>
-#endif
-
-#if HAVE_LLVM >= 0x0305
-#include <llvm/MC/MCContext.h>
-#endif
-
 #include "util/u_math.h"
 #include "util/u_debug.h"
 
@@ -133,7 +105,7 @@ lp_get_module_id(LLVMModuleRef module)
 extern "C" void
 lp_debug_dump_value(LLVMValueRef value)
 {
-#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED)
+#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBEDDED)
    raw_debug_ostream os;
    llvm::unwrap(value)->print(os);
    os.flush();
@@ -143,46 +115,6 @@ lp_debug_dump_value(LLVMValueRef value)
 }
 
 
-#if HAVE_LLVM < 0x0306
-
-/*
- * MemoryObject wrapper around a buffer of memory, to be used by MC
- * disassembler.
- */
-class BufferMemoryObject:
-   public llvm::MemoryObject
-{
-private:
-   const uint8_t *Bytes;
-   uint64_t Length;
-public:
-   BufferMemoryObject(const uint8_t *bytes, uint64_t length) :
-      Bytes(bytes), Length(length)
-   {
-   }
-
-   uint64_t getBase() const
-   {
-      return 0;
-   }
-
-   uint64_t getExtent() const
-   {
-      return Length;
-   }
-
-   int readByte(uint64_t addr, uint8_t *byte) const
-   {
-      if (addr > getExtent())
-         return -1;
-      *byte = Bytes[addr];
-      return 0;
-   }
-};
-
-#endif /* HAVE_LLVM < 0x0306 */
-
-
 /*
  * Disassemble a function, using the LLVM MC disassembler.
  *
@@ -193,8 +125,6 @@ public:
 static size_t
 disassemble(const void* func, llvm::raw_ostream & Out)
 {
-   using namespace llvm;
-
    const uint8_t *bytes = (const uint8_t *)func;
 
    /*
@@ -202,99 +132,23 @@ disassemble(const void* func, llvm::raw_ostream & Out)
     */
    const uint64_t extent = 96 * 1024;
 
-   uint64_t max_pc = 0;
-
    /*
     * Initialize all used objects.
     */
 
-   std::string Triple = sys::getDefaultTargetTriple();
-
-   std::string Error;
-   const Target *T = TargetRegistry::lookupTarget(Triple, Error);
-
-#if HAVE_LLVM >= 0x0304
-   OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(*T->createMCRegInfo(Triple), Triple));
-#else
-   OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(Triple));
-#endif
-
-   if (!AsmInfo) {
-      Out << "error: no assembly info for target " << Triple << "\n";
-      Out.flush();
-      return 0;
-   }
-
-   unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
-
-   OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(Triple));
-   if (!MRI) {
-      Out << "error: no register info for target " << Triple.c_str() << "\n";
-      Out.flush();
-      return 0;
-   }
+   std::string Triple = llvm::sys::getProcessTriple();
+   LLVMDisasmContextRef D = LLVMCreateDisasm(Triple.c_str(), NULL, 0, NULL, NULL);
+   char outline[1024];
 
-   OwningPtr<const MCInstrInfo> MII(T->createMCInstrInfo());
-   if (!MII) {
-      Out << "error: no instruction info for target " << Triple.c_str() << "\n";
-      Out.flush();
+   if (!D) {
+      Out << "error: couldn't create disassembler for triple " << Triple << "\n";
       return 0;
    }
 
-#if HAVE_LLVM >= 0x0305
-   OwningPtr<const MCSubtargetInfo> STI(T->createMCSubtargetInfo(Triple, sys::getHostCPUName(), ""));
-   OwningPtr<MCContext> MCCtx(new MCContext(AsmInfo.get(), MRI.get(), 0));
-   OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler(*STI, *MCCtx));
-#else
-   OwningPtr<const MCSubtargetInfo> STI(T->createMCSubtargetInfo(Triple, sys::getHostCPUName(), ""));
-   OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler(*STI));
-#endif
-   if (!DisAsm) {
-      Out << "error: no disassembler for target " << Triple << "\n";
-      Out.flush();
-      return 0;
-   }
-
-
-#if HAVE_LLVM >= 0x0307
-   OwningPtr<MCInstPrinter> Printer(
-         T->createMCInstPrinter(llvm::Triple(Triple), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
-#else
-   OwningPtr<MCInstPrinter> Printer(
-         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
-#endif
-   if (!Printer) {
-      Out << "error: no instruction printer for target " << Triple.c_str() << "\n";
-      Out.flush();
-      return 0;
-   }
-
-   TargetOptions options;
-#if defined(DEBUG) && HAVE_LLVM < 0x0307
-   options.JITEmitDebugInfo = true;
-#endif
-#if defined(PIPE_ARCH_X86)
-   options.StackAlignmentOverride = 4;
-#endif
-#if defined(DEBUG) || defined(PROFILE)
-   options.NoFramePointerElim = true;
-#endif
-   OwningPtr<TargetMachine> TM(T->createTargetMachine(Triple, sys::getHostCPUName(), "", options));
-
-   /*
-    * Wrap the data in a MemoryObject
-    */
-#if HAVE_LLVM >= 0x0306
-   ArrayRef<uint8_t> memoryObject((const uint8_t *)bytes, extent);
-#else
-   BufferMemoryObject memoryObject((const uint8_t *)bytes, extent);
-#endif
-
    uint64_t pc;
    pc = 0;
-   while (true) {
-      MCInst Inst;
-      uint64_t Size;
+   while (pc < extent) {
+      size_t Size;
 
       /*
        * Print address.  We use addresses relative to the start of the function,
@@ -303,11 +157,13 @@ disassemble(const void* func, llvm::raw_ostream & Out)
 
       Out << llvm::format("%6lu:\t", (unsigned long)pc);
 
-      if (!DisAsm->getInstruction(Inst, Size, memoryObject,
-                                 pc,
-                                 nulls(), nulls())) {
-         Out << "invalid";
+      Size = LLVMDisasmInstruction(D, (uint8_t *)bytes + pc, extent - pc, 0, outline,
+                                   sizeof outline);
+
+      if (!Size) {
+         Out << "invalid\n";
          pc += 1;
+         break;
       }
 
       /*
@@ -317,7 +173,7 @@ disassemble(const void* func, llvm::raw_ostream & Out)
       if (0) {
          unsigned i;
          for (i = 0; i < Size; ++i) {
-            Out << llvm::format("%02x ", ((const uint8_t*)bytes)[pc + i]);
+            Out << llvm::format("%02x ", bytes[pc + i]);
          }
          for (; i < 16; ++i) {
             Out << "   ";
@@ -327,81 +183,27 @@ disassemble(const void* func, llvm::raw_ostream & Out)
       /*
        * Print the instruction.
        */
-#if HAVE_LLVM >= 0x0307
-      Printer->printInst(&Inst, Out, "", *STI);
-#else
-      Printer->printInst(&Inst, Out, "");
-#endif
 
-      /*
-       * Advance.
-       */
+      Out << outline;
 
-      pc += Size;
-
-      const MCInstrDesc &TID = MII->get(Inst.getOpcode());
+      Out << "\n";
 
       /*
-       * Keep track of forward jumps to a nearby address.
+       * Stop disassembling on return statements, if there is no record of a
+       * jump to a successive address.
+       *
+       * XXX: This currently assumes x86
        */
 
-      if (TID.isBranch()) {
-         for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
-            const MCOperand &operand = Inst.getOperand(i);
-            if (operand.isImm()) {
-               uint64_t jump;
-
-               /*
-                * FIXME: Handle both relative and absolute addresses correctly.
-                * EDInstInfo actually has this info, but operandTypes and
-                * operandFlags enums are not exposed in the public interface.
-                */
-
-               if (1) {
-                  /*
-                   * PC relative addr.
-                   */
-
-                  jump = pc + operand.getImm();
-               } else {
-                  /*
-                   * Absolute addr.
-                   */
-
-                  jump = (uint64_t)operand.getImm();
-               }
-
-               /*
-                * Output the address relative to the function start, given
-                * that MC will print the addresses relative the current pc.
-                */
-               Out << "\t\t; " << jump;
-
-               /*
-                * Ignore far jumps given it could be actually a tail return to
-                * a random address.
-                */
-
-               if (jump > max_pc &&
-                   jump < extent) {
-                  max_pc = jump;
-               }
-            }
-         }
+      if (Size == 1 && bytes[pc] == 0xc3) {
+         break;
       }
 
-      Out << "\n";
-
       /*
-       * Stop disassembling on return statements, if there is no record of a
-       * jump to a successive address.
+       * Advance.
        */
 
-      if (TID.isReturn()) {
-         if (pc > max_pc) {
-            break;
-         }
-      }
+      pc += Size;
 
       if (pc >= extent) {
          Out << "disassembly larger than " << extent << "bytes, aborting\n";
@@ -412,6 +214,8 @@ disassemble(const void* func, llvm::raw_ostream & Out)
    Out << "\n";
    Out.flush();
 
+   LLVMDisasmDispose(D);
+
    /*
     * Print GDB command, useful to verify output.
     */
@@ -442,7 +246,7 @@ lp_disassemble(LLVMValueRef func, const void *code) {
 extern "C" void
 lp_profile(LLVMValueRef func, const void *code)
 {
-#if defined(__linux__) && (defined(DEBUG) || defined(PROFILE))
+#if defined(__linux__) && defined(PROFILE)
    static boolean first_time = TRUE;
    static FILE *perf_map_file = NULL;
    static int perf_asm_fd = -1;
index 3c25c329edde4dcb5bcc4dbf3448442c5f314ff5..efe71704c3a6eef5ae6caa673054d017a2e46825 100644 (file)
@@ -405,6 +405,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
                                aligned, base_ptr, offset, TRUE);
 
       assert(format_desc->block.bits <= vec_len);
+      (void) vec_len; /* silence unused var warning for non-debug build */
 
       packed = LLVMBuildBitCast(gallivm->builder, packed, dst_vec_type, "");
       return lp_build_format_swizzle_aos(format_desc, &bld, packed);
index 7b906c27ed5c2851a5906db3dd6067df198238d1..384ea8640815deb297b773ced762e62450f4a29d 100644 (file)
@@ -533,6 +533,16 @@ gallivm_compile_module(struct gallivm_state *gallivm)
       if (0) {
          debug_printf("optimizing func %s...\n", LLVMGetValueName(func));
       }
+
+   /* Disable frame pointer omission on debug/profile builds */
+   /* XXX: And workaround http://llvm.org/PR21435 */
+#if HAVE_LLVM >= 0x0307 && \
+    (defined(DEBUG) || defined(PROFILE) || \
+     defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64))
+      LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim", "true");
+      LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim-non-leaf", "true");
+#endif
+
       LLVMRunFunctionPassManager(gallivm->passmgr, func);
       func = LLVMGetNextFunction(func);
    }
index c5c51c18a0a4301a5e1fc0db73c439f69b00aec3..db503514881336aaaca284765c9c8d6182168f26 100644 (file)
 
 #define LP_MAX_TGSI_PREDS 16
 
+#define LP_MAX_TGSI_CONSTS 4096
+
 #define LP_MAX_TGSI_CONST_BUFFERS 16
 
+#define LP_MAX_TGSI_CONST_BUFFER_SIZE (LP_MAX_TGSI_CONSTS * sizeof(float[4]))
+
 /*
  * For quick access we cache registers in statically
  * allocated arrays. Here we define the maximum size
@@ -100,7 +104,7 @@ gallivm_get_shader_param(enum pipe_shader_cap param)
    case PIPE_SHADER_CAP_MAX_OUTPUTS:
       return 32;
    case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
-      return sizeof(float[4]) * 4096;
+      return LP_MAX_TGSI_CONST_BUFFER_SIZE;
    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
       return PIPE_MAX_CONSTANT_BUFFERS;
    case PIPE_SHADER_CAP_MAX_TEMPS:
@@ -125,6 +129,7 @@ gallivm_get_shader_param(enum pipe_shader_cap param)
    case PIPE_SHADER_CAP_PREFERRED_IR:
       return PIPE_SHADER_IR_TGSI;
    case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
+   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
       return 1;
    case PIPE_SHADER_CAP_DOUBLES:
    case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
index 5e8a634f01998882c0bfd9f132cccb7aea62b07c..5e25819ac5578fa1bd06b3400b161fa14f001796 100644 (file)
 
 #include <stddef.h>
 
+// Workaround http://llvm.org/PR23628
+#if HAVE_LLVM >= 0x0307
+#  pragma push_macro("DEBUG")
+#  undef DEBUG
+#endif
+
 #include <llvm-c/Core.h>
 #include <llvm-c/ExecutionEngine.h>
 #include <llvm/Target/TargetOptions.h>
 #include <llvm/IR/Module.h>
 #include <llvm/Support/CBindingWrapping.h>
 
+// Workaround http://llvm.org/PR23628
+#if HAVE_LLVM >= 0x0307
+#  pragma pop_macro("DEBUG")
+#endif
+
 #include "pipe/p_config.h"
 #include "util/u_debug.h"
 #include "util/u_cpu_detect.h"
@@ -439,7 +450,9 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
 #if HAVE_LLVM < 0x0304
    options.NoFramePointerElimNonLeaf = true;
 #endif
+#if HAVE_LLVM < 0x0307
    options.NoFramePointerElim = true;
+#endif
 #endif
 
    builder.setEngineKind(EngineKind::JIT)
index 5b220450bf31318d2c10b95dc35200e348a37d0f..4befb3a1c80328503d33a4b3b7917e1aa731a160 100644 (file)
@@ -113,7 +113,7 @@ lp_sampler_static_texture_state(struct lp_static_texture_state *state,
    state->swizzle_b         = view->swizzle_b;
    state->swizzle_a         = view->swizzle_a;
 
-   state->target            = texture->target;
+   state->target            = view->target;
    state->pot_width         = util_is_power_of_two(texture->width0);
    state->pot_height        = util_is_power_of_two(texture->height0);
    state->pot_depth         = util_is_power_of_two(texture->depth0);
index 1a60ca9d3cb7f5185539567d36b72037a7cafbb5..b5c06b695711f16c4b2d01f70416a0995d6ed247 100644 (file)
@@ -2501,7 +2501,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
        * all zero as mandated by d3d10 in this case.
        */
       unsigned chan;
-      LLVMValueRef zero = lp_build_const_vec(gallivm, type, 0.0F);
+      LLVMValueRef zero = lp_build_zero(gallivm, type);
       for (chan = 0; chan < 4; chan++) {
          texel_out[chan] = zero;
       }
@@ -2748,11 +2748,37 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
    else {
       LLVMValueRef lod_fpart = NULL, lod_positive = NULL;
       LLVMValueRef ilevel0 = NULL, ilevel1 = NULL;
-      boolean use_aos = util_format_fits_8unorm(bld.format_desc) &&
-                        op_is_tex &&
-                        /* not sure this is strictly needed or simply impossible */
-                        derived_sampler_state.compare_mode == PIPE_TEX_COMPARE_NONE &&
-                        lp_is_simple_wrap_mode(derived_sampler_state.wrap_s);
+      boolean use_aos;
+
+      if (util_format_is_pure_integer(static_texture_state->format) &&
+          !util_format_has_depth(bld.format_desc) &&
+          (static_sampler_state->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR ||
+           static_sampler_state->min_img_filter == PIPE_TEX_FILTER_LINEAR ||
+           static_sampler_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR)) {
+         /*
+          * Bail if impossible filtering is specified (the awkard additional
+          * depth check is because it is legal in gallium to have things like S8Z24
+          * here which would say it's pure int despite such formats should sample
+          * the depth component).
+          * In GL such filters make the texture incomplete, this makes it robust
+          * against state trackers which set this up regardless (we'd crash in the
+          * lerp later (except for gather)).
+          * Must do this after fetch_texel code since with GL state tracker we'll
+          * get some junk sampler for buffer textures.
+          */
+         unsigned chan;
+         LLVMValueRef zero = lp_build_zero(gallivm, type);
+         for (chan = 0; chan < 4; chan++) {
+            texel_out[chan] = zero;
+         }
+         return;
+      }
+
+      use_aos = util_format_fits_8unorm(bld.format_desc) &&
+                op_is_tex &&
+                /* not sure this is strictly needed or simply impossible */
+                derived_sampler_state.compare_mode == PIPE_TEX_COMPARE_NONE &&
+                lp_is_simple_wrap_mode(derived_sampler_state.wrap_s);
 
       use_aos &= bld.num_lods <= num_quads ||
                  derived_sampler_state.min_img_filter ==
index 3f76b79b8d11601d4932442c3f390da69dd499eb..967373ccdaef173a8094a1f46ddf40a55a5a235c 100644 (file)
@@ -165,6 +165,7 @@ struct lp_bld_tgsi_system_values {
    LLVMValueRef vertex_id_nobase;
    LLVMValueRef prim_id;
    LLVMValueRef basevertex;
+   LLVMValueRef invocation_id;
 };
 
 
index 738d5e9fd648916a6b6b057a16d4e831d77e2da7..610283d791221d2b92defcbd78779eedb6cb8ca9 100644 (file)
@@ -232,23 +232,9 @@ lp_emit_store_aos(
    /*
     * Saturate the value
     */
-
-   switch (inst->Instruction.Saturate) {
-   case TGSI_SAT_NONE:
-      break;
-
-   case TGSI_SAT_ZERO_ONE:
+   if (inst->Instruction.Saturate) {
       value = lp_build_max(&bld->bld_base.base, value, bld->bld_base.base.zero);
       value = lp_build_min(&bld->bld_base.base, value, bld->bld_base.base.one);
-      break;
-
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      value = lp_build_max(&bld->bld_base.base, value, lp_build_const_vec(bld->bld_base.base.gallivm, bld->bld_base.base.type, -1.0));
-      value = lp_build_min(&bld->bld_base.base, value, bld->bld_base.base.one);
-      break;
-
-   default:
-      assert(0);
    }
 
    /*
index 448c99d35472679671060fba2f84db0ef5e40428..268379e7d13bbe104fa0b16e4818a6a2a137b873 100644 (file)
@@ -1532,6 +1532,11 @@ emit_fetch_system_value(
       atype = TGSI_TYPE_UNSIGNED;
       break;
 
+   case TGSI_SEMANTIC_INVOCATIONID:
+      res = lp_build_broadcast_scalar(&bld_base->uint_bld, bld->system_values.invocation_id);
+      atype = TGSI_TYPE_UNSIGNED;
+      break;
+
    default:
       assert(!"unexpected semantic in emit_fetch_system_value");
       res = bld_base->base.zero;
@@ -1670,30 +1675,11 @@ emit_store_chan(
     *
     * It is always assumed to be float.
     */
-   switch( inst->Instruction.Saturate ) {
-   case TGSI_SAT_NONE:
-      break;
-
-   case TGSI_SAT_ZERO_ONE:
+   if (inst->Instruction.Saturate) {
       assert(dtype == TGSI_TYPE_FLOAT ||
              dtype == TGSI_TYPE_UNTYPED);
       value = LLVMBuildBitCast(builder, value, float_bld->vec_type, "");
       value = lp_build_clamp_zero_one_nanzero(float_bld, value);
-      break;
-
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      assert(dtype == TGSI_TYPE_FLOAT ||
-             dtype == TGSI_TYPE_UNTYPED);
-      value = LLVMBuildBitCast(builder, value, float_bld->vec_type, "");
-      /* This will give -1.0 for NaN which is probably not what we want. */
-      value = lp_build_max_ext(float_bld, value,
-                               lp_build_const_vec(gallivm, float_bld->type, -1.0),
-                               GALLIVM_NAN_RETURN_OTHER_SECOND_NONNAN);
-      value = lp_build_min(float_bld, value, float_bld->one);
-      break;
-
-   default:
-      assert(0);
    }
 
    if (reg->Register.Indirect) {
index 00ec20589c4b5a1c1ac0e17ebc2e6dfb5088802a..6a124f7d716a026cb175dba00c29e9040a05c274 100644 (file)
@@ -423,6 +423,8 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_save_viewport(cso);
    cso_save_stream_outputs(cso);
    cso_save_geometry_shader(cso);
+   cso_save_tessctrl_shader(cso);
+   cso_save_tesseval_shader(cso);
    cso_save_vertex_shader(cso);
    cso_save_vertex_elements(cso);
    cso_save_aux_vertex_buffer_slot(cso);
@@ -456,6 +458,8 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_set_rasterizer(cso, &hud->rasterizer);
    cso_set_viewport(cso, &viewport);
    cso_set_stream_outputs(cso, 0, NULL, NULL);
+   cso_set_tessctrl_shader_handle(cso, NULL);
+   cso_set_tesseval_shader_handle(cso, NULL);
    cso_set_geometry_shader_handle(cso, NULL);
    cso_set_vertex_shader_handle(cso, hud->vs);
    cso_set_vertex_elements(cso, 2, hud->velems);
@@ -548,6 +552,8 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_restore_rasterizer(cso);
    cso_restore_viewport(cso);
    cso_restore_stream_outputs(cso);
+   cso_restore_tessctrl_shader(cso);
+   cso_restore_tesseval_shader(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_vertex_shader(cso);
    cso_restore_vertex_elements(cso);
index 59aaf67788848842b3a075319e3ebd5e983f72a2..061f39ac6f3ab2f58d6ca54e1eb1e9b78674f75b 100644 (file)
@@ -58,6 +58,9 @@ struct ttn_compile {
    struct ttn_reg_info *temp_regs;
    nir_ssa_def **imm_defs;
 
+   unsigned num_samp_types;
+   nir_alu_type *samp_types;
+
    nir_register *addr_reg;
 
    /**
@@ -156,6 +159,30 @@ ttn_emit_declaration(struct ttn_compile *c)
       /* Nothing to record for system values. */
    } else if (file == TGSI_FILE_SAMPLER) {
       /* Nothing to record for samplers. */
+   } else if (file == TGSI_FILE_SAMPLER_VIEW) {
+      struct tgsi_declaration_sampler_view *sview = &decl->SamplerView;
+      nir_alu_type type;
+
+      assert((sview->ReturnTypeX == sview->ReturnTypeY) &&
+             (sview->ReturnTypeX == sview->ReturnTypeZ) &&
+             (sview->ReturnTypeX == sview->ReturnTypeW));
+
+      switch (sview->ReturnTypeX) {
+      case TGSI_RETURN_TYPE_SINT:
+         type = nir_type_int;
+         break;
+      case TGSI_RETURN_TYPE_UINT:
+         type = nir_type_unsigned;
+         break;
+      case TGSI_RETURN_TYPE_FLOAT:
+      default:
+         type = nir_type_float;
+         break;
+      }
+
+      for (i = 0; i < array_size; i++) {
+         c->samp_types[decl->Range.First + i] = type;
+      }
    } else {
       nir_variable *var;
       assert(file == TGSI_FILE_INPUT ||
@@ -401,7 +428,6 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
 
       load->num_components = 4;
       load->const_index[0] = index;
-      load->const_index[1] = 1;
       if (dim) {
          if (dimind) {
             load->src[srcn] =
@@ -1027,7 +1053,7 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
    struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
    nir_tex_instr *instr;
    nir_texop op;
-   unsigned num_srcs, samp = 1, i;
+   unsigned num_srcs, samp = 1, sview, i;
 
    switch (tgsi_inst->Instruction.Opcode) {
    case TGSI_OPCODE_TEX:
@@ -1106,6 +1132,18 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
    assert(tgsi_inst->Src[samp].Register.File == TGSI_FILE_SAMPLER);
    instr->sampler_index = tgsi_inst->Src[samp].Register.Index;
 
+   /* TODO if we supported any opc's which take an explicit SVIEW
+    * src, we would use that here instead.  But for the "legacy"
+    * texture opc's the SVIEW index is same as SAMP index:
+    */
+   sview = instr->sampler_index;
+
+   if (sview < c->num_samp_types) {
+      instr->dest_type = c->samp_types[sview];
+   } else {
+      instr->dest_type = nir_type_float;
+   }
+
    unsigned src_number = 0;
 
    instr->src[src_number].src =
@@ -1286,6 +1324,7 @@ static const nir_op op_trans[TGSI_OPCODE_LAST] = {
    [TGSI_OPCODE_SEQ] = nir_op_seq,
    [TGSI_OPCODE_SGT] = 0,
    [TGSI_OPCODE_SIN] = nir_op_fsin,
+   [TGSI_OPCODE_SNE] = nir_op_sne,
    [TGSI_OPCODE_SLE] = 0,
    [TGSI_OPCODE_TEX] = 0,
    [TGSI_OPCODE_TXD] = 0,
@@ -1625,7 +1664,6 @@ ttn_emit_instruction(struct ttn_compile *c)
    }
 
    if (tgsi_inst->Instruction.Saturate) {
-      assert(tgsi_inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
       assert(!dest.dest.is_ssa);
       ttn_move_dest(b, dest, nir_fsat(b, ttn_src_for_dest(b, &dest)));
    }
@@ -1672,7 +1710,6 @@ ttn_add_output_stores(struct ttn_compile *c)
             nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_output);
          store->num_components = 4;
          store->const_index[0] = var->data.driver_location + i;
-         store->const_index[1] = 1;
          store->src[0].reg.reg = c->output_regs[var->data.driver_location].reg;
          nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
       }
@@ -1713,6 +1750,9 @@ tgsi_to_nir(const void *tgsi_tokens,
    c->imm_defs = rzalloc_array(c, nir_ssa_def *,
                                scan.file_max[TGSI_FILE_IMMEDIATE] + 1);
 
+   c->num_samp_types = scan.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
+   c->samp_types = rzalloc_array(c, nir_alu_type, c->num_samp_types);
+
    c->if_stack = rzalloc_array(c, struct exec_list *,
                                (scan.opcode_count[TGSI_OPCODE_IF] +
                                 scan.opcode_count[TGSI_OPCODE_UIF]) * 2);
index 3bd9cd70ae37280251f46d49fc123331a9e6126b..fc81e11b972a603ee2eb9b6d98e2a97cd22e47c4 100644 (file)
@@ -376,6 +376,7 @@ fenced_buffer_finish_locked(struct fenced_manager *fenced_mgr,
          /* TODO: remove consequents buffers with the same fence? */
 
          assert(!destroyed);
+         (void) destroyed; /* silence unused var warning for non-debug build */
 
          fenced_buf->flags &= ~PB_USAGE_GPU_READ_WRITE;
 
index c72f2c4b4078f87802a593974db6974871a7680f..9b9f981a5ff6be35254c19b888b8698a5a43f0f7 100644 (file)
 
 #include "pipe/p_state.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct cso_context;
 
 struct pp_queue_t;              /* Forward definition */
@@ -85,4 +89,9 @@ void pp_celshade_free(struct pp_queue_t *, unsigned int);
 void pp_nocolor_free(struct pp_queue_t *, unsigned int);
 void pp_jimenezmlaa_free(struct pp_queue_t *, unsigned int);
 
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index 06281c8ce340dbb7284ba6e565ad0fa8bb1c3b74..e76ce854442c55478b8a840a2a345da693dc5ef3 100644 (file)
@@ -119,6 +119,8 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
    cso_save_depth_stencil_alpha(cso);
    cso_save_fragment_shader(cso);
    cso_save_framebuffer(cso);
+   cso_save_tessctrl_shader(cso);
+   cso_save_tesseval_shader(cso);
    cso_save_geometry_shader(cso);
    cso_save_rasterizer(cso);
    cso_save_sample_mask(cso);
@@ -139,6 +141,8 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
    cso_set_sample_mask(cso, ~0);
    cso_set_min_samples(cso, 1);
    cso_set_stream_outputs(cso, 0, NULL, NULL);
+   cso_set_tessctrl_shader_handle(cso, NULL);
+   cso_set_tesseval_shader_handle(cso, NULL);
    cso_set_geometry_shader_handle(cso, NULL);
    cso_set_render_condition(cso, NULL, FALSE, 0);
 
@@ -186,6 +190,8 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
    cso_restore_depth_stencil_alpha(cso);
    cso_restore_fragment_shader(cso);
    cso_restore_framebuffer(cso);
+   cso_restore_tessctrl_shader(cso);
+   cso_restore_tesseval_shader(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_rasterizer(cso);
    cso_restore_sample_mask(cso);
index 8c3dbefd109b5854a50d6d4c3e63cb41889cdf86..f7e605e9563323626de81403079fda27e80699b3 100644 (file)
@@ -49,7 +49,7 @@
 #include <windows.h>
 #endif
 
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
+#if defined(PIPE_OS_UNIX)
 
 
 /*
index 39a4296a3a13c63ef88c362023c9381ed10df6e5..fdb7febf7eafbe1dd9ee9b75c9a4beddc9e6dd23 100644 (file)
@@ -610,7 +610,7 @@ tgsi_default_instruction( void )
    instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
    instruction.NrTokens = 0;
    instruction.Opcode = TGSI_OPCODE_MOV;
-   instruction.Saturate = TGSI_SAT_NONE;
+   instruction.Saturate = 0;
    instruction.Predicate = 0;
    instruction.NumDstRegs = 1;
    instruction.NumSrcRegs = 1;
@@ -632,7 +632,7 @@ tgsi_build_instruction(unsigned opcode,
    struct tgsi_instruction instruction;
 
    assert (opcode <= TGSI_OPCODE_LAST);
-   assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE);
+   assert (saturate <= 1);
    assert (num_dst_regs <= 3);
    assert (num_src_regs <= 15);
 
index 13d67691897b8671562835aea4073650099d25f8..c80d7a20481c4ff40a93fa8280b0dde2678bf98c 100644 (file)
@@ -271,14 +271,30 @@ iter_declaration(
    struct tgsi_full_declaration *decl )
 {
    struct dump_ctx *ctx = (struct dump_ctx *)iter;
+   boolean patch = decl->Semantic.Name == TGSI_SEMANTIC_PATCH ||
+      decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER ||
+      decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER ||
+      decl->Semantic.Name == TGSI_SEMANTIC_PRIMID;
 
    TXT( "DCL " );
 
    TXT(tgsi_file_name(decl->Declaration.File));
 
-   /* all geometry shader inputs are two dimensional */
+   /* all geometry shader inputs and non-patch tessellation shader inputs are
+    * two dimensional
+    */
    if (decl->Declaration.File == TGSI_FILE_INPUT &&
-       iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+       (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
+        (!patch &&
+         (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
+          iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL)))) {
+      TXT("[]");
+   }
+
+   /* all non-patch tess ctrl shader outputs are two dimensional */
+   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
+       !patch &&
+       iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
       TXT("[]");
    }
 
@@ -523,17 +539,8 @@ iter_instruction(
 
    TXT( info->mnemonic );
 
-   switch (inst->Instruction.Saturate) {
-   case TGSI_SAT_NONE:
-      break;
-   case TGSI_SAT_ZERO_ONE:
+   if (inst->Instruction.Saturate) {
       TXT( "_SAT" );
-      break;
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      TXT( "_SATNV" );
-      break;
-   default:
-      assert( 0 );
    }
 
    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
index d9e40506afa7ca613740e1d728a97f4dfadf5ddc..44000ffdb6c1316e68cf12b9e95c4372f937147f 100644 (file)
@@ -1765,14 +1765,12 @@ store_dest(struct tgsi_exec_machine *mach,
    if (!dst)
       return;
 
-   switch (inst->Instruction.Saturate) {
-   case TGSI_SAT_NONE:
+   if (!inst->Instruction.Saturate) {
       for (i = 0; i < TGSI_QUAD_SIZE; i++)
          if (execmask & (1 << i))
             dst->i[i] = chan->i[i];
-      break;
-
-   case TGSI_SAT_ZERO_ONE:
+   }
+   else {
       for (i = 0; i < TGSI_QUAD_SIZE; i++)
          if (execmask & (1 << i)) {
             if (chan->f[i] < 0.0f)
@@ -1782,22 +1780,6 @@ store_dest(struct tgsi_exec_machine *mach,
             else
                dst->i[i] = chan->i[i];
          }
-      break;
-
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      for (i = 0; i < TGSI_QUAD_SIZE; i++)
-         if (execmask & (1 << i)) {
-            if (chan->f[i] < -1.0f)
-               dst->f[i] = -1.0f;
-            else if (chan->f[i] > 1.0f)
-               dst->f[i] = 1.0f;
-            else
-               dst->i[i] = chan->i[i];
-         }
-      break;
-
-   default:
-      assert( 0 );
    }
 }
 
@@ -1952,7 +1934,7 @@ fetch_texel( struct tgsi_sampler *sampler,
 #define TEX_MODIFIER_LOD_BIAS       2
 #define TEX_MODIFIER_EXPLICIT_LOD   3
 #define TEX_MODIFIER_LEVEL_ZERO     4
-
+#define TEX_MODIFIER_GATHER         5
 
 /*
  * Fetch all 3 (for s,t,r coords) texel offsets, put them into int array.
@@ -2006,6 +1988,35 @@ fetch_assign_deriv_channel(struct tgsi_exec_machine *mach,
    derivs[1][3] = d.f[3];
 }
 
+static uint
+fetch_sampler_unit(struct tgsi_exec_machine *mach,
+                   const struct tgsi_full_instruction *inst,
+                   uint sampler)
+{
+   uint unit;
+
+   if (inst->Src[sampler].Register.Indirect) {
+      const struct tgsi_full_src_register *reg = &inst->Src[sampler];
+      union tgsi_exec_channel indir_index, index2;
+
+      index2.i[0] =
+      index2.i[1] =
+      index2.i[2] =
+      index2.i[3] = reg->Indirect.Index;
+
+      fetch_src_file_channel(mach,
+                             0,
+                             reg->Indirect.File,
+                             reg->Indirect.Swizzle,
+                             &index2,
+                             &ZeroVec,
+                             &indir_index);
+      unit = inst->Src[sampler].Register.Index + indir_index.i[0];
+   } else {
+      unit = inst->Src[sampler].Register.Index;
+   }
+   return unit;
+}
 
 /*
  * execute a texture instruction.
@@ -2019,14 +2030,15 @@ exec_tex(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst,
          uint modifier, uint sampler)
 {
-   const uint unit = inst->Src[sampler].Register.Index;
    const union tgsi_exec_channel *args[5], *proj = NULL;
    union tgsi_exec_channel r[5];
    enum tgsi_sampler_control control =  tgsi_sampler_lod_none;
    uint chan;
+   uint unit;
    int8_t offsets[3];
    int dim, shadow_ref, i;
 
+   unit = fetch_sampler_unit(mach, inst, sampler);
    /* always fetch all 3 offsets, overkill but keeps code simple */
    fetch_texel_offsets(mach, inst, offsets);
 
@@ -2069,6 +2081,8 @@ exec_tex(struct tgsi_exec_machine *mach,
          control = tgsi_sampler_lod_explicit;
       else if (modifier == TEX_MODIFIER_LOD_BIAS)
          control = tgsi_sampler_lod_bias;
+      else if (modifier == TEX_MODIFIER_GATHER)
+         control = tgsi_sampler_gather;
    }
    else {
       for (i = dim; i < Elements(args); i++)
@@ -2123,12 +2137,13 @@ static void
 exec_txd(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst)
 {
-   const uint unit = inst->Src[3].Register.Index;
    union tgsi_exec_channel r[4];
    float derivs[3][2][TGSI_QUAD_SIZE];
    uint chan;
+   uint unit;
    int8_t offsets[3];
 
+   unit = fetch_sampler_unit(mach, inst, 3);
    /* always fetch all 3 offsets, overkill but keeps code simple */
    fetch_texel_offsets(mach, inst, offsets);
 
@@ -2230,14 +2245,15 @@ static void
 exec_txf(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst)
 {
-   const uint unit = inst->Src[1].Register.Index;
    union tgsi_exec_channel r[4];
    uint chan;
+   uint unit;
    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
    int j;
    int8_t offsets[3];
    unsigned target;
 
+   unit = fetch_sampler_unit(mach, inst, 1);
    /* always fetch all 3 offsets, overkill but keeps code simple */
    fetch_texel_offsets(mach, inst, offsets);
 
@@ -2312,12 +2328,14 @@ static void
 exec_txq(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst)
 {
-   const uint unit = inst->Src[1].Register.Index;
    int result[4];
    union tgsi_exec_channel r[4], src;
    uint chan;
+   uint unit;
    int i,j;
 
+   unit = fetch_sampler_unit(mach, inst, 1);
+
    fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_INT);
 
    /* XXX: This interface can't return per-pixel values */
@@ -3315,16 +3333,14 @@ store_double_channel(struct tgsi_exec_machine *mach,
    union tgsi_double_channel temp;
    const uint execmask = mach->ExecMask;
 
-   switch (inst->Instruction.Saturate) {
-   case TGSI_SAT_NONE:
+   if (!inst->Instruction.Saturate) {
       for (i = 0; i < TGSI_QUAD_SIZE; i++)
          if (execmask & (1 << i)) {
             dst[0].u[i] = chan->u[i][0];
             dst[1].u[i] = chan->u[i][1];
          }
-      break;
-
-   case TGSI_SAT_ZERO_ONE:
+   }
+   else {
       for (i = 0; i < TGSI_QUAD_SIZE; i++)
          if (execmask & (1 << i)) {
             if (chan->d[i] < 0.0)
@@ -3337,25 +3353,6 @@ store_double_channel(struct tgsi_exec_machine *mach,
             dst[0].u[i] = temp.u[i][0];
             dst[1].u[i] = temp.u[i][1];
          }
-      break;
-
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      for (i = 0; i < TGSI_QUAD_SIZE; i++)
-         if (execmask & (1 << i)) {
-            if (chan->d[i] < -1.0)
-               temp.d[i] = -1.0;
-            else if (chan->d[i] > 1.0)
-               temp.d[i] = 1.0;
-            else
-               temp.d[i] = chan->d[i];
-
-            dst[0].u[i] = temp.u[i][0];
-            dst[1].u[i] = temp.u[i][1];
-         }
-      break;
-
-   default:
-      assert( 0 );
    }
 
    store_dest_double(mach, &dst[0], reg, inst, chan_0, TGSI_EXEC_DATA_UINT);
@@ -4374,6 +4371,13 @@ exec_instruction(
       exec_tex(mach, inst, TEX_MODIFIER_PROJECTED, 1);
       break;
 
+   case TGSI_OPCODE_TG4:
+      /* src[0] = texcoord */
+      /* src[1] = component */
+      /* src[2] = sampler unit */
+      exec_tex(mach, inst, TEX_MODIFIER_GATHER, 2);
+      break;
+
    case TGSI_OPCODE_UP2H:
       assert (0);
       break;
@@ -4431,8 +4435,12 @@ exec_instruction(
          mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
          mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
 
-         /* Finally, jump to the subroutine */
+         /* Finally, jump to the subroutine.  The label is a pointer
+          * (an instruction number) to the BGNSUB instruction.
+          */
          *pc = inst->Label.Label;
+         assert(mach->Instructions[*pc].Instruction.Opcode
+                == TGSI_OPCODE_BGNSUB);
       }
       break;
 
index 0e59b884897ecd4044c234379b0d7ff81c3ee5fd..208640cfd468a38db2dc953835a5ef5ad5211108 100644 (file)
@@ -93,7 +93,8 @@ enum tgsi_sampler_control {
    tgsi_sampler_lod_bias,
    tgsi_sampler_lod_explicit,
    tgsi_sampler_lod_zero,
-   tgsi_sampler_derivs_explicit
+   tgsi_sampler_derivs_explicit,
+   tgsi_sampler_gather,
 };
 
 /**
@@ -457,6 +458,7 @@ tgsi_exec_get_shader_param(enum pipe_shader_cap param)
       return 1;
    case PIPE_SHADER_CAP_DOUBLES:
    case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
+   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
       return 1;
    case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
    case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
index 3cab86efbfe1d0fc3ff308f1e6ac422ead4641d0..929531109e50170387dad8cfca3964f80f4f3ae7 100644 (file)
@@ -302,6 +302,10 @@ tgsi_get_processor_name( uint processor )
       return "fragment shader";
    case TGSI_PROCESSOR_GEOMETRY:
       return "geometry shader";
+   case TGSI_PROCESSOR_TESS_CTRL:
+      return "tessellation control shader";
+   case TGSI_PROCESSOR_TESS_EVAL:
+      return "tessellation evaluation shader";
    default:
       return "unknown shader type!";
    }
index 4954c1178e566ab8a6e33c870d8225f1927ba14e..a3b90bdb509e5c0c9007b7672a7bf867dabe42fe 100644 (file)
@@ -1133,8 +1133,7 @@ transform_samp(struct tgsi_transform_context *tctx,
 
    /* MOV_SAT tmpA.<mask>, tmpA */
    if (mask) {
-      create_mov(tctx, &ctx->tmp[A].dst, &ctx->tmp[A].src, mask,
-                 TGSI_SAT_ZERO_ONE);
+      create_mov(tctx, &ctx->tmp[A].dst, &ctx->tmp[A].src, mask, 1);
    }
 
    /* modify the texture samp instruction to take fixed up coord: */
index fbfe652e425716397688d063adbd4b52979245d4..be4851f5dcb05b7e4e86da2e500e29633d4344ec 100644 (file)
@@ -58,6 +58,7 @@ struct sanity_check_ctx
    uint errors;
    uint warnings;
    uint implied_array_size;
+   uint implied_out_array_size;
 
    boolean print;
 };
@@ -406,16 +407,30 @@ iter_declaration(
    if (!check_file_name( ctx, file ))
       return TRUE;
    for (i = decl->Range.First; i <= decl->Range.Last; i++) {
-      /* declared TGSI_FILE_INPUT's for geometry processor
+      /* declared TGSI_FILE_INPUT's for geometry and tessellation
        * have an implied second dimension */
-      if (file == TGSI_FILE_INPUT &&
-          ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+      uint processor = ctx->iter.processor.Processor;
+      uint patch = decl->Semantic.Name == TGSI_SEMANTIC_PATCH ||
+         decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER ||
+         decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER;
+      if (file == TGSI_FILE_INPUT && !patch && (
+                processor == TGSI_PROCESSOR_GEOMETRY ||
+                processor == TGSI_PROCESSOR_TESS_CTRL ||
+                processor == TGSI_PROCESSOR_TESS_EVAL)) {
          uint vert;
          for (vert = 0; vert < ctx->implied_array_size; ++vert) {
             scan_register *reg = MALLOC(sizeof(scan_register));
             fill_scan_register2d(reg, file, i, vert);
             check_and_declare(ctx, reg);
          }
+      } else if (file == TGSI_FILE_OUTPUT && !patch &&
+                 processor == TGSI_PROCESSOR_TESS_CTRL) {
+         uint vert;
+         for (vert = 0; vert < ctx->implied_out_array_size; ++vert) {
+            scan_register *reg = MALLOC(sizeof(scan_register));
+            fill_scan_register2d(reg, file, i, vert);
+            check_and_declare(ctx, reg);
+         }
       } else {
          scan_register *reg = MALLOC(sizeof(scan_register));
          if (decl->Declaration.Dimension) {
@@ -474,6 +489,19 @@ iter_property(
        prop->Property.PropertyName == TGSI_PROPERTY_GS_INPUT_PRIM) {
       ctx->implied_array_size = u_vertices_per_prim(prop->u[0].Data);
    }
+   if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL &&
+       prop->Property.PropertyName == TGSI_PROPERTY_TCS_VERTICES_OUT)
+      ctx->implied_out_array_size = prop->u[0].Data;
+   return TRUE;
+}
+
+static boolean
+prolog(struct tgsi_iterate_context *iter)
+{
+   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+   if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
+       iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL)
+      ctx->implied_array_size = 32;
    return TRUE;
 }
 
@@ -532,7 +560,7 @@ tgsi_sanity_check(
 {
    struct sanity_check_ctx ctx;
 
-   ctx.iter.prolog = NULL;
+   ctx.iter.prolog = prolog;
    ctx.iter.iterate_instruction = iter_instruction;
    ctx.iter.iterate_declaration = iter_declaration;
    ctx.iter.iterate_immediate = iter_immediate;
index e6011d2d85a73fec30fb2620e76a42a6e39df2af..7523baf4ce01018eb5b3b045e96fba3082c1bb54 100644 (file)
@@ -62,6 +62,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
       info->file_max[i] = -1;
    for (i = 0; i < Elements(info->const_file_max); i++)
       info->const_file_max[i] = -1;
+   info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = 1;
 
    /**
     ** Setup to begin parsing input shader
@@ -74,6 +75,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
    assert(procType == TGSI_PROCESSOR_FRAGMENT ||
           procType == TGSI_PROCESSOR_VERTEX ||
           procType == TGSI_PROCESSOR_GEOMETRY ||
+          procType == TGSI_PROCESSOR_TESS_CTRL ||
+          procType == TGSI_PROCESSOR_TESS_EVAL ||
           procType == TGSI_PROCESSOR_COMPUTE);
    info->processor = procType;
 
@@ -165,13 +168,31 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                = &parse.FullToken.FullDeclaration;
             const uint file = fulldecl->Declaration.File;
             uint reg;
-            if (fulldecl->Declaration.Array)
-               info->array_max[file] = MAX2(info->array_max[file], fulldecl->Array.ArrayID);
+
+            if (fulldecl->Declaration.Array) {
+               unsigned array_id = fulldecl->Array.ArrayID;
+
+               switch (file) {
+               case TGSI_FILE_INPUT:
+                  assert(array_id < ARRAY_SIZE(info->input_array_first));
+                  info->input_array_first[array_id] = fulldecl->Range.First;
+                  info->input_array_last[array_id] = fulldecl->Range.Last;
+                  break;
+               case TGSI_FILE_OUTPUT:
+                  assert(array_id < ARRAY_SIZE(info->output_array_first));
+                  info->output_array_first[array_id] = fulldecl->Range.First;
+                  info->output_array_last[array_id] = fulldecl->Range.Last;
+                  break;
+               }
+               info->array_max[file] = MAX2(info->array_max[file], array_id);
+            }
+
             for (reg = fulldecl->Range.First;
                  reg <= fulldecl->Range.Last;
                  reg++) {
                unsigned semName = fulldecl->Semantic.Name;
-               unsigned semIndex = fulldecl->Semantic.Index;
+               unsigned semIndex =
+                  fulldecl->Semantic.Index + (reg - fulldecl->Range.First);
 
                /* only first 32 regs will appear in this bitfield */
                info->file_mask[file] |= (1 << reg);
@@ -228,6 +249,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                   }
                   else if (semName == TGSI_SEMANTIC_PRIMID) {
                      info->uses_primid = TRUE;
+                  } else if (semName == TGSI_SEMANTIC_INVOCATIONID) {
+                     info->uses_invocationid = TRUE;
                   }
                }
                else if (file == TGSI_FILE_OUTPUT) {
@@ -236,7 +259,9 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                   info->num_outputs++;
 
                   if (procType == TGSI_PROCESSOR_VERTEX ||
-                      procType == TGSI_PROCESSOR_GEOMETRY) {
+                      procType == TGSI_PROCESSOR_GEOMETRY ||
+                      procType == TGSI_PROCESSOR_TESS_CTRL ||
+                      procType == TGSI_PROCESSOR_TESS_EVAL) {
                      if (semName == TGSI_SEMANTIC_CLIPDIST) {
                         info->num_written_clipdistance +=
                            util_bitcount(fulldecl->Declaration.UsageMask);
index 0ea0e8846be10e601e4e0d95f95e3c9bf48534e7..b81bdd71f143cdd8075da8093eb1ea78e672c159 100644 (file)
@@ -65,6 +65,10 @@ struct tgsi_shader_info
    int file_max[TGSI_FILE_COUNT];  /**< highest index of declared registers */
    int const_file_max[PIPE_MAX_CONSTANT_BUFFERS];
 
+   ubyte input_array_first[PIPE_MAX_SHADER_INPUTS];
+   ubyte input_array_last[PIPE_MAX_SHADER_INPUTS];
+   ubyte output_array_first[PIPE_MAX_SHADER_OUTPUTS];
+   ubyte output_array_last[PIPE_MAX_SHADER_OUTPUTS];
    unsigned array_max[TGSI_FILE_COUNT];  /**< highest index array per register file */
 
    uint immediate_count; /**< number of immediates declared */
@@ -85,6 +89,7 @@ struct tgsi_shader_info
    boolean uses_basevertex;
    boolean uses_primid;
    boolean uses_frontface;
+   boolean uses_invocationid;
    boolean writes_psize;
    boolean writes_clipvertex;
    boolean writes_viewport_index;
index 9b727cf9a8105ab5a82cb8a951dbba45a0e4c99d..6b6a14f55f56cca5e85ce1b61d625dd1d99c917a 100644 (file)
 #include "tgsi_strings.h"
 
 
-const char *tgsi_processor_type_names[4] =
+const char *tgsi_processor_type_names[6] =
 {
    "FRAG",
    "VERT",
    "GEOM",
+   "TESS_CTRL",
+   "TESS_EVAL",
    "COMP"
 };
 
@@ -88,6 +90,11 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] =
    "INVOCATIONID",
    "VERTEXID_NOBASE",
    "BASEVERTEX",
+   "PATCH",
+   "TESSCOORD",
+   "TESSOUTER",
+   "TESSINNER",
+   "VERTICESIN",
 };
 
 const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] =
@@ -124,7 +131,12 @@ const char *tgsi_property_names[TGSI_PROPERTY_COUNT] =
    "FS_DEPTH_LAYOUT",
    "VS_PROHIBIT_UCPS",
    "GS_INVOCATIONS",
-   "VS_WINDOW_SPACE_POSITION"
+   "VS_WINDOW_SPACE_POSITION",
+   "TCS_VERTICES_OUT",
+   "TES_PRIM_MODE",
+   "TES_SPACING",
+   "TES_VERTEX_ORDER_CW",
+   "TES_POINT_MODE",
 };
 
 const char *tgsi_return_type_names[TGSI_RETURN_TYPE_COUNT] =
@@ -166,7 +178,8 @@ const char *tgsi_primitive_names[PIPE_PRIM_MAX] =
    "LINES_ADJACENCY",
    "LINE_STRIP_ADJACENCY",
    "TRIANGLES_ADJACENCY",
-   "TRIANGLE_STRIP_ADJACENCY"
+   "TRIANGLE_STRIP_ADJACENCY",
+   "PATCHES",
 };
 
 const char *tgsi_fs_coord_origin_names[2] =
index 90014a225b06e165edae9c4eaba1a71ee4df3f9c..71e74372f221dc41b605618942985421d4c6390b 100644 (file)
@@ -38,7 +38,7 @@ extern "C" {
 #endif
 
 
-extern const char *tgsi_processor_type_names[4];
+extern const char *tgsi_processor_type_names[6];
 
 extern const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT];
 
index b6b3585d561b06bb857b43ff7e02f27a90f8da5e..a6675c5168df068fdd7fbc21525ee65497ce6380 100644 (file)
@@ -297,6 +297,10 @@ static boolean parse_header( struct translate_ctx *ctx )
       processor = TGSI_PROCESSOR_VERTEX;
    else if (str_match_nocase_whole( &ctx->cur, "GEOM" ))
       processor = TGSI_PROCESSOR_GEOMETRY;
+   else if (str_match_nocase_whole( &ctx->cur, "TESS_CTRL" ))
+      processor = TGSI_PROCESSOR_TESS_CTRL;
+   else if (str_match_nocase_whole( &ctx->cur, "TESS_EVAL" ))
+      processor = TGSI_PROCESSOR_TESS_EVAL;
    else if (str_match_nocase_whole( &ctx->cur, "COMP" ))
       processor = TGSI_PROCESSOR_COMPUTE;
    else {
@@ -903,7 +907,7 @@ match_inst(const char **pcur,
    /* simple case: the whole string matches the instruction name */
    if (str_match_nocase_whole(&cur, info->mnemonic)) {
       *pcur = cur;
-      *saturate = TGSI_SAT_NONE;
+      *saturate = 0;
       return TRUE;
    }
 
@@ -911,13 +915,7 @@ match_inst(const char **pcur,
       /* the instruction has a suffix, figure it out */
       if (str_match_nocase_whole(&cur, "_SAT")) {
          *pcur = cur;
-         *saturate = TGSI_SAT_ZERO_ONE;
-         return TRUE;
-      }
-
-      if (str_match_nocase_whole(&cur, "_SATNV")) {
-         *pcur = cur;
-         *saturate = TGSI_SAT_MINUS_PLUS_ONE;
+         *saturate = 1;
          return TRUE;
       }
    }
@@ -931,7 +929,7 @@ parse_instruction(
    boolean has_label )
 {
    uint i;
-   uint saturate = TGSI_SAT_NONE;
+   uint saturate = 0;
    const struct tgsi_opcode_info *info;
    struct tgsi_full_instruction inst;
    const char *cur;
index 921aa906527e781c256caf37f7622678f1bf9755..39d7688ab3b98399aa9273fd932fd7ba1b7dcc27 100644 (file)
@@ -143,6 +143,27 @@ tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
    ctx->emit_declaration(ctx, &decl);
 }
 
+static INLINE void
+tgsi_transform_sampler_view_decl(struct tgsi_transform_context *ctx,
+                                 unsigned index,
+                                 unsigned target,
+                                 enum tgsi_return_type type)
+{
+   struct tgsi_full_declaration decl;
+
+   decl = tgsi_default_full_declaration();
+   decl.Declaration.File = TGSI_FILE_SAMPLER_VIEW;
+   decl.Declaration.UsageMask = 0xf;
+   decl.Range.First =
+   decl.Range.Last = index;
+   decl.SamplerView.Resource = target;
+   decl.SamplerView.ReturnTypeX = type;
+   decl.SamplerView.ReturnTypeY = type;
+   decl.SamplerView.ReturnTypeZ = type;
+   decl.SamplerView.ReturnTypeW = type;
+
+   ctx->emit_declaration(ctx, &decl);
+}
 
 static INLINE void
 tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
index a4c0fc50c6cdd39fc2bbc1cffb930ef9dafd6e0d..201a849ef95dba2f0cd13fb2bd9020a18b57d3c6 100644 (file)
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 
+#include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "tgsi/tgsi_ureg.h"
@@ -73,7 +74,7 @@ struct ureg_tokens {
    unsigned count;
 };
 
-#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS
+#define UREG_MAX_INPUT PIPE_MAX_SHADER_INPUTS
 #define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS
 #define UREG_MAX_OUTPUT PIPE_MAX_SHADER_OUTPUTS
 #define UREG_MAX_CONSTANT_RANGE 32
@@ -96,7 +97,7 @@ struct const_decl {
 struct ureg_program
 {
    unsigned processor;
-   struct pipe_context *pipe;
+   bool supports_any_inout_decl_range;
 
    struct {
       unsigned semantic_name;
@@ -104,17 +105,13 @@ struct ureg_program
       unsigned interp;
       unsigned char cylindrical_wrap;
       unsigned interp_location;
-   } fs_input[UREG_MAX_INPUT];
-   unsigned nr_fs_inputs;
+      unsigned first;
+      unsigned last;
+      unsigned array_id;
+   } input[UREG_MAX_INPUT];
+   unsigned nr_inputs, nr_input_regs;
 
-   unsigned vs_inputs[UREG_MAX_INPUT/32];
-
-   struct {
-      unsigned index;
-      unsigned semantic_name;
-      unsigned semantic_index;
-   } gs_input[UREG_MAX_INPUT];
-   unsigned nr_gs_inputs;
+   unsigned vs_inputs[PIPE_MAX_ATTRIBS/32];
 
    struct {
       unsigned index;
@@ -127,8 +124,11 @@ struct ureg_program
       unsigned semantic_name;
       unsigned semantic_index;
       unsigned usage_mask; /* = TGSI_WRITEMASK_* */
+      unsigned first;
+      unsigned last;
+      unsigned array_id;
    } output[UREG_MAX_OUTPUT];
-   unsigned nr_outputs;
+   unsigned nr_outputs, nr_output_regs;
 
    struct {
       union {
@@ -254,30 +254,42 @@ ureg_DECL_fs_input_cyl_centroid(struct ureg_program *ureg,
                        unsigned semantic_index,
                        unsigned interp_mode,
                        unsigned cylindrical_wrap,
-                       unsigned interp_location)
+                       unsigned interp_location,
+                       unsigned array_id,
+                       unsigned array_size)
 {
    unsigned i;
 
-   for (i = 0; i < ureg->nr_fs_inputs; i++) {
-      if (ureg->fs_input[i].semantic_name == semantic_name &&
-          ureg->fs_input[i].semantic_index == semantic_index) {
+   for (i = 0; i < ureg->nr_inputs; i++) {
+      if (ureg->input[i].semantic_name == semantic_name &&
+          ureg->input[i].semantic_index == semantic_index) {
+         assert(ureg->input[i].interp == interp_mode);
+         assert(ureg->input[i].cylindrical_wrap == cylindrical_wrap);
+         assert(ureg->input[i].interp_location == interp_location);
+         assert(ureg->input[i].array_id == array_id);
          goto out;
       }
    }
 
-   if (ureg->nr_fs_inputs < UREG_MAX_INPUT) {
-      ureg->fs_input[i].semantic_name = semantic_name;
-      ureg->fs_input[i].semantic_index = semantic_index;
-      ureg->fs_input[i].interp = interp_mode;
-      ureg->fs_input[i].cylindrical_wrap = cylindrical_wrap;
-      ureg->fs_input[i].interp_location = interp_location;
-      ureg->nr_fs_inputs++;
+   if (ureg->nr_inputs < UREG_MAX_INPUT) {
+      assert(array_size >= 1);
+      ureg->input[i].semantic_name = semantic_name;
+      ureg->input[i].semantic_index = semantic_index;
+      ureg->input[i].interp = interp_mode;
+      ureg->input[i].cylindrical_wrap = cylindrical_wrap;
+      ureg->input[i].interp_location = interp_location;
+      ureg->input[i].first = ureg->nr_input_regs;
+      ureg->input[i].last = ureg->nr_input_regs + array_size - 1;
+      ureg->input[i].array_id = array_id;
+      ureg->nr_input_regs += array_size;
+      ureg->nr_inputs++;
    } else {
       set_bad(ureg);
    }
 
 out:
-   return ureg_src_register(TGSI_FILE_INPUT, i);
+   return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first,
+                                  array_id);
 }
 
 
@@ -286,29 +298,22 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
                     unsigned index )
 {
    assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
-   
+   assert(index / 32 < ARRAY_SIZE(ureg->vs_inputs));
+
    ureg->vs_inputs[index/32] |= 1 << (index % 32);
    return ureg_src_register( TGSI_FILE_INPUT, index );
 }
 
 
 struct ureg_src
-ureg_DECL_gs_input(struct ureg_program *ureg,
-                   unsigned index,
-                   unsigned semantic_name,
-                   unsigned semantic_index)
-{
-   if (ureg->nr_gs_inputs < UREG_MAX_INPUT) {
-      ureg->gs_input[ureg->nr_gs_inputs].index = index;
-      ureg->gs_input[ureg->nr_gs_inputs].semantic_name = semantic_name;
-      ureg->gs_input[ureg->nr_gs_inputs].semantic_index = semantic_index;
-      ureg->nr_gs_inputs++;
-   } else {
-      set_bad(ureg);
-   }
-
-   /* XXX: Add suport for true 2D input registers. */
-   return ureg_src_register(TGSI_FILE_INPUT, index);
+ureg_DECL_input(struct ureg_program *ureg,
+                unsigned semantic_name,
+                unsigned semantic_index,
+                unsigned array_id,
+                unsigned array_size)
+{
+   return ureg_DECL_fs_input_cyl_centroid(ureg, semantic_name, semantic_index,
+                                          0, 0, 0, array_id, array_size);
 }
 
 
@@ -332,10 +337,12 @@ ureg_DECL_system_value(struct ureg_program *ureg,
 
 
 struct ureg_dst 
-ureg_DECL_output_masked( struct ureg_program *ureg,
-                         unsigned name,
-                         unsigned index,
-                         unsigned usage_mask )
+ureg_DECL_output_masked(struct ureg_program *ureg,
+                        unsigned name,
+                        unsigned index,
+                        unsigned usage_mask,
+                        unsigned array_id,
+                        unsigned array_size)
 {
    unsigned i;
 
@@ -343,7 +350,8 @@ ureg_DECL_output_masked( struct ureg_program *ureg,
 
    for (i = 0; i < ureg->nr_outputs; i++) {
       if (ureg->output[i].semantic_name == name &&
-          ureg->output[i].semantic_index == index) { 
+          ureg->output[i].semantic_index == index) {
+         assert(ureg->output[i].array_id == array_id);
          ureg->output[i].usage_mask |= usage_mask;
          goto out;
       }
@@ -353,6 +361,10 @@ ureg_DECL_output_masked( struct ureg_program *ureg,
       ureg->output[i].semantic_name = name;
       ureg->output[i].semantic_index = index;
       ureg->output[i].usage_mask = usage_mask;
+      ureg->output[i].first = ureg->nr_output_regs;
+      ureg->output[i].last = ureg->nr_output_regs + array_size - 1;
+      ureg->output[i].array_id = array_id;
+      ureg->nr_output_regs += array_size;
       ureg->nr_outputs++;
    }
    else {
@@ -360,16 +372,30 @@ ureg_DECL_output_masked( struct ureg_program *ureg,
    }
 
 out:
-   return ureg_dst_register( TGSI_FILE_OUTPUT, i );
+   return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first,
+                                  array_id);
 }
 
 
 struct ureg_dst 
-ureg_DECL_output( struct ureg_program *ureg,
-                  unsigned name,
-                  unsigned index )
+ureg_DECL_output(struct ureg_program *ureg,
+                 unsigned name,
+                 unsigned index)
+{
+   return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW,
+                                  0, 1);
+}
+
+struct ureg_dst
+ureg_DECL_output_array(struct ureg_program *ureg,
+                       unsigned semantic_name,
+                       unsigned semantic_index,
+                       unsigned array_id,
+                       unsigned array_size)
 {
-   return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW);
+   return ureg_DECL_output_masked(ureg, semantic_name, semantic_index,
+                                  TGSI_WRITEMASK_XYZW,
+                                  array_id, array_size);
 }
 
 
@@ -882,7 +908,11 @@ ureg_emit_src( struct ureg_program *ureg,
       out[n].ind.File = src.IndirectFile;
       out[n].ind.Swizzle = src.IndirectSwizzle;
       out[n].ind.Index = src.IndirectIndex;
-      out[n].ind.ArrayID = src.ArrayID;
+      if (!ureg->supports_any_inout_decl_range &&
+          (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))
+         out[n].ind.ArrayID = 0;
+      else
+         out[n].ind.ArrayID = src.ArrayID;
       n++;
    }
 
@@ -898,7 +928,11 @@ ureg_emit_src( struct ureg_program *ureg,
          out[n].ind.File = src.DimIndFile;
          out[n].ind.Swizzle = src.DimIndSwizzle;
          out[n].ind.Index = src.DimIndIndex;
-         out[n].ind.ArrayID = src.ArrayID;
+         if (!ureg->supports_any_inout_decl_range &&
+             (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))
+            out[n].ind.ArrayID = 0;
+         else
+            out[n].ind.ArrayID = src.ArrayID;
       } else {
          out[n].dim.Indirect = 0;
          out[n].dim.Index = src.DimensionIndex;
@@ -914,8 +948,8 @@ void
 ureg_emit_dst( struct ureg_program *ureg,
                struct ureg_dst dst )
 {
-   unsigned size = (1 + 
-                    (dst.Indirect ? 1 : 0));
+   unsigned size = 1 + (dst.Indirect ? 1 : 0) +
+                   (dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0);
 
    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
    unsigned n = 0;
@@ -940,7 +974,35 @@ ureg_emit_dst( struct ureg_program *ureg,
       out[n].ind.File = dst.IndirectFile;
       out[n].ind.Swizzle = dst.IndirectSwizzle;
       out[n].ind.Index = dst.IndirectIndex;
-      out[n].ind.ArrayID = dst.ArrayID;
+      if (!ureg->supports_any_inout_decl_range &&
+          (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))
+         out[n].ind.ArrayID = 0;
+      else
+         out[n].ind.ArrayID = dst.ArrayID;
+      n++;
+   }
+
+   if (dst.Dimension) {
+      out[0].dst.Dimension = 1;
+      out[n].dim.Dimension = 0;
+      out[n].dim.Padding = 0;
+      if (dst.DimIndirect) {
+         out[n].dim.Indirect = 1;
+         out[n].dim.Index = dst.DimensionIndex;
+         n++;
+         out[n].value = 0;
+         out[n].ind.File = dst.DimIndFile;
+         out[n].ind.Swizzle = dst.DimIndSwizzle;
+         out[n].ind.Index = dst.DimIndIndex;
+         if (!ureg->supports_any_inout_decl_range &&
+             (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))
+            out[n].ind.ArrayID = 0;
+         else
+            out[n].ind.ArrayID = dst.ArrayID;
+      } else {
+         out[n].dim.Indirect = 0;
+         out[n].dim.Index = dst.DimensionIndex;
+      }
       n++;
    }
 
@@ -1007,6 +1069,12 @@ ureg_emit_insn(struct ureg_program *ureg,
 }
 
 
+/**
+ * Emit a label token.
+ * \param label_token returns a token number indicating where the label
+ * needs to be patched later.  Later, this value should be passed to the
+ * ureg_fixup_label() function.
+ */
 void
 ureg_emit_label(struct ureg_program *ureg,
                 unsigned extended_token,
@@ -1234,12 +1302,14 @@ ureg_label_insn(struct ureg_program *ureg,
 static void
 emit_decl_semantic(struct ureg_program *ureg,
                    unsigned file,
-                   unsigned index,
+                   unsigned first,
+                   unsigned last,
                    unsigned semantic_name,
                    unsigned semantic_index,
-                   unsigned usage_mask)
+                   unsigned usage_mask,
+                   unsigned array_id)
 {
-   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
+   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
 
    out[0].value = 0;
    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
@@ -1247,28 +1317,37 @@ emit_decl_semantic(struct ureg_program *ureg,
    out[0].decl.File = file;
    out[0].decl.UsageMask = usage_mask;
    out[0].decl.Semantic = 1;
+   out[0].decl.Array = array_id != 0;
 
    out[1].value = 0;
-   out[1].decl_range.First = index;
-   out[1].decl_range.Last = index;
+   out[1].decl_range.First = first;
+   out[1].decl_range.Last = last;
 
    out[2].value = 0;
    out[2].decl_semantic.Name = semantic_name;
    out[2].decl_semantic.Index = semantic_index;
+
+   if (array_id) {
+      out[3].value = 0;
+      out[3].array.ArrayID = array_id;
+   }
 }
 
 
 static void
 emit_decl_fs(struct ureg_program *ureg,
              unsigned file,
-             unsigned index,
+             unsigned first,
+             unsigned last,
              unsigned semantic_name,
              unsigned semantic_index,
              unsigned interpolate,
              unsigned cylindrical_wrap,
-             unsigned interpolate_location)
+             unsigned interpolate_location,
+             unsigned array_id)
 {
-   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 4);
+   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL,
+                                          array_id ? 5 : 4);
 
    out[0].value = 0;
    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
@@ -1277,10 +1356,11 @@ emit_decl_fs(struct ureg_program *ureg,
    out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */
    out[0].decl.Interpolate = 1;
    out[0].decl.Semantic = 1;
+   out[0].decl.Array = array_id != 0;
 
    out[1].value = 0;
-   out[1].decl_range.First = index;
-   out[1].decl_range.Last = index;
+   out[1].decl_range.First = first;
+   out[1].decl_range.Last = last;
 
    out[2].value = 0;
    out[2].decl_interp.Interpolate = interpolate;
@@ -1290,6 +1370,11 @@ emit_decl_fs(struct ureg_program *ureg,
    out[3].value = 0;
    out[3].decl_semantic.Name = semantic_name;
    out[3].decl_semantic.Index = semantic_index;
+
+   if (array_id) {
+      out[4].value = 0;
+      out[4].array.ArrayID = array_id;
+   }
 }
 
 static void
@@ -1428,37 +1513,73 @@ emit_property(struct ureg_program *ureg,
 
 static void emit_decls( struct ureg_program *ureg )
 {
-   unsigned i;
+   unsigned i,j;
 
    for (i = 0; i < Elements(ureg->properties); i++)
       if (ureg->properties[i] != ~0)
          emit_property(ureg, i, ureg->properties[i]);
 
    if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
-      for (i = 0; i < UREG_MAX_INPUT; i++) {
+      for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
          if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
             emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
          }
       }
    } else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) {
-      for (i = 0; i < ureg->nr_fs_inputs; i++) {
-         emit_decl_fs(ureg,
-                      TGSI_FILE_INPUT,
-                      i,
-                      ureg->fs_input[i].semantic_name,
-                      ureg->fs_input[i].semantic_index,
-                      ureg->fs_input[i].interp,
-                      ureg->fs_input[i].cylindrical_wrap,
-                      ureg->fs_input[i].interp_location);
+      if (ureg->supports_any_inout_decl_range) {
+         for (i = 0; i < ureg->nr_inputs; i++) {
+            emit_decl_fs(ureg,
+                         TGSI_FILE_INPUT,
+                         ureg->input[i].first,
+                         ureg->input[i].last,
+                         ureg->input[i].semantic_name,
+                         ureg->input[i].semantic_index,
+                         ureg->input[i].interp,
+                         ureg->input[i].cylindrical_wrap,
+                         ureg->input[i].interp_location,
+                         ureg->input[i].array_id);
+         }
       }
-   } else {
-      for (i = 0; i < ureg->nr_gs_inputs; i++) {
-         emit_decl_semantic(ureg,
+      else {
+         for (i = 0; i < ureg->nr_inputs; i++) {
+            for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
+               emit_decl_fs(ureg,
                             TGSI_FILE_INPUT,
-                            ureg->gs_input[i].index,
-                            ureg->gs_input[i].semantic_name,
-                            ureg->gs_input[i].semantic_index,
-                            TGSI_WRITEMASK_XYZW);
+                            j, j,
+                            ureg->input[i].semantic_name,
+                            ureg->input[i].semantic_index +
+                            (j - ureg->input[i].first),
+                            ureg->input[i].interp,
+                            ureg->input[i].cylindrical_wrap,
+                            ureg->input[i].interp_location, 0);
+            }
+         }
+      }
+   } else {
+      if (ureg->supports_any_inout_decl_range) {
+         for (i = 0; i < ureg->nr_inputs; i++) {
+            emit_decl_semantic(ureg,
+                               TGSI_FILE_INPUT,
+                               ureg->input[i].first,
+                               ureg->input[i].last,
+                               ureg->input[i].semantic_name,
+                               ureg->input[i].semantic_index,
+                               TGSI_WRITEMASK_XYZW,
+                               ureg->input[i].array_id);
+         }
+      }
+      else {
+         for (i = 0; i < ureg->nr_inputs; i++) {
+            for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
+               emit_decl_semantic(ureg,
+                                  TGSI_FILE_INPUT,
+                                  j, j,
+                                  ureg->input[i].semantic_name,
+                                  ureg->input[i].semantic_index +
+                                  (j - ureg->input[i].first),
+                                  TGSI_WRITEMASK_XYZW, 0);
+            }
+         }
       }
    }
 
@@ -1466,18 +1587,36 @@ static void emit_decls( struct ureg_program *ureg )
       emit_decl_semantic(ureg,
                          TGSI_FILE_SYSTEM_VALUE,
                          ureg->system_value[i].index,
+                         ureg->system_value[i].index,
                          ureg->system_value[i].semantic_name,
                          ureg->system_value[i].semantic_index,
-                         TGSI_WRITEMASK_XYZW);
+                         TGSI_WRITEMASK_XYZW, 0);
    }
 
-   for (i = 0; i < ureg->nr_outputs; i++) {
-      emit_decl_semantic(ureg,
-                         TGSI_FILE_OUTPUT,
-                         i,
-                         ureg->output[i].semantic_name,
-                         ureg->output[i].semantic_index,
-                         ureg->output[i].usage_mask);
+   if (ureg->supports_any_inout_decl_range) {
+      for (i = 0; i < ureg->nr_outputs; i++) {
+         emit_decl_semantic(ureg,
+                            TGSI_FILE_OUTPUT,
+                            ureg->output[i].first,
+                            ureg->output[i].last,
+                            ureg->output[i].semantic_name,
+                            ureg->output[i].semantic_index,
+                            ureg->output[i].usage_mask,
+                            ureg->output[i].array_id);
+      }
+   }
+   else {
+      for (i = 0; i < ureg->nr_outputs; i++) {
+         for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) {
+            emit_decl_semantic(ureg,
+                               TGSI_FILE_OUTPUT,
+                               j, j,
+                               ureg->output[i].semantic_name,
+                               ureg->output[i].semantic_index +
+                               (j - ureg->output[i].first),
+                               ureg->output[i].usage_mask, 0);
+         }
+      }
    }
 
    for (i = 0; i < ureg->nr_samplers; i++) {
@@ -1647,10 +1786,20 @@ void *ureg_create_shader( struct ureg_program *ureg,
    else
       memset(&state.stream_output, 0, sizeof(state.stream_output));
 
-   if (ureg->processor == TGSI_PROCESSOR_VERTEX)
-      return pipe->create_vs_state( pipe, &state );
-   else
-      return pipe->create_fs_state( pipe, &state );
+   switch (ureg->processor) {
+   case TGSI_PROCESSOR_VERTEX:
+      return pipe->create_vs_state(pipe, &state);
+   case TGSI_PROCESSOR_TESS_CTRL:
+      return pipe->create_tcs_state(pipe, &state);
+   case TGSI_PROCESSOR_TESS_EVAL:
+      return pipe->create_tes_state(pipe, &state);
+   case TGSI_PROCESSOR_GEOMETRY:
+      return pipe->create_gs_state(pipe, &state);
+   case TGSI_PROCESSOR_FRAGMENT:
+      return pipe->create_fs_state(pipe, &state);
+   default:
+      return NULL;
+   }
 }
 
 
@@ -1681,7 +1830,38 @@ void ureg_free_tokens( const struct tgsi_token *tokens )
 }
 
 
-struct ureg_program *ureg_create( unsigned processor )
+static INLINE unsigned
+pipe_shader_from_tgsi_processor(unsigned processor)
+{
+   switch (processor) {
+   case TGSI_PROCESSOR_VERTEX:
+      return PIPE_SHADER_VERTEX;
+   case TGSI_PROCESSOR_TESS_CTRL:
+      return PIPE_SHADER_TESS_CTRL;
+   case TGSI_PROCESSOR_TESS_EVAL:
+      return PIPE_SHADER_TESS_EVAL;
+   case TGSI_PROCESSOR_GEOMETRY:
+      return PIPE_SHADER_GEOMETRY;
+   case TGSI_PROCESSOR_FRAGMENT:
+      return PIPE_SHADER_FRAGMENT;
+   case TGSI_PROCESSOR_COMPUTE:
+      return PIPE_SHADER_COMPUTE;
+   default:
+      assert(0);
+      return PIPE_SHADER_VERTEX;
+   }
+}
+
+
+struct ureg_program *
+ureg_create(unsigned processor)
+{
+   return ureg_create_with_screen(processor, NULL);
+}
+
+
+struct ureg_program *
+ureg_create_with_screen(unsigned processor, struct pipe_screen *screen)
 {
    int i;
    struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
@@ -1689,6 +1869,11 @@ struct ureg_program *ureg_create( unsigned processor )
       goto no_ureg;
 
    ureg->processor = processor;
+   ureg->supports_any_inout_decl_range =
+      screen &&
+      screen->get_shader_param(screen,
+                               pipe_shader_from_tgsi_processor(processor),
+                               PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0;
 
    for (i = 0; i < Elements(ureg->properties); i++)
       ureg->properties[i] = ~0;
index 8a2ed0a61d7a47e0c8942837ef5225c175d48089..1891b0687740117624920c017a81a9ea81e1e660 100644 (file)
@@ -36,6 +36,7 @@
 extern "C" {
 #endif
    
+struct pipe_screen;
 struct ureg_program;
 struct pipe_stream_output_info;
 
@@ -75,6 +76,8 @@ struct ureg_dst
    unsigned File            : 4;  /* TGSI_FILE_ */
    unsigned WriteMask       : 4;  /* TGSI_WRITEMASK_ */
    unsigned Indirect        : 1;  /* BOOL */
+   unsigned DimIndirect     : 1;  /* BOOL */
+   unsigned Dimension       : 1;  /* BOOL */
    unsigned Saturate        : 1;  /* BOOL */
    unsigned Predicate       : 1;
    unsigned PredNegate      : 1;  /* BOOL */
@@ -86,13 +89,20 @@ struct ureg_dst
    int      IndirectIndex   : 16; /* SINT */
    unsigned IndirectFile    : 4;  /* TGSI_FILE_ */
    int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
+   unsigned DimIndFile      : 4;  /* TGSI_FILE_ */
+   unsigned DimIndSwizzle   : 2;  /* TGSI_SWIZZLE_ */
+   int      DimensionIndex  : 16; /* SINT */
+   int      DimIndIndex     : 16; /* SINT */
    unsigned ArrayID         : 10; /* UINT */
 };
 
 struct pipe_context;
 
 struct ureg_program *
-ureg_create( unsigned processor );
+ureg_create(unsigned processor);
+
+struct ureg_program *
+ureg_create_with_screen(unsigned processor, struct pipe_screen *screen);
 
 const struct tgsi_token *
 ureg_finalize( struct ureg_program * );
@@ -166,7 +176,9 @@ ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,
                        unsigned semantic_index,
                        unsigned interp_mode,
                        unsigned cylindrical_wrap,
-                       unsigned interp_location);
+                       unsigned interp_location,
+                       unsigned array_id,
+                       unsigned array_size);
 
 static INLINE struct ureg_src
 ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
@@ -180,7 +192,7 @@ ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
                                  semantic_index,
                                  interp_mode,
                                  cylindrical_wrap,
-                                 0);
+                                 0, 0, 1);
 }
 
 static INLINE struct ureg_src
@@ -193,7 +205,7 @@ ureg_DECL_fs_input(struct ureg_program *ureg,
                                  semantic_name,
                                  semantic_index,
                                  interp_mode,
-                                 0, 0);
+                                 0, 0, 0, 1);
 }
 
 struct ureg_src
@@ -201,10 +213,11 @@ ureg_DECL_vs_input( struct ureg_program *,
                     unsigned index );
 
 struct ureg_src
-ureg_DECL_gs_input(struct ureg_program *,
-                   unsigned index,
-                   unsigned semantic_name,
-                   unsigned semantic_index);
+ureg_DECL_input(struct ureg_program *,
+                unsigned semantic_name,
+                unsigned semantic_index,
+                unsigned array_id,
+                unsigned array_size);
 
 struct ureg_src
 ureg_DECL_system_value(struct ureg_program *,
@@ -213,15 +226,24 @@ ureg_DECL_system_value(struct ureg_program *,
                        unsigned semantic_index);
 
 struct ureg_dst
-ureg_DECL_output_masked( struct ureg_program *,
-                         unsigned semantic_name,
-                         unsigned semantic_index,
-                         unsigned usage_mask );
+ureg_DECL_output_masked(struct ureg_program *,
+                        unsigned semantic_name,
+                        unsigned semantic_index,
+                        unsigned usage_mask,
+                        unsigned array_id,
+                        unsigned array_size);
 
 struct ureg_dst
-ureg_DECL_output( struct ureg_program *,
-                  unsigned semantic_name,
-                  unsigned semantic_index );
+ureg_DECL_output(struct ureg_program *,
+                 unsigned semantic_name,
+                 unsigned semantic_index);
+
+struct ureg_dst
+ureg_DECL_output_array(struct ureg_program *ureg,
+                       unsigned semantic_name,
+                       unsigned semantic_index,
+                       unsigned array_id,
+                       unsigned array_size);
 
 struct ureg_src
 ureg_DECL_immediate( struct ureg_program *,
@@ -1108,6 +1130,16 @@ ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
    return reg;
 }
 
+static INLINE struct ureg_dst
+ureg_dst_dimension( struct ureg_dst reg, int index )
+{
+   assert(reg.File != TGSI_FILE_NULL);
+   reg.Dimension = 1;
+   reg.DimIndirect = 0;
+   reg.DimensionIndex = index;
+   return reg;
+}
+
 static INLINE struct ureg_src
 ureg_src_dimension( struct ureg_src reg, int index )
 {
@@ -1118,6 +1150,19 @@ ureg_src_dimension( struct ureg_src reg, int index )
    return reg;
 }
 
+static INLINE struct ureg_dst
+ureg_dst_dimension_indirect( struct ureg_dst reg, struct ureg_src addr,
+                             int index )
+{
+   assert(reg.File != TGSI_FILE_NULL);
+   reg.Dimension = 1;
+   reg.DimIndirect = 1;
+   reg.DimensionIndex = index;
+   reg.DimIndFile = addr.File;
+   reg.DimIndIndex = addr.Index;
+   reg.DimIndSwizzle = addr.SwizzleX;
+   return reg;
+}
 
 static INLINE struct ureg_src
 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
@@ -1133,17 +1178,24 @@ ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
    return reg;
 }
 
+static INLINE struct ureg_src
+ureg_src_array_offset(struct ureg_src reg, int offset)
+{
+   reg.Index += offset;
+   return reg;
+}
+
 static INLINE struct ureg_dst
 ureg_dst_array_offset( struct ureg_dst reg, int offset )
 {
-   assert(reg.File == TGSI_FILE_TEMPORARY);
    reg.Index += offset;
    return reg;
 }
 
 static INLINE struct ureg_dst
-ureg_dst_register( unsigned file,
-                   unsigned index )
+ureg_dst_array_register(unsigned file,
+                        unsigned index,
+                        unsigned array_id)
 {
    struct ureg_dst dst;
 
@@ -1161,11 +1213,24 @@ ureg_dst_register( unsigned file,
    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
    dst.PredSwizzleW = TGSI_SWIZZLE_W;
    dst.Index     = index;
-   dst.ArrayID = 0;
+   dst.Dimension = 0;
+   dst.DimensionIndex = 0;
+   dst.DimIndirect = 0;
+   dst.DimIndFile = TGSI_FILE_NULL;
+   dst.DimIndIndex = 0;
+   dst.DimIndSwizzle = 0;
+   dst.ArrayID = array_id;
 
    return dst;
 }
 
+static INLINE struct ureg_dst
+ureg_dst_register(unsigned file,
+                  unsigned index)
+{
+   return ureg_dst_array_register(file, index, 0);
+}
+
 static INLINE struct ureg_dst
 ureg_dst( struct ureg_src src )
 {
@@ -1189,14 +1254,21 @@ ureg_dst( struct ureg_src src )
    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
    dst.PredSwizzleW = TGSI_SWIZZLE_W;
    dst.Index     = src.Index;
+   dst.Dimension = src.Dimension;
+   dst.DimensionIndex = src.DimensionIndex;
+   dst.DimIndirect = src.DimIndirect;
+   dst.DimIndFile = src.DimIndFile;
+   dst.DimIndIndex = src.DimIndIndex;
+   dst.DimIndSwizzle = src.DimIndSwizzle;
    dst.ArrayID = src.ArrayID;
 
    return dst;
 }
 
 static INLINE struct ureg_src
-ureg_src_register(unsigned file,
-                  unsigned index)
+ureg_src_array_register(unsigned file,
+                        unsigned index,
+                        unsigned array_id)
 {
    struct ureg_src src;
 
@@ -1218,11 +1290,18 @@ ureg_src_register(unsigned file,
    src.DimIndFile = TGSI_FILE_NULL;
    src.DimIndIndex = 0;
    src.DimIndSwizzle = 0;
-   src.ArrayID = 0;
+   src.ArrayID = array_id;
 
    return src;
 }
 
+static INLINE struct ureg_src
+ureg_src_register(unsigned file,
+                  unsigned index)
+{
+   return ureg_src_array_register(file, index, 0);
+}
+
 static INLINE struct ureg_src
 ureg_src( struct ureg_dst dst )
 {
@@ -1240,12 +1319,12 @@ ureg_src( struct ureg_dst dst )
    src.Absolute  = 0;
    src.Index     = dst.Index;
    src.Negate    = 0;
-   src.Dimension = 0;
-   src.DimensionIndex = 0;
-   src.DimIndirect = 0;
-   src.DimIndFile = TGSI_FILE_NULL;
-   src.DimIndIndex = 0;
-   src.DimIndSwizzle = 0;
+   src.Dimension = dst.Dimension;
+   src.DimensionIndex = dst.DimensionIndex;
+   src.DimIndirect = dst.DimIndirect;
+   src.DimIndFile = dst.DimIndFile;
+   src.DimIndIndex = dst.DimIndIndex;
+   src.DimIndSwizzle = dst.DimIndSwizzle;
    src.ArrayID = dst.ArrayID;
 
    return src;
@@ -1272,6 +1351,12 @@ ureg_dst_undef( void )
    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
    dst.PredSwizzleW = TGSI_SWIZZLE_W;
    dst.Index     = 0;
+   dst.Dimension = 0;
+   dst.DimensionIndex = 0;
+   dst.DimIndirect = 0;
+   dst.DimIndFile = TGSI_FILE_NULL;
+   dst.DimIndIndex = 0;
+   dst.DimIndSwizzle = 0;
    dst.ArrayID = 0;
 
    return dst;
index 90408ffdcc6b4ad1f58ce5ab05c88e70b5f78a7b..e3f30557a03d097e1d9f982fc3e1a0390ff6d550 100644 (file)
@@ -65,7 +65,7 @@ struct blit_state
    struct pipe_vertex_element velem[2];
 
    void *vs;
-   void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1];
+   void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1][3];
 
    struct pipe_resource *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -135,15 +135,17 @@ void
 util_destroy_blit(struct blit_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
-   unsigned i, j;
+   unsigned i, j, k;
 
    if (ctx->vs)
       pipe->delete_vs_state(pipe, ctx->vs);
 
    for (i = 0; i < Elements(ctx->fs); i++) {
       for (j = 0; j < Elements(ctx->fs[i]); j++) {
-         if (ctx->fs[i][j])
-            pipe->delete_fs_state(pipe, ctx->fs[i][j]);
+         for (k = 0; k < Elements(ctx->fs[i][j]); k++) {
+            if (ctx->fs[i][j][k])
+               pipe->delete_fs_state(pipe, ctx->fs[i][j][k]);
+         }
       }
    }
 
@@ -158,18 +160,34 @@ util_destroy_blit(struct blit_state *ctx)
  */
 static INLINE void
 set_fragment_shader(struct blit_state *ctx, uint writemask,
+                    enum pipe_format format,
                     enum pipe_texture_target pipe_tex)
 {
-   if (!ctx->fs[pipe_tex][writemask]) {
+   enum tgsi_return_type stype;
+   unsigned idx;
+
+   if (util_format_is_pure_uint(format)) {
+      stype = TGSI_RETURN_TYPE_UINT;
+      idx = 0;
+   } else if (util_format_is_pure_sint(format)) {
+      stype = TGSI_RETURN_TYPE_SINT;
+      idx = 1;
+   } else {
+      stype = TGSI_RETURN_TYPE_FLOAT;
+      idx = 2;
+   }
+
+   if (!ctx->fs[pipe_tex][writemask][idx]) {
       unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
 
-      ctx->fs[pipe_tex][writemask] =
+      ctx->fs[pipe_tex][writemask][idx] =
          util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex,
                                                  TGSI_INTERPOLATE_LINEAR,
-                                                 writemask);
+                                                 writemask,
+                                                 stype);
    }
 
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]);
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask][idx]);
 }
 
 
@@ -535,6 +553,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
+   cso_save_tessctrl_shader(ctx->cso);
+   cso_save_tesseval_shader(ctx->cso);
    cso_save_geometry_shader(ctx->cso);
    cso_save_vertex_elements(ctx->cso);
    cso_save_aux_vertex_buffer_slot(ctx->cso);
@@ -569,8 +589,11 @@ util_blit_pixels_tex(struct blit_state *ctx,
 
    /* shaders */
    set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
+                       src_sampler_view->format,
                        src_sampler_view->texture->target);
    set_vertex_shader(ctx);
+   cso_set_tessctrl_shader_handle(ctx->cso, NULL);
+   cso_set_tesseval_shader_handle(ctx->cso, NULL);
    cso_set_geometry_shader_handle(ctx->cso, NULL);
 
    /* drawing dest */
@@ -611,6 +634,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
+   cso_restore_tessctrl_shader(ctx->cso);
+   cso_restore_tesseval_shader(ctx->cso);
    cso_restore_geometry_shader(ctx->cso);
    cso_restore_vertex_elements(ctx->cso);
    cso_restore_aux_vertex_buffer_slot(ctx->cso);
index 9d087fe8a66fc9068b5c93a77e50d097e4635a56..b5ef9a23966e0dd05f737f0ea949bfce3085b0f3 100644 (file)
@@ -81,6 +81,8 @@ struct blitter_context_priv
    /* FS which outputs a color from a texture,
       where the index is PIPE_TEXTURE_* to be sampled. */
    void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
+   void *fs_texfetch_col_uint[PIPE_MAX_TEXTURE_TYPES];
+   void *fs_texfetch_col_sint[PIPE_MAX_TEXTURE_TYPES];
 
    /* FS which outputs a depth from a texture,
       where the index is PIPE_TEXTURE_* to be sampled. */
@@ -90,6 +92,8 @@ struct blitter_context_priv
 
    /* FS which outputs one sample from a multisample texture. */
    void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES];
+   void *fs_texfetch_col_msaa_uint[PIPE_MAX_TEXTURE_TYPES];
+   void *fs_texfetch_col_msaa_sint[PIPE_MAX_TEXTURE_TYPES];
    void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
    void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES];
    void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
@@ -130,6 +134,7 @@ struct blitter_context_priv
    unsigned dst_height;
 
    boolean has_geometry_shader;
+   boolean has_tessellation;
    boolean has_layered;
    boolean has_stream_out;
    boolean has_stencil_export;
@@ -183,6 +188,11 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    ctx->has_geometry_shader =
       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
                                      PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
+
+   ctx->has_tessellation =
+      pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
+                                     PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
+
    ctx->has_stream_out =
       pipe->screen->get_param(pipe->screen,
                               PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
@@ -432,6 +442,10 @@ void util_blitter_destroy(struct blitter_context *blitter)
    for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
       if (ctx->fs_texfetch_col[i])
          ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
+      if (ctx->fs_texfetch_col_sint[i])
+         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_sint[i]);
+      if (ctx->fs_texfetch_col_uint[i])
+         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_uint[i]);
       if (ctx->fs_texfetch_depth[i])
          ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
       if (ctx->fs_texfetch_depthstencil[i])
@@ -441,6 +455,10 @@ void util_blitter_destroy(struct blitter_context *blitter)
 
       if (ctx->fs_texfetch_col_msaa[i])
          ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[i]);
+      if (ctx->fs_texfetch_col_msaa_sint[i])
+         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa_sint[i]);
+      if (ctx->fs_texfetch_col_msaa_uint[i])
+         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa_uint[i]);
       if (ctx->fs_texfetch_depth_msaa[i])
          ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i]);
       if (ctx->fs_texfetch_depthstencil_msaa[i])
@@ -510,6 +528,8 @@ static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
    assert(ctx->base.saved_velem_state != INVALID_PTR);
    assert(ctx->base.saved_vs != INVALID_PTR);
    assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
+   assert(!ctx->has_tessellation || ctx->base.saved_tcs != INVALID_PTR);
+   assert(!ctx->has_tessellation || ctx->base.saved_tes != INVALID_PTR);
    assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0);
    assert(ctx->base.saved_rs_state != INVALID_PTR);
 }
@@ -538,6 +558,13 @@ static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
       ctx->base.saved_gs = INVALID_PTR;
    }
 
+   if (ctx->has_tessellation) {
+      pipe->bind_tcs_state(pipe, ctx->base.saved_tcs);
+      pipe->bind_tes_state(pipe, ctx->base.saved_tes);
+      ctx->base.saved_tcs = INVALID_PTR;
+      ctx->base.saved_tes = INVALID_PTR;
+   }
+
    /* Stream outputs. */
    if (ctx->has_stream_out) {
       unsigned offsets[PIPE_MAX_SO_BUFFERS];
@@ -829,25 +856,29 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
 {
    struct pipe_context *pipe = ctx->base.pipe;
    unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
+   enum tgsi_return_type stype;
 
    assert(target < PIPE_MAX_TEXTURE_TYPES);
 
+   if (util_format_is_pure_uint(format))
+      stype = TGSI_RETURN_TYPE_UINT;
+   else if (util_format_is_pure_sint(format))
+      stype = TGSI_RETURN_TYPE_SINT;
+   else
+      stype = TGSI_RETURN_TYPE_FLOAT;
+
    if (src_nr_samples > 1) {
       void **shader;
 
       if (dst_nr_samples <= 1) {
          /* The destination has one sample, so we'll do color resolve. */
-         boolean is_uint, is_sint;
          unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
 
-         is_uint = util_format_is_pure_uint(format);
-         is_sint = util_format_is_pure_sint(format);
-
          assert(filter < 2);
 
-         if (is_uint)
+         if (stype == TGSI_RETURN_TYPE_UINT)
             shader = &ctx->fs_resolve_uint[target][index][filter];
-         else if (is_sint)
+         else if (stype == TGSI_RETURN_TYPE_SINT)
             shader = &ctx->fs_resolve_sint[target][index][filter];
          else
             shader = &ctx->fs_resolve[target][index][filter];
@@ -857,12 +888,12 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
             if (filter == PIPE_TEX_FILTER_LINEAR) {
                *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
                                                    src_nr_samples,
-                                                   is_uint, is_sint);
+                                                   stype);
             }
             else {
                *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
                                                    src_nr_samples,
-                                                   is_uint, is_sint);
+                                                   stype);
             }
          }
       }
@@ -870,24 +901,37 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
          /* The destination has multiple samples, we'll do
           * an MSAA->MSAA copy.
           */
-         shader = &ctx->fs_texfetch_col_msaa[target];
+          if (stype == TGSI_RETURN_TYPE_UINT)
+             shader = &ctx->fs_texfetch_col_msaa_uint[target];
+          else if (stype == TGSI_RETURN_TYPE_SINT)
+             shader = &ctx->fs_texfetch_col_msaa_sint[target];
+          else
+             shader = &ctx->fs_texfetch_col_msaa[target];
 
          /* Create the fragment shader on-demand. */
          if (!*shader) {
             assert(!ctx->cached_all_shaders);
-            *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex);
+            *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype);
          }
       }
 
       return *shader;
    } else {
-      void **shader = &ctx->fs_texfetch_col[target];
+      void **shader;
+
+      if (stype == TGSI_RETURN_TYPE_UINT)
+         shader = &ctx->fs_texfetch_col_uint[target];
+      else if (stype == TGSI_RETURN_TYPE_SINT)
+         shader = &ctx->fs_texfetch_col_sint[target];
+      else
+         shader = &ctx->fs_texfetch_col[target];
 
       /* Create the fragment shader on-demand. */
       if (!*shader) {
          assert(!ctx->cached_all_shaders);
          *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
-                                                 TGSI_INTERPOLATE_LINEAR);
+                                                 TGSI_INTERPOLATE_LINEAR,
+                                                 stype);
       }
 
       return *shader;
@@ -1051,6 +1095,10 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter)
           */
          blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, target,
                                      samples, samples, 0);
+         blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, target,
+                                     samples, samples, 0);
+         blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, target,
+                                     samples, samples, 0);
          blitter_get_fs_texfetch_depth(ctx, target, samples);
          if (ctx->has_stencil_export) {
             blitter_get_fs_texfetch_depthstencil(ctx, target, samples);
@@ -1108,6 +1156,10 @@ static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
 
    if (ctx->has_geometry_shader)
       pipe->bind_gs_state(pipe, NULL);
+   if (ctx->has_tessellation) {
+      pipe->bind_tcs_state(pipe, NULL);
+      pipe->bind_tes_state(pipe, NULL);
+   }
    if (ctx->has_stream_out)
       pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
 }
@@ -1306,6 +1358,7 @@ void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
                                       unsigned srclevel)
 {
     memset(src_templ, 0, sizeof(*src_templ));
+    src_templ->target = src->target;
     src_templ->format = util_format_linear(src->format);
     src_templ->u.tex.first_level = srclevel;
     src_templ->u.tex.last_level = srclevel;
@@ -1966,6 +2019,10 @@ void util_blitter_copy_buffer(struct blitter_context *blitter,
    bind_vs_pos_only(ctx);
    if (ctx->has_geometry_shader)
       pipe->bind_gs_state(pipe, NULL);
+   if (ctx->has_tessellation) {
+      pipe->bind_tcs_state(pipe, NULL);
+      pipe->bind_tes_state(pipe, NULL);
+   }
    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
 
    so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
@@ -2026,6 +2083,10 @@ void util_blitter_clear_buffer(struct blitter_context *blitter,
    bind_vs_pos_only(ctx);
    if (ctx->has_geometry_shader)
       pipe->bind_gs_state(pipe, NULL);
+   if (ctx->has_tessellation) {
+      pipe->bind_tcs_state(pipe, NULL);
+      pipe->bind_tes_state(pipe, NULL);
+   }
    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
 
    so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
index 1568030acfaec23bcc14b80fbef9c7f6dc32510d..93b0e513bd08b45593e46f8b1bbbe7a4f528aa04 100644 (file)
@@ -102,7 +102,7 @@ struct blitter_context
    void *saved_dsa_state;     /**< depth stencil alpha state */
    void *saved_velem_state;   /**< vertex elements state */
    void *saved_rs_state;      /**< rasterizer state */
-   void *saved_fs, *saved_vs, *saved_gs; /**< shaders */
+   void *saved_fs, *saved_vs, *saved_gs, *saved_tcs, *saved_tes; /**< shaders */
 
    struct pipe_framebuffer_state saved_fb_state;  /**< framebuffer state */
    struct pipe_stencil_ref saved_stencil_ref;     /**< stencil ref */
@@ -427,6 +427,20 @@ void util_blitter_save_geometry_shader(struct blitter_context *blitter,
    blitter->saved_gs = gs;
 }
 
+static INLINE void
+util_blitter_save_tessctrl_shader(struct blitter_context *blitter,
+                                  void *sh)
+{
+   blitter->saved_tcs = sh;
+}
+
+static INLINE void
+util_blitter_save_tesseval_shader(struct blitter_context *blitter,
+                                  void *sh)
+{
+   blitter->saved_tes = sh;
+}
+
 static INLINE
 void util_blitter_save_framebuffer(struct blitter_context *blitter,
                                    const struct pipe_framebuffer_state *state)
index e6614d5d22c9e6726ae68c049295f54a373b84be..7f620b50cf056b33befa1b9c0ce00e65e163c15c 100644 (file)
@@ -750,6 +750,8 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
    util_dump_member(stream, uint, state, start_instance);
    util_dump_member(stream, uint, state, instance_count);
 
+   util_dump_member(stream, uint, state, vertices_per_patch);
+
    util_dump_member(stream, int,  state, index_bias);
    util_dump_member(stream, uint, state, min_index);
    util_dump_member(stream, uint, state, max_index);
index f909b16081a37ddeb3417dd56f91dad0644a8d7c..63e03ff5cc2b22adf77469b7f8595bee4460f9cf 100644 (file)
@@ -65,11 +65,10 @@ util_format_etc1_rgb8_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, con
 void
 util_format_etc1_rgb8_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
 {
-   const unsigned bw = 4, bh = 4;
    struct etc1_block block;
    uint8_t tmp[3];
 
-   assert(i < bw && j < bh);
+   assert(i < 4 && j < 4); /* check i, j against 4x4 block size */
 
    etc1_parse_block(&block, src);
    etc1_fetch_texel(&block, i, j, tmp);
index 3d27a59e8c0bf579528cdb1e58a6825e24895cc9..3b4040f0ee2685090fc126d152f28938be5d224c 100644 (file)
@@ -42,6 +42,7 @@
 #include "pipe/p_compiler.h"
 
 #include "c99_math.h"
+#include <assert.h>
 #include <float.h>
 #include <stdarg.h>
 
@@ -423,6 +424,25 @@ util_last_bit(unsigned u)
 #endif
 }
 
+/**
+ * Find last bit set in a word.  The least significant bit is 1.
+ * Return 0 if no bits are set.
+ */
+static INLINE unsigned
+util_last_bit64(uint64_t u)
+{
+#if defined(HAVE___BUILTIN_CLZLL)
+   return u == 0 ? 0 : 64 - __builtin_clzll(u);
+#else
+   unsigned r = 0;
+   while (u) {
+       r++;
+       u >>= 1;
+   }
+   return r;
+#endif
+}
+
 /**
  * Find last bit in a word that does not match the sign bit. The least
  * significant bit is 1.
index 0a20bdb474714d49982747531d77656dc91d74af..1f65672221fc3ea9ecbb451f87670765a67bf29b 100644 (file)
@@ -55,7 +55,7 @@
 #include "tgsi/tgsi_scan.h"
 
 /** Approx number of new tokens for instructions in pstip_transform_inst() */
-#define NUM_NEW_TOKENS 50
+#define NUM_NEW_TOKENS 53
 
 
 static void
@@ -262,6 +262,7 @@ pstip_transform_prolog(struct tgsi_transform_context *ctx)
       (struct pstip_transform_context *) ctx;
    int wincoordInput;
    int texTemp;
+   int sampIdx;
 
    /* find free texture sampler */
    pctx->freeSampler = free_bit(pctx->samplersUsed);
@@ -280,9 +281,21 @@ pstip_transform_prolog(struct tgsi_transform_context *ctx)
                                 TGSI_INTERPOLATE_LINEAR);
    }
 
+   sampIdx = pctx->hasFixedUnit ? pctx->fixedUnit : pctx->freeSampler;
+
    /* declare new sampler */
-   tgsi_transform_sampler_decl(ctx,
-         pctx->hasFixedUnit ? pctx->fixedUnit : pctx->freeSampler);
+   tgsi_transform_sampler_decl(ctx, sampIdx);
+
+   /* if the src shader has SVIEW decl's for each SAMP decl, we
+    * need to continue the trend and ensure there is a matching
+    * SVIEW for the new SAMP we just created
+    */
+   if (pctx->info.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) {
+      tgsi_transform_sampler_view_decl(ctx,
+                                       sampIdx,
+                                       TGSI_TEXTURE_2D,
+                                       TGSI_RETURN_TYPE_FLOAT);
+   }
 
    /* Declare temp[0] reg if not already declared.
     * We can always use temp[0] since this code is before
@@ -321,8 +334,7 @@ pstip_transform_prolog(struct tgsi_transform_context *ctx)
    tgsi_transform_tex_2d_inst(ctx,
                               TGSI_FILE_TEMPORARY, texTemp,
                               TGSI_FILE_TEMPORARY, texTemp,
-                              pctx->hasFixedUnit ? pctx->fixedUnit
-                                                 : pctx->freeSampler);
+                              sampIdx);
 
    /* KILL_IF -texTemp;   # if -texTemp < 0, kill fragment */
    tgsi_transform_kill_inst(ctx,
index c612b67e284a5fb661133551120d34cd200a0f9a..6d29cab9207df85f1264990ab85edcf30d1f3e16 100644 (file)
@@ -216,7 +216,8 @@ void *
 util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
                                         unsigned tex_target,
                                         unsigned interp_mode,
-                                        unsigned writemask )
+                                        unsigned writemask,
+                                        enum tgsi_return_type stype)
 {
    struct ureg_program *ureg;
    struct ureg_src sampler;
@@ -232,6 +233,8 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
    
    sampler = ureg_DECL_sampler( ureg, 0 );
 
+   ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype);
+
    tex = ureg_DECL_fs_input( ureg, 
                              TGSI_SEMANTIC_GENERIC, 0, 
                              interp_mode );
@@ -268,12 +271,14 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
  */
 void *
 util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
-                              unsigned interp_mode)
+                              unsigned interp_mode,
+                              enum tgsi_return_type stype)
 {
    return util_make_fragment_tex_shader_writemask( pipe,
                                                    tex_target,
                                                    interp_mode,
-                                                   TGSI_WRITEMASK_XYZW );
+                                                   TGSI_WRITEMASK_XYZW,
+                                                   stype );
 }
 
 
@@ -298,6 +303,12 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
 
    sampler = ureg_DECL_sampler( ureg, 0 );
 
+   ureg_DECL_sampler_view(ureg, 0, tex_target,
+                          TGSI_RETURN_TYPE_FLOAT,
+                          TGSI_RETURN_TYPE_FLOAT,
+                          TGSI_RETURN_TYPE_FLOAT,
+                          TGSI_RETURN_TYPE_FLOAT);
+
    tex = ureg_DECL_fs_input( ureg,
                              TGSI_SEMANTIC_GENERIC, 0,
                              interp_mode );
@@ -343,7 +354,17 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
       return NULL;
 
    depth_sampler = ureg_DECL_sampler( ureg, 0 );
+   ureg_DECL_sampler_view(ureg, 0, tex_target,
+                          TGSI_RETURN_TYPE_FLOAT,
+                          TGSI_RETURN_TYPE_FLOAT,
+                          TGSI_RETURN_TYPE_FLOAT,
+                          TGSI_RETURN_TYPE_FLOAT);
    stencil_sampler = ureg_DECL_sampler( ureg, 1 );
+   ureg_DECL_sampler_view(ureg, 0, tex_target,
+                          TGSI_RETURN_TYPE_UINT,
+                          TGSI_RETURN_TYPE_UINT,
+                          TGSI_RETURN_TYPE_UINT,
+                          TGSI_RETURN_TYPE_UINT);
 
    tex = ureg_DECL_fs_input( ureg,
                              TGSI_SEMANTIC_GENERIC, 0,
@@ -398,6 +419,12 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
 
    stencil_sampler = ureg_DECL_sampler( ureg, 0 );
 
+   ureg_DECL_sampler_view(ureg, 0, tex_target,
+                          TGSI_RETURN_TYPE_UINT,
+                          TGSI_RETURN_TYPE_UINT,
+                          TGSI_RETURN_TYPE_UINT,
+                          TGSI_RETURN_TYPE_UINT);
+
    tex = ureg_DECL_fs_input( ureg,
                              TGSI_SEMANTIC_GENERIC, 0,
                              interp_mode );
@@ -512,6 +539,7 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
 static void *
 util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
                            unsigned tgsi_tex,
+                           const char *samp_type,
                            const char *output_semantic,
                            const char *output_mask)
 {
@@ -519,6 +547,7 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
          "FRAG\n"
          "DCL IN[0], GENERIC[0], LINEAR\n"
          "DCL SAMP[0]\n"
+         "DCL SVIEW[0], %s, %s\n"
          "DCL OUT[0], %s\n"
          "DCL TEMP[0]\n"
 
@@ -534,7 +563,8 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
    assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
           tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);
 
-   sprintf(text, shader_templ, output_semantic, output_mask, type);
+   sprintf(text, shader_templ, type, samp_type,
+           output_semantic, output_mask, type);
 
    if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
       puts(text);
@@ -556,9 +586,19 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
  */
 void *
 util_make_fs_blit_msaa_color(struct pipe_context *pipe,
-                             unsigned tgsi_tex)
+                             unsigned tgsi_tex,
+                             enum tgsi_return_type stype)
 {
-   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex,
+   const char *samp_type;
+
+   if (stype == TGSI_RETURN_TYPE_UINT)
+      samp_type = "UINT";
+   else if (stype == TGSI_RETURN_TYPE_SINT)
+      samp_type = "SINT";
+   else
+      samp_type = "FLOAT";
+
+   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, samp_type,
                                      "COLOR[0]", "");
 }
 
@@ -572,7 +612,7 @@ void *
 util_make_fs_blit_msaa_depth(struct pipe_context *pipe,
                              unsigned tgsi_tex)
 {
-   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex,
+   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "FLOAT",
                                      "POSITION", ".z");
 }
 
@@ -586,7 +626,7 @@ void *
 util_make_fs_blit_msaa_stencil(struct pipe_context *pipe,
                                unsigned tgsi_tex)
 {
-   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex,
+   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "UINT",
                                      "STENCIL", ".y");
 }
 
@@ -640,7 +680,7 @@ util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe,
 void *
 util_make_fs_msaa_resolve(struct pipe_context *pipe,
                           unsigned tgsi_tex, unsigned nr_samples,
-                          boolean is_uint, boolean is_sint)
+                          enum tgsi_return_type stype)
 {
    struct ureg_program *ureg;
    struct ureg_src sampler, coord;
@@ -653,6 +693,7 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
 
    /* Declarations. */
    sampler = ureg_DECL_sampler(ureg, 0);
+   ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype);
    coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
                               TGSI_INTERPOLATE_LINEAR);
    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
@@ -670,9 +711,9 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
                ureg_imm1u(ureg, i));
       ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord), sampler);
 
-      if (is_uint)
+      if (stype == TGSI_RETURN_TYPE_UINT)
          ureg_U2F(ureg, tmp, ureg_src(tmp));
-      else if (is_sint)
+      else if (stype == TGSI_RETURN_TYPE_SINT)
          ureg_I2F(ureg, tmp, ureg_src(tmp));
 
       /* Add it to the sum.*/
@@ -683,9 +724,9 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
    ureg_MUL(ureg, tmp_sum, ureg_src(tmp_sum),
             ureg_imm1f(ureg, 1.0 / nr_samples));
 
-   if (is_uint)
+   if (stype == TGSI_RETURN_TYPE_UINT)
       ureg_F2U(ureg, out, ureg_src(tmp_sum));
-   else if (is_sint)
+   else if (stype == TGSI_RETURN_TYPE_SINT)
       ureg_F2I(ureg, out, ureg_src(tmp_sum));
    else
       ureg_MOV(ureg, out, ureg_src(tmp_sum));
@@ -699,7 +740,7 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
 void *
 util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
                                    unsigned tgsi_tex, unsigned nr_samples,
-                                   boolean is_uint, boolean is_sint)
+                                   enum tgsi_return_type stype)
 {
    struct ureg_program *ureg;
    struct ureg_src sampler, coord;
@@ -713,6 +754,7 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
 
    /* Declarations. */
    sampler = ureg_DECL_sampler(ureg, 0);
+   ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype);
    coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
                               TGSI_INTERPOLATE_LINEAR);
    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
@@ -744,9 +786,9 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
                   ureg_imm1u(ureg, i));
          ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord[c]), sampler);
 
-         if (is_uint)
+         if (stype == TGSI_RETURN_TYPE_UINT)
             ureg_U2F(ureg, tmp, ureg_src(tmp));
-         else if (is_sint)
+         else if (stype == TGSI_RETURN_TYPE_SINT)
             ureg_I2F(ureg, tmp, ureg_src(tmp));
 
          /* Add it to the sum.*/
@@ -778,9 +820,9 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
             ureg_src(top));
 
    /* Convert to the texture format and return. */
-   if (is_uint)
+   if (stype == TGSI_RETURN_TYPE_UINT)
       ureg_F2U(ureg, out, ureg_src(tmp));
-   else if (is_sint)
+   else if (stype == TGSI_RETURN_TYPE_SINT)
       ureg_F2I(ureg, out, ureg_src(tmp));
    else
       ureg_MOV(ureg, out, ureg_src(tmp));
index dd282e02a13fa3fe1f16a9b0b28b3d45d299fc73..08d798ef541ab039c1a8b5e1f00dfb411566c9d2 100644 (file)
@@ -68,15 +68,16 @@ extern void *
 util_make_layered_clear_geometry_shader(struct pipe_context *pipe);
 
 extern void *
-util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, 
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
                                         unsigned tex_target,
                                         unsigned interp_mode,
-                                        unsigned writemask);
+                                        unsigned writemask,
+                                        enum tgsi_return_type stype);
 
 extern void *
 util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
-                              unsigned interp_mode);
-
+                              unsigned interp_mode,
+                              enum tgsi_return_type stype);
 
 extern void *
 util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
@@ -115,7 +116,8 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
 
 extern void *
 util_make_fs_blit_msaa_color(struct pipe_context *pipe,
-                             unsigned tgsi_tex);
+                             unsigned tgsi_tex,
+                             enum tgsi_return_type stype);
 
 
 extern void *
@@ -136,13 +138,13 @@ util_make_fs_blit_msaa_stencil(struct pipe_context *pipe,
 void *
 util_make_fs_msaa_resolve(struct pipe_context *pipe,
                           unsigned tgsi_tex, unsigned nr_samples,
-                          boolean is_uint, boolean is_sint);
+                          enum tgsi_return_type stype);
 
 
 void *
 util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
                                    unsigned tgsi_tex, unsigned nr_samples,
-                                   boolean is_uint, boolean is_sint);
+                                   enum tgsi_return_type stype);
 
 #ifdef __cplusplus
 }
index fe549723c3382df2f02962f11b49a14a00e251c7..6a489d63c090b5802e70191ede171502847faa31 100644 (file)
@@ -373,7 +373,8 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target)
 
    /* Fragment shader. */
    fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target,
-                                      TGSI_INTERPOLATE_LINEAR);
+                                      TGSI_INTERPOLATE_LINEAR,
+                                      TGSI_RETURN_TYPE_FLOAT);
    cso_set_fragment_shader_handle(cso, fs);
 
    /* Vertex shader. */
index 49ae54f876bc91d76fbe799b5a9400cb9a02203f..106b0a0a9386f8f15164b7182081aa6d6d42ca0f 100644 (file)
 
 #include "pipe/p_compiler.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct pipe_screen;
 
 void util_run_tests(struct pipe_screen *screen);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index b1b89bf1b6db0b2efade2f055ae73c79d5947fad..02ae0b840f028ede57b2f2f2ced2fbd856bc4d68 100644 (file)
@@ -781,10 +781,11 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
    ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers;
    ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers;
 
-   /* Align the formats to the size of DWORD if needed. */
+   /* Align the formats and offsets to the size of DWORD if needed. */
    if (!mgr->caps.velem_src_offset_unaligned) {
       for (i = 0; i < count; i++) {
          ve->native_format_size[i] = align(ve->native_format_size[i], 4);
+         driver_attribs[i].src_offset = align(ve->ve[i].src_offset, 4);
       }
    }
 
index 5861f46b30dabe3b7aedb7d5514cc92c7bc972f4..0908ee7e0583f1d958fe0b55e172fb53250686d9 100644 (file)
@@ -79,6 +79,11 @@ objects. They all follow simple, one-method binding calls, e.g.
   should be the same as the number of set viewports and can be up to
   PIPE_MAX_VIEWPORTS.
 * ``set_viewport_states``
+* ``set_tess_state`` configures the default tessellation parameters:
+  * ``default_outer_level`` is the default value for the outer tessellation
+    levels. This corresponds to GL's ``PATCH_DEFAULT_OUTER_LEVEL``.
+  * ``default_inner_level`` is the default value for the inner tessellation
+    levels. This corresponds to GL's ``PATCH_DEFAULT_INNER_LEVEL``.
 
 
 Sampler Views
index 68931cf35196c5953285841efa6a5c2870c15ad0..8f64817fe5fd37e7cf627b97f1dca6963e216e8f 100644 (file)
@@ -252,6 +252,8 @@ The integer capabilities:
   existing user memory into the device address space for direct device access.
   The create function is pipe_screen::resource_from_user_memory. The address
   and size must be page-aligned.
+* ``PIPE_CAP_DEVICE_RESET_STATUS_QUERY``:
+  Whether pipe_context::get_device_reset_status is implemented.
 
 
 .. _pipe_capf:
@@ -338,6 +340,8 @@ to be 0.
   DLDEXP are supported.
 * ``PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED``: Whether FMA and DFMA (doubles only)
   are supported.
+* ``PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE``: Whether the driver doesn't
+  ignore tgsi_declaration_range::Last for shader inputs and outputs.
 
 
 .. _pipe_compute_cap:
index 7771136f167a2df0db49e8b24260bbd568029d36..89ca172080e24883234bcd59f35d9716f0083dc4 100644 (file)
@@ -2894,6 +2894,43 @@ and only the X component is used.
 FIXME: This right now can be either a ordinary input or a system value...
 
 
+TGSI_SEMANTIC_PATCH
+"""""""""""""""""""
+
+For tessellation evaluation/control shaders, this semantic label indicates a
+generic per-patch attribute. Such semantics will not implicitly be per-vertex
+arrays.
+
+TGSI_SEMANTIC_TESSCOORD
+"""""""""""""""""""""""
+
+For tessellation evaluation shaders, this semantic label indicates the
+coordinates of the vertex being processed. This is available in XYZ; W is
+undefined.
+
+TGSI_SEMANTIC_TESSOUTER
+"""""""""""""""""""""""
+
+For tessellation evaluation/control shaders, this semantic label indicates the
+outer tessellation levels of the patch. Isoline tessellation will only have XY
+defined, triangle will have XYZ and quads will have XYZW defined. This
+corresponds to gl_TessLevelOuter.
+
+TGSI_SEMANTIC_TESSINNER
+"""""""""""""""""""""""
+
+For tessellation evaluation/control shaders, this semantic label indicates the
+inner tessellation levels of the patch. The X value is only defined for
+triangle tessellation, while quads will have XY defined. This is entirely
+undefined for isoline tessellation.
+
+TGSI_SEMANTIC_VERTICESIN
+""""""""""""""""""""""""
+
+For tessellation evaluation/control shaders, this semantic label indicates the
+number of vertices provided in the input patch. Only the X value is defined.
+
+
 Declaration Interpolate
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -2928,6 +2965,18 @@ resource can be one of BUFFER, 1D, 2D, 3D, 1DArray and 2DArray.
 type must be 1 or 4 entries (if specifying on a per-component
 level) out of UNORM, SNORM, SINT, UINT and FLOAT.
 
+For TEX\* style texture sample opcodes (as opposed to SAMPLE\* opcodes
+which take an explicit SVIEW[#] source register), there may be optionally
+SVIEW[#] declarations.  In this case, the SVIEW index is implied by the
+SAMP index, and there must be a corresponding SVIEW[#] declaration for
+each SAMP[#] declaration.  Drivers are free to ignore this if they wish.
+But note in particular that some drivers need to know the sampler type
+(float/int/unsigned) in order to generate the correct code, so cases
+where integer textures are sampled, SVIEW[#] declarations should be
+used.
+
+NOTE: It is NOT legal to mix SAMPLE\* style opcodes and TEX\* opcodes
+in the same shader.
 
 Declaration Resource
 ^^^^^^^^^^^^^^^^^^^^
@@ -3034,6 +3083,39 @@ Naturally, clipping is not performed on window coordinates either.
 The effect of this property is undefined if a geometry or tessellation shader
 are in use.
 
+TCS_VERTICES_OUT
+""""""""""""""""
+
+The number of vertices written by the tessellation control shader. This
+effectively defines the patch input size of the tessellation evaluation shader
+as well.
+
+TES_PRIM_MODE
+"""""""""""""
+
+This sets the tessellation primitive mode, one of ``PIPE_PRIM_TRIANGLES``,
+``PIPE_PRIM_QUADS``, or ``PIPE_PRIM_LINES``. (Unlike in GL, there is no
+separate isolines settings, the regular lines is assumed to mean isolines.)
+
+TES_SPACING
+"""""""""""
+
+This sets the spacing mode of the tessellation generator, one of
+``PIPE_TESS_SPACING_*``.
+
+TES_VERTEX_ORDER_CW
+"""""""""""""""""""
+
+This sets the vertex order to be clockwise if the value is 1, or
+counter-clockwise if set to 0.
+
+TES_POINT_MODE
+""""""""""""""
+
+If set to a non-zero value, this turns on point mode for the tessellator,
+which means that points will be generated instead of primitives.
+
+
 Texture Sampling and Texture Formats
 ------------------------------------
 
index 4b2629f77bdeae0387efda6ae25b385df30aa07f..cbf62c6daae833c827796f5b571c40f2f4ccf3c5 100644 (file)
@@ -21,15 +21,16 @@ libfreedreno_la_SOURCES = \
 
 noinst_PROGRAMS = ir3_compiler
 
+# XXX: Required due to the C++ sources in libnir/libglsl_util
+nodist_EXTRA_ir3_compiler_SOURCES = dummy.cpp
 ir3_compiler_SOURCES = \
        ir3/ir3_cmdline.c
 
 ir3_compiler_LDADD = \
        libfreedreno.la \
-       ../../auxiliary/libgallium.la \
+       $(top_builddir)/src/gallium/auxiliary/libgallium.la \
        $(top_builddir)/src/glsl/libnir.la \
        $(top_builddir)/src/libglsl_util.la \
-       -lstdc++ \
        $(top_builddir)/src/util/libmesautil.la \
        $(GALLIUM_COMMON_LIB_DEPS) \
        $(FREEDRENO_LIBS)
index a565a9c4e4da8cb27ddc04deac3a7097ec735853..baae9144005507dff91e9390c87ca98221186827 100644 (file)
@@ -120,18 +120,17 @@ ir3_SOURCES := \
        ir3/disasm-a3xx.c \
        ir3/instr-a3xx.h \
        ir3/ir3.c \
-       ir3/ir3_compiler.c \
        ir3/ir3_compiler_nir.c \
+       ir3/ir3_compiler.c \
        ir3/ir3_compiler.h \
        ir3/ir3_cp.c \
        ir3/ir3_depth.c \
-       ir3/ir3_dump.c \
-       ir3/ir3_flatten.c \
        ir3/ir3_group.c \
        ir3/ir3.h \
        ir3/ir3_legalize.c \
        ir3/ir3_nir.h \
        ir3/ir3_nir_lower_if_else.c \
+       ir3/ir3_print.c \
        ir3/ir3_ra.c \
        ir3/ir3_sched.c \
        ir3/ir3_shader.c \
index e4acc7e95b48815bd785a8f138656d4a2f755df1..b48fb4659cd2470a6d5259bda3eb4dd2082bd663 100644 (file)
@@ -414,32 +414,16 @@ add_src_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu,
 static void
 add_vector_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
 {
-       switch (inst->Instruction.Saturate) {
-       case TGSI_SAT_NONE:
-               break;
-       case TGSI_SAT_ZERO_ONE:
+       if (inst->Instruction.Saturate) {
                alu->alu.vector_clamp = true;
-               break;
-       case TGSI_SAT_MINUS_PLUS_ONE:
-               DBG("unsupported saturate");
-               assert(0);
-               break;
        }
 }
 
 static void
 add_scalar_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
 {
-       switch (inst->Instruction.Saturate) {
-       case TGSI_SAT_NONE:
-               break;
-       case TGSI_SAT_ZERO_ONE:
+       if (inst->Instruction.Saturate) {
                alu->alu.scalar_clamp = true;
-               break;
-       case TGSI_SAT_MINUS_PLUS_ONE:
-               DBG("unsupported saturate");
-               assert(0);
-               break;
        }
 }
 
@@ -758,7 +742,7 @@ translate_tex(struct fd2_compile_context *ctx,
        struct tgsi_src_register tmp_src;
        const struct tgsi_src_register *coord;
        bool using_temp = (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) ||
-                       (inst->Instruction.Saturate != TGSI_SAT_NONE);
+                       inst->Instruction.Saturate;
        int idx;
 
        if (using_temp || (opc == TGSI_OPCODE_TXP))
index 4e3f521716e3e48e08a94434b0820a610ff6dff2..77e4605e55045030fe9485da216377a80fbadbbf 100644 (file)
@@ -105,9 +105,6 @@ struct fd3_context {
         */
        unsigned fsaturate_s, fsaturate_t, fsaturate_r;
 
-       /* bitmask of integer texture samplers */
-       uint16_t vinteger_s, finteger_s;
-
        /* some state changes require a different shader variant.  Keep
         * track of this so we know when we need to re-emit shader state
         * due to variant change.  See fixup_shader_state()
index b522cf8669537a1f99430818789bf3fa57adb159..b5838b58eb24308d6812b4158c0d1dec4a38b127 100644 (file)
@@ -104,14 +104,12 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
                if (last_key->has_per_samp || key->has_per_samp) {
                        if ((last_key->vsaturate_s != key->vsaturate_s) ||
                                        (last_key->vsaturate_t != key->vsaturate_t) ||
-                                       (last_key->vsaturate_r != key->vsaturate_r) ||
-                                       (last_key->vinteger_s != key->vinteger_s))
+                                       (last_key->vsaturate_r != key->vsaturate_r))
                                ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
 
                        if ((last_key->fsaturate_s != key->fsaturate_s) ||
                                        (last_key->fsaturate_t != key->fsaturate_t) ||
-                                       (last_key->fsaturate_r != key->fsaturate_r) ||
-                                       (last_key->finteger_s != key->finteger_s))
+                                       (last_key->fsaturate_r != key->fsaturate_r))
                                ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
                }
 
@@ -140,16 +138,13 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                        // TODO set .half_precision based on render target format,
                        // ie. float16 and smaller use half, float32 use full..
                        .half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
-                       .has_per_samp = (fd3_ctx->fsaturate || fd3_ctx->vsaturate ||
-                                                        fd3_ctx->vinteger_s || fd3_ctx->finteger_s),
+                       .has_per_samp = (fd3_ctx->fsaturate || fd3_ctx->vsaturate),
                        .vsaturate_s = fd3_ctx->vsaturate_s,
                        .vsaturate_t = fd3_ctx->vsaturate_t,
                        .vsaturate_r = fd3_ctx->vsaturate_r,
                        .fsaturate_s = fd3_ctx->fsaturate_s,
                        .fsaturate_t = fd3_ctx->fsaturate_t,
                        .fsaturate_r = fd3_ctx->fsaturate_r,
-                       .vinteger_s = fd3_ctx->vinteger_s,
-                       .finteger_s = fd3_ctx->finteger_s,
                },
                .rasterflat = ctx->rasterizer && ctx->rasterizer->flatshade,
                .sprite_coord_enable = ctx->rasterizer ? ctx->rasterizer->sprite_coord_enable : 0,
index a6824ef92e7719b04f2d9ea90481c80778d187c9..57fcaa9020ea454fb805bf5316703698c0c959f9 100644 (file)
@@ -413,12 +413,15 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
                                }
                        }
 
-                       /* TODO: Figure out if there's a way to make it spit out 0's and
-                        * 1's for the .z and .w components.
+                       /* Replace the .xy coordinates with S/T from the point sprite. Set
+                        * interpolation bits for .zw such that they become .01
                         */
-                       if (emit->sprite_coord_enable & (1 << sem2idx(fp->inputs[j].semantic)))
+                       if (emit->sprite_coord_enable & (1 << sem2idx(fp->inputs[j].semantic))) {
                                vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
                                        << ((inloc % 16) * 2);
+                               vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
+                               vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
+                       }
                }
 
                OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2);
index 3497921257cda98dddf20c5ee18b2757001c520d..094dcf376e51e016da4a025fc44f4aa586cd39bb 100644 (file)
@@ -32,6 +32,7 @@
 #include "fd3_screen.h"
 #include "fd3_context.h"
 #include "fd3_format.h"
+#include "ir3_compiler.h"
 
 static boolean
 fd3_screen_is_format_supported(struct pipe_screen *pscreen,
@@ -103,7 +104,9 @@ fd3_screen_is_format_supported(struct pipe_screen *pscreen,
 void
 fd3_screen_init(struct pipe_screen *pscreen)
 {
-       fd_screen(pscreen)->max_rts = 4;
+       struct fd_screen *screen = fd_screen(pscreen);
+       screen->max_rts = 4;
+       screen->compiler = ir3_compiler_create(screen->gpu_id);
        pscreen->context_create = fd3_context_create;
        pscreen->is_format_supported = fd3_screen_is_format_supported;
 }
index 6f44ee3c08e8f89383fb05440ff13f57de80ab90..a278bf5c603d5464b8908423a128ae7580d152c0 100644 (file)
@@ -263,44 +263,11 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        return &so->base;
 }
 
-static void
-fd3_set_sampler_views(struct pipe_context *pctx, unsigned shader,
-                                         unsigned start, unsigned nr,
-                                         struct pipe_sampler_view **views)
-{
-       struct fd_context *ctx = fd_context(pctx);
-       struct fd3_context *fd3_ctx = fd3_context(ctx);
-       struct fd_texture_stateobj *tex;
-       uint16_t integer_s = 0, *ptr;
-       int i;
-
-       fd_set_sampler_views(pctx, shader, start, nr, views);
-
-       switch (shader) {
-       case PIPE_SHADER_FRAGMENT:
-               tex = &ctx->fragtex;
-               ptr = &fd3_ctx->finteger_s;
-               break;
-       case PIPE_SHADER_VERTEX:
-               tex = &ctx->verttex;
-               ptr = &fd3_ctx->vinteger_s;
-               break;
-       default:
-               return;
-       }
-
-       for (i = 0; i < tex->num_textures; i++)
-               if (util_format_is_pure_integer(tex->textures[i]->format))
-                       integer_s |= 1 << i;
-       *ptr = integer_s;
-}
-
-
 void
 fd3_texture_init(struct pipe_context *pctx)
 {
        pctx->create_sampler_state = fd3_sampler_state_create;
        pctx->bind_sampler_states = fd3_sampler_states_bind;
        pctx->create_sampler_view = fd3_sampler_view_create;
-       pctx->set_sampler_views = fd3_set_sampler_views;
+       pctx->set_sampler_views = fd_set_sampler_views;
 }
index 384602a2e4f34330efc386826ee7724056384305..53e1bf6a2e6da991b56bbdc2567fa6be9b4e3abd 100644 (file)
@@ -83,9 +83,6 @@ struct fd4_context {
         */
        uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
 
-       /* bitmask of integer texture samplers */
-       uint16_t vinteger_s, finteger_s;
-
        /* some state changes require a different shader variant.  Keep
         * track of this so we know when we need to re-emit shader state
         * due to variant change.  See fixup_shader_state()
index ae407f753fe7c2173ce10e5abcd50d905cfa45a4..de5a306af609ac517bdc6d08e8161cfb9651afa7 100644 (file)
@@ -82,8 +82,7 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
                if (last_key->has_per_samp || key->has_per_samp) {
                        if ((last_key->vsaturate_s != key->vsaturate_s) ||
                                        (last_key->vsaturate_t != key->vsaturate_t) ||
-                                       (last_key->vsaturate_r != key->vsaturate_r) ||
-                                       (last_key->vinteger_s != key->vinteger_s))
+                                       (last_key->vsaturate_r != key->vsaturate_r))
                                ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
 
                        if ((last_key->fsaturate_s != key->fsaturate_s) ||
@@ -122,16 +121,13 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                        // TODO set .half_precision based on render target format,
                        // ie. float16 and smaller use half, float32 use full..
                        .half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
-                       .has_per_samp = (fd4_ctx->fsaturate || fd4_ctx->vsaturate ||
-                                       fd4_ctx->vinteger_s || fd4_ctx->finteger_s),
+                       .has_per_samp = (fd4_ctx->fsaturate || fd4_ctx->vsaturate),
                        .vsaturate_s = fd4_ctx->vsaturate_s,
                        .vsaturate_t = fd4_ctx->vsaturate_t,
                        .vsaturate_r = fd4_ctx->vsaturate_r,
                        .fsaturate_s = fd4_ctx->fsaturate_s,
                        .fsaturate_t = fd4_ctx->fsaturate_t,
                        .fsaturate_r = fd4_ctx->fsaturate_r,
-                       .vinteger_s = fd4_ctx->vinteger_s,
-                       .finteger_s = fd4_ctx->finteger_s,
                },
                .format = fd4_emit_format(pfb->cbufs[0]),
                .pformat = pipe_surface_format(pfb->cbufs[0]),
index f5b46685bdfbf532d7c81727385b9c89d4a270e1..e8cbb2d201af6f4d83880bf5d8638abb506978c9 100644 (file)
@@ -32,6 +32,7 @@
 #include "fd4_screen.h"
 #include "fd4_context.h"
 #include "fd4_format.h"
+#include "ir3_compiler.h"
 
 static boolean
 fd4_screen_is_format_supported(struct pipe_screen *pscreen,
@@ -100,7 +101,9 @@ fd4_screen_is_format_supported(struct pipe_screen *pscreen,
 void
 fd4_screen_init(struct pipe_screen *pscreen)
 {
-       fd_screen(pscreen)->max_rts = 1;
+       struct fd_screen *screen = fd_screen(pscreen);
+       screen->max_rts = 1;
+       screen->compiler = ir3_compiler_create(screen->gpu_id);
        pscreen->context_create = fd4_context_create;
        pscreen->is_format_supported = fd4_screen_is_format_supported;
 }
index ff1ff8f0d3433f0fd5a8aa615ed2ec7112fdf204..6ba25d0816d3afcdbff4626e8bd641c879d9a81e 100644 (file)
@@ -205,43 +205,11 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        return &so->base;
 }
 
-static void
-fd4_set_sampler_views(struct pipe_context *pctx, unsigned shader,
-               unsigned start, unsigned nr, struct pipe_sampler_view **views)
-{
-       struct fd_context *ctx = fd_context(pctx);
-       struct fd4_context *fd4_ctx = fd4_context(ctx);
-       struct fd_texture_stateobj *tex;
-       uint16_t integer_s = 0, *ptr;
-       int i;
-
-       fd_set_sampler_views(pctx, shader, start, nr, views);
-
-       switch (shader) {
-       case PIPE_SHADER_FRAGMENT:
-               tex = &ctx->fragtex;
-               ptr = &fd4_ctx->finteger_s;
-               break;
-       case PIPE_SHADER_VERTEX:
-               tex = &ctx->verttex;
-               ptr = &fd4_ctx->vinteger_s;
-               break;
-       default:
-               return;
-       }
-
-       for (i = 0; i < tex->num_textures; i++)
-               if (util_format_is_pure_integer(tex->textures[i]->format))
-                       integer_s |= 1 << i;
-
-       *ptr = integer_s;
-}
-
 void
 fd4_texture_init(struct pipe_context *pctx)
 {
        pctx->create_sampler_state = fd4_sampler_state_create;
        pctx->bind_sampler_states = fd_sampler_states_bind;
        pctx->create_sampler_view = fd4_sampler_view_create;
-       pctx->set_sampler_views = fd4_set_sampler_views;
+       pctx->set_sampler_views = fd_set_sampler_views;
 }
index 2c816b4b1f649371299826a021b873df0f88580a..e420f1e5bd98ec6e220da8ba756d67c4fc970384 100644 (file)
@@ -297,7 +297,7 @@ struct fd_context {
         */
        struct fd_gmem_stateobj gmem;
        struct fd_vsc_pipe      pipe[8];
-       struct fd_tile          tile[64];
+       struct fd_tile          tile[256];
 
        /* which state objects need to be re-emit'd: */
        enum {
index 46b057d90622b47932a8385bed8823127646d794..375e58f702278e421ea10e00a34fbc05850076d1 100644 (file)
@@ -35,6 +35,7 @@
 struct pipe_fence_handle {
        struct pipe_reference reference;
        struct fd_context *ctx;
+       struct fd_screen *screen;
        uint32_t timestamp;
 };
 
@@ -68,7 +69,7 @@ boolean fd_screen_fence_finish(struct pipe_screen *screen,
                struct pipe_fence_handle *fence,
                uint64_t timeout)
 {
-       if (fd_pipe_wait(fence->ctx->screen->pipe, fence->timestamp))
+       if (fd_pipe_wait(fence->screen->pipe, fence->timestamp))
                return false;
 
        return true;
@@ -86,6 +87,7 @@ struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx)
        pipe_reference_init(&fence->reference, 1);
 
        fence->ctx = ctx;
+       fence->screen = ctx->screen;
        fence->timestamp = fd_ringbuffer_timestamp(ctx->ring);
 
        return fence;
index 11a1b62b26b721d0c6a0da87efb525326bced255..c105378ec4e67e3ba23bb8e5eaa4fd50acb9caf6 100644 (file)
@@ -117,6 +117,7 @@ calculate_tiles(struct fd_context *ctx)
        uint32_t i, j, t, xoff, yoff;
        uint32_t tpp_x, tpp_y;
        bool has_zs = !!(ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL));
+       int tile_n[ARRAY_SIZE(ctx->pipe)];
 
        if (has_zs) {
                struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
@@ -247,6 +248,7 @@ calculate_tiles(struct fd_context *ctx)
        /* configure tiles: */
        t = 0;
        yoff = miny;
+       memset(tile_n, 0, sizeof(tile_n));
        for (i = 0; i < nbins_y; i++) {
                uint32_t bw, bh;
 
@@ -257,20 +259,17 @@ calculate_tiles(struct fd_context *ctx)
 
                for (j = 0; j < nbins_x; j++) {
                        struct fd_tile *tile = &ctx->tile[t];
-                       uint32_t n, p;
+                       uint32_t p;
 
                        assert(t < ARRAY_SIZE(ctx->tile));
 
                        /* pipe number: */
                        p = ((i / tpp_y) * div_round_up(nbins_x, tpp_x)) + (j / tpp_x);
 
-                       /* slot number: */
-                       n = ((i % tpp_y) * tpp_x) + (j % tpp_x);
-
                        /* clip bin width: */
                        bw = MIN2(bin_w, minx + width - xoff);
 
-                       tile->n = n;
+                       tile->n = tile_n[p]++;
                        tile->p = p;
                        tile->bin_w = bw;
                        tile->bin_h = bh;
index 556c8ab18d4ffd54145a321cdc8dd634d9bb5153..b3b5462b4375a8182f050941288ebfeb8c039bb7 100644 (file)
@@ -68,10 +68,7 @@ static const struct debug_named_value debug_options[] = {
                {"fraghalf",  FD_DBG_FRAGHALF, "Use half-precision in fragment shader"},
                {"nobin",     FD_DBG_NOBIN,  "Disable hw binning"},
                {"optmsgs",   FD_DBG_OPTMSGS,"Enable optimizer debug messages"},
-               {"optdump",   FD_DBG_OPTDUMP,"Dump shader DAG to .dot files"},
                {"glsl120",   FD_DBG_GLSL120,"Temporary flag to force GLSL 120 (rather than 130) on a3xx+"},
-               {"nocp",      FD_DBG_NOCP,   "Disable copy-propagation"},
-               {"nir",       FD_DBG_NIR,    "Enable experimental NIR compiler"},
                DEBUG_NAMED_VALUE_END
 };
 
@@ -220,6 +217,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_POLYGON_OFFSET_CLAMP:
        case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
        case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+       case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
                return 0;
 
        case PIPE_CAP_MAX_VIEWPORTS:
@@ -374,6 +372,7 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
                return 0;
        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
                return 1;
@@ -519,6 +518,7 @@ fd_screen_create(struct fd_device *dev)
        case 220:
                fd2_screen_init(pscreen);
                break;
+       case 307:
        case 320:
        case 330:
                fd3_screen_init(pscreen);
index 3b470d1d8a6bf2f6c673e7bc00db2579696ee07d..dbc2808262acabfa7b548d1fdd90928751d1287f 100644 (file)
@@ -46,7 +46,9 @@ struct fd_screen {
        uint32_t device_id;
        uint32_t gpu_id;         /* 220, 305, etc */
        uint32_t chip_id;        /* coreid:8 majorrev:8 minorrev:8 patch:8 */
-       uint32_t max_rts;
+       uint32_t max_rts;        /* max # of render targets */
+
+       void *compiler;          /* currently unused for a2xx */
 
        struct fd_device *dev;
        struct fd_pipe *pipe;
index 2735ae4131537eaac2b20af76b0cb7b56e1a6f1d..deb0e602ce2446c5750d42c6b2a2ad8a00df386c 100644 (file)
@@ -62,11 +62,8 @@ enum adreno_stencil_op fd_stencil_op(unsigned op);
 #define FD_DBG_NOBYPASS 0x0040
 #define FD_DBG_FRAGHALF 0x0080
 #define FD_DBG_NOBIN    0x0100
-#define FD_DBG_OPTMSGS  0x0400
-#define FD_DBG_OPTDUMP  0x0800
-#define FD_DBG_GLSL120  0x1000
-#define FD_DBG_NOCP     0x2000
-#define FD_DBG_NIR      0x4000
+#define FD_DBG_OPTMSGS  0x0200
+#define FD_DBG_GLSL120  0x0400
 
 extern int fd_mesa_debug;
 extern bool fd_binning_enabled;
index a5136c6bd3d9ca0bebdfb117905b0d6058faeea6..48ae7c71b9f16e3d5b4f0b479cffe7985fe847f8 100644 (file)
@@ -133,16 +133,16 @@ static void print_instr_cat0(instr_t *instr)
                break;
        case OPC_BR:
                printf(" %sp0.%c, #%d", cat0->inv ? "!" : "",
-                               component[cat0->comp], cat0->immed);
+                               component[cat0->comp], cat0->a3xx.immed);
                break;
        case OPC_JUMP:
        case OPC_CALL:
-               printf(" #%d", cat0->immed);
+               printf(" #%d", cat0->a3xx.immed);
                break;
        }
 
-       if ((debug & PRINT_VERBOSE) && (cat0->dummy1|cat0->dummy2|cat0->dummy3|cat0->dummy4))
-               printf("\t{0: %x,%x,%x,%x}", cat0->dummy1, cat0->dummy2, cat0->dummy3, cat0->dummy4);
+       if ((debug & PRINT_VERBOSE) && (cat0->a3xx.dummy1|cat0->dummy2|cat0->dummy3|cat0->dummy4))
+               printf("\t{0: %x,%x,%x,%x}", cat0->a3xx.dummy1, cat0->dummy2, cat0->dummy3, cat0->dummy4);
 }
 
 static void print_instr_cat1(instr_t *instr)
index cffa62b6f34208a78f2228cc23271c4b6436fbbb..efb07ea479e0c8043199684c3644c70eb7d80ccb 100644 (file)
@@ -191,9 +191,9 @@ typedef enum {
        OPC_LDLV = 31,
 
        /* meta instructions (category -1): */
-       /* placeholder instr to mark inputs/outputs: */
+       /* placeholder instr to mark shader inputs: */
        OPC_META_INPUT = 0,
-       OPC_META_OUTPUT = 1,
+       OPC_META_PHI = 1,
        /* The "fan-in" and "fan-out" instructions are used for keeping
         * track of instructions that write to multiple dst registers
         * (fan-out) like texture sample instructions, or read multiple
@@ -201,9 +201,6 @@ typedef enum {
         */
        OPC_META_FO = 2,
        OPC_META_FI = 3,
-       /* branches/flow control */
-       OPC_META_FLOW = 4,
-       OPC_META_PHI = 5,
 
 } opc_t;
 
@@ -281,8 +278,16 @@ static inline int reg_special(reg_t reg)
 
 typedef struct PACKED {
        /* dword0: */
-       int16_t  immed    : 16;
-       uint32_t dummy1   : 16;
+       union PACKED {
+               struct PACKED {
+                       int16_t  immed    : 16;
+                       uint32_t dummy1   : 16;
+               } a3xx;
+               struct PACKED {
+                       int32_t  immed    : 20;
+                       uint32_t dummy1   : 12;
+               } a4xx;
+       };
 
        /* dword1: */
        uint32_t dummy2   : 8;
index e015de91c33412899965f540748ea14f1bedaf3f..a166b67d7cfc31389c45a536de6e06b433f057dc 100644 (file)
@@ -66,11 +66,22 @@ void * ir3_alloc(struct ir3 *shader, int sz)
        return ptr;
 }
 
-struct ir3 * ir3_create(void)
+struct ir3 * ir3_create(struct ir3_compiler *compiler,
+               unsigned nin, unsigned nout)
 {
-       struct ir3 *shader =
-                       calloc(1, sizeof(struct ir3));
+       struct ir3 *shader = calloc(1, sizeof(struct ir3));
+
        grow_heap(shader);
+
+       shader->compiler = compiler;
+       shader->ninputs = nin;
+       shader->inputs = ir3_alloc(shader, sizeof(shader->inputs[0]) * nin);
+
+       shader->noutputs = nout;
+       shader->outputs = ir3_alloc(shader, sizeof(shader->outputs[0]) * nout);
+
+       list_inithead(&shader->block_list);
+
        return shader;
 }
 
@@ -81,7 +92,8 @@ void ir3_destroy(struct ir3 *shader)
                shader->chunk = chunk->next;
                free(chunk);
        }
-       free(shader->instrs);
+       free(shader->indirects);
+       free(shader->predicates);
        free(shader->baryfs);
        free(shader);
 }
@@ -142,7 +154,11 @@ static int emit_cat0(struct ir3_instruction *instr, void *ptr,
 {
        instr_cat0_t *cat0 = ptr;
 
-       cat0->immed    = instr->cat0.immed;
+       if (info->gpu_id >= 400) {
+               cat0->a4xx.immed = instr->cat0.immed;
+       } else {
+               cat0->a3xx.immed = instr->cat0.immed;
+       }
        cat0->repeat   = instr->repeat;
        cat0->ss       = !!(instr->flags & IR3_INSTR_SS);
        cat0->inv      = instr->cat0.inv;
@@ -535,32 +551,40 @@ void * ir3_assemble(struct ir3 *shader, struct ir3_info *info,
                uint32_t gpu_id)
 {
        uint32_t *ptr, *dwords;
-       uint32_t i;
 
+       info->gpu_id        = gpu_id;
        info->max_reg       = -1;
        info->max_half_reg  = -1;
        info->max_const     = -1;
        info->instrs_count  = 0;
+       info->sizedwords    = 0;
+
+       list_for_each_entry (struct ir3_block, block, &shader->block_list, node) {
+               list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+                       info->sizedwords += 2;
+               }
+       }
 
        /* need a integer number of instruction "groups" (sets of 16
         * instructions on a4xx or sets of 4 instructions on a3xx),
         * so pad out w/ NOPs if needed: (NOTE each instruction is 64bits)
         */
        if (gpu_id >= 400) {
-               info->sizedwords = 2 * align(shader->instrs_count, 16);
+               info->sizedwords = align(info->sizedwords, 16 * 2);
        } else {
-               info->sizedwords = 2 * align(shader->instrs_count, 4);
+               info->sizedwords = align(info->sizedwords, 4 * 2);
        }
 
        ptr = dwords = calloc(4, info->sizedwords);
 
-       for (i = 0; i < shader->instrs_count; i++) {
-               struct ir3_instruction *instr = shader->instrs[i];
-               int ret = emit[instr->category](instr, dwords, info);
-               if (ret)
-                       goto fail;
-               info->instrs_count += 1 + instr->repeat;
-               dwords += 2;
+       list_for_each_entry (struct ir3_block, block, &shader->block_list, node) {
+               list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+                       int ret = emit[instr->category](instr, dwords, info);
+                       if (ret)
+                               goto fail;
+                       info->instrs_count += 1 + instr->repeat;
+                       dwords += 2;
+               }
        }
 
        return ptr;
@@ -581,50 +605,30 @@ static struct ir3_register * reg_create(struct ir3 *shader,
        return reg;
 }
 
-static void insert_instr(struct ir3 *shader,
+static void insert_instr(struct ir3_block *block,
                struct ir3_instruction *instr)
 {
+       struct ir3 *shader = block->shader;
 #ifdef DEBUG
        static uint32_t serialno = 0;
        instr->serialno = ++serialno;
 #endif
-       array_insert(shader->instrs, instr);
+       list_addtail(&instr->node, &block->instr_list);
 
        if (is_input(instr))
                array_insert(shader->baryfs, instr);
 }
 
-struct ir3_block * ir3_block_create(struct ir3 *shader,
-               unsigned ntmp, unsigned nin, unsigned nout)
+struct ir3_block * ir3_block_create(struct ir3 *shader)
 {
-       struct ir3_block *block;
-       unsigned size;
-       char *ptr;
-
-       size = sizeof(*block);
-       size += sizeof(block->temporaries[0]) * ntmp;
-       size += sizeof(block->inputs[0]) * nin;
-       size += sizeof(block->outputs[0]) * nout;
-
-       ptr = ir3_alloc(shader, size);
-
-       block = (void *)ptr;
-       ptr += sizeof(*block);
-
-       block->temporaries = (void *)ptr;
-       block->ntemporaries = ntmp;
-       ptr += sizeof(block->temporaries[0]) * ntmp;
-
-       block->inputs = (void *)ptr;
-       block->ninputs = nin;
-       ptr += sizeof(block->inputs[0]) * nin;
-
-       block->outputs = (void *)ptr;
-       block->noutputs = nout;
-       ptr += sizeof(block->outputs[0]) * nout;
-
+       struct ir3_block *block = ir3_alloc(shader, sizeof(*block));
+#ifdef DEBUG
+       static uint32_t serialno = 0;
+       block->serialno = ++serialno;
+#endif
        block->shader = shader;
-
+       list_inithead(&block->node);
+       list_inithead(&block->instr_list);
        return block;
 }
 
@@ -652,7 +656,7 @@ struct ir3_instruction * ir3_instr_create2(struct ir3_block *block,
        instr->block = block;
        instr->category = category;
        instr->opc = opc;
-       insert_instr(block->shader, instr);
+       insert_instr(block, instr);
        return instr;
 }
 
@@ -677,7 +681,7 @@ struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr)
        *new_instr = *instr;
        new_instr->regs = regs;
 
-       insert_instr(instr->block->shader, new_instr);
+       insert_instr(instr->block, new_instr);
 
        /* clone registers: */
        new_instr->regs_count = 0;
@@ -694,10 +698,40 @@ struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr)
 struct ir3_register * ir3_reg_create(struct ir3_instruction *instr,
                int num, int flags)
 {
-       struct ir3_register *reg = reg_create(instr->block->shader, num, flags);
+       struct ir3 *shader = instr->block->shader;
+       struct ir3_register *reg = reg_create(shader, num, flags);
 #ifdef DEBUG
        debug_assert(instr->regs_count < instr->regs_max);
 #endif
        instr->regs[instr->regs_count++] = reg;
        return reg;
 }
+
+void
+ir3_block_clear_mark(struct ir3_block *block)
+{
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node)
+               instr->flags &= ~IR3_INSTR_MARK;
+}
+
+void
+ir3_clear_mark(struct ir3 *ir)
+{
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               ir3_block_clear_mark(block);
+       }
+}
+
+/* note: this will destroy instr->depth, don't do it until after sched! */
+void
+ir3_count_instructions(struct ir3 *ir)
+{
+       unsigned ip = 0;
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+                       instr->ip = ip++;
+               }
+               block->start_ip = list_first_entry(&block->instr_list, struct ir3_instruction, node)->ip;
+               block->end_ip = list_last_entry(&block->instr_list, struct ir3_instruction, node)->ip;
+       }
+}
index c0a14a07d48a2e044123d4e5c2e80277a87e066a..9c35a763d583da83558b34acd099e068d83a8457 100644 (file)
 #include <stdbool.h>
 
 #include "util/u_debug.h"
+#include "util/list.h"
 
 #include "instr-a3xx.h"
 #include "disasm.h"  /* TODO move 'enum shader_t' somewhere else.. */
 
 /* low level intermediate representation of an adreno shader program */
 
+struct ir3_compiler;
 struct ir3;
 struct ir3_instruction;
 struct ir3_block;
 
 struct ir3_info {
+       uint32_t gpu_id;
        uint16_t sizedwords;
        uint16_t instrs_count;   /* expanded to account for rpt's */
        /* NOTE: max_reg, etc, does not include registers not touched
@@ -80,8 +83,8 @@ struct ir3_register {
                 * before register assignment is done:
                 */
                IR3_REG_SSA    = 0x2000,   /* 'instr' is ptr to assigning instr */
-               IR3_REG_IA     = 0x4000,   /* meta-input dst is "assigned" */
-               IR3_REG_ADDR   = 0x8000,   /* register is a0.x */
+               IR3_REG_PHI_SRC= 0x4000,   /* phi src, regs[0]->instr points to phi */
+
        } flags;
        union {
                /* normal registers:
@@ -185,6 +188,7 @@ struct ir3_instruction {
                        char inv;
                        char comp;
                        int  immed;
+                       struct ir3_block *target;
                } cat0;
                struct {
                        type_t src_type, dst_type;
@@ -218,14 +222,14 @@ struct ir3_instruction {
                        int aid;
                } fi;
                struct {
-                       struct ir3_block *if_block, *else_block;
-               } flow;
+                       /* used to temporarily hold reference to nir_phi_instr
+                        * until we resolve the phi srcs
+                        */
+                       void *nphi;
+               } phi;
                struct {
                        struct ir3_block *block;
                } inout;
-
-               /* XXX keep this as big as all other union members! */
-               uint32_t info[3];
        };
 
        /* transient values used during various algorithms: */
@@ -243,6 +247,13 @@ struct ir3_instruction {
                 */
 #define DEPTH_UNUSED  ~0
                unsigned depth;
+               /* When we get to the RA stage, we no longer need depth, but
+                * we do need instruction's position/name:
+                */
+               struct {
+                       uint16_t ip;
+                       uint16_t name;
+               };
        };
 
        /* Used during CP and RA stages.  For fanin and shader inputs/
@@ -290,7 +301,9 @@ struct ir3_instruction {
         */
        struct ir3_instruction *fanin;
 
-       struct ir3_instruction *next;
+       /* Entry in ir3_block's instruction list: */
+       struct list_head node;
+
 #ifdef DEBUG
        uint32_t serialno;
 #endif
@@ -321,8 +334,11 @@ static inline int ir3_neighbor_count(struct ir3_instruction *instr)
 struct ir3_heap_chunk;
 
 struct ir3 {
-       unsigned instrs_count, instrs_sz;
-       struct ir3_instruction **instrs;
+       struct ir3_compiler *compiler;
+
+       unsigned ninputs, noutputs;
+       struct ir3_instruction **inputs;
+       struct ir3_instruction **outputs;
 
        /* Track bary.f (and ldlv) instructions.. this is needed in
         * scheduling to ensure that all varying fetches happen before
@@ -345,33 +361,54 @@ struct ir3 {
         */
        unsigned indirects_count, indirects_sz;
        struct ir3_instruction **indirects;
+       /* and same for instructions that consume predicate register: */
+       unsigned predicates_count, predicates_sz;
+       struct ir3_instruction **predicates;
+
+       /* List of blocks: */
+       struct list_head block_list;
 
-       struct ir3_block *block;
        unsigned heap_idx;
        struct ir3_heap_chunk *chunk;
 };
 
+typedef struct nir_block nir_block;
+
 struct ir3_block {
+       struct list_head node;
        struct ir3 *shader;
-       unsigned ntemporaries, ninputs, noutputs;
-       /* maps TGSI_FILE_TEMPORARY index back to the assigning instruction: */
-       struct ir3_instruction **temporaries;
-       struct ir3_instruction **inputs;
-       struct ir3_instruction **outputs;
-       /* only a single address register: */
-       struct ir3_instruction *address;
-       struct ir3_block *parent;
-       struct ir3_instruction *head;
+
+       nir_block *nblock;
+
+       struct list_head instr_list;  /* list of ir3_instruction */
+
+       /* each block has either one or two successors.. in case of
+        * two successors, 'condition' decides which one to follow.
+        * A block preceding an if/else has two successors.
+        */
+       struct ir3_instruction *condition;
+       struct ir3_block *successors[2];
+
+       uint16_t start_ip, end_ip;
+
+       /* used for per-pass extra block data.  Mainly used right
+        * now in RA step to track livein/liveout.
+        */
+       void *bd;
+
+#ifdef DEBUG
+       uint32_t serialno;
+#endif
 };
 
-struct ir3 * ir3_create(void);
+struct ir3 * ir3_create(struct ir3_compiler *compiler,
+               unsigned nin, unsigned nout);
 void ir3_destroy(struct ir3 *shader);
 void * ir3_assemble(struct ir3 *shader,
                struct ir3_info *info, uint32_t gpu_id);
 void * ir3_alloc(struct ir3 *shader, int sz);
 
-struct ir3_block * ir3_block_create(struct ir3 *shader,
-               unsigned ntmp, unsigned nin, unsigned nout);
+struct ir3_block * ir3_block_create(struct ir3 *shader);
 
 struct ir3_instruction * ir3_instr_create(struct ir3_block *block,
                int category, opc_t opc);
@@ -383,7 +420,6 @@ const char *ir3_instr_name(struct ir3_instruction *instr);
 struct ir3_register * ir3_reg_create(struct ir3_instruction *instr,
                int num, int flags);
 
-
 static inline bool ir3_instr_check_mark(struct ir3_instruction *instr)
 {
        if (instr->flags & IR3_INSTR_MARK)
@@ -392,22 +428,10 @@ static inline bool ir3_instr_check_mark(struct ir3_instruction *instr)
        return false;
 }
 
-static inline void ir3_clear_mark(struct ir3 *shader)
-{
-       /* TODO would be nice to drop the instruction array.. for
-        * new compiler, _clear_mark() is all we use it for, and
-        * we could probably manage a linked list instead..
-        *
-        * Also, we'll probably want to mark instructions within
-        * a block, so tracking the list of instrs globally is
-        * unlikely to be what we want.
-        */
-       unsigned i;
-       for (i = 0; i < shader->instrs_count; i++) {
-               struct ir3_instruction *instr = shader->instrs[i];
-               instr->flags &= ~IR3_INSTR_MARK;
-       }
-}
+void ir3_block_clear_mark(struct ir3_block *block);
+void ir3_clear_mark(struct ir3 *shader);
+
+void ir3_count_instructions(struct ir3 *ir);
 
 static inline int ir3_instr_regno(struct ir3_instruction *instr,
                struct ir3_register *reg)
@@ -501,6 +525,28 @@ static inline bool is_mem(struct ir3_instruction *instr)
        return (instr->category == 6);
 }
 
+static inline bool
+is_store(struct ir3_instruction *instr)
+{
+       if (is_mem(instr)) {
+               /* these instructions, the "destination" register is
+                * actually a source, the address to store to.
+                */
+               switch (instr->opc) {
+               case OPC_STG:
+               case OPC_STP:
+               case OPC_STL:
+               case OPC_STLW:
+               case OPC_L2G:
+               case OPC_G2L:
+                       return true;
+               default:
+                       break;
+               }
+       }
+       return false;
+}
+
 static inline bool is_input(struct ir3_instruction *instr)
 {
        /* in some cases, ldlv is used to fetch varying without
@@ -525,7 +571,7 @@ static inline bool writes_addr(struct ir3_instruction *instr)
 {
        if (instr->regs_count > 0) {
                struct ir3_register *dst = instr->regs[0];
-               return !!(dst->flags & IR3_REG_ADDR);
+               return reg_num(dst) == REG_A0;
        }
        return false;
 }
@@ -556,13 +602,29 @@ static inline bool conflicts(struct ir3_instruction *a,
 
 static inline bool reg_gpr(struct ir3_register *r)
 {
-       if (r->flags & (IR3_REG_CONST | IR3_REG_IMMED | IR3_REG_ADDR))
+       if (r->flags & (IR3_REG_CONST | IR3_REG_IMMED))
                return false;
        if ((reg_num(r) == REG_A0) || (reg_num(r) == REG_P0))
                return false;
        return true;
 }
 
+static inline type_t half_type(type_t type)
+{
+       switch (type) {
+       case TYPE_F32: return TYPE_F16;
+       case TYPE_U32: return TYPE_U16;
+       case TYPE_S32: return TYPE_S16;
+       case TYPE_F16:
+       case TYPE_U16:
+       case TYPE_S16:
+               return type;
+       default:
+               assert(0);
+               return ~0;
+       }
+}
+
 /* some cat2 instructions (ie. those which are not float) can embed an
  * immediate:
  */
@@ -747,37 +809,31 @@ static inline struct ir3_instruction * __ssa_src_n(struct ir3_instruction *instr
 
 
 /* dump: */
-#include <stdio.h>
-void ir3_dump(struct ir3 *shader, const char *name,
-               struct ir3_block *block /* XXX maybe 'block' ptr should move to ir3? */,
-               FILE *f);
-void ir3_dump_instr_single(struct ir3_instruction *instr);
-void ir3_dump_instr_list(struct ir3_instruction *instr);
-
-/* flatten if/else: */
-int ir3_block_flatten(struct ir3_block *block);
+void ir3_print(struct ir3 *ir);
+void ir3_print_instr(struct ir3_instruction *instr);
 
 /* depth calculation: */
 int ir3_delayslots(struct ir3_instruction *assigner,
                struct ir3_instruction *consumer, unsigned n);
-void ir3_block_depth(struct ir3_block *block);
+void ir3_insert_by_depth(struct ir3_instruction *instr, struct list_head *list);
+void ir3_depth(struct ir3 *ir);
 
 /* copy-propagate: */
-void ir3_block_cp(struct ir3_block *block);
+void ir3_cp(struct ir3 *ir);
 
-/* group neightbors and insert mov's to resolve conflicts: */
-void ir3_block_group(struct ir3_block *block);
+/* group neighbors and insert mov's to resolve conflicts: */
+void ir3_group(struct ir3 *ir);
 
 /* scheduling: */
-int ir3_block_sched(struct ir3_block *block);
+int ir3_sched(struct ir3 *ir);
 
 /* register assignment: */
-int ir3_block_ra(struct ir3_block *block, enum shader_t type,
+struct ir3_ra_reg_set * ir3_ra_alloc_reg_set(void *memctx);
+int ir3_ra(struct ir3 *ir3, enum shader_t type,
                bool frag_coord, bool frag_face);
 
 /* legalize: */
-void ir3_block_legalize(struct ir3_block *block,
-               bool *has_samp, int *max_bary);
+void ir3_legalize(struct ir3 *ir, bool *has_samp, int *max_bary);
 
 /* ************************************************************************* */
 /* instruction helpers */
@@ -807,6 +863,21 @@ ir3_COV(struct ir3_block *block, struct ir3_instruction *src,
        return instr;
 }
 
+static inline struct ir3_instruction *
+ir3_NOP(struct ir3_block *block)
+{
+       return ir3_instr_create(block, 0, OPC_NOP);
+}
+
+#define INSTR0(CAT, name)                                                \
+static inline struct ir3_instruction *                                   \
+ir3_##name(struct ir3_block *block)                                      \
+{                                                                        \
+       struct ir3_instruction *instr =                                      \
+               ir3_instr_create(block, CAT, OPC_##name);                        \
+       return instr;                                                        \
+}
+
 #define INSTR1(CAT, name)                                                \
 static inline struct ir3_instruction *                                   \
 ir3_##name(struct ir3_block *block,                                      \
@@ -850,7 +921,10 @@ ir3_##name(struct ir3_block *block,                                      \
 }
 
 /* cat0 instructions: */
+INSTR0(0, BR);
+INSTR0(0, JUMP);
 INSTR1(0, KILL);
+INSTR0(0, END);
 
 /* cat2 instructions, most 2 src but some 1 src: */
 INSTR2(2, ADD_F)
index d0517aab8ce9a868cc69ac2004cff58fe4cd0f52..ad9d2719d59a0a9f9497f567e989c3774362ab69 100644 (file)
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <err.h>
 
 #include "tgsi/tgsi_parse.h"
@@ -65,34 +66,34 @@ static void dump_info(struct ir3_shader_variant *so, const char *str)
        // TODO make gpu_id configurable on cmdline
        bin = ir3_shader_assemble(so, 320);
        if (fd_mesa_debug & FD_DBG_DISASM) {
-               struct ir3_block *block = so->ir->block;
+               struct ir3 *ir = so->ir;
                struct ir3_register *reg;
                uint8_t regid;
                unsigned i;
 
                debug_printf("; %s: %s\n", type, str);
 
-               for (i = 0; i < block->ninputs; i++) {
-                       if (!block->inputs[i]) {
+               for (i = 0; i < ir->ninputs; i++) {
+                       if (!ir->inputs[i]) {
                                debug_printf("; in%d unused\n", i);
                                continue;
                        }
-                       reg = block->inputs[i]->regs[0];
+                       reg = ir->inputs[i]->regs[0];
                        regid = reg->num;
                        debug_printf("@in(%sr%d.%c)\tin%d\n",
                                        (reg->flags & IR3_REG_HALF) ? "h" : "",
                                        (regid >> 2), "xyzw"[regid & 0x3], i);
                }
 
-               for (i = 0; i < block->noutputs; i++) {
-                       if (!block->outputs[i]) {
+               for (i = 0; i < ir->noutputs; i++) {
+                       if (!ir->outputs[i]) {
                                debug_printf("; out%d unused\n", i);
                                continue;
                        }
                        /* kill shows up as a virtual output.. skip it! */
-                       if (is_kill(block->outputs[i]))
+                       if (is_kill(ir->outputs[i]))
                                continue;
-                       reg = block->outputs[i]->regs[0];
+                       reg = ir->outputs[i]->regs[0];
                        regid = reg->num;
                        debug_printf("@out(%sr%d.%c)\tout%d\n",
                                        (reg->flags & IR3_REG_HALF) ? "h" : "",
@@ -194,16 +195,6 @@ read_file(const char *filename, void **ptr, size_t *size)
        return 0;
 }
 
-static void reset_variant(struct ir3_shader_variant *v, const char *msg)
-{
-       printf("; %s\n", msg);
-       v->inputs_count = 0;
-       v->outputs_count = 0;
-       v->total_in = 0;
-       v->has_samp = false;
-       v->immediates_count = 0;
-}
-
 static void print_usage(void)
 {
        printf("Usage: ir3_compiler [OPTIONS]... FILE\n");
@@ -225,12 +216,12 @@ int main(int argc, char **argv)
        const char *filename;
        struct tgsi_token toks[65536];
        struct tgsi_parse_context parse;
+       struct ir3_compiler *compiler;
        struct ir3_shader_variant v;
        struct ir3_shader_key key = {};
        const char *info;
        void *ptr;
        size_t size;
-       int use_nir = 0;
 
        fd_mesa_debug |= FD_DBG_DISASM;
 
@@ -243,7 +234,7 @@ int main(int argc, char **argv)
 
        while (n < argc) {
                if (!strcmp(argv[n], "--verbose")) {
-                       fd_mesa_debug |=  FD_DBG_OPTDUMP | FD_DBG_MSGS | FD_DBG_OPTMSGS;
+                       fd_mesa_debug |= FD_DBG_MSGS | FD_DBG_OPTMSGS;
                        n++;
                        continue;
                }
@@ -290,17 +281,6 @@ int main(int argc, char **argv)
                        continue;
                }
 
-               if (!strcmp(argv[n], "--nocp")) {
-                       fd_mesa_debug |= FD_DBG_NOCP;
-                       n++;
-                       continue;
-               }
-               if (!strcmp(argv[n], "--nir")) {
-                       use_nir = true;
-                       n++;
-                       continue;
-               }
-
                if (!strcmp(argv[n], "--help")) {
                        print_usage();
                        return 0;
@@ -340,31 +320,14 @@ int main(int argc, char **argv)
                break;
        }
 
-       if (use_nir) {
-               info = "NIR compiler";
-               ret = ir3_compile_shader_nir(&v, toks, key);
-       } else {
-               info = "TGSI compiler";
-               ret = ir3_compile_shader(&v, toks, key, true);
-       }
-
-       if (ret) {
-               reset_variant(&v, "compiler failed, trying without copy propagation!");
-               info = "compiler (no copy propagation)";
-               ret = ir3_compile_shader(&v, toks, key, false);
-       }
+       /* TODO cmdline option to target different gpus: */
+       compiler = ir3_compiler_create(320);
 
+       info = "NIR compiler";
+       ret = ir3_compile_shader_nir(compiler, &v, toks, key);
        if (ret) {
                fprintf(stderr, "compiler failed!\n");
                return ret;
        }
        dump_info(&v, info);
 }
-
-void _mesa_error_no_memory(const char *caller);
-
-void
-_mesa_error_no_memory(const char *caller)
-{
-       fprintf(stderr, "Mesa error: out of memory in %s", caller);
-}
index 43f4c955ac065ad5a673a658a7a223dcb72dff8b..7c8eccb54e1f1bcb8a3ff72f86722381e0ecd0f4 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
 
 /*
- * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
+ * Copyright (C) 2015 Rob Clark <robclark@freedesktop.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  *    Rob Clark <robclark@freedesktop.org>
  */
 
-#include <stdarg.h>
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "tgsi/tgsi_lowering.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_ureg.h"
-#include "tgsi/tgsi_info.h"
-#include "tgsi/tgsi_strings.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_scan.h"
-
-#include "freedreno_util.h"
+#include "util/ralloc.h"
 
 #include "ir3_compiler.h"
-#include "ir3_shader.h"
-
-#include "instr-a3xx.h"
-#include "ir3.h"
-
-struct ir3_compile_context {
-       const struct tgsi_token *tokens;
-       bool free_tokens;
-       struct ir3 *ir;
-       struct ir3_shader_variant *so;
-       uint16_t integer_s;
-
-       struct ir3_block *block;
-       struct ir3_instruction *current_instr;
-
-       /* we need to defer updates to block->outputs[] until the end
-        * of an instruction (so we don't see new value until *after*
-        * the src registers are processed)
-        */
-       struct {
-               struct ir3_instruction *instr, **instrp;
-       } output_updates[64];
-       unsigned num_output_updates;
-
-       /* are we in a sequence of "atomic" instructions?
-        */
-       bool atomic;
-
-       /* For fragment shaders, from the hw perspective the only
-        * actual input is r0.xy position register passed to bary.f.
-        * But TGSI doesn't know that, it still declares things as
-        * IN[] registers.  So we do all the input tracking normally
-        * and fix things up after compile_instructions()
-        *
-        * NOTE that frag_pos is the hardware position (possibly it
-        * is actually an index or tag or some such.. it is *not*
-        * values that can be directly used for gl_FragCoord..)
-        */
-       struct ir3_instruction *frag_pos, *frag_face, *frag_coord[4];
-
-       /* For vertex shaders, keep track of the system values sources */
-       struct ir3_instruction *vertex_id, *basevertex, *instance_id;
-
-       struct tgsi_parse_context parser;
-       unsigned type;
-
-       struct tgsi_shader_info info;
-
-       /* hmm, would be nice if tgsi_scan_shader figured this out
-        * for us:
-        */
-       struct {
-               unsigned first, last;
-               struct ir3_instruction *fanin;
-       } array[MAX_ARRAYS];
-       uint32_t array_dirty;
-       /* offset into array[], per file, of first array info */
-       uint8_t array_offsets[TGSI_FILE_COUNT];
-
-       /* for calculating input/output positions/linkages: */
-       unsigned next_inloc;
-
-       /* a4xx (at least patchlevel 0) cannot seem to flat-interpolate
-        * so we need to use ldlv.u32 to load the varying directly:
-        */
-       bool flat_bypass;
-
-       unsigned num_internal_temps;
-       struct tgsi_src_register internal_temps[8];
-
-       /* for looking up which system value is which */
-       unsigned sysval_semantics[8];
-
-       /* idx/slot for last compiler generated immediate */
-       unsigned immediate_idx;
-
-       /* stack of branch instructions that mark (potentially nested)
-        * branch if/else/loop/etc
-        */
-       struct {
-               struct ir3_instruction *instr, *cond;
-               bool inv;   /* true iff in else leg of branch */
-       } branch[16];
-       unsigned int branch_count;
-
-       /* list of kill instructions: */
-       struct ir3_instruction *kill[16];
-       unsigned int kill_count;
-
-       /* used when dst is same as one of the src, to avoid overwriting a
-        * src element before the remaining scalar instructions that make
-        * up the vector operation
-        */
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-
-       /* just for catching incorrect use of get_dst()/put_dst():
-        */
-       bool using_tmp_dst;
-};
-
-
-static void vectorize(struct ir3_compile_context *ctx,
-               struct ir3_instruction *instr, struct tgsi_dst_register *dst,
-               int nsrcs, ...);
-static void create_mov(struct ir3_compile_context *ctx,
-               struct tgsi_dst_register *dst, struct tgsi_src_register *src);
-static type_t get_ftype(struct ir3_compile_context *ctx);
-static type_t get_utype(struct ir3_compile_context *ctx);
-
-static unsigned setup_arrays(struct ir3_compile_context *ctx, unsigned file, unsigned i)
-{
-       /* ArrayID 0 for a given file is the legacy array spanning the entire file: */
-       ctx->array[i].first = 0;
-       ctx->array[i].last = ctx->info.file_max[file];
-       ctx->array_offsets[file] = i;
-       i += ctx->info.array_max[file] + 1;
-       return i;
-}
-
-static unsigned
-compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
-               const struct tgsi_token *tokens)
-{
-       unsigned ret, i;
-       struct tgsi_shader_info *info = &ctx->info;
-       struct tgsi_lowering_config lconfig = {
-                       .color_two_side = so->key.color_two_side,
-                       .lower_DST  = true,
-                       .lower_XPD  = true,
-                       .lower_SCS  = true,
-                       .lower_LRP  = true,
-                       .lower_FRC  = true,
-                       .lower_POW  = true,
-                       .lower_LIT  = true,
-                       .lower_EXP  = true,
-                       .lower_LOG  = true,
-                       .lower_DP4  = true,
-                       .lower_DP3  = true,
-                       .lower_DPH  = true,
-                       .lower_DP2  = true,
-                       .lower_DP2A = true,
-       };
-
-       switch (so->type) {
-       case SHADER_FRAGMENT:
-       case SHADER_COMPUTE:
-               lconfig.saturate_s = so->key.fsaturate_s;
-               lconfig.saturate_t = so->key.fsaturate_t;
-               lconfig.saturate_r = so->key.fsaturate_r;
-               ctx->integer_s = so->key.finteger_s;
-               break;
-       case SHADER_VERTEX:
-               lconfig.saturate_s = so->key.vsaturate_s;
-               lconfig.saturate_t = so->key.vsaturate_t;
-               lconfig.saturate_r = so->key.vsaturate_r;
-               ctx->integer_s = so->key.vinteger_s;
-               break;
-       }
-
-       if (!so->shader) {
-               /* hack for standalone compiler which does not have
-                * screen/context:
-                */
-       } else if (ir3_shader_gpuid(so->shader) >= 400) {
-               /* a4xx seems to have *no* sam.p */
-               lconfig.lower_TXP = ~0;  /* lower all txp */
-               /* need special handling for "flat" */
-               ctx->flat_bypass = true;
-       } else {
-               /* a3xx just needs to avoid sam.p for 3d tex */
-               lconfig.lower_TXP = (1 << TGSI_TEXTURE_3D);
-               /* no special handling for "flat" */
-               ctx->flat_bypass = false;
-       }
-
-       ctx->tokens = tgsi_transform_lowering(&lconfig, tokens, &ctx->info);
-       ctx->free_tokens = !!ctx->tokens;
-       if (!ctx->tokens) {
-               /* no lowering */
-               ctx->tokens = tokens;
-       }
-       ctx->ir = so->ir;
-       ctx->so = so;
-       ctx->array_dirty = 0;
-       ctx->next_inloc = 8;
-       ctx->num_internal_temps = 0;
-       ctx->branch_count = 0;
-       ctx->kill_count = 0;
-       ctx->block = NULL;
-       ctx->current_instr = NULL;
-       ctx->num_output_updates = 0;
-       ctx->atomic = false;
-       ctx->frag_pos = NULL;
-       ctx->frag_face = NULL;
-       ctx->vertex_id = NULL;
-       ctx->instance_id = NULL;
-       ctx->tmp_src = NULL;
-       ctx->using_tmp_dst = false;
-
-       memset(ctx->frag_coord, 0, sizeof(ctx->frag_coord));
-       memset(ctx->array, 0, sizeof(ctx->array));
-       memset(ctx->array_offsets, 0, sizeof(ctx->array_offsets));
-
-#define FM(x) (1 << TGSI_FILE_##x)
-       /* NOTE: if relative addressing is used, we set constlen in
-        * the compiler (to worst-case value) since we don't know in
-        * the assembler what the max addr reg value can be:
-        */
-       if (info->indirect_files & FM(CONSTANT))
-               so->constlen = MIN2(255, ctx->info.const_file_max[0] + 1);
-
-       i = 0;
-       i += setup_arrays(ctx, TGSI_FILE_INPUT, i);
-       i += setup_arrays(ctx, TGSI_FILE_TEMPORARY, i);
-       i += setup_arrays(ctx, TGSI_FILE_OUTPUT, i);
-       /* any others? we don't track arrays for const..*/
-
-       /* Immediates go after constants: */
-       so->first_immediate = so->first_driver_param =
-               info->const_file_max[0] + 1;
-       /* 1 unit for the vertex id base */
-       if (so->type == SHADER_VERTEX)
-               so->first_immediate++;
-       /* 4 (vec4) units for ubo base addresses */
-       so->first_immediate += 4;
-       ctx->immediate_idx = 4 * (ctx->info.file_max[TGSI_FILE_IMMEDIATE] + 1);
-
-       ret = tgsi_parse_init(&ctx->parser, ctx->tokens);
-       if (ret != TGSI_PARSE_OK)
-               return ret;
-
-       ctx->type = ctx->parser.FullHeader.Processor.Processor;
-
-       return ret;
-}
-
-static void
-compile_error(struct ir3_compile_context *ctx, const char *format, ...)
-{
-       va_list ap;
-       va_start(ap, format);
-       _debug_vprintf(format, ap);
-       va_end(ap);
-       tgsi_dump(ctx->tokens, 0);
-       debug_assert(0);
-}
-
-#define compile_assert(ctx, cond) do { \
-               if (!(cond)) compile_error((ctx), "failed assert: "#cond"\n"); \
-       } while (0)
-
-static void
-compile_free(struct ir3_compile_context *ctx)
-{
-       if (ctx->free_tokens)
-               free((void *)ctx->tokens);
-       tgsi_parse_free(&ctx->parser);
-}
-
-struct instr_translater {
-       void (*fxn)(const struct instr_translater *t,
-                       struct ir3_compile_context *ctx,
-                       struct tgsi_full_instruction *inst);
-       unsigned tgsi_opc;
-       opc_t opc;
-       opc_t hopc;    /* opc to use for half_precision mode, if different */
-       unsigned arg;
-};
-
-static void
-instr_finish(struct ir3_compile_context *ctx)
-{
-       unsigned i;
-
-       if (ctx->atomic)
-               return;
-
-       for (i = 0; i < ctx->num_output_updates; i++)
-               *(ctx->output_updates[i].instrp) = ctx->output_updates[i].instr;
-
-       ctx->num_output_updates = 0;
-
-       while (ctx->array_dirty) {
-               unsigned aid = ffs(ctx->array_dirty) - 1;
-               ctx->array[aid].fanin = NULL;
-               ctx->array_dirty &= ~(1 << aid);
-       }
-}
-
-/* For "atomic" groups of instructions, for example the four scalar
- * instructions to perform a vec4 operation.  Basically this just
- * blocks out handling of output_updates so the next scalar instruction
- * still sees the result from before the start of the atomic group.
- *
- * NOTE: when used properly, this could probably replace get/put_dst()
- * stuff.
- */
-static void
-instr_atomic_start(struct ir3_compile_context *ctx)
-{
-       ctx->atomic = true;
-}
-
-static void
-instr_atomic_end(struct ir3_compile_context *ctx)
-{
-       ctx->atomic = false;
-       instr_finish(ctx);
-}
-
-static struct ir3_instruction *
-instr_create(struct ir3_compile_context *ctx, int category, opc_t opc)
-{
-       instr_finish(ctx);
-       return (ctx->current_instr = ir3_instr_create(ctx->block, category, opc));
-}
-
-static struct ir3_block *
-push_block(struct ir3_compile_context *ctx)
-{
-       struct ir3_block *block;
-       unsigned ntmp, nin, nout;
-
-#define SCALAR_REGS(file) (4 * (ctx->info.file_max[TGSI_FILE_ ## file] + 1))
-
-       /* hmm, give ourselves room to create 8 extra temporaries (vec4):
-        */
-       ntmp = SCALAR_REGS(TEMPORARY);
-       ntmp += 8 * 4;
-
-       nout = SCALAR_REGS(OUTPUT);
-       nin  = SCALAR_REGS(INPUT) + SCALAR_REGS(SYSTEM_VALUE);
-
-       /* for outermost block, 'inputs' are the actual shader INPUT
-        * register file.  Reads from INPUT registers always go back to
-        * top block.  For nested blocks, 'inputs' is used to track any
-        * TEMPORARY file register from one of the enclosing blocks that
-        * is ready in this block.
-        */
-       if (!ctx->block) {
-               /* NOTE: fragment shaders actually have two inputs (r0.xy, the
-                * position)
-                */
-               if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
-                       int n = 2;
-                       if (ctx->info.reads_position)
-                               n += 4;
-                       if (ctx->info.uses_frontface)
-                               n += 4;
-                       nin = MAX2(n, nin);
-                       nout += ARRAY_SIZE(ctx->kill);
-               }
-       } else {
-               nin = ntmp;
-       }
-
-       block = ir3_block_create(ctx->ir, ntmp, nin, nout);
-
-       if ((ctx->type == TGSI_PROCESSOR_FRAGMENT) && !ctx->block)
-               block->noutputs -= ARRAY_SIZE(ctx->kill);
-
-       block->parent = ctx->block;
-       ctx->block = block;
-
-       return block;
-}
-
-static void
-pop_block(struct ir3_compile_context *ctx)
-{
-       ctx->block = ctx->block->parent;
-       compile_assert(ctx, ctx->block);
-}
-
-static struct ir3_instruction *
-create_output(struct ir3_block *block, struct ir3_instruction *instr,
-               unsigned n)
-{
-       struct ir3_instruction *out;
-
-       out = ir3_instr_create(block, -1, OPC_META_OUTPUT);
-       out->inout.block = block;
-       ir3_reg_create(out, n, 0);
-       if (instr)
-               ir3_reg_create(out, 0, IR3_REG_SSA)->instr = instr;
-
-       return out;
-}
-
-static struct ir3_instruction *
-create_input(struct ir3_block *block, struct ir3_instruction *instr,
-               unsigned n)
-{
-       struct ir3_instruction *in;
-
-       in = ir3_instr_create(block, -1, OPC_META_INPUT);
-       in->inout.block = block;
-       ir3_reg_create(in, n, 0);
-       if (instr)
-               ir3_reg_create(in, 0, IR3_REG_SSA)->instr = instr;
-
-       return in;
-}
-
-static struct ir3_instruction *
-block_input(struct ir3_block *block, unsigned n)
-{
-       /* references to INPUT register file always go back up to
-        * top level:
-        */
-       if (block->parent)
-               return block_input(block->parent, n);
-       return block->inputs[n];
-}
-
-/* return temporary in scope, creating if needed meta-input node
- * to track block inputs
- */
-static struct ir3_instruction *
-block_temporary(struct ir3_block *block, unsigned n)
-{
-       /* references to TEMPORARY register file, find the nearest
-        * enclosing block which has already assigned this temporary,
-        * creating meta-input instructions along the way to keep
-        * track of block inputs
-        */
-       if (block->parent && !block->temporaries[n]) {
-               /* if already have input for this block, reuse: */
-               if (!block->inputs[n])
-                       block->inputs[n] = block_temporary(block->parent, n);
-
-               /* and create new input to return: */
-               return create_input(block, block->inputs[n], n);
-       }
-       return block->temporaries[n];
-}
-
-static struct ir3_instruction *
-create_immed(struct ir3_compile_context *ctx, float val)
-{
-       /* NOTE: *don't* use instr_create() here!
-        */
-       struct ir3_instruction *instr;
-       instr = ir3_instr_create(ctx->block, 1, 0);
-       instr->cat1.src_type = get_ftype(ctx);
-       instr->cat1.dst_type = get_ftype(ctx);
-       ir3_reg_create(instr, 0, 0);
-       ir3_reg_create(instr, 0, IR3_REG_IMMED)->fim_val = val;
-       return instr;
-}
-
-static void
-ssa_instr_set(struct ir3_compile_context *ctx, unsigned file, unsigned n,
-               struct ir3_instruction *instr)
-{
-       struct ir3_block *block = ctx->block;
-       unsigned idx = ctx->num_output_updates;
-
-       compile_assert(ctx, idx < ARRAY_SIZE(ctx->output_updates));
-
-       /* NOTE: defer update of temporaries[idx] or output[idx]
-        * until instr_finish(), so that if the current instruction
-        * reads the same TEMP/OUT[] it gets the old value:
-        *
-        * bleh.. this might be a bit easier to just figure out
-        * in instr_finish().  But at that point we've already
-        * lost information about OUTPUT vs TEMPORARY register
-        * file..
-        */
-
-       switch (file) {
-       case TGSI_FILE_OUTPUT:
-               compile_assert(ctx, n < block->noutputs);
-               ctx->output_updates[idx].instrp = &block->outputs[n];
-               ctx->output_updates[idx].instr = instr;
-               ctx->num_output_updates++;
-               break;
-       case TGSI_FILE_TEMPORARY:
-               compile_assert(ctx, n < block->ntemporaries);
-               ctx->output_updates[idx].instrp = &block->temporaries[n];
-               ctx->output_updates[idx].instr = instr;
-               ctx->num_output_updates++;
-               break;
-       case TGSI_FILE_ADDRESS:
-               compile_assert(ctx, n < 1);
-               ctx->output_updates[idx].instrp = &block->address;
-               ctx->output_updates[idx].instr = instr;
-               ctx->num_output_updates++;
-               break;
-       }
-}
-
-static struct ir3_instruction *
-ssa_instr_get(struct ir3_compile_context *ctx, unsigned file, unsigned n)
-{
-       struct ir3_block *block = ctx->block;
-       struct ir3_instruction *instr = NULL;
-
-       switch (file) {
-       case TGSI_FILE_INPUT:
-               instr = block_input(ctx->block, n);
-               break;
-       case TGSI_FILE_OUTPUT:
-               /* really this should just happen in case of 'MOV_SAT OUT[n], ..',
-                * for the following clamp instructions:
-                */
-               instr = block->outputs[n];
-               /* we don't have to worry about read from an OUTPUT that was
-                * assigned outside of the current block, because the _SAT
-                * clamp instructions will always be in the same block as
-                * the original instruction which wrote the OUTPUT
-                */
-               compile_assert(ctx, instr);
-               break;
-       case TGSI_FILE_TEMPORARY:
-               instr = block_temporary(ctx->block, n);
-               if (!instr) {
-                       /* this can happen when registers (or components of a TGSI
-                        * register) are used as src before they have been assigned
-                        * (undefined contents).  To avoid confusing the rest of the
-                        * compiler, and to generally keep things peachy, substitute
-                        * an instruction that sets the src to 0.0.  Or to keep
-                        * things undefined, I could plug in a random number? :-P
-                        *
-                        * NOTE: *don't* use instr_create() here!
-                        */
-                       instr = create_immed(ctx, 0.0);
-                       /* no need to recreate the immed for every access: */
-                       block->temporaries[n] = instr;
-               }
-               break;
-       case TGSI_FILE_SYSTEM_VALUE:
-               switch (ctx->sysval_semantics[n >> 2]) {
-               case TGSI_SEMANTIC_VERTEXID_NOBASE:
-                       instr = ctx->vertex_id;
-                       break;
-               case TGSI_SEMANTIC_BASEVERTEX:
-                       instr = ctx->basevertex;
-                       break;
-               case TGSI_SEMANTIC_INSTANCEID:
-                       instr = ctx->instance_id;
-                       break;
-               }
-               break;
-       }
-
-       return instr;
-}
-
-static int dst_array_id(struct ir3_compile_context *ctx,
-               const struct tgsi_dst_register *dst)
-{
-       // XXX complete hack to recover tgsi_full_dst_register...
-       // nothing that isn't wrapped in a tgsi_full_dst_register
-       // should be indirect
-       const struct tgsi_full_dst_register *fdst = (const void *)dst;
-       return fdst->Indirect.ArrayID + ctx->array_offsets[dst->File];
-}
-
-static int src_array_id(struct ir3_compile_context *ctx,
-               const struct tgsi_src_register *src)
-{
-       // XXX complete hack to recover tgsi_full_src_register...
-       // nothing that isn't wrapped in a tgsi_full_src_register
-       // should be indirect
-       const struct tgsi_full_src_register *fsrc = (const void *)src;
-       debug_assert(src->File != TGSI_FILE_CONSTANT);
-       return fsrc->Indirect.ArrayID + ctx->array_offsets[src->File];
-}
-
-static struct ir3_instruction *
-array_fanin(struct ir3_compile_context *ctx, unsigned aid, unsigned file)
-{
-       struct ir3_instruction *instr;
-
-       if (ctx->array[aid].fanin) {
-               instr = ctx->array[aid].fanin;
-       } else {
-               unsigned first = ctx->array[aid].first;
-               unsigned last  = ctx->array[aid].last;
-               unsigned i, j;
-
-               instr = ir3_instr_create2(ctx->block, -1, OPC_META_FI,
-                               1 + (4 * (last + 1 - first)));
-               ir3_reg_create(instr, 0, 0);
-               for (i = first; i <= last; i++) {
-                       for (j = 0; j < 4; j++) {
-                               unsigned n = regid(i, j);
-                               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr =
-                                               ssa_instr_get(ctx, file, n);
-                       }
-               }
-               ctx->array[aid].fanin = instr;
-               ctx->array_dirty |= (1 << aid);
-       }
-
-       return instr;
-}
-
-static void
-ssa_dst(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
-               const struct tgsi_dst_register *dst, unsigned chan)
-{
-       if (dst->Indirect) {
-               struct ir3_register *reg = instr->regs[0];
-               unsigned i, aid = dst_array_id(ctx, dst);
-               unsigned first = ctx->array[aid].first;
-               unsigned last  = ctx->array[aid].last;
-               unsigned off   = dst->Index - first; /* vec4 offset */
-
-               reg->size = 4 * (1 + last - first);
-               reg->offset = regid(off, chan);
-
-               instr->fanin = array_fanin(ctx, aid, dst->File);
-
-               /* annotate with the array-id, to help out the register-
-                * assignment stage.  At least for the case of indirect
-                * writes, we should capture enough dependencies to
-                * preserve the order of reads/writes of the array, so
-                * the multiple "names" for the array should end up all
-                * assigned to the same registers.
-                */
-               instr->fanin->fi.aid = aid;
 
-               /* Since we are scalarizing vec4 tgsi instructions/regs, we
-                * run into a slight complication here.  To do the naive thing
-                * and setup a fanout for each scalar array element would end
-                * up with the result that the instructions generated for each
-                * component of the vec4 would end up clobbering each other.
-                * So we take advantage here of knowing that the array index
-                * (after the shl.b) will be a multiple of four, and only set
-                * every fourth scalar component in the array.  See also
-                * fixup_ssa_dst_array()
-                */
-               for (i = first; i <= last; i++) {
-                       struct ir3_instruction *split;
-                       unsigned n = regid(i, chan);
-                       int off = (4 * (i - first)) + chan;
-
-                       if (is_meta(instr) && (instr->opc == OPC_META_FO))
-                               off -= instr->fo.off;
-
-                       split = ir3_instr_create(ctx->block, -1, OPC_META_FO);
-                       split->fo.off = off;
-                       ir3_reg_create(split, 0, 0);
-                       ir3_reg_create(split, 0, IR3_REG_SSA)->instr = instr;
-
-                       ssa_instr_set(ctx, dst->File, n, split);
-               }
-       } else {
-               /* normal case (not relative addressed GPR) */
-               ssa_instr_set(ctx, dst->File, regid(dst->Index, chan), instr);
-       }
-}
-
-static void
-ssa_src(struct ir3_compile_context *ctx, struct ir3_register *reg,
-               const struct tgsi_src_register *src, unsigned chan)
-{
-       struct ir3_instruction *instr;
-
-       if (src->Indirect && (src->File != TGSI_FILE_CONSTANT)) {
-               /* for relative addressing of gpr's (due to register assignment)
-                * we must generate a fanin instruction to collect all possible
-                * array elements that the instruction could address together:
-                */
-               unsigned aid   = src_array_id(ctx, src);
-               unsigned first = ctx->array[aid].first;
-               unsigned last  = ctx->array[aid].last;
-               unsigned off   = src->Index - first; /* vec4 offset */
-
-               reg->size = 4 * (1 + last - first);
-               reg->offset = regid(off, chan);
-
-               instr = array_fanin(ctx, aid, src->File);
-       } else if (src->File == TGSI_FILE_CONSTANT && src->Dimension) {
-               const struct tgsi_full_src_register *fsrc = (const void *)src;
-               struct ir3_instruction *temp = NULL;
-               int ubo_regid = regid(ctx->so->first_driver_param, 0) +
-                       fsrc->Dimension.Index - 1;
-               int offset = 0;
-
-               /* We don't handle indirect UBO array accesses... yet. */
-               compile_assert(ctx, !fsrc->Dimension.Indirect);
-               /* UBOs start at index 1. */
-               compile_assert(ctx, fsrc->Dimension.Index > 0);
-
-               if (src->Indirect) {
-                       /* In case of an indirect index, it will have been loaded into an
-                        * address register. There will be a sequence of
-                        *
-                        *   shl.b x, val, 2
-                        *   mova a0, x
-                        *
-                        * We rely on this sequence to get the original val out and shift
-                        * it by 4, since we're dealing in vec4 units.
-                        */
-                       compile_assert(ctx, ctx->block->address);
-                       compile_assert(ctx, ctx->block->address->regs[1]->instr->opc ==
-                                                  OPC_SHL_B);
-
-                       temp = instr = instr_create(ctx, 2, OPC_SHL_B);
-                       ir3_reg_create(instr, 0, 0);
-                       ir3_reg_create(instr, 0, IR3_REG_HALF | IR3_REG_SSA)->instr =
-                               ctx->block->address->regs[1]->instr->regs[1]->instr;
-                       ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 4;
-               } else if (src->Index >= 64) {
-                       /* Otherwise it's a plain index (in vec4 units). Move it into a
-                        * register.
-                        */
-                       temp = instr = instr_create(ctx, 1, 0);
-                       instr->cat1.src_type = get_utype(ctx);
-                       instr->cat1.dst_type = get_utype(ctx);
-                       ir3_reg_create(instr, 0, 0);
-                       ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = src->Index * 16;
-               } else {
-                       /* The offset is small enough to fit into the ldg instruction
-                        * directly.
-                        */
-                       offset = src->Index * 16;
-               }
-
-               if (temp) {
-                       /* If there was an offset (most common), add it to the buffer
-                        * address.
-                        */
-                       instr = instr_create(ctx, 2, OPC_ADD_S);
-                       ir3_reg_create(instr, 0, 0);
-                       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = temp;
-                       ir3_reg_create(instr, ubo_regid, IR3_REG_CONST);
-               } else {
-                       /* Otherwise just load the buffer address directly */
-                       instr = instr_create(ctx, 1, 0);
-                       instr->cat1.src_type = get_utype(ctx);
-                       instr->cat1.dst_type = get_utype(ctx);
-                       ir3_reg_create(instr, 0, 0);
-                       ir3_reg_create(instr, ubo_regid, IR3_REG_CONST);
-               }
-
-               temp = instr;
-
-               instr = instr_create(ctx, 6, OPC_LDG);
-               instr->cat6.type = TYPE_U32;
-               instr->cat6.offset = offset + chan * 4;
-               ir3_reg_create(instr, 0, 0);
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = temp;
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1;
-
-               reg->flags &= ~(IR3_REG_RELATIV | IR3_REG_CONST);
-       } else {
-               /* normal case (not relative addressed GPR) */
-               instr = ssa_instr_get(ctx, src->File, regid(src->Index, chan));
-       }
-
-       if (instr) {
-               reg->flags |= IR3_REG_SSA;
-               reg->instr = instr;
-       } else if (reg->flags & IR3_REG_SSA) {
-               /* special hack for trans_samp() which calls ssa_src() directly
-                * to build up the collect (fanin) for const src.. (so SSA flag
-                * set but no src instr... it basically gets lucky because we
-                * default to 0.0 for "undefined" src instructions, which is
-                * what it wants.  We probably need to give it a better way to
-                * do this, but for now this hack:
-                */
-               reg->instr = create_immed(ctx, 0.0);
-       }
-}
-
-static struct ir3_register *
-add_dst_reg_wrmask(struct ir3_compile_context *ctx,
-               struct ir3_instruction *instr, const struct tgsi_dst_register *dst,
-               unsigned chan, unsigned wrmask)
-{
-       unsigned flags = 0, num = 0;
-       struct ir3_register *reg;
-
-       switch (dst->File) {
-       case TGSI_FILE_OUTPUT:
-       case TGSI_FILE_TEMPORARY:
-               /* uses SSA */
-               break;
-       case TGSI_FILE_ADDRESS:
-               flags |= IR3_REG_ADDR;
-               /* uses SSA */
-               break;
-       default:
-               compile_error(ctx, "unsupported dst register file: %s\n",
-                       tgsi_file_name(dst->File));
-               break;
-       }
-
-       if (dst->Indirect) {
-               flags |= IR3_REG_RELATIV;
-
-               /* shouldn't happen, and we can't cope with it below: */
-               compile_assert(ctx, wrmask == 0x1);
-
-               compile_assert(ctx, ctx->block->address);
-               if (instr->address)
-                       compile_assert(ctx, ctx->block->address == instr->address);
-
-               instr->address = ctx->block->address;
-               array_insert(ctx->ir->indirects, instr);
-       }
-
-       reg = ir3_reg_create(instr, regid(num, chan), flags);
-       reg->wrmask = wrmask;
-
-       if (wrmask == 0x1) {
-               /* normal case */
-               ssa_dst(ctx, instr, dst, chan);
-       } else if ((dst->File == TGSI_FILE_TEMPORARY) ||
-                       (dst->File == TGSI_FILE_OUTPUT) ||
-                       (dst->File == TGSI_FILE_ADDRESS)) {
-               struct ir3_instruction *prev = NULL;
-               unsigned i;
-
-               compile_assert(ctx, !dst->Indirect);
-
-               /* if instruction writes multiple, we need to create
-                * some place-holder collect the registers:
-                */
-               for (i = 0; i < 4; i++) {
-                       /* NOTE: slightly ugly that we setup neighbor ptrs
-                        * for FO here, but handle FI in CP pass.. we should
-                        * probably just always setup neighbor ptrs in the
-                        * frontend?
-                        */
-                       struct ir3_instruction *split =
-                                       ir3_instr_create(ctx->block, -1, OPC_META_FO);
-                       split->fo.off = i;
-                       /* unused dst reg: */
-                       /* NOTE: set SSA flag on dst here, because unused FO's
-                        * which don't get scheduled will end up not in the
-                        * instruction list when RA sets SSA flag on each dst.
-                        * Slight hack.  We really should set SSA flag on
-                        * every dst register in the frontend.
-                        */
-                       ir3_reg_create(split, 0, IR3_REG_SSA);
-                       /* and src reg used to hold original instr */
-                       ir3_reg_create(split, 0, IR3_REG_SSA)->instr = instr;
-                       if (prev) {
-                               split->cp.left = prev;
-                               split->cp.left_cnt++;
-                               prev->cp.right = split;
-                               prev->cp.right_cnt++;
-                       }
-                       if ((wrmask & (1 << i)) && !ctx->atomic)
-                               ssa_dst(ctx, split, dst, chan+i);
-                       prev = split;
-               }
-       }
-
-       return reg;
-}
-
-static struct ir3_register *
-add_dst_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
-               const struct tgsi_dst_register *dst, unsigned chan)
-{
-       return add_dst_reg_wrmask(ctx, instr, dst, chan, 0x1);
-}
-
-static struct ir3_register *
-add_src_reg_wrmask(struct ir3_compile_context *ctx,
-               struct ir3_instruction *instr, const struct tgsi_src_register *src,
-               unsigned chan, unsigned wrmask)
-{
-       unsigned flags = 0, num = 0;
-       struct ir3_register *reg;
-
-       switch (src->File) {
-       case TGSI_FILE_IMMEDIATE:
-               /* TODO if possible, use actual immediate instead of const.. but
-                * TGSI has vec4 immediates, we can only embed scalar (of limited
-                * size, depending on instruction..)
-                */
-               flags |= IR3_REG_CONST;
-               num = src->Index + ctx->so->first_immediate;
-               break;
-       case TGSI_FILE_CONSTANT:
-               flags |= IR3_REG_CONST;
-               num = src->Index;
-               break;
-       case TGSI_FILE_OUTPUT:
-               /* NOTE: we should only end up w/ OUTPUT file for things like
-                * clamp()'ing saturated dst instructions
-                */
-       case TGSI_FILE_INPUT:
-       case TGSI_FILE_TEMPORARY:
-       case TGSI_FILE_SYSTEM_VALUE:
-               /* uses SSA */
-               break;
-       default:
-               compile_error(ctx, "unsupported src register file: %s\n",
-                       tgsi_file_name(src->File));
-               break;
-       }
-
-       /* We seem to have 8 bits (6.2) for dst register always, so I think
-        * it is safe to assume GPR cannot be >=64
-        *
-        * cat3 instructions only have 8 bits for src2, but cannot take a
-        * const for src2
-        *
-        * cat5 and cat6 in some cases only has 8 bits, but cannot take a
-        * const for any src.
-        *
-        * Other than that we seem to have 12 bits to encode const src,
-        * except for cat1 which may only have 11 bits (but that seems like
-        * a bug)
-        */
-       if (flags & IR3_REG_CONST)
-               compile_assert(ctx, src->Index < (1 << 9));
-       else
-               compile_assert(ctx, src->Index < (1 << 6));
-
-       /* NOTE: abs/neg modifiers in tgsi only apply to float */
-       if (src->Absolute)
-               flags |= IR3_REG_FABS;
-       if (src->Negate)
-               flags |= IR3_REG_FNEG;
-
-       if (src->Indirect) {
-               flags |= IR3_REG_RELATIV;
-
-               /* shouldn't happen, and we can't cope with it below: */
-               compile_assert(ctx, wrmask == 0x1);
-
-               compile_assert(ctx, ctx->block->address);
-               if (instr->address)
-                       compile_assert(ctx, ctx->block->address == instr->address);
-
-               instr->address = ctx->block->address;
-               array_insert(ctx->ir->indirects, instr);
-       }
-
-       reg = ir3_reg_create(instr, regid(num, chan), flags);
-       reg->wrmask = wrmask;
-
-       if (wrmask == 0x1) {
-               /* normal case */
-               ssa_src(ctx, reg, src, chan);
-       } else if ((src->File == TGSI_FILE_TEMPORARY) ||
-                       (src->File == TGSI_FILE_OUTPUT) ||
-                       (src->File == TGSI_FILE_INPUT)) {
-               struct ir3_instruction *collect;
-               unsigned i;
-
-               compile_assert(ctx, !src->Indirect);
-
-               /* if instruction reads multiple, we need to create
-                * some place-holder collect the registers:
-                */
-               collect = ir3_instr_create(ctx->block, -1, OPC_META_FI);
-               ir3_reg_create(collect, 0, 0);   /* unused dst reg */
-
-               for (i = 0; i < 4; i++) {
-                       if (wrmask & (1 << i)) {
-                               /* and src reg used point to the original instr */
-                               ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA),
-                                               src, chan + i);
-                       } else if (wrmask & ~((i << i) - 1)) {
-                               /* if any remaining components, then dummy
-                                * placeholder src reg to fill in the blanks:
-                                */
-                               ir3_reg_create(collect, 0, 0);
-                       }
-               }
-
-               reg->flags |= IR3_REG_SSA;
-               reg->instr = collect;
-       }
-
-       return reg;
-}
-
-static struct ir3_register *
-add_src_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
-               const struct tgsi_src_register *src, unsigned chan)
-{
-       return add_src_reg_wrmask(ctx, instr, src, chan, 0x1);
-}
-
-static void
-src_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst)
-{
-       src->File      = dst->File;
-       src->Indirect  = dst->Indirect;
-       src->Dimension = dst->Dimension;
-       src->Index     = dst->Index;
-       src->Absolute  = 0;
-       src->Negate    = 0;
-       src->SwizzleX  = TGSI_SWIZZLE_X;
-       src->SwizzleY  = TGSI_SWIZZLE_Y;
-       src->SwizzleZ  = TGSI_SWIZZLE_Z;
-       src->SwizzleW  = TGSI_SWIZZLE_W;
-}
-
-/* Get internal-temp src/dst to use for a sequence of instructions
- * generated by a single TGSI op.
- */
-static struct tgsi_src_register *
-get_internal_temp(struct ir3_compile_context *ctx,
-               struct tgsi_dst_register *tmp_dst)
-{
-       struct tgsi_src_register *tmp_src;
-       int n;
-
-       tmp_dst->File      = TGSI_FILE_TEMPORARY;
-       tmp_dst->WriteMask = TGSI_WRITEMASK_XYZW;
-       tmp_dst->Indirect  = 0;
-       tmp_dst->Dimension = 0;
-
-       /* assign next temporary: */
-       n = ctx->num_internal_temps++;
-       compile_assert(ctx, n < ARRAY_SIZE(ctx->internal_temps));
-       tmp_src = &ctx->internal_temps[n];
-
-       tmp_dst->Index = ctx->info.file_max[TGSI_FILE_TEMPORARY] + n + 1;
-
-       src_from_dst(tmp_src, tmp_dst);
-
-       return tmp_src;
-}
-
-static inline bool
-is_const(struct tgsi_src_register *src)
-{
-       return (src->File == TGSI_FILE_CONSTANT) ||
-                       (src->File == TGSI_FILE_IMMEDIATE);
-}
-
-static inline bool
-is_relative(struct tgsi_src_register *src)
-{
-       return src->Indirect;
-}
-
-static inline bool
-is_rel_or_const(struct tgsi_src_register *src)
-{
-       return is_relative(src) || is_const(src);
-}
-
-static type_t
-get_ftype(struct ir3_compile_context *ctx)
-{
-       return TYPE_F32;
-}
-
-static type_t
-get_utype(struct ir3_compile_context *ctx)
-{
-       return TYPE_U32;
-}
-
-static type_t
-get_stype(struct ir3_compile_context *ctx)
-{
-       return TYPE_S32;
-}
-
-static unsigned
-src_swiz(struct tgsi_src_register *src, int chan)
-{
-       switch (chan) {
-       case 0: return src->SwizzleX;
-       case 1: return src->SwizzleY;
-       case 2: return src->SwizzleZ;
-       case 3: return src->SwizzleW;
-       }
-       assert(0);
-       return 0;
-}
-
-/* for instructions that cannot take a const register as src, if needed
- * generate a move to temporary gpr:
- */
-static struct tgsi_src_register *
-get_unconst(struct ir3_compile_context *ctx, struct tgsi_src_register *src)
-{
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-
-       compile_assert(ctx, is_rel_or_const(src));
-
-       tmp_src = get_internal_temp(ctx, &tmp_dst);
-
-       create_mov(ctx, &tmp_dst, src);
-
-       return tmp_src;
-}
-
-static void
-get_immediate(struct ir3_compile_context *ctx,
-               struct tgsi_src_register *reg, uint32_t val)
+struct ir3_compiler * ir3_compiler_create(uint32_t gpu_id)
 {
-       unsigned neg, swiz, idx, i;
-       /* actually maps 1:1 currently.. not sure if that is safe to rely on: */
-       static const unsigned swiz2tgsi[] = {
-                       TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W,
-       };
-
-       for (i = 0; i < ctx->immediate_idx; i++) {
-               swiz = i % 4;
-               idx  = i / 4;
-
-               if (ctx->so->immediates[idx].val[swiz] == val) {
-                       neg = 0;
-                       break;
-               }
-
-               if (ctx->so->immediates[idx].val[swiz] == -val) {
-                       neg = 1;
-                       break;
-               }
-       }
-
-       if (i == ctx->immediate_idx) {
-               /* need to generate a new immediate: */
-               swiz = i % 4;
-               idx  = i / 4;
-               neg  = 0;
-               ctx->so->immediates[idx].val[swiz] = val;
-               ctx->so->immediates_count = idx + 1;
-               ctx->immediate_idx++;
-       }
-
-       reg->File      = TGSI_FILE_IMMEDIATE;
-       reg->Indirect  = 0;
-       reg->Dimension = 0;
-       reg->Index     = idx;
-       reg->Absolute  = 0;
-       reg->Negate    = neg;
-       reg->SwizzleX  = swiz2tgsi[swiz];
-       reg->SwizzleY  = swiz2tgsi[swiz];
-       reg->SwizzleZ  = swiz2tgsi[swiz];
-       reg->SwizzleW  = swiz2tgsi[swiz];
-}
-
-static void
-create_mov(struct ir3_compile_context *ctx, struct tgsi_dst_register *dst,
-               struct tgsi_src_register *src)
-{
-       type_t type_mov = get_ftype(ctx);
-       unsigned i;
-
-       for (i = 0; i < 4; i++) {
-               /* move to destination: */
-               if (dst->WriteMask & (1 << i)) {
-                       struct ir3_instruction *instr;
-
-                       if (src->Absolute || src->Negate) {
-                               /* can't have abs or neg on a mov instr, so use
-                                * absneg.f instead to handle these cases:
-                                */
-                               instr = instr_create(ctx, 2, OPC_ABSNEG_F);
-                       } else {
-                               instr = instr_create(ctx, 1, 0);
-                               instr->cat1.src_type = type_mov;
-                               instr->cat1.dst_type = type_mov;
-                       }
-
-                       add_dst_reg(ctx, instr, dst, i);
-                       add_src_reg(ctx, instr, src, src_swiz(src, i));
-               }
-       }
-}
-
-static void
-create_clamp(struct ir3_compile_context *ctx,
-               struct tgsi_dst_register *dst, struct tgsi_src_register *val,
-               struct tgsi_src_register *minval, struct tgsi_src_register *maxval)
-{
-       struct ir3_instruction *instr;
-
-       instr = instr_create(ctx, 2, OPC_MAX_F);
-       vectorize(ctx, instr, dst, 2, val, 0, minval, 0);
-
-       instr = instr_create(ctx, 2, OPC_MIN_F);
-       vectorize(ctx, instr, dst, 2, val, 0, maxval, 0);
+       struct ir3_compiler *compiler = rzalloc(NULL, struct ir3_compiler);
+       compiler->gpu_id = gpu_id;
+       compiler->set = ir3_ra_alloc_reg_set(compiler);
+       return compiler;
 }
 
-static void
-create_clamp_imm(struct ir3_compile_context *ctx,
-               struct tgsi_dst_register *dst,
-               uint32_t minval, uint32_t maxval)
-{
-       struct tgsi_src_register minconst, maxconst;
-       struct tgsi_src_register src;
-
-       src_from_dst(&src, dst);
-
-       get_immediate(ctx, &minconst, minval);
-       get_immediate(ctx, &maxconst, maxval);
-
-       create_clamp(ctx, dst, &src, &minconst, &maxconst);
-}
-
-static struct tgsi_dst_register *
-get_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst)
-{
-       struct tgsi_dst_register *dst = &inst->Dst[0].Register;
-       unsigned i;
-
-       compile_assert(ctx, !ctx->using_tmp_dst);
-       ctx->using_tmp_dst = true;
-
-       for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-               struct tgsi_src_register *src = &inst->Src[i].Register;
-               if ((src->File == dst->File) && (src->Index == dst->Index)) {
-                       if ((dst->WriteMask == TGSI_WRITEMASK_XYZW) &&
-                                       (src->SwizzleX == TGSI_SWIZZLE_X) &&
-                                       (src->SwizzleY == TGSI_SWIZZLE_Y) &&
-                                       (src->SwizzleZ == TGSI_SWIZZLE_Z) &&
-                                       (src->SwizzleW == TGSI_SWIZZLE_W))
-                               continue;
-                       ctx->tmp_src = get_internal_temp(ctx, &ctx->tmp_dst);
-                       ctx->tmp_dst.WriteMask = dst->WriteMask;
-                       dst = &ctx->tmp_dst;
-                       break;
-               }
-       }
-       return dst;
-}
-
-static void
-put_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst,
-               struct tgsi_dst_register *dst)
-{
-       compile_assert(ctx, ctx->using_tmp_dst);
-       ctx->using_tmp_dst = false;
-
-       /* if necessary, add mov back into original dst: */
-       if (dst != &inst->Dst[0].Register) {
-               create_mov(ctx, &inst->Dst[0].Register, ctx->tmp_src);
-       }
-}
-
-/* helper to generate the necessary repeat and/or additional instructions
- * to turn a scalar instruction into a vector operation:
- */
-static void
-vectorize(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
-               struct tgsi_dst_register *dst, int nsrcs, ...)
+void ir3_compiler_destroy(struct ir3_compiler *compiler)
 {
-       va_list ap;
-       int i, j, n = 0;
-
-       instr_atomic_start(ctx);
-
-       for (i = 0; i < 4; i++) {
-               if (dst->WriteMask & (1 << i)) {
-                       struct ir3_instruction *cur;
-
-                       if (n++ == 0) {
-                               cur = instr;
-                       } else {
-                               cur = instr_create(ctx, instr->category, instr->opc);
-                               memcpy(cur->info, instr->info, sizeof(cur->info));
-                       }
-
-                       add_dst_reg(ctx, cur, dst, i);
-
-                       va_start(ap, nsrcs);
-                       for (j = 0; j < nsrcs; j++) {
-                               struct tgsi_src_register *src =
-                                               va_arg(ap, struct tgsi_src_register *);
-                               unsigned flags = va_arg(ap, unsigned);
-                               struct ir3_register *reg;
-                               if (flags & IR3_REG_IMMED) {
-                                       reg = ir3_reg_create(cur, 0, IR3_REG_IMMED);
-                                       /* this is an ugly cast.. should have put flags first! */
-                                       reg->iim_val = *(int *)&src;
-                               } else {
-                                       reg = add_src_reg(ctx, cur, src, src_swiz(src, i));
-                               }
-                               reg->flags |= flags & ~(IR3_REG_FNEG | IR3_REG_SNEG);
-                               if (flags & IR3_REG_FNEG)
-                                       reg->flags ^= IR3_REG_FNEG;
-                               if (flags & IR3_REG_SNEG)
-                                       reg->flags ^= IR3_REG_SNEG;
-                       }
-                       va_end(ap);
-               }
-       }
-
-       instr_atomic_end(ctx);
-}
-
-/*
- * Handlers for TGSI instructions which do not have a 1:1 mapping to
- * native instructions:
- */
-
-static void
-trans_clamp(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *src0 = &inst->Src[0].Register;
-       struct tgsi_src_register *src1 = &inst->Src[1].Register;
-       struct tgsi_src_register *src2 = &inst->Src[2].Register;
-
-       create_clamp(ctx, dst, src0, src1, src2);
-
-       put_dst(ctx, inst, dst);
-}
-
-/* ARL(x) = x, but mova from hrN.x to a0.. */
-static void
-trans_arl(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-       struct tgsi_dst_register *dst = &inst->Dst[0].Register;
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-       unsigned chan = src->SwizzleX;
-
-       compile_assert(ctx, dst->File == TGSI_FILE_ADDRESS);
-
-       /* NOTE: we allocate a temporary from a flat register
-        * namespace (ignoring half vs full).  It turns out
-        * not to really matter since registers get reassigned
-        * later in ir3_ra which (hopefully!) can deal a bit
-        * better with mixed half and full precision.
-        */
-       tmp_src = get_internal_temp(ctx, &tmp_dst);
-
-       /* cov.{u,f}{32,16}s16 Rtmp, Rsrc */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = (t->tgsi_opc == TGSI_OPCODE_ARL) ?
-                       get_ftype(ctx) : get_utype(ctx);
-       instr->cat1.dst_type = TYPE_S16;
-       add_dst_reg(ctx, instr, &tmp_dst, chan)->flags |= IR3_REG_HALF;
-       add_src_reg(ctx, instr, src, chan);
-
-       /* shl.b Rtmp, Rtmp, 2 */
-       instr = instr_create(ctx, 2, OPC_SHL_B);
-       add_dst_reg(ctx, instr, &tmp_dst, chan)->flags |= IR3_REG_HALF;
-       add_src_reg(ctx, instr, tmp_src, chan)->flags |= IR3_REG_HALF;
-       ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 2;
-
-       /* mova a0, Rtmp */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = TYPE_S16;
-       instr->cat1.dst_type = TYPE_S16;
-       add_dst_reg(ctx, instr, dst, 0)->flags |= IR3_REG_HALF;
-       add_src_reg(ctx, instr, tmp_src, chan)->flags |= IR3_REG_HALF;
-}
-
-/*
- * texture fetch/sample instructions:
- */
-
-struct tex_info {
-       int8_t order[4];
-       int8_t args;
-       unsigned src_wrmask, flags;
-};
-
-struct target_info {
-       uint8_t dims;
-       uint8_t cube;
-       uint8_t array;
-       uint8_t shadow;
-};
-
-static const struct target_info tex_targets[] = {
-       [TGSI_TEXTURE_1D]               = { 1, 0, 0, 0 },
-       [TGSI_TEXTURE_2D]               = { 2, 0, 0, 0 },
-       [TGSI_TEXTURE_3D]               = { 3, 0, 0, 0 },
-       [TGSI_TEXTURE_CUBE]             = { 3, 1, 0, 0 },
-       [TGSI_TEXTURE_RECT]             = { 2, 0, 0, 0 },
-       [TGSI_TEXTURE_SHADOW1D]         = { 1, 0, 0, 1 },
-       [TGSI_TEXTURE_SHADOW2D]         = { 2, 0, 0, 1 },
-       [TGSI_TEXTURE_SHADOWRECT]       = { 2, 0, 0, 1 },
-       [TGSI_TEXTURE_1D_ARRAY]         = { 1, 0, 1, 0 },
-       [TGSI_TEXTURE_2D_ARRAY]         = { 2, 0, 1, 0 },
-       [TGSI_TEXTURE_SHADOW1D_ARRAY]   = { 1, 0, 1, 1 },
-       [TGSI_TEXTURE_SHADOW2D_ARRAY]   = { 2, 0, 1, 1 },
-       [TGSI_TEXTURE_SHADOWCUBE]       = { 3, 1, 0, 1 },
-       [TGSI_TEXTURE_2D_MSAA]          = { 2, 0, 0, 0 },
-       [TGSI_TEXTURE_2D_ARRAY_MSAA]    = { 2, 0, 1, 0 },
-       [TGSI_TEXTURE_CUBE_ARRAY]       = { 3, 1, 1, 0 },
-       [TGSI_TEXTURE_SHADOWCUBE_ARRAY] = { 3, 1, 1, 1 },
-};
-
-static void
-fill_tex_info(struct ir3_compile_context *ctx,
-                         struct tgsi_full_instruction *inst,
-                         struct tex_info *info)
-{
-       const struct target_info *tgt = &tex_targets[inst->Texture.Texture];
-
-       if (tgt->dims == 3)
-               info->flags |= IR3_INSTR_3D;
-       if (tgt->array)
-               info->flags |= IR3_INSTR_A;
-       if (tgt->shadow)
-               info->flags |= IR3_INSTR_S;
-
-       switch (inst->Instruction.Opcode) {
-       case TGSI_OPCODE_TXB:
-       case TGSI_OPCODE_TXB2:
-       case TGSI_OPCODE_TXL:
-       case TGSI_OPCODE_TXF:
-               info->args = 2;
-               break;
-       case TGSI_OPCODE_TXP:
-               info->flags |= IR3_INSTR_P;
-               /* fallthrough */
-       case TGSI_OPCODE_TEX:
-       case TGSI_OPCODE_TXD:
-               info->args = 1;
-               break;
-       }
-
-       /*
-        * lay out the first argument in the proper order:
-        *  - actual coordinates first
-        *  - shadow reference
-        *  - array index
-        *  - projection w
-        *
-        * bias/lod go into the second arg
-        */
-       int arg, pos = 0;
-       for (arg = 0; arg < tgt->dims; arg++)
-               info->order[arg] = pos++;
-       if (tgt->dims == 1)
-               info->order[pos++] = -1;
-       if (tgt->shadow)
-               info->order[pos++] = MAX2(arg + tgt->array, 2);
-       if (tgt->array)
-               info->order[pos++] = arg++;
-       if (info->flags & IR3_INSTR_P)
-               info->order[pos++] = 3;
-
-       info->src_wrmask = (1 << pos) - 1;
-
-       for (; pos < 4; pos++)
-               info->order[pos] = -1;
-
-       assert(pos <= 4);
-}
-
-static bool check_swiz(struct tgsi_src_register *src, const int8_t order[4])
-{
-       unsigned i;
-       for (i = 1; (i < 4) && order[i] >= 0; i++)
-               if (src_swiz(src, i) != (src_swiz(src, 0) + order[i]))
-                       return false;
-       return true;
-}
-
-static bool is_1d(unsigned tex)
-{
-       return tex_targets[tex].dims == 1;
-}
-
-static struct tgsi_src_register *
-get_tex_coord(struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst,
-               const struct tex_info *tinf)
-{
-       struct tgsi_src_register *coord = &inst->Src[0].Register;
-       struct ir3_instruction *instr;
-       unsigned tex = inst->Texture.Texture;
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-       type_t type_mov = get_ftype(ctx);
-       unsigned j;
-
-       /* need to move things around: */
-       tmp_src = get_internal_temp(ctx, &tmp_dst);
-
-       for (j = 0; j < 4; j++) {
-               if (tinf->order[j] < 0)
-                       continue;
-               instr = instr_create(ctx, 1, 0);  /* mov */
-               instr->cat1.src_type = type_mov;
-               instr->cat1.dst_type = type_mov;
-               add_dst_reg(ctx, instr, &tmp_dst, j);
-               add_src_reg(ctx, instr, coord,
-                               src_swiz(coord, tinf->order[j]));
-       }
-
-       /* fix up .y coord: */
-       if (is_1d(tex)) {
-               struct ir3_register *imm;
-               instr = instr_create(ctx, 1, 0);  /* mov */
-               instr->cat1.src_type = type_mov;
-               instr->cat1.dst_type = type_mov;
-               add_dst_reg(ctx, instr, &tmp_dst, 1);  /* .y */
-               imm = ir3_reg_create(instr, 0, IR3_REG_IMMED);
-               if (inst->Instruction.Opcode == TGSI_OPCODE_TXF)
-                       imm->iim_val = 0;
-               else
-                       imm->fim_val = 0.5;
-       }
-
-       return tmp_src;
-}
-
-static void
-trans_samp(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr, *collect;
-       struct ir3_register *reg;
-       struct tgsi_dst_register *dst = &inst->Dst[0].Register;
-       struct tgsi_src_register *orig, *coord, *samp, *offset, *dpdx, *dpdy;
-       struct tgsi_src_register zero;
-       const struct target_info *tgt = &tex_targets[inst->Texture.Texture];
-       struct tex_info tinf;
-       int i;
-
-       memset(&tinf, 0, sizeof(tinf));
-       fill_tex_info(ctx, inst, &tinf);
-       coord = get_tex_coord(ctx, inst, &tinf);
-       get_immediate(ctx, &zero, 0);
-
-       switch (inst->Instruction.Opcode) {
-       case TGSI_OPCODE_TXB2:
-               orig = &inst->Src[1].Register;
-               samp = &inst->Src[2].Register;
-               break;
-       case TGSI_OPCODE_TXD:
-               orig = &inst->Src[0].Register;
-               dpdx = &inst->Src[1].Register;
-               dpdy = &inst->Src[2].Register;
-               samp = &inst->Src[3].Register;
-               if (is_rel_or_const(dpdx))
-                               dpdx = get_unconst(ctx, dpdx);
-               if (is_rel_or_const(dpdy))
-                               dpdy = get_unconst(ctx, dpdy);
-               break;
-       default:
-               orig = &inst->Src[0].Register;
-               samp = &inst->Src[1].Register;
-               break;
-       }
-       if (tinf.args > 1 && is_rel_or_const(orig))
-               orig = get_unconst(ctx, orig);
-
-       /* scale up integer coords for TXF based on the LOD */
-       if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
-               struct tgsi_dst_register tmp_dst;
-               struct tgsi_src_register *tmp_src;
-               type_t type_mov = get_utype(ctx);
-
-               tmp_src = get_internal_temp(ctx, &tmp_dst);
-               for (i = 0; i < tgt->dims; i++) {
-                       instr = instr_create(ctx, 2, OPC_SHL_B);
-                       add_dst_reg(ctx, instr, &tmp_dst, i);
-                       add_src_reg(ctx, instr, coord, src_swiz(coord, i));
-                       add_src_reg(ctx, instr, orig, orig->SwizzleW);
-               }
-               if (tgt->dims < 2) {
-                       instr = instr_create(ctx, 1, 0);
-                       instr->cat1.src_type = type_mov;
-                       instr->cat1.dst_type = type_mov;
-                       add_dst_reg(ctx, instr, &tmp_dst, i);
-                       add_src_reg(ctx, instr, &zero, 0);
-                       i++;
-               }
-               if (tgt->array) {
-                       instr = instr_create(ctx, 1, 0);
-                       instr->cat1.src_type = type_mov;
-                       instr->cat1.dst_type = type_mov;
-                       add_dst_reg(ctx, instr, &tmp_dst, i);
-                       add_src_reg(ctx, instr, coord, src_swiz(coord, i));
-               }
-               coord = tmp_src;
-       }
-
-       if (inst->Texture.NumOffsets) {
-               struct tgsi_texture_offset *tex_offset = &inst->TexOffsets[0];
-               struct tgsi_src_register offset_src = {0};
-
-               offset_src.File = tex_offset->File;
-               offset_src.Index = tex_offset->Index;
-               offset_src.SwizzleX = tex_offset->SwizzleX;
-               offset_src.SwizzleY = tex_offset->SwizzleY;
-               offset_src.SwizzleZ = tex_offset->SwizzleZ;
-               offset = get_unconst(ctx, &offset_src);
-               tinf.flags |= IR3_INSTR_O;
-       }
-
-       instr = instr_create(ctx, 5, t->opc);
-       if (ctx->integer_s & (1 << samp->Index))
-               instr->cat5.type = get_utype(ctx);
-       else
-               instr->cat5.type = get_ftype(ctx);
-       instr->cat5.samp = samp->Index;
-       instr->cat5.tex  = samp->Index;
-       instr->flags |= tinf.flags;
-
-       add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask);
-
-       reg = ir3_reg_create(instr, 0, IR3_REG_SSA);
-
-       collect = ir3_instr_create2(ctx->block, -1, OPC_META_FI, 12);
-       ir3_reg_create(collect, 0, 0);
-       for (i = 0; i < 4; i++) {
-               if (tinf.src_wrmask & (1 << i))
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA),
-                                       coord, src_swiz(coord, i));
-               else if (tinf.src_wrmask & ~((1 << i) - 1))
-                       ir3_reg_create(collect, 0, 0);
-       }
-
-       /* Attach derivatives onto the end of the fan-in. Derivatives start after
-        * the 4th argument, so make sure that fi is padded up to 4 first.
-        */
-       if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
-               while (collect->regs_count < 5)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0);
-               for (i = 0; i < tgt->dims; i++)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), dpdx, i);
-               if (tgt->dims < 2)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0);
-               for (i = 0; i < tgt->dims; i++)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), dpdy, i);
-               if (tgt->dims < 2)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0);
-               tinf.src_wrmask |= ((1 << (2 * MAX2(tgt->dims, 2))) - 1) << 4;
-       }
-
-       reg->instr = collect;
-       reg->wrmask = tinf.src_wrmask;
-
-       /* The second argument contains the offsets, followed by the lod/bias
-        * argument. This is constructed more manually due to the dynamic nature.
-        */
-       if (inst->Texture.NumOffsets == 0 && tinf.args == 1)
-               return;
-
-       reg = ir3_reg_create(instr, 0, IR3_REG_SSA);
-
-       collect = ir3_instr_create2(ctx->block, -1, OPC_META_FI, 5);
-       ir3_reg_create(collect, 0, 0);
-
-       if (inst->Texture.NumOffsets) {
-               for (i = 0; i < tgt->dims; i++)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA),
-                                       offset, i);
-               if (tgt->dims < 2)
-                       ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0);
-       }
-       if (inst->Instruction.Opcode == TGSI_OPCODE_TXB2)
-               ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA),
-                               orig, orig->SwizzleX);
-       else if (tinf.args > 1)
-               ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA),
-                               orig, orig->SwizzleW);
-
-       reg->instr = collect;
-       reg->wrmask = (1 << (collect->regs_count - 1)) - 1;
-}
-
-static void
-trans_txq(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = &inst->Dst[0].Register;
-       struct tgsi_src_register *level = &inst->Src[0].Register;
-       struct tgsi_src_register *samp = &inst->Src[1].Register;
-       const struct target_info *tgt = &tex_targets[inst->Texture.Texture];
-       struct tex_info tinf;
-
-       memset(&tinf, 0, sizeof(tinf));
-       fill_tex_info(ctx, inst, &tinf);
-       if (is_rel_or_const(level))
-               level = get_unconst(ctx, level);
-
-       instr = instr_create(ctx, 5, OPC_GETSIZE);
-       instr->cat5.type = get_utype(ctx);
-       instr->cat5.samp = samp->Index;
-       instr->cat5.tex  = samp->Index;
-       instr->flags |= tinf.flags;
-
-       if (tgt->array && (dst->WriteMask & (1 << tgt->dims))) {
-               /* Array size actually ends up in .w rather than .z. This doesn't
-                * matter for miplevel 0, but for higher mips the value in z is
-                * minified whereas w stays. Also, the value in TEX_CONST_3_DEPTH is
-                * returned, which means that we have to add 1 to it for arrays.
-                */
-               struct tgsi_dst_register tmp_dst;
-               struct tgsi_src_register *tmp_src;
-               type_t type_mov = get_utype(ctx);
-
-               tmp_src = get_internal_temp(ctx, &tmp_dst);
-               add_dst_reg_wrmask(ctx, instr, &tmp_dst, 0,
-                                                  dst->WriteMask | TGSI_WRITEMASK_W);
-               add_src_reg_wrmask(ctx, instr, level, level->SwizzleX, 0x1);
-
-               if (dst->WriteMask & TGSI_WRITEMASK_X) {
-                       instr = instr_create(ctx, 1, 0);
-                       instr->cat1.src_type = type_mov;
-                       instr->cat1.dst_type = type_mov;
-                       add_dst_reg(ctx, instr, dst, 0);
-                       add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 0));
-               }
-
-               if (tgt->dims == 2) {
-                       if (dst->WriteMask & TGSI_WRITEMASK_Y) {
-                               instr = instr_create(ctx, 1, 0);
-                               instr->cat1.src_type = type_mov;
-                               instr->cat1.dst_type = type_mov;
-                               add_dst_reg(ctx, instr, dst, 1);
-                               add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 1));
-                       }
-               }
-
-               instr = instr_create(ctx, 2, OPC_ADD_U);
-               add_dst_reg(ctx, instr, dst, tgt->dims);
-               add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 3));
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1;
-       } else {
-               add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask);
-               add_src_reg_wrmask(ctx, instr, level, level->SwizzleX, 0x1);
-       }
-
-       if (dst->WriteMask & TGSI_WRITEMASK_W) {
-               /* The # of levels comes from getinfo.z. We need to add 1 to it, since
-                * the value in TEX_CONST_0 is zero-based.
-                */
-               struct tgsi_dst_register tmp_dst;
-               struct tgsi_src_register *tmp_src;
-
-               tmp_src = get_internal_temp(ctx, &tmp_dst);
-               instr = instr_create(ctx, 5, OPC_GETINFO);
-               instr->cat5.type = get_utype(ctx);
-               instr->cat5.samp = samp->Index;
-               instr->cat5.tex  = samp->Index;
-               add_dst_reg_wrmask(ctx, instr, &tmp_dst, 0, TGSI_WRITEMASK_Z);
-
-               instr = instr_create(ctx, 2, OPC_ADD_U);
-               add_dst_reg(ctx, instr, dst, 3);
-               add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 2));
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1;
-       }
-}
-
-/* DDX/DDY */
-static void
-trans_deriv(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = &inst->Dst[0].Register;
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-       static const int8_t order[4] = {0, 1, 2, 3};
-
-       if (!check_swiz(src, order)) {
-               struct tgsi_dst_register tmp_dst;
-               struct tgsi_src_register *tmp_src;
-
-               tmp_src = get_internal_temp(ctx, &tmp_dst);
-               create_mov(ctx, &tmp_dst, src);
-
-               src = tmp_src;
-       }
-
-       /* This might be a workaround for hw bug?  Blob compiler always
-        * seems to work two components at a time for dsy/dsx.  It does
-        * actually seem to work in some cases (or at least some piglit
-        * tests) for four components at a time.  But seems more reliable
-        * to split this into two instructions like the blob compiler
-        * does:
-        */
-
-       instr = instr_create(ctx, 5, t->opc);
-       instr->cat5.type = get_ftype(ctx);
-       add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask & 0x3);
-       add_src_reg_wrmask(ctx, instr, src, 0, dst->WriteMask & 0x3);
-
-       instr = instr_create(ctx, 5, t->opc);
-       instr->cat5.type = get_ftype(ctx);
-       add_dst_reg_wrmask(ctx, instr, dst, 2, (dst->WriteMask >> 2) & 0x3);
-       add_src_reg_wrmask(ctx, instr, src, 2, (dst->WriteMask >> 2) & 0x3);
-}
-
-/*
- * SEQ(a,b) = (a == b) ? 1.0 : 0.0
- *   cmps.f.eq tmp0, a, b
- *   cov.u16f16 dst, tmp0
- *
- * SNE(a,b) = (a != b) ? 1.0 : 0.0
- *   cmps.f.ne tmp0, a, b
- *   cov.u16f16 dst, tmp0
- *
- * SGE(a,b) = (a >= b) ? 1.0 : 0.0
- *   cmps.f.ge tmp0, a, b
- *   cov.u16f16 dst, tmp0
- *
- * SLE(a,b) = (a <= b) ? 1.0 : 0.0
- *   cmps.f.le tmp0, a, b
- *   cov.u16f16 dst, tmp0
- *
- * SGT(a,b) = (a > b)  ? 1.0 : 0.0
- *   cmps.f.gt tmp0, a, b
- *   cov.u16f16 dst, tmp0
- *
- * SLT(a,b) = (a < b)  ? 1.0 : 0.0
- *   cmps.f.lt tmp0, a, b
- *   cov.u16f16 dst, tmp0
- *
- * CMP(a,b,c) = (a < 0.0) ? b : c
- *   cmps.f.lt tmp0, a, {0.0}
- *   sel.b16 dst, b, tmp0, c
- */
-static void
-trans_cmp(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-       struct tgsi_src_register constval0;
-       /* final instruction for CMP() uses orig src1 and src2: */
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *a0, *a1, *a2;
-       unsigned condition;
-
-       tmp_src = get_internal_temp(ctx, &tmp_dst);
-
-       a0 = &inst->Src[0].Register;  /* a */
-       a1 = &inst->Src[1].Register;  /* b */
-
-       switch (t->tgsi_opc) {
-       case TGSI_OPCODE_SEQ:
-       case TGSI_OPCODE_FSEQ:
-               condition = IR3_COND_EQ;
-               break;
-       case TGSI_OPCODE_SNE:
-       case TGSI_OPCODE_FSNE:
-               condition = IR3_COND_NE;
-               break;
-       case TGSI_OPCODE_SGE:
-       case TGSI_OPCODE_FSGE:
-               condition = IR3_COND_GE;
-               break;
-       case TGSI_OPCODE_SLT:
-       case TGSI_OPCODE_FSLT:
-               condition = IR3_COND_LT;
-               break;
-       case TGSI_OPCODE_SLE:
-               condition = IR3_COND_LE;
-               break;
-       case TGSI_OPCODE_SGT:
-               condition = IR3_COND_GT;
-               break;
-       case TGSI_OPCODE_CMP:
-               get_immediate(ctx, &constval0, fui(0.0));
-               a0 = &inst->Src[0].Register;  /* a */
-               a1 = &constval0;              /* {0.0} */
-               condition = IR3_COND_LT;
-               break;
-       default:
-               compile_assert(ctx, 0);
-               return;
-       }
-
-       if (is_const(a0) && is_const(a1))
-               a0 = get_unconst(ctx, a0);
-
-       /* cmps.f.<cond> tmp, a0, a1 */
-       instr = instr_create(ctx, 2, OPC_CMPS_F);
-       instr->cat2.condition = condition;
-       vectorize(ctx, instr, &tmp_dst, 2, a0, 0, a1, 0);
-
-       switch (t->tgsi_opc) {
-       case TGSI_OPCODE_SEQ:
-       case TGSI_OPCODE_SGE:
-       case TGSI_OPCODE_SLE:
-       case TGSI_OPCODE_SNE:
-       case TGSI_OPCODE_SGT:
-       case TGSI_OPCODE_SLT:
-               /* cov.u16f16 dst, tmp0 */
-               instr = instr_create(ctx, 1, 0);
-               instr->cat1.src_type = get_utype(ctx);
-               instr->cat1.dst_type = get_ftype(ctx);
-               vectorize(ctx, instr, dst, 1, tmp_src, 0);
-               break;
-       case TGSI_OPCODE_FSEQ:
-       case TGSI_OPCODE_FSGE:
-       case TGSI_OPCODE_FSNE:
-       case TGSI_OPCODE_FSLT:
-               /* absneg.s dst, (neg)tmp0 */
-               instr = instr_create(ctx, 2, OPC_ABSNEG_S);
-               vectorize(ctx, instr, dst, 1, tmp_src, IR3_REG_SNEG);
-               break;
-       case TGSI_OPCODE_CMP:
-               a1 = &inst->Src[1].Register;
-               a2 = &inst->Src[2].Register;
-               /* sel.{b32,b16} dst, src2, tmp, src1 */
-               instr = instr_create(ctx, 3, OPC_SEL_B32);
-               vectorize(ctx, instr, dst, 3, a1, 0, tmp_src, 0, a2, 0);
-
-               break;
-       }
-
-       put_dst(ctx, inst, dst);
-}
-
-/*
- * USNE(a,b) = (a != b) ? ~0 : 0
- *   cmps.u32.ne dst, a, b
- *
- * USEQ(a,b) = (a == b) ? ~0 : 0
- *   cmps.u32.eq dst, a, b
- *
- * ISGE(a,b) = (a > b) ? ~0 : 0
- *   cmps.s32.ge dst, a, b
- *
- * USGE(a,b) = (a > b) ? ~0 : 0
- *   cmps.u32.ge dst, a, b
- *
- * ISLT(a,b) = (a < b) ? ~0 : 0
- *   cmps.s32.lt dst, a, b
- *
- * USLT(a,b) = (a < b) ? ~0 : 0
- *   cmps.u32.lt dst, a, b
- *
- */
-static void
-trans_icmp(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-       struct tgsi_src_register *a0, *a1;
-       unsigned condition;
-
-       a0 = &inst->Src[0].Register;  /* a */
-       a1 = &inst->Src[1].Register;  /* b */
-
-       switch (t->tgsi_opc) {
-       case TGSI_OPCODE_USNE:
-               condition = IR3_COND_NE;
-               break;
-       case TGSI_OPCODE_USEQ:
-               condition = IR3_COND_EQ;
-               break;
-       case TGSI_OPCODE_ISGE:
-       case TGSI_OPCODE_USGE:
-               condition = IR3_COND_GE;
-               break;
-       case TGSI_OPCODE_ISLT:
-       case TGSI_OPCODE_USLT:
-               condition = IR3_COND_LT;
-               break;
-
-       default:
-               compile_assert(ctx, 0);
-               return;
-       }
-
-       if (is_const(a0) && is_const(a1))
-               a0 = get_unconst(ctx, a0);
-
-       tmp_src = get_internal_temp(ctx, &tmp_dst);
-       /* cmps.{u32,s32}.<cond> tmp, a0, a1 */
-       instr = instr_create(ctx, 2, t->opc);
-       instr->cat2.condition = condition;
-       vectorize(ctx, instr, &tmp_dst, 2, a0, 0, a1, 0);
-
-       /* absneg.s dst, (neg)tmp */
-       instr = instr_create(ctx, 2, OPC_ABSNEG_S);
-       vectorize(ctx, instr, dst, 1, tmp_src, IR3_REG_SNEG);
-
-       put_dst(ctx, inst, dst);
-}
-
-/*
- * UCMP(a,b,c) = a ? b : c
- *   sel.b16 dst, b, a, c
- */
-static void
-trans_ucmp(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *a0, *a1, *a2;
-
-       a0 = &inst->Src[0].Register;  /* a */
-       a1 = &inst->Src[1].Register;  /* b */
-       a2 = &inst->Src[2].Register;  /* c */
-
-       if (is_rel_or_const(a0))
-               a0 = get_unconst(ctx, a0);
-
-       /* sel.{b32,b16} dst, b, a, c */
-       instr = instr_create(ctx, 3, OPC_SEL_B32);
-       vectorize(ctx, instr, dst, 3, a1, 0, a0, 0, a2, 0);
-       put_dst(ctx, inst, dst);
-}
-
-/*
- * ISSG(a) = a < 0 ? -1 : a > 0 ? 1 : 0
- *   cmps.s.lt tmp_neg, a, 0  # 1 if a is negative
- *   cmps.s.gt tmp_pos, a, 0  # 1 if a is positive
- *   sub.u dst, tmp_pos, tmp_neg
- */
-static void
-trans_issg(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *a = &inst->Src[0].Register;
-       struct tgsi_dst_register neg_dst, pos_dst;
-       struct tgsi_src_register *neg_src, *pos_src;
-
-       neg_src = get_internal_temp(ctx, &neg_dst);
-       pos_src = get_internal_temp(ctx, &pos_dst);
-
-       /* cmps.s.lt neg, a, 0 */
-       instr = instr_create(ctx, 2, OPC_CMPS_S);
-       instr->cat2.condition = IR3_COND_LT;
-       vectorize(ctx, instr, &neg_dst, 2, a, 0, 0, IR3_REG_IMMED);
-
-       /* cmps.s.gt pos, a, 0 */
-       instr = instr_create(ctx, 2, OPC_CMPS_S);
-       instr->cat2.condition = IR3_COND_GT;
-       vectorize(ctx, instr, &pos_dst, 2, a, 0, 0, IR3_REG_IMMED);
-
-       /* sub.u dst, pos, neg */
-       instr = instr_create(ctx, 2, OPC_SUB_U);
-       vectorize(ctx, instr, dst, 2, pos_src, 0, neg_src, 0);
-
-       put_dst(ctx, inst, dst);
-}
-
-
-
-/*
- * Conditional / Flow control
- */
-
-static void
-push_branch(struct ir3_compile_context *ctx, bool inv,
-               struct ir3_instruction *instr, struct ir3_instruction *cond)
-{
-       unsigned int idx = ctx->branch_count++;
-       compile_assert(ctx, idx < ARRAY_SIZE(ctx->branch));
-       ctx->branch[idx].instr = instr;
-       ctx->branch[idx].inv = inv;
-       /* else side of branch has same condition: */
-       if (!inv)
-               ctx->branch[idx].cond = cond;
-}
-
-static struct ir3_instruction *
-pop_branch(struct ir3_compile_context *ctx)
-{
-       unsigned int idx = --ctx->branch_count;
-       return ctx->branch[idx].instr;
-}
-
-static void
-trans_if(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr, *cond;
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-       struct tgsi_dst_register tmp_dst;
-       struct tgsi_src_register *tmp_src;
-       struct tgsi_src_register constval;
-
-       get_immediate(ctx, &constval, fui(0.0));
-       tmp_src = get_internal_temp(ctx, &tmp_dst);
-
-       if (is_const(src))
-               src = get_unconst(ctx, src);
-
-       /* cmps.{f,u}.ne tmp0, b, {0.0} */
-       instr = instr_create(ctx, 2, t->opc);
-       add_dst_reg(ctx, instr, &tmp_dst, 0);
-       add_src_reg(ctx, instr, src, src->SwizzleX);
-       add_src_reg(ctx, instr, &constval, constval.SwizzleX);
-       instr->cat2.condition = IR3_COND_NE;
-
-       compile_assert(ctx, instr->regs[1]->flags & IR3_REG_SSA); /* because get_unconst() */
-       cond = instr->regs[1]->instr;
-
-       /* meta:flow tmp0 */
-       instr = instr_create(ctx, -1, OPC_META_FLOW);
-       ir3_reg_create(instr, 0, 0);  /* dummy dst */
-       add_src_reg(ctx, instr, tmp_src, TGSI_SWIZZLE_X);
-
-       push_branch(ctx, false, instr, cond);
-       instr->flow.if_block = push_block(ctx);
-}
-
-static void
-trans_else(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-
-       pop_block(ctx);
-
-       instr = pop_branch(ctx);
-
-       compile_assert(ctx, (instr->category == -1) &&
-                       (instr->opc == OPC_META_FLOW));
-
-       push_branch(ctx, true, instr, NULL);
-       instr->flow.else_block = push_block(ctx);
-}
-
-static struct ir3_instruction *
-find_temporary(struct ir3_block *block, unsigned n)
-{
-       if (block->parent && !block->temporaries[n])
-               return find_temporary(block->parent, n);
-       return block->temporaries[n];
-}
-
-static struct ir3_instruction *
-find_output(struct ir3_block *block, unsigned n)
-{
-       if (block->parent && !block->outputs[n])
-               return find_output(block->parent, n);
-       return block->outputs[n];
-}
-
-static struct ir3_instruction *
-create_phi(struct ir3_compile_context *ctx, struct ir3_instruction *cond,
-               struct ir3_instruction *a, struct ir3_instruction *b)
-{
-       struct ir3_instruction *phi;
-
-       compile_assert(ctx, cond);
-
-       /* Either side of the condition could be null..  which
-        * indicates a variable written on only one side of the
-        * branch.  Normally this should only be variables not
-        * used outside of that side of the branch.  So we could
-        * just 'return a ? a : b;' in that case.  But for better
-        * defined undefined behavior we just stick in imm{0.0}.
-        * In the common case of a value only used within the
-        * one side of the branch, the PHI instruction will not
-        * get scheduled
-        */
-       if (!a)
-               a = create_immed(ctx, 0.0);
-       if (!b)
-               b = create_immed(ctx, 0.0);
-
-       phi = instr_create(ctx, -1, OPC_META_PHI);
-       ir3_reg_create(phi, 0, 0);  /* dummy dst */
-       ir3_reg_create(phi, 0, IR3_REG_SSA)->instr = cond;
-       ir3_reg_create(phi, 0, IR3_REG_SSA)->instr = a;
-       ir3_reg_create(phi, 0, IR3_REG_SSA)->instr = b;
-
-       return phi;
-}
-
-static void
-trans_endif(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct ir3_block *ifb, *elseb;
-       struct ir3_instruction **ifout, **elseout;
-       unsigned i, ifnout = 0, elsenout = 0;
-
-       pop_block(ctx);
-
-       instr = pop_branch(ctx);
-
-       compile_assert(ctx, (instr->category == -1) &&
-                       (instr->opc == OPC_META_FLOW));
-
-       ifb = instr->flow.if_block;
-       elseb = instr->flow.else_block;
-       /* if there is no else block, the parent block is used for the
-        * branch-not-taken src of the PHI instructions:
-        */
-       if (!elseb)
-               elseb = ifb->parent;
-
-       /* worst case sizes: */
-       ifnout = ifb->ntemporaries + ifb->noutputs;
-       elsenout = elseb->ntemporaries + elseb->noutputs;
-
-       ifout = ir3_alloc(ctx->ir, sizeof(ifb->outputs[0]) * ifnout);
-       if (elseb != ifb->parent)
-               elseout = ir3_alloc(ctx->ir, sizeof(ifb->outputs[0]) * elsenout);
-
-       ifnout = 0;
-       elsenout = 0;
-
-       /* generate PHI instructions for any temporaries written: */
-       for (i = 0; i < ifb->ntemporaries; i++) {
-               struct ir3_instruction *a = ifb->temporaries[i];
-               struct ir3_instruction *b = elseb->temporaries[i];
-
-               /* if temporary written in if-block, or if else block
-                * is present and temporary written in else-block:
-                */
-               if (a || ((elseb != ifb->parent) && b)) {
-                       struct ir3_instruction *phi;
-
-                       /* if only written on one side, find the closest
-                        * enclosing update on other side:
-                        */
-                       if (!a)
-                               a = find_temporary(ifb, i);
-                       if (!b)
-                               b = find_temporary(elseb, i);
-
-                       ifout[ifnout] = a;
-                       a = create_output(ifb, a, ifnout++);
-
-                       if (elseb != ifb->parent) {
-                               elseout[elsenout] = b;
-                               b = create_output(elseb, b, elsenout++);
-                       }
-
-                       phi = create_phi(ctx, instr, a, b);
-                       ctx->block->temporaries[i] = phi;
-               }
-       }
-
-       compile_assert(ctx, ifb->noutputs == elseb->noutputs);
-
-       /* .. and any outputs written: */
-       for (i = 0; i < ifb->noutputs; i++) {
-               struct ir3_instruction *a = ifb->outputs[i];
-               struct ir3_instruction *b = elseb->outputs[i];
-
-               /* if output written in if-block, or if else block
-                * is present and output written in else-block:
-                */
-               if (a || ((elseb != ifb->parent) && b)) {
-                       struct ir3_instruction *phi;
-
-                       /* if only written on one side, find the closest
-                        * enclosing update on other side:
-                        */
-                       if (!a)
-                               a = find_output(ifb, i);
-                       if (!b)
-                               b = find_output(elseb, i);
-
-                       ifout[ifnout] = a;
-                       a = create_output(ifb, a, ifnout++);
-
-                       if (elseb != ifb->parent) {
-                               elseout[elsenout] = b;
-                               b = create_output(elseb, b, elsenout++);
-                       }
-
-                       phi = create_phi(ctx, instr, a, b);
-                       ctx->block->outputs[i] = phi;
-               }
-       }
-
-       ifb->noutputs = ifnout;
-       ifb->outputs = ifout;
-
-       if (elseb != ifb->parent) {
-               elseb->noutputs = elsenout;
-               elseb->outputs = elseout;
-       }
-
-       // TODO maybe we want to compact block->inputs?
-}
-
-/*
- * Kill
- */
-
-static void
-trans_kill(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr, *immed, *cond = NULL;
-       bool inv = false;
-
-       /* unconditional kill, use enclosing if condition: */
-       if (ctx->branch_count > 0) {
-               unsigned int idx = ctx->branch_count - 1;
-               cond = ctx->branch[idx].cond;
-               inv = ctx->branch[idx].inv;
-       } else {
-               cond = create_immed(ctx, 1.0);
-       }
-
-       compile_assert(ctx, cond);
-
-       immed = create_immed(ctx, 0.0);
-
-       /* cmps.f.ne p0.x, cond, {0.0} */
-       instr = instr_create(ctx, 2, OPC_CMPS_F);
-       instr->cat2.condition = IR3_COND_NE;
-       ir3_reg_create(instr, regid(REG_P0, 0), 0);
-       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = cond;
-       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = immed;
-       cond = instr;
-
-       /* kill p0.x */
-       instr = instr_create(ctx, 0, OPC_KILL);
-       instr->cat0.inv = inv;
-       ir3_reg_create(instr, 0, 0);  /* dummy dst */
-       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = cond;
-
-       ctx->kill[ctx->kill_count++] = instr;
-
-       ctx->so->has_kill = true;
-}
-
-/*
- * Kill-If
- */
-
-static void
-trans_killif(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-       struct ir3_instruction *instr, *immed, *cond = NULL;
-       bool inv = false;
-
-       immed = create_immed(ctx, 0.0);
-
-       /* cmps.f.ne p0.x, cond, {0.0} */
-       instr = instr_create(ctx, 2, OPC_CMPS_F);
-       instr->cat2.condition = IR3_COND_NE;
-       ir3_reg_create(instr, regid(REG_P0, 0), 0);
-       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = immed;
-       add_src_reg(ctx, instr, src, src->SwizzleX);
-
-       cond = instr;
-
-       /* kill p0.x */
-       instr = instr_create(ctx, 0, OPC_KILL);
-       instr->cat0.inv = inv;
-       ir3_reg_create(instr, 0, 0);  /* dummy dst */
-       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = cond;
-
-       ctx->kill[ctx->kill_count++] = instr;
-
-       ctx->so->has_kill = true;
-
-}
-/*
- * I2F / U2F / F2I / F2U
- */
-
-static void
-trans_cov(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-
-       // cov.f32s32 dst, tmp0 /
-       instr = instr_create(ctx, 1, 0);
-       switch (t->tgsi_opc) {
-       case TGSI_OPCODE_U2F:
-               instr->cat1.src_type = TYPE_U32;
-               instr->cat1.dst_type = TYPE_F32;
-               break;
-       case TGSI_OPCODE_I2F:
-               instr->cat1.src_type = TYPE_S32;
-               instr->cat1.dst_type = TYPE_F32;
-               break;
-       case TGSI_OPCODE_F2U:
-               instr->cat1.src_type = TYPE_F32;
-               instr->cat1.dst_type = TYPE_U32;
-               break;
-       case TGSI_OPCODE_F2I:
-               instr->cat1.src_type = TYPE_F32;
-               instr->cat1.dst_type = TYPE_S32;
-               break;
-
-       }
-       vectorize(ctx, instr, dst, 1, src, 0);
-       put_dst(ctx, inst, dst);
-}
-
-/*
- * UMUL / UMAD
- *
- * There is no 32-bit multiply instruction, so splitting a and b into high and
- * low components, we get that
- *
- * dst = al * bl + ah * bl << 16 + al * bh << 16
- *
- *  mull.u tmp0, a, b (mul low, i.e. al * bl)
- *  madsh.m16 tmp1, a, b, tmp0 (mul-add shift high mix, i.e. ah * bl << 16)
- *  madsh.m16 dst, b, a, tmp1 (i.e. al * bh << 16)
- *
- * For UMAD, add in the extra argument after mull.u.
- */
-static void
-trans_umul(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *a = &inst->Src[0].Register;
-       struct tgsi_src_register *b = &inst->Src[1].Register;
-
-       struct tgsi_dst_register tmp0_dst, tmp1_dst;
-       struct tgsi_src_register *tmp0_src, *tmp1_src;
-
-       tmp0_src = get_internal_temp(ctx, &tmp0_dst);
-       tmp1_src = get_internal_temp(ctx, &tmp1_dst);
-
-       if (is_rel_or_const(a))
-               a = get_unconst(ctx, a);
-       if (is_rel_or_const(b))
-               b = get_unconst(ctx, b);
-
-       /* mull.u tmp0, a, b */
-       instr = instr_create(ctx, 2, OPC_MULL_U);
-       vectorize(ctx, instr, &tmp0_dst, 2, a, 0, b, 0);
-
-       if (t->tgsi_opc == TGSI_OPCODE_UMAD) {
-               struct tgsi_src_register *c = &inst->Src[2].Register;
-
-               /* add.u tmp0, tmp0, c */
-               instr = instr_create(ctx, 2, OPC_ADD_U);
-               vectorize(ctx, instr, &tmp0_dst, 2, tmp0_src, 0, c, 0);
-       }
-
-       /* madsh.m16 tmp1, a, b, tmp0 */
-       instr = instr_create(ctx, 3, OPC_MADSH_M16);
-       vectorize(ctx, instr, &tmp1_dst, 3, a, 0, b, 0, tmp0_src, 0);
-
-       /* madsh.m16 dst, b, a, tmp1 */
-       instr = instr_create(ctx, 3, OPC_MADSH_M16);
-       vectorize(ctx, instr, dst, 3, b, 0, a, 0, tmp1_src, 0);
-       put_dst(ctx, inst, dst);
-}
-
-/*
- * IDIV / UDIV / MOD / UMOD
- *
- * See NV50LegalizeSSA::handleDIV for the origin of this implementation. For
- * MOD/UMOD, it becomes a - [IU]DIV(a, modulus) * modulus.
- */
-static void
-trans_idiv(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct ir3_instruction *instr;
-       struct tgsi_dst_register *dst = get_dst(ctx, inst), *premod_dst = dst;
-       struct tgsi_src_register *a = &inst->Src[0].Register;
-       struct tgsi_src_register *b = &inst->Src[1].Register;
-
-       struct tgsi_dst_register af_dst, bf_dst, q_dst, r_dst, a_dst, b_dst;
-       struct tgsi_src_register *af_src, *bf_src, *q_src, *r_src, *a_src, *b_src;
-
-       struct tgsi_src_register negative_2, thirty_one;
-       type_t src_type;
-
-       if (t->tgsi_opc == TGSI_OPCODE_IDIV || t->tgsi_opc == TGSI_OPCODE_MOD)
-               src_type = get_stype(ctx);
-       else
-               src_type = get_utype(ctx);
-
-       af_src = get_internal_temp(ctx, &af_dst);
-       bf_src = get_internal_temp(ctx, &bf_dst);
-       q_src = get_internal_temp(ctx, &q_dst);
-       r_src = get_internal_temp(ctx, &r_dst);
-       a_src = get_internal_temp(ctx, &a_dst);
-       b_src = get_internal_temp(ctx, &b_dst);
-
-       get_immediate(ctx, &negative_2, -2);
-       get_immediate(ctx, &thirty_one, 31);
-
-       if (t->tgsi_opc == TGSI_OPCODE_MOD || t->tgsi_opc == TGSI_OPCODE_UMOD)
-               premod_dst = &q_dst;
-
-       /* cov.[us]32f32 af, numerator */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = src_type;
-       instr->cat1.dst_type = get_ftype(ctx);
-       vectorize(ctx, instr, &af_dst, 1, a, 0);
-
-       /* cov.[us]32f32 bf, denominator */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = src_type;
-       instr->cat1.dst_type = get_ftype(ctx);
-       vectorize(ctx, instr, &bf_dst, 1, b, 0);
-
-       /* Get the absolute values for IDIV */
-       if (type_sint(src_type)) {
-               /* absneg.f af, (abs)af */
-               instr = instr_create(ctx, 2, OPC_ABSNEG_F);
-               vectorize(ctx, instr, &af_dst, 1, af_src, IR3_REG_FABS);
-
-               /* absneg.f bf, (abs)bf */
-               instr = instr_create(ctx, 2, OPC_ABSNEG_F);
-               vectorize(ctx, instr, &bf_dst, 1, bf_src, IR3_REG_FABS);
-
-               /* absneg.s a, (abs)numerator */
-               instr = instr_create(ctx, 2, OPC_ABSNEG_S);
-               vectorize(ctx, instr, &a_dst, 1, a, IR3_REG_SABS);
-
-               /* absneg.s b, (abs)denominator */
-               instr = instr_create(ctx, 2, OPC_ABSNEG_S);
-               vectorize(ctx, instr, &b_dst, 1, b, IR3_REG_SABS);
-       } else {
-               /* mov.u32u32 a, numerator */
-               instr = instr_create(ctx, 1, 0);
-               instr->cat1.src_type = src_type;
-               instr->cat1.dst_type = src_type;
-               vectorize(ctx, instr, &a_dst, 1, a, 0);
-
-               /* mov.u32u32 b, denominator */
-               instr = instr_create(ctx, 1, 0);
-               instr->cat1.src_type = src_type;
-               instr->cat1.dst_type = src_type;
-               vectorize(ctx, instr, &b_dst, 1, b, 0);
-       }
-
-       /* rcp.f bf, bf */
-       instr = instr_create(ctx, 4, OPC_RCP);
-       vectorize(ctx, instr, &bf_dst, 1, bf_src, 0);
-
-       /* That's right, subtract 2 as an integer from the float */
-       /* add.u bf, bf, -2 */
-       instr = instr_create(ctx, 2, OPC_ADD_U);
-       vectorize(ctx, instr, &bf_dst, 2, bf_src, 0, &negative_2, 0);
-
-       /* mul.f q, af, bf */
-       instr = instr_create(ctx, 2, OPC_MUL_F);
-       vectorize(ctx, instr, &q_dst, 2, af_src, 0, bf_src, 0);
-
-       /* cov.f32[us]32 q, q */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = get_ftype(ctx);
-       instr->cat1.dst_type = src_type;
-       vectorize(ctx, instr, &q_dst, 1, q_src, 0);
-
-       /* integer multiply q by b */
-       /* mull.u r, q, b */
-       instr = instr_create(ctx, 2, OPC_MULL_U);
-       vectorize(ctx, instr, &r_dst, 2, q_src, 0, b_src, 0);
-
-       /* madsh.m16 r, q, b, r */
-       instr = instr_create(ctx, 3, OPC_MADSH_M16);
-       vectorize(ctx, instr, &r_dst, 3, q_src, 0, b_src, 0, r_src, 0);
-
-       /* madsh.m16, r, b, q, r */
-       instr = instr_create(ctx, 3, OPC_MADSH_M16);
-       vectorize(ctx, instr, &r_dst, 3, b_src, 0, q_src, 0, r_src, 0);
-
-       /* sub.u r, a, r */
-       instr = instr_create(ctx, 2, OPC_SUB_U);
-       vectorize(ctx, instr, &r_dst, 2, a_src, 0, r_src, 0);
-
-       /* cov.u32f32, r, r */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = get_utype(ctx);
-       instr->cat1.dst_type = get_ftype(ctx);
-       vectorize(ctx, instr, &r_dst, 1, r_src, 0);
-
-       /* mul.f r, r, bf */
-       instr = instr_create(ctx, 2, OPC_MUL_F);
-       vectorize(ctx, instr, &r_dst, 2, r_src, 0, bf_src, 0);
-
-       /* cov.f32u32 r, r */
-       instr = instr_create(ctx, 1, 0);
-       instr->cat1.src_type = get_ftype(ctx);
-       instr->cat1.dst_type = get_utype(ctx);
-       vectorize(ctx, instr, &r_dst, 1, r_src, 0);
-
-       /* add.u q, q, r */
-       instr = instr_create(ctx, 2, OPC_ADD_U);
-       vectorize(ctx, instr, &q_dst, 2, q_src, 0, r_src, 0);
-
-       /* mull.u r, q, b */
-       instr = instr_create(ctx, 2, OPC_MULL_U);
-       vectorize(ctx, instr, &r_dst, 2, q_src, 0, b_src, 0);
-
-       /* madsh.m16 r, q, b, r */
-       instr = instr_create(ctx, 3, OPC_MADSH_M16);
-       vectorize(ctx, instr, &r_dst, 3, q_src, 0, b_src, 0, r_src, 0);
-
-       /* madsh.m16 r, b, q, r */
-       instr = instr_create(ctx, 3, OPC_MADSH_M16);
-       vectorize(ctx, instr, &r_dst, 3, b_src, 0, q_src, 0, r_src, 0);
-
-       /* sub.u r, a, r */
-       instr = instr_create(ctx, 2, OPC_SUB_U);
-       vectorize(ctx, instr, &r_dst, 2, a_src, 0, r_src, 0);
-
-       /* cmps.u.ge r, r, b */
-       instr = instr_create(ctx, 2, OPC_CMPS_U);
-       instr->cat2.condition = IR3_COND_GE;
-       vectorize(ctx, instr, &r_dst, 2, r_src, 0, b_src, 0);
-
-       if (type_uint(src_type)) {
-               /* add.u dst, q, r */
-               instr = instr_create(ctx, 2, OPC_ADD_U);
-               vectorize(ctx, instr, premod_dst, 2, q_src, 0, r_src, 0);
-       } else {
-               /* add.u q, q, r */
-               instr = instr_create(ctx, 2, OPC_ADD_U);
-               vectorize(ctx, instr, &q_dst, 2, q_src, 0, r_src, 0);
-
-               /* negate result based on the original arguments */
-               if (is_const(a) && is_const(b))
-                       a = get_unconst(ctx, a);
-
-               /* xor.b r, numerator, denominator */
-               instr = instr_create(ctx, 2, OPC_XOR_B);
-               vectorize(ctx, instr, &r_dst, 2, a, 0, b, 0);
-
-               /* shr.b r, r, 31 */
-               instr = instr_create(ctx, 2, OPC_SHR_B);
-               vectorize(ctx, instr, &r_dst, 2, r_src, 0, &thirty_one, 0);
-
-               /* absneg.s b, (neg)q */
-               instr = instr_create(ctx, 2, OPC_ABSNEG_S);
-               vectorize(ctx, instr, &b_dst, 1, q_src, IR3_REG_SNEG);
-
-               /* sel.b dst, b, r, q */
-               instr = instr_create(ctx, 3, OPC_SEL_B32);
-               vectorize(ctx, instr, premod_dst, 3, b_src, 0, r_src, 0, q_src, 0);
-       }
-
-       if (t->tgsi_opc == TGSI_OPCODE_MOD || t->tgsi_opc == TGSI_OPCODE_UMOD) {
-               /* The division result will have ended up in q. */
-
-               if (is_rel_or_const(b))
-                       b = get_unconst(ctx, b);
-
-               /* mull.u r, q, b */
-               instr = instr_create(ctx, 2, OPC_MULL_U);
-               vectorize(ctx, instr, &r_dst, 2, q_src, 0, b, 0);
-
-               /* madsh.m16 r, q, b, r */
-               instr = instr_create(ctx, 3, OPC_MADSH_M16);
-               vectorize(ctx, instr, &r_dst, 3, q_src, 0, b, 0, r_src, 0);
-
-               /* madsh.m16 r, b, q, r */
-               instr = instr_create(ctx, 3, OPC_MADSH_M16);
-               vectorize(ctx, instr, &r_dst, 3, b, 0, q_src, 0, r_src, 0);
-
-               /* sub.u dst, a, r */
-               instr = instr_create(ctx, 2, OPC_SUB_U);
-               vectorize(ctx, instr, dst, 2, a, 0, r_src, 0);
-       }
-
-       put_dst(ctx, inst, dst);
-}
-
-/*
- * Handlers for TGSI instructions which do have 1:1 mapping to native
- * instructions:
- */
-
-static void
-instr_cat0(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       instr_create(ctx, 0, t->opc);
-}
-
-static void
-instr_cat1(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct tgsi_dst_register *dst = &inst->Dst[0].Register;
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-
-       /* NOTE: atomic start/end, rather than in create_mov() since
-        * create_mov() is used already w/in atomic sequences (and
-        * we aren't clever enough to deal with the nesting)
-        */
-       instr_atomic_start(ctx);
-       create_mov(ctx, dst, src);
-       instr_atomic_end(ctx);
-}
-
-static void
-instr_cat2(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *src0 = &inst->Src[0].Register;
-       struct tgsi_src_register *src1 = &inst->Src[1].Register;
-       struct ir3_instruction *instr;
-       unsigned src0_flags = 0, src1_flags = 0;
-
-       switch (t->tgsi_opc) {
-       case TGSI_OPCODE_ABS:
-               src0_flags = IR3_REG_FABS;
-               break;
-       case TGSI_OPCODE_IABS:
-               src0_flags = IR3_REG_SABS;
-               break;
-       case TGSI_OPCODE_INEG:
-               src0_flags = IR3_REG_SNEG;
-               break;
-       case TGSI_OPCODE_SUB:
-               src1_flags = IR3_REG_FNEG;
-               break;
-       }
-
-       switch (t->opc) {
-       case OPC_ABSNEG_F:
-       case OPC_ABSNEG_S:
-       case OPC_CLZ_B:
-       case OPC_CLZ_S:
-       case OPC_SIGN_F:
-       case OPC_FLOOR_F:
-       case OPC_CEIL_F:
-       case OPC_RNDNE_F:
-       case OPC_RNDAZ_F:
-       case OPC_TRUNC_F:
-       case OPC_NOT_B:
-       case OPC_BFREV_B:
-       case OPC_SETRM:
-       case OPC_CBITS_B:
-               /* these only have one src reg */
-               instr = instr_create(ctx, 2, t->opc);
-               vectorize(ctx, instr, dst, 1, src0, src0_flags);
-               break;
-       default:
-               if (is_const(src0) && is_const(src1))
-                       src0 = get_unconst(ctx, src0);
-
-               instr = instr_create(ctx, 2, t->opc);
-               vectorize(ctx, instr, dst, 2, src0, src0_flags,
-                               src1, src1_flags);
-               break;
-       }
-
-       put_dst(ctx, inst, dst);
-}
-
-static void
-instr_cat3(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *src0 = &inst->Src[0].Register;
-       struct tgsi_src_register *src1 = &inst->Src[1].Register;
-       struct ir3_instruction *instr;
-
-       /* in particular, can't handle const for src1 for cat3..
-        * for mad, we can swap first two src's if needed:
-        */
-       if (is_rel_or_const(src1)) {
-               if (is_mad(t->opc) && !is_rel_or_const(src0)) {
-                       struct tgsi_src_register *tmp;
-                       tmp = src0;
-                       src0 = src1;
-                       src1 = tmp;
-               } else {
-                       src1 = get_unconst(ctx, src1);
-               }
-       }
-
-       instr = instr_create(ctx, 3, t->opc);
-       vectorize(ctx, instr, dst, 3, src0, 0, src1, 0,
-                       &inst->Src[2].Register, 0);
-       put_dst(ctx, inst, dst);
-}
-
-static void
-instr_cat4(const struct instr_translater *t,
-               struct ir3_compile_context *ctx,
-               struct tgsi_full_instruction *inst)
-{
-       struct tgsi_dst_register *dst = get_dst(ctx, inst);
-       struct tgsi_src_register *src = &inst->Src[0].Register;
-       struct ir3_instruction *instr;
-       unsigned i;
-
-       /* seems like blob compiler avoids const as src.. */
-       if (is_const(src))
-               src = get_unconst(ctx, src);
-
-       /* we need to replicate into each component: */
-       for (i = 0; i < 4; i++) {
-               if (dst->WriteMask & (1 << i)) {
-                       instr = instr_create(ctx, 4, t->opc);
-                       add_dst_reg(ctx, instr, dst, i);
-                       add_src_reg(ctx, instr, src, src->SwizzleX);
-               }
-       }
-
-       put_dst(ctx, inst, dst);
-}
-
-static const struct instr_translater translaters[TGSI_OPCODE_LAST] = {
-#define INSTR(n, f, ...) \
-       [TGSI_OPCODE_ ## n] = { .fxn = (f), .tgsi_opc = TGSI_OPCODE_ ## n, ##__VA_ARGS__ }
-
-       INSTR(MOV,          instr_cat1),
-       INSTR(RCP,          instr_cat4, .opc = OPC_RCP),
-       INSTR(RSQ,          instr_cat4, .opc = OPC_RSQ),
-       INSTR(SQRT,         instr_cat4, .opc = OPC_SQRT),
-       INSTR(MUL,          instr_cat2, .opc = OPC_MUL_F),
-       INSTR(ADD,          instr_cat2, .opc = OPC_ADD_F),
-       INSTR(SUB,          instr_cat2, .opc = OPC_ADD_F),
-       INSTR(MIN,          instr_cat2, .opc = OPC_MIN_F),
-       INSTR(MAX,          instr_cat2, .opc = OPC_MAX_F),
-       INSTR(UADD,         instr_cat2, .opc = OPC_ADD_U),
-       INSTR(IMIN,         instr_cat2, .opc = OPC_MIN_S),
-       INSTR(UMIN,         instr_cat2, .opc = OPC_MIN_U),
-       INSTR(IMAX,         instr_cat2, .opc = OPC_MAX_S),
-       INSTR(UMAX,         instr_cat2, .opc = OPC_MAX_U),
-       INSTR(AND,          instr_cat2, .opc = OPC_AND_B),
-       INSTR(OR,           instr_cat2, .opc = OPC_OR_B),
-       INSTR(NOT,          instr_cat2, .opc = OPC_NOT_B),
-       INSTR(XOR,          instr_cat2, .opc = OPC_XOR_B),
-       INSTR(UMUL,         trans_umul),
-       INSTR(UMAD,         trans_umul),
-       INSTR(UDIV,         trans_idiv),
-       INSTR(IDIV,         trans_idiv),
-       INSTR(MOD,          trans_idiv),
-       INSTR(UMOD,         trans_idiv),
-       INSTR(SHL,          instr_cat2, .opc = OPC_SHL_B),
-       INSTR(USHR,         instr_cat2, .opc = OPC_SHR_B),
-       INSTR(ISHR,         instr_cat2, .opc = OPC_ASHR_B),
-       INSTR(IABS,         instr_cat2, .opc = OPC_ABSNEG_S),
-       INSTR(INEG,         instr_cat2, .opc = OPC_ABSNEG_S),
-       INSTR(AND,          instr_cat2, .opc = OPC_AND_B),
-       INSTR(MAD,          instr_cat3, .opc = OPC_MAD_F32, .hopc = OPC_MAD_F16),
-       INSTR(TRUNC,        instr_cat2, .opc = OPC_TRUNC_F),
-       INSTR(CLAMP,        trans_clamp),
-       INSTR(FLR,          instr_cat2, .opc = OPC_FLOOR_F),
-       INSTR(ROUND,        instr_cat2, .opc = OPC_RNDNE_F),
-       INSTR(SSG,          instr_cat2, .opc = OPC_SIGN_F),
-       INSTR(CEIL,         instr_cat2, .opc = OPC_CEIL_F),
-       INSTR(ARL,          trans_arl),
-       INSTR(UARL,         trans_arl),
-       INSTR(EX2,          instr_cat4, .opc = OPC_EXP2),
-       INSTR(LG2,          instr_cat4, .opc = OPC_LOG2),
-       INSTR(ABS,          instr_cat2, .opc = OPC_ABSNEG_F),
-       INSTR(COS,          instr_cat4, .opc = OPC_COS),
-       INSTR(SIN,          instr_cat4, .opc = OPC_SIN),
-       INSTR(TEX,          trans_samp, .opc = OPC_SAM),
-       INSTR(TXP,          trans_samp, .opc = OPC_SAM),
-       INSTR(TXB,          trans_samp, .opc = OPC_SAMB),
-       INSTR(TXB2,         trans_samp, .opc = OPC_SAMB),
-       INSTR(TXL,          trans_samp, .opc = OPC_SAML),
-       INSTR(TXD,          trans_samp, .opc = OPC_SAMGQ),
-       INSTR(TXF,          trans_samp, .opc = OPC_ISAML),
-       INSTR(TXQ,          trans_txq),
-       INSTR(DDX,          trans_deriv, .opc = OPC_DSX),
-       INSTR(DDY,          trans_deriv, .opc = OPC_DSY),
-       INSTR(SGT,          trans_cmp),
-       INSTR(SLT,          trans_cmp),
-       INSTR(FSLT,         trans_cmp),
-       INSTR(SGE,          trans_cmp),
-       INSTR(FSGE,         trans_cmp),
-       INSTR(SLE,          trans_cmp),
-       INSTR(SNE,          trans_cmp),
-       INSTR(FSNE,         trans_cmp),
-       INSTR(SEQ,          trans_cmp),
-       INSTR(FSEQ,         trans_cmp),
-       INSTR(CMP,          trans_cmp),
-       INSTR(USNE,         trans_icmp, .opc = OPC_CMPS_U),
-       INSTR(USEQ,         trans_icmp, .opc = OPC_CMPS_U),
-       INSTR(ISGE,         trans_icmp, .opc = OPC_CMPS_S),
-       INSTR(USGE,         trans_icmp, .opc = OPC_CMPS_U),
-       INSTR(ISLT,         trans_icmp, .opc = OPC_CMPS_S),
-       INSTR(USLT,         trans_icmp, .opc = OPC_CMPS_U),
-       INSTR(UCMP,         trans_ucmp),
-       INSTR(ISSG,         trans_issg),
-       INSTR(IF,           trans_if,   .opc = OPC_CMPS_F),
-       INSTR(UIF,          trans_if,   .opc = OPC_CMPS_U),
-       INSTR(ELSE,         trans_else),
-       INSTR(ENDIF,        trans_endif),
-       INSTR(END,          instr_cat0, .opc = OPC_END),
-       INSTR(KILL,         trans_kill, .opc = OPC_KILL),
-       INSTR(KILL_IF,      trans_killif, .opc = OPC_KILL),
-       INSTR(I2F,          trans_cov),
-       INSTR(U2F,          trans_cov),
-       INSTR(F2I,          trans_cov),
-       INSTR(F2U,          trans_cov),
-};
-
-static ir3_semantic
-decl_semantic(const struct tgsi_declaration_semantic *sem)
-{
-       return ir3_semantic_name(sem->Name, sem->Index);
-}
-
-static struct ir3_instruction *
-decl_in_frag_bary(struct ir3_compile_context *ctx, unsigned regid,
-               unsigned j, unsigned inloc, bool use_ldlv)
-{
-       struct ir3_instruction *instr;
-       struct ir3_register *src;
-
-       if (use_ldlv) {
-               /* ldlv.u32 dst, l[#inloc], 1 */
-               instr = instr_create(ctx, 6, OPC_LDLV);
-               instr->cat6.type = TYPE_U32;
-               instr->cat6.iim_val = 1;
-               ir3_reg_create(instr, regid, 0);   /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = inloc;
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1;
-
-               return instr;
-       }
-
-       /* bary.f dst, #inloc, r0.x */
-       instr = instr_create(ctx, 2, OPC_BARY_F);
-       ir3_reg_create(instr, regid, 0);   /* dummy dst */
-       ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = inloc;
-       src = ir3_reg_create(instr, 0, IR3_REG_SSA);
-       src->wrmask = 0x3;
-       src->instr = ctx->frag_pos;
-
-       return instr;
-}
-
-/* TGSI_SEMANTIC_POSITION
- * """"""""""""""""""""""
- *
- * For fragment shaders, TGSI_SEMANTIC_POSITION is used to indicate that
- * fragment shader input contains the fragment's window position.  The X
- * component starts at zero and always increases from left to right.
- * The Y component starts at zero and always increases but Y=0 may either
- * indicate the top of the window or the bottom depending on the fragment
- * coordinate origin convention (see TGSI_PROPERTY_FS_COORD_ORIGIN).
- * The Z coordinate ranges from 0 to 1 to represent depth from the front
- * to the back of the Z buffer.  The W component contains the reciprocol
- * of the interpolated vertex position W component.
- */
-static struct ir3_instruction *
-decl_in_frag_coord(struct ir3_compile_context *ctx, unsigned regid,
-               unsigned j)
-{
-       struct ir3_instruction *instr, *src;
-
-       compile_assert(ctx, !ctx->frag_coord[j]);
-
-       ctx->frag_coord[j] = create_input(ctx->block, NULL, 0);
-
-
-       switch (j) {
-       case 0: /* .x */
-       case 1: /* .y */
-               /* for frag_coord, we get unsigned values.. we need
-                * to subtract (integer) 8 and divide by 16 (right-
-                * shift by 4) then convert to float:
-                */
-
-               /* add.s tmp, src, -8 */
-               instr = instr_create(ctx, 2, OPC_ADD_S);
-               ir3_reg_create(instr, regid, 0);    /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = ctx->frag_coord[j];
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = -8;
-               src = instr;
-
-               /* shr.b tmp, tmp, 4 */
-               instr = instr_create(ctx, 2, OPC_SHR_B);
-               ir3_reg_create(instr, regid, 0);    /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 4;
-               src = instr;
-
-               /* mov.u32f32 dst, tmp */
-               instr = instr_create(ctx, 1, 0);
-               instr->cat1.src_type = TYPE_U32;
-               instr->cat1.dst_type = TYPE_F32;
-               ir3_reg_create(instr, regid, 0);    /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
-
-               break;
-       case 2: /* .z */
-       case 3: /* .w */
-               /* seems that we can use these as-is: */
-               instr = ctx->frag_coord[j];
-               break;
-       default:
-               compile_error(ctx, "invalid channel\n");
-               instr = create_immed(ctx, 0.0);
-               break;
-       }
-
-       return instr;
-}
-
-/* TGSI_SEMANTIC_FACE
- * """"""""""""""""""
- *
- * This label applies to fragment shader inputs only and indicates that
- * the register contains front/back-face information of the form (F, 0,
- * 0, 1).  The first component will be positive when the fragment belongs
- * to a front-facing polygon, and negative when the fragment belongs to a
- * back-facing polygon.
- */
-static struct ir3_instruction *
-decl_in_frag_face(struct ir3_compile_context *ctx, unsigned regid,
-               unsigned j)
-{
-       struct ir3_instruction *instr, *src;
-
-       switch (j) {
-       case 0: /* .x */
-               compile_assert(ctx, !ctx->frag_face);
-
-               ctx->frag_face = create_input(ctx->block, NULL, 0);
-
-               /* for faceness, we always get -1 or 0 (int).. but TGSI expects
-                * positive vs negative float.. and piglit further seems to
-                * expect -1.0 or 1.0:
-                *
-                *    mul.s tmp, hr0.x, 2
-                *    add.s tmp, tmp, 1
-                *    mov.s16f32, dst, tmp
-                *
-                */
-
-               instr = instr_create(ctx, 2, OPC_MUL_S);
-               ir3_reg_create(instr, regid, 0);    /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = ctx->frag_face;
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 2;
-               src = instr;
-
-               instr = instr_create(ctx, 2, OPC_ADD_S);
-               ir3_reg_create(instr, regid, 0);    /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
-               ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1;
-               src = instr;
-
-               instr = instr_create(ctx, 1, 0); /* mov */
-               instr->cat1.src_type = TYPE_S32;
-               instr->cat1.dst_type = TYPE_F32;
-               ir3_reg_create(instr, regid, 0);    /* dummy dst */
-               ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
-
-               break;
-       case 1: /* .y */
-       case 2: /* .z */
-               instr = create_immed(ctx, 0.0);
-               break;
-       case 3: /* .w */
-               instr = create_immed(ctx, 1.0);
-               break;
-       default:
-               compile_error(ctx, "invalid channel\n");
-               instr = create_immed(ctx, 0.0);
-               break;
-       }
-
-       return instr;
-}
-
-static void
-decl_in(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
-{
-       struct ir3_shader_variant *so = ctx->so;
-       unsigned name = decl->Semantic.Name;
-       unsigned i;
-
-       /* I don't think we should get frag shader input without
-        * semantic info?  Otherwise how do inputs get linked to
-        * vert outputs?
-        */
-       compile_assert(ctx, (ctx->type == TGSI_PROCESSOR_VERTEX) ||
-                       decl->Declaration.Semantic);
-
-       for (i = decl->Range.First; i <= decl->Range.Last; i++) {
-               unsigned n = so->inputs_count++;
-               unsigned r = regid(i, 0);
-               unsigned ncomp, j;
-
-               /* we'll figure out the actual components used after scheduling */
-               ncomp = 4;
-
-               DBG("decl in -> r%d", i);
-
-               compile_assert(ctx, n < ARRAY_SIZE(so->inputs));
-
-               so->inputs[n].semantic = decl_semantic(&decl->Semantic);
-               so->inputs[n].compmask = (1 << ncomp) - 1;
-               so->inputs[n].regid = r;
-               so->inputs[n].inloc = ctx->next_inloc;
-               so->inputs[n].interpolate = decl->Interp.Interpolate;
-
-               for (j = 0; j < ncomp; j++) {
-                       struct ir3_instruction *instr = NULL;
-
-                       if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
-                               /* for fragment shaders, POSITION and FACE are handled
-                                * specially, not using normal varying / bary.f
-                                */
-                               if (name == TGSI_SEMANTIC_POSITION) {
-                                       so->inputs[n].bary = false;
-                                       so->frag_coord = true;
-                                       instr = decl_in_frag_coord(ctx, r + j, j);
-                               } else if (name == TGSI_SEMANTIC_FACE) {
-                                       so->inputs[n].bary = false;
-                                       so->frag_face = true;
-                                       instr = decl_in_frag_face(ctx, r + j, j);
-                               } else {
-                                       bool use_ldlv = false;
-
-                                       /* if no interpolation given, pick based on
-                                        * semantic:
-                                        */
-                                       if (!decl->Declaration.Interpolate) {
-                                               switch (decl->Semantic.Name) {
-                                               case TGSI_SEMANTIC_COLOR:
-                                                       so->inputs[n].interpolate =
-                                                                       TGSI_INTERPOLATE_COLOR;
-                                                       break;
-                                               default:
-                                                       so->inputs[n].interpolate =
-                                                                       TGSI_INTERPOLATE_LINEAR;
-                                               }
-                                       }
-
-                                       if (ctx->flat_bypass) {
-                                               switch (so->inputs[n].interpolate) {
-                                               case TGSI_INTERPOLATE_COLOR:
-                                                       if (!ctx->so->key.rasterflat)
-                                                               break;
-                                                       /* fallthrough */
-                                               case TGSI_INTERPOLATE_CONSTANT:
-                                                       use_ldlv = true;
-                                                       break;
-                                               }
-                                       }
-
-                                       so->inputs[n].bary = true;
-
-                                       instr = decl_in_frag_bary(ctx, r + j, j,
-                                                       so->inputs[n].inloc + j - 8, use_ldlv);
-                               }
-                       } else {
-                               instr = create_input(ctx->block, NULL, (i * 4) + j);
-                       }
-
-                       ctx->block->inputs[(i * 4) + j] = instr;
-               }
-
-               if (so->inputs[n].bary || (ctx->type == TGSI_PROCESSOR_VERTEX)) {
-                       ctx->next_inloc += ncomp;
-                       so->total_in += ncomp;
-               }
-       }
-}
-
-static void
-decl_sv(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
-{
-       struct ir3_shader_variant *so = ctx->so;
-       unsigned r = regid(so->inputs_count, 0);
-       unsigned n = so->inputs_count++;
-
-       DBG("decl sv -> r%d", n);
-
-       compile_assert(ctx, n < ARRAY_SIZE(so->inputs));
-       compile_assert(ctx, decl->Range.First < ARRAY_SIZE(ctx->sysval_semantics));
-
-       ctx->sysval_semantics[decl->Range.First] = decl->Semantic.Name;
-       so->inputs[n].semantic = decl_semantic(&decl->Semantic);
-       so->inputs[n].compmask = 1;
-       so->inputs[n].regid = r;
-       so->inputs[n].inloc = ctx->next_inloc;
-       so->inputs[n].interpolate = TGSI_INTERPOLATE_CONSTANT;
-
-       struct ir3_instruction *instr = NULL;
-
-       switch (decl->Semantic.Name) {
-       case TGSI_SEMANTIC_VERTEXID_NOBASE:
-               ctx->vertex_id = instr = create_input(ctx->block, NULL, r);
-               break;
-       case TGSI_SEMANTIC_BASEVERTEX:
-               ctx->basevertex = instr = instr_create(ctx, 1, 0);
-               instr->cat1.src_type = get_stype(ctx);
-               instr->cat1.dst_type = get_stype(ctx);
-               ir3_reg_create(instr, 0, 0);
-               ir3_reg_create(instr, regid(so->first_driver_param + 4, 0),
-                                          IR3_REG_CONST);
-               break;
-       case TGSI_SEMANTIC_INSTANCEID:
-               ctx->instance_id = instr = create_input(ctx->block, NULL, r);
-               break;
-       default:
-               compile_error(ctx, "Unknown semantic: %s\n",
-                                         tgsi_semantic_names[decl->Semantic.Name]);
-       }
-
-       ctx->block->inputs[r] = instr;
-       ctx->next_inloc++;
-       so->total_in++;
-}
-
-static void
-decl_out(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
-{
-       struct ir3_shader_variant *so = ctx->so;
-       unsigned comp = 0;
-       unsigned name = decl->Semantic.Name;
-       unsigned i;
-
-       compile_assert(ctx, decl->Declaration.Semantic);
-
-       DBG("decl out[%d] -> r%d", name, decl->Range.First);
-
-       if (ctx->type == TGSI_PROCESSOR_VERTEX) {
-               switch (name) {
-               case TGSI_SEMANTIC_POSITION:
-                       so->writes_pos = true;
-                       break;
-               case TGSI_SEMANTIC_PSIZE:
-                       so->writes_psize = true;
-                       break;
-               case TGSI_SEMANTIC_COLOR:
-               case TGSI_SEMANTIC_BCOLOR:
-               case TGSI_SEMANTIC_GENERIC:
-               case TGSI_SEMANTIC_FOG:
-               case TGSI_SEMANTIC_TEXCOORD:
-                       break;
-               default:
-                       compile_error(ctx, "unknown VS semantic name: %s\n",
-                                       tgsi_semantic_names[name]);
-               }
-       } else {
-               switch (name) {
-               case TGSI_SEMANTIC_POSITION:
-                       comp = 2;  /* tgsi will write to .z component */
-                       so->writes_pos = true;
-                       break;
-               case TGSI_SEMANTIC_COLOR:
-                       break;
-               default:
-                       compile_error(ctx, "unknown FS semantic name: %s\n",
-                                       tgsi_semantic_names[name]);
-               }
-       }
-
-       for (i = decl->Range.First; i <= decl->Range.Last; i++) {
-               unsigned n = so->outputs_count++;
-               unsigned ncomp, j;
-
-               ncomp = 4;
-
-               compile_assert(ctx, n < ARRAY_SIZE(so->outputs));
-
-               so->outputs[n].semantic = decl_semantic(&decl->Semantic);
-               so->outputs[n].regid = regid(i, comp);
-
-               /* avoid undefined outputs, stick a dummy mov from imm{0.0},
-                * which if the output is actually assigned will be over-
-                * written
-                */
-               for (j = 0; j < ncomp; j++)
-                       ctx->block->outputs[(i * 4) + j] = create_immed(ctx, 0.0);
-       }
-}
-
-/* from TGSI perspective, we actually have inputs.  But most of the "inputs"
- * for a fragment shader are just bary.f instructions.  The *actual* inputs
- * from the hw perspective are the frag_pos and optionally frag_coord and
- * frag_face.
- */
-static void
-fixup_frag_inputs(struct ir3_compile_context *ctx)
-{
-       struct ir3_shader_variant *so = ctx->so;
-       struct ir3_block *block = ctx->block;
-       struct ir3_instruction **inputs;
-       struct ir3_instruction *instr;
-       int n, regid = 0;
-
-       block->ninputs = 0;
-
-       n  = 4;  /* always have frag_pos */
-       n += COND(so->frag_face, 4);
-       n += COND(so->frag_coord, 4);
-
-       inputs = ir3_alloc(ctx->ir, n * (sizeof(struct ir3_instruction *)));
-
-       if (so->frag_face) {
-               /* this ultimately gets assigned to hr0.x so doesn't conflict
-                * with frag_coord/frag_pos..
-                */
-               inputs[block->ninputs++] = ctx->frag_face;
-               ctx->frag_face->regs[0]->num = 0;
-
-               /* remaining channels not used, but let's avoid confusing
-                * other parts that expect inputs to come in groups of vec4
-                */
-               inputs[block->ninputs++] = NULL;
-               inputs[block->ninputs++] = NULL;
-               inputs[block->ninputs++] = NULL;
-       }
-
-       /* since we don't know where to set the regid for frag_coord,
-        * we have to use r0.x for it.  But we don't want to *always*
-        * use r1.x for frag_pos as that could increase the register
-        * footprint on simple shaders:
-        */
-       if (so->frag_coord) {
-               ctx->frag_coord[0]->regs[0]->num = regid++;
-               ctx->frag_coord[1]->regs[0]->num = regid++;
-               ctx->frag_coord[2]->regs[0]->num = regid++;
-               ctx->frag_coord[3]->regs[0]->num = regid++;
-
-               inputs[block->ninputs++] = ctx->frag_coord[0];
-               inputs[block->ninputs++] = ctx->frag_coord[1];
-               inputs[block->ninputs++] = ctx->frag_coord[2];
-               inputs[block->ninputs++] = ctx->frag_coord[3];
-       }
-
-       /* we always have frag_pos: */
-       so->pos_regid = regid;
-
-       /* r0.x */
-       instr = create_input(block, NULL, block->ninputs);
-       instr->regs[0]->num = regid++;
-       inputs[block->ninputs++] = instr;
-       ctx->frag_pos->regs[1]->instr = instr;
-
-       /* r0.y */
-       instr = create_input(block, NULL, block->ninputs);
-       instr->regs[0]->num = regid++;
-       inputs[block->ninputs++] = instr;
-       ctx->frag_pos->regs[2]->instr = instr;
-
-       block->inputs = inputs;
-}
-
-static void
-compile_instructions(struct ir3_compile_context *ctx)
-{
-       push_block(ctx);
-
-       /* for fragment shader, we have a single input register (usually
-        * r0.xy) which is used as the base for bary.f varying fetch instrs:
-        */
-       if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
-               struct ir3_instruction *instr;
-               instr = ir3_instr_create(ctx->block, -1, OPC_META_FI);
-               ir3_reg_create(instr, 0, 0);
-               ir3_reg_create(instr, 0, IR3_REG_SSA);    /* r0.x */
-               ir3_reg_create(instr, 0, IR3_REG_SSA);    /* r0.y */
-               ctx->frag_pos = instr;
-       }
-
-       while (!tgsi_parse_end_of_tokens(&ctx->parser)) {
-               tgsi_parse_token(&ctx->parser);
-
-               switch (ctx->parser.FullToken.Token.Type) {
-               case TGSI_TOKEN_TYPE_DECLARATION: {
-                       struct tgsi_full_declaration *decl =
-                                       &ctx->parser.FullToken.FullDeclaration;
-                       unsigned file = decl->Declaration.File;
-                       if (file == TGSI_FILE_OUTPUT) {
-                               decl_out(ctx, decl);
-                       } else if (file == TGSI_FILE_INPUT) {
-                               decl_in(ctx, decl);
-                       } else if (decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
-                               decl_sv(ctx, decl);
-                       }
-
-                       if ((file != TGSI_FILE_CONSTANT) && decl->Declaration.Array) {
-                               int aid = decl->Array.ArrayID + ctx->array_offsets[file];
-
-                               compile_assert(ctx, aid < ARRAY_SIZE(ctx->array));
-
-                               /* legacy ArrayID==0 stuff probably isn't going to work
-                                * well (and is at least untested).. let's just scream:
-                                */
-                               compile_assert(ctx, aid != 0);
-
-                               ctx->array[aid].first = decl->Range.First;
-                               ctx->array[aid].last  = decl->Range.Last;
-                       }
-                       break;
-               }
-               case TGSI_TOKEN_TYPE_IMMEDIATE: {
-                       /* TODO: if we know the immediate is small enough, and only
-                        * used with instructions that can embed an immediate, we
-                        * can skip this:
-                        */
-                       struct tgsi_full_immediate *imm =
-                                       &ctx->parser.FullToken.FullImmediate;
-                       unsigned n = ctx->so->immediates_count++;
-                       compile_assert(ctx, n < ARRAY_SIZE(ctx->so->immediates));
-                       memcpy(ctx->so->immediates[n].val, imm->u, 16);
-                       break;
-               }
-               case TGSI_TOKEN_TYPE_INSTRUCTION: {
-                       struct tgsi_full_instruction *inst =
-                                       &ctx->parser.FullToken.FullInstruction;
-                       unsigned opc = inst->Instruction.Opcode;
-                       const struct instr_translater *t = &translaters[opc];
-
-                       if (t->fxn) {
-                               t->fxn(t, ctx, inst);
-                               ctx->num_internal_temps = 0;
-
-                               compile_assert(ctx, !ctx->using_tmp_dst);
-                       } else {
-                               compile_error(ctx, "unknown TGSI opc: %s\n",
-                                               tgsi_get_opcode_name(opc));
-                       }
-
-                       switch (inst->Instruction.Saturate) {
-                       case TGSI_SAT_ZERO_ONE:
-                               create_clamp_imm(ctx, &inst->Dst[0].Register,
-                                               fui(0.0), fui(1.0));
-                               break;
-                       case TGSI_SAT_MINUS_PLUS_ONE:
-                               create_clamp_imm(ctx, &inst->Dst[0].Register,
-                                               fui(-1.0), fui(1.0));
-                               break;
-                       }
-
-                       instr_finish(ctx);
-
-                       break;
-               }
-               case TGSI_TOKEN_TYPE_PROPERTY: {
-                       struct tgsi_full_property *prop =
-                               &ctx->parser.FullToken.FullProperty;
-                       switch (prop->Property.PropertyName) {
-                       case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
-                               ctx->so->color0_mrt = !!prop->u[0].Data;
-                               break;
-                       }
-               }
-               default:
-                       break;
-               }
-       }
-}
-
-static void
-compile_dump(struct ir3_compile_context *ctx)
-{
-       const char *name = (ctx->so->type == SHADER_VERTEX) ? "vert" : "frag";
-       static unsigned n = 0;
-       char fname[16];
-       FILE *f;
-       snprintf(fname, sizeof(fname), "%s-%04u.dot", name, n++);
-       f = fopen(fname, "w");
-       if (!f)
-               return;
-       ir3_block_depth(ctx->block);
-       ir3_dump(ctx->ir, name, ctx->block, f);
-       fclose(f);
-}
-
-int
-ir3_compile_shader(struct ir3_shader_variant *so,
-               const struct tgsi_token *tokens, struct ir3_shader_key key,
-               bool cp)
-{
-       struct ir3_compile_context ctx;
-       struct ir3_block *block;
-       struct ir3_instruction **inputs;
-       unsigned i, j, actual_in;
-       int ret = 0, max_bary;
-
-       assert(!so->ir);
-
-       so->ir = ir3_create();
-
-       assert(so->ir);
-
-       if (compile_init(&ctx, so, tokens) != TGSI_PARSE_OK) {
-               DBG("INIT failed!");
-               ret = -1;
-               goto out;
-       }
-
-       /* for now, until the edge cases are worked out: */
-       if (ctx.info.indirect_files_written & (FM(TEMPORARY) | FM(INPUT) | FM(OUTPUT)))
-               cp = false;
-
-       compile_instructions(&ctx);
-
-       block = ctx.block;
-       so->ir->block = block;
-
-       /* keep track of the inputs from TGSI perspective.. */
-       inputs = block->inputs;
-
-       /* but fixup actual inputs for frag shader: */
-       if (ctx.type == TGSI_PROCESSOR_FRAGMENT)
-               fixup_frag_inputs(&ctx);
-
-       /* at this point, for binning pass, throw away unneeded outputs: */
-       if (key.binning_pass) {
-               for (i = 0, j = 0; i < so->outputs_count; i++) {
-                       unsigned name = sem2name(so->outputs[i].semantic);
-                       unsigned idx = sem2idx(so->outputs[i].semantic);
-
-                       /* throw away everything but first position/psize */
-                       if ((idx == 0) && ((name == TGSI_SEMANTIC_POSITION) ||
-                                       (name == TGSI_SEMANTIC_PSIZE))) {
-                               if (i != j) {
-                                       so->outputs[j] = so->outputs[i];
-                                       block->outputs[(j*4)+0] = block->outputs[(i*4)+0];
-                                       block->outputs[(j*4)+1] = block->outputs[(i*4)+1];
-                                       block->outputs[(j*4)+2] = block->outputs[(i*4)+2];
-                                       block->outputs[(j*4)+3] = block->outputs[(i*4)+3];
-                               }
-                               j++;
-                       }
-               }
-               so->outputs_count = j;
-               block->noutputs = j * 4;
-       }
-
-       /* if we want half-precision outputs, mark the output registers
-        * as half:
-        */
-       if (key.half_precision) {
-               for (i = 0; i < block->noutputs; i++) {
-                       if (!block->outputs[i])
-                               continue;
-                       block->outputs[i]->regs[0]->flags |= IR3_REG_HALF;
-               }
-       }
-
-       /* at this point, we want the kill's in the outputs array too,
-        * so that they get scheduled (since they have no dst).. we've
-        * already ensured that the array is big enough in push_block():
-        */
-       if (ctx.type == TGSI_PROCESSOR_FRAGMENT) {
-               for (i = 0; i < ctx.kill_count; i++)
-                       block->outputs[block->noutputs++] = ctx.kill[i];
-       }
-
-       if (fd_mesa_debug & FD_DBG_OPTDUMP)
-               compile_dump(&ctx);
-
-       ret = ir3_block_flatten(block);
-       if (ret < 0) {
-               DBG("FLATTEN failed!");
-               goto out;
-       }
-       if ((ret > 0) && (fd_mesa_debug & FD_DBG_OPTDUMP))
-               compile_dump(&ctx);
-
-       if (fd_mesa_debug & FD_DBG_OPTMSGS) {
-               printf("BEFORE CP:\n");
-               ir3_dump_instr_list(block->head);
-       }
-
-       ir3_block_depth(block);
-
-       /* First remove all the extra mov's (which we could skip if the
-        * front-end was clever enough not to insert them in the first
-        * place).  Then figure out left/right neighbors, re-inserting
-        * extra mov's when needed to avoid conflicts.
-        */
-       if (cp && !(fd_mesa_debug & FD_DBG_NOCP))
-               ir3_block_cp(block);
-
-       if (fd_mesa_debug & FD_DBG_OPTMSGS) {
-               printf("BEFORE GROUPING:\n");
-               ir3_dump_instr_list(block->head);
-       }
-
-       /* Group left/right neighbors, inserting mov's where needed to
-        * solve conflicts:
-        */
-       ir3_block_group(block);
-
-       if (fd_mesa_debug & FD_DBG_OPTDUMP)
-               compile_dump(&ctx);
-
-       ir3_block_depth(block);
-
-       if (fd_mesa_debug & FD_DBG_OPTMSGS) {
-               printf("AFTER DEPTH:\n");
-               ir3_dump_instr_list(block->head);
-       }
-
-       ret = ir3_block_sched(block);
-       if (ret) {
-               DBG("SCHED failed!");
-               goto out;
-       }
-
-       if (fd_mesa_debug & FD_DBG_OPTMSGS) {
-               printf("AFTER SCHED:\n");
-               ir3_dump_instr_list(block->head);
-       }
-
-       ret = ir3_block_ra(block, so->type, so->frag_coord, so->frag_face);
-       if (ret) {
-               DBG("RA failed!");
-               goto out;
-       }
-
-       if (fd_mesa_debug & FD_DBG_OPTMSGS) {
-               printf("AFTER RA:\n");
-               ir3_dump_instr_list(block->head);
-       }
-
-       ir3_block_legalize(block, &so->has_samp, &max_bary);
-
-       /* fixup input/outputs: */
-       for (i = 0; i < so->outputs_count; i++) {
-               so->outputs[i].regid = block->outputs[i*4]->regs[0]->num;
-               /* preserve hack for depth output.. tgsi writes depth to .z,
-                * but what we give the hw is the scalar register:
-                */
-               if ((ctx.type == TGSI_PROCESSOR_FRAGMENT) &&
-                       (sem2name(so->outputs[i].semantic) == TGSI_SEMANTIC_POSITION))
-                       so->outputs[i].regid += 2;
-       }
-       /* Note that some or all channels of an input may be unused: */
-       actual_in = 0;
-       for (i = 0; i < so->inputs_count; i++) {
-               unsigned j, regid = ~0, compmask = 0;
-               so->inputs[i].ncomp = 0;
-               for (j = 0; j < 4; j++) {
-                       struct ir3_instruction *in = inputs[(i*4) + j];
-                       if (in) {
-                               compmask |= (1 << j);
-                               regid = in->regs[0]->num - j;
-                               actual_in++;
-                               so->inputs[i].ncomp++;
-                       }
-               }
-               so->inputs[i].regid = regid;
-               so->inputs[i].compmask = compmask;
-       }
-
-       /* fragment shader always gets full vec4's even if it doesn't
-        * fetch all components, but vertex shader we need to update
-        * with the actual number of components fetch, otherwise thing
-        * will hang due to mismaptch between VFD_DECODE's and
-        * TOTALATTRTOVS
-        */
-       if (so->type == SHADER_VERTEX)
-               so->total_in = actual_in;
-       else
-               so->total_in = align(max_bary + 1, 4);
-
-out:
-       if (ret) {
-               ir3_destroy(so->ir);
-               so->ir = NULL;
-       }
-       compile_free(&ctx);
-
-       return ret;
+       ralloc_free(compiler);
 }
index 9213386e00c341cc04fb089591cf1f4d28e7294d..86b1161d9cb678f515e2676e81ef0fdef79c00b3 100644 (file)
 
 #include "ir3_shader.h"
 
+struct ir3_ra_reg_set;
 
-int ir3_compile_shader_nir(struct ir3_shader_variant *so,
-               const struct tgsi_token *tokens, struct ir3_shader_key key);
+struct ir3_compiler {
+       uint32_t gpu_id;
+       struct ir3_ra_reg_set *set;
+};
 
-int ir3_compile_shader(struct ir3_shader_variant *so,
+struct ir3_compiler * ir3_compiler_create(uint32_t gpu_id);
+void ir3_compiler_destroy(struct ir3_compiler *compiler);
+
+int ir3_compile_shader_nir(struct ir3_compiler *compiler,
+               struct ir3_shader_variant *so,
                const struct tgsi_token *tokens,
-               struct ir3_shader_key key, bool cp);
+               struct ir3_shader_key key);
 
 #endif /* IR3_COMPILER_H_ */
index 05e7049ad55221e8b9c9add681f83888aad347eb..48b1d8f3606a5a528c4ec3dda5c8464751b28fc7 100644 (file)
 #include "ir3.h"
 
 
-static struct ir3_instruction * create_immed(struct ir3_block *block, uint32_t val);
-
 struct ir3_compile {
+       struct ir3_compiler *compiler;
+
        const struct tgsi_token *tokens;
        struct nir_shader *s;
 
        struct ir3 *ir;
        struct ir3_shader_variant *so;
 
-       /* bitmask of which samplers are integer: */
-       uint16_t integer_s;
+       struct ir3_block *block;      /* the current block */
+       struct ir3_block *in_block;   /* block created for shader inputs */
 
-       struct ir3_block *block;
+       nir_function_impl *impl;
 
        /* For fragment shaders, from the hw perspective the only
         * actual input is r0.xy position register passed to bary.f.
@@ -92,6 +92,11 @@ struct ir3_compile {
         */
        struct hash_table *addr_ht;
 
+       /* maps nir_block to ir3_block, mostly for the purposes of
+        * figuring out the blocks successors
+        */
+       struct hash_table *block_ht;
+
        /* for calculating input/output positions/linkages: */
        unsigned next_inloc;
 
@@ -104,6 +109,11 @@ struct ir3_compile {
         */
        bool levels_add_one;
 
+       /* on a3xx, we need to scale up integer coords for isaml based
+        * on LoD:
+        */
+       bool unminify_coords;
+
        /* for looking up which system value is which */
        unsigned sysval_semantics[8];
 
@@ -118,6 +128,9 @@ struct ir3_compile {
 };
 
 
+static struct ir3_instruction * create_immed(struct ir3_block *block, uint32_t val);
+static struct ir3_block * get_block(struct ir3_compile *ctx, nir_block *nblock);
+
 static struct nir_shader *to_nir(const struct tgsi_token *tokens)
 {
        struct nir_shader_compiler_options options = {
@@ -146,6 +159,7 @@ static struct nir_shader *to_nir(const struct tgsi_token *tokens)
 
                nir_lower_vars_to_ssa(s);
                nir_lower_alu_to_scalar(s);
+               nir_lower_phis_to_scalar(s);
 
                progress |= nir_copy_prop(s);
                progress |= nir_opt_dce(s);
@@ -170,7 +184,8 @@ static struct nir_shader *to_nir(const struct tgsi_token *tokens)
 
 /* TODO nir doesn't lower everything for us yet, but ideally it would: */
 static const struct tgsi_token *
-lower_tgsi(const struct tgsi_token *tokens, struct ir3_shader_variant *so)
+lower_tgsi(struct ir3_compile *ctx, const struct tgsi_token *tokens,
+               struct ir3_shader_variant *so)
 {
        struct tgsi_shader_info info;
        struct tgsi_lowering_config lconfig = {
@@ -192,11 +207,7 @@ lower_tgsi(const struct tgsi_token *tokens, struct ir3_shader_variant *so)
                break;
        }
 
-       if (!so->shader) {
-               /* hack for standalone compiler which does not have
-                * screen/context:
-                */
-       } else if (ir3_shader_gpuid(so->shader) >= 400) {
+       if (ctx->compiler->gpu_id >= 400) {
                /* a4xx seems to have *no* sam.p */
                lconfig.lower_TXP = ~0;  /* lower all txp */
        } else {
@@ -208,36 +219,26 @@ lower_tgsi(const struct tgsi_token *tokens, struct ir3_shader_variant *so)
 }
 
 static struct ir3_compile *
-compile_init(struct ir3_shader_variant *so,
+compile_init(struct ir3_compiler *compiler,
+               struct ir3_shader_variant *so,
                const struct tgsi_token *tokens)
 {
        struct ir3_compile *ctx = rzalloc(NULL, struct ir3_compile);
        const struct tgsi_token *lowered_tokens;
 
-       if (!so->shader) {
-               /* hack for standalone compiler which does not have
-                * screen/context:
-                */
-       } else if (ir3_shader_gpuid(so->shader) >= 400) {
+       if (compiler->gpu_id >= 400) {
                /* need special handling for "flat" */
                ctx->flat_bypass = true;
                ctx->levels_add_one = false;
+               ctx->unminify_coords = false;
        } else {
                /* no special handling for "flat" */
                ctx->flat_bypass = false;
                ctx->levels_add_one = true;
+               ctx->unminify_coords = true;
        }
 
-       switch (so->type) {
-       case SHADER_FRAGMENT:
-       case SHADER_COMPUTE:
-               ctx->integer_s = so->key.finteger_s;
-               break;
-       case SHADER_VERTEX:
-               ctx->integer_s = so->key.vinteger_s;
-               break;
-       }
-
+       ctx->compiler = compiler;
        ctx->ir = so->ir;
        ctx->so = so;
        ctx->next_inloc = 8;
@@ -247,8 +248,10 @@ compile_init(struct ir3_shader_variant *so,
                        _mesa_hash_pointer, _mesa_key_pointer_equal);
        ctx->addr_ht = _mesa_hash_table_create(ctx,
                        _mesa_hash_pointer, _mesa_key_pointer_equal);
+       ctx->block_ht = _mesa_hash_table_create(ctx,
+                       _mesa_hash_pointer, _mesa_key_pointer_equal);
 
-       lowered_tokens = lower_tgsi(tokens, so);
+       lowered_tokens = lower_tgsi(ctx, tokens, so);
        if (!lowered_tokens)
                lowered_tokens = tokens;
        ctx->s = to_nir(lowered_tokens);
@@ -290,33 +293,206 @@ compile_free(struct ir3_compile *ctx)
        ralloc_free(ctx);
 }
 
-
+/* global per-array information: */
 struct ir3_array {
        unsigned length, aid;
+};
+
+/* per-block array state: */
+struct ir3_array_value {
+       /* TODO drop length/aid, and just have ptr back to ir3_array */
+       unsigned length, aid;
+       /* initial array element values are phi's, other than for the
+        * entry block.  The phi src's get added later in a resolve step
+        * after we have visited all the blocks, to account for back
+        * edges in the cfg.
+        */
+       struct ir3_instruction **phis;
+       /* current array element values (as block is processed).  When
+        * the array phi's are resolved, it will contain the array state
+        * at exit of block, so successor blocks can use it to add their
+        * phi srcs.
+        */
        struct ir3_instruction *arr[];
 };
 
+/* track array assignments per basic block.  When an array is read
+ * outside of the same basic block, we can use NIR's dominance-frontier
+ * information to figure out where phi nodes are needed.
+ */
+struct ir3_nir_block_data {
+       unsigned foo;
+       /* indexed by array-id (aid): */
+       struct ir3_array_value *arrs[];
+};
+
+static struct ir3_nir_block_data *
+get_block_data(struct ir3_compile *ctx, struct ir3_block *block)
+{
+       if (!block->bd) {
+               struct ir3_nir_block_data *bd = ralloc_size(ctx, sizeof(*bd) +
+                               ((ctx->num_arrays + 1) * sizeof(bd->arrs[0])));
+               block->bd = bd;
+       }
+       return block->bd;
+}
+
 static void
 declare_var(struct ir3_compile *ctx, nir_variable *var)
 {
        unsigned length = glsl_get_length(var->type) * 4;  /* always vec4, at least with ttn */
-       struct ir3_array *arr = ralloc_size(ctx, sizeof(*arr) +
-                       (length * sizeof(arr->arr[0])));
+       struct ir3_array *arr = ralloc(ctx, struct ir3_array);
        arr->length = length;
        arr->aid = ++ctx->num_arrays;
-       /* Some shaders end up reading array elements without first writing..
-        * so initialize things to prevent null instr ptrs later:
-        */
-       for (unsigned i = 0; i < length; i++)
-               arr->arr[i] = create_immed(ctx->block, 0);
        _mesa_hash_table_insert(ctx->var_ht, var, arr);
 }
 
-static struct ir3_array *
+static nir_block *
+nir_block_pred(nir_block *block)
+{
+       assert(block->predecessors->entries < 2);
+       if (block->predecessors->entries == 0)
+               return NULL;
+       return (nir_block *)_mesa_set_next_entry(block->predecessors, NULL)->key;
+}
+
+static struct ir3_array_value *
 get_var(struct ir3_compile *ctx, nir_variable *var)
 {
        struct hash_entry *entry = _mesa_hash_table_search(ctx->var_ht, var);
-       return entry->data;
+       struct ir3_block *block = ctx->block;
+       struct ir3_nir_block_data *bd = get_block_data(ctx, block);
+       struct ir3_array *arr = entry->data;
+
+       if (!bd->arrs[arr->aid]) {
+               struct ir3_array_value *av = ralloc_size(bd, sizeof(*av) +
+                               (arr->length * sizeof(av->arr[0])));
+               struct ir3_array_value *defn = NULL;
+               nir_block *pred_block;
+
+               av->length = arr->length;
+               av->aid = arr->aid;
+
+               /* For loops, we have to consider that we have not visited some
+                * of the blocks who should feed into the phi (ie. back-edges in
+                * the cfg).. for example:
+                *
+                *   loop {
+                *      block { load_var; ... }
+                *      if then block {} else block {}
+                *      block { store_var; ... }
+                *      if then block {} else block {}
+                *      block {...}
+                *   }
+                *
+                * We can skip the phi if we can chase the block predecessors
+                * until finding the block previously defining the array without
+                * crossing a block that has more than one predecessor.
+                *
+                * Otherwise create phi's and resolve them as a post-pass after
+                * all the blocks have been visited (to handle back-edges).
+                */
+
+               for (pred_block = block->nblock;
+                               pred_block && (pred_block->predecessors->entries < 2) && !defn;
+                               pred_block = nir_block_pred(pred_block)) {
+                       struct ir3_block *pblock = get_block(ctx, pred_block);
+                       struct ir3_nir_block_data *pbd = pblock->bd;
+                       if (!pbd)
+                               continue;
+                       defn = pbd->arrs[arr->aid];
+               }
+
+               if (defn) {
+                       /* only one possible definer: */
+                       for (unsigned i = 0; i < arr->length; i++)
+                               av->arr[i] = defn->arr[i];
+               } else if (pred_block) {
+                       /* not the first block, and multiple potential definers: */
+                       av->phis = ralloc_size(av, arr->length * sizeof(av->phis[0]));
+
+                       for (unsigned i = 0; i < arr->length; i++) {
+                               struct ir3_instruction *phi;
+
+                               phi = ir3_instr_create2(block, -1, OPC_META_PHI,
+                                               1 + ctx->impl->num_blocks);
+                               ir3_reg_create(phi, 0, 0);         /* dst */
+
+                               /* phi's should go at head of block: */
+                               list_delinit(&phi->node);
+                               list_add(&phi->node, &block->instr_list);
+
+                               av->phis[i] = av->arr[i] = phi;
+                       }
+               } else {
+                       /* Some shaders end up reading array elements without
+                        * first writing.. so initialize things to prevent null
+                        * instr ptrs later:
+                        */
+                       for (unsigned i = 0; i < arr->length; i++)
+                               av->arr[i] = create_immed(block, 0);
+               }
+
+               bd->arrs[arr->aid] = av;
+       }
+
+       return bd->arrs[arr->aid];
+}
+
+static void
+add_array_phi_srcs(struct ir3_compile *ctx, nir_block *nblock,
+               struct ir3_array_value *av, BITSET_WORD *visited)
+{
+       struct ir3_block *block;
+       struct ir3_nir_block_data *bd;
+
+       if (BITSET_TEST(visited, nblock->index))
+               return;
+
+       BITSET_SET(visited, nblock->index);
+
+       block = get_block(ctx, nblock);
+       bd = block->bd;
+
+       if (bd && bd->arrs[av->aid]) {
+               struct ir3_array_value *dav = bd->arrs[av->aid];
+               for (unsigned i = 0; i < av->length; i++) {
+                       ir3_reg_create(av->phis[i], 0, IR3_REG_SSA)->instr =
+                                       dav->arr[i];
+               }
+       } else {
+               /* didn't find defn, recurse predecessors: */
+               struct set_entry *entry;
+               set_foreach(nblock->predecessors, entry) {
+                       add_array_phi_srcs(ctx, (nir_block *)entry->key, av, visited);
+               }
+       }
+}
+
+static void
+resolve_array_phis(struct ir3_compile *ctx, struct ir3_block *block)
+{
+       struct ir3_nir_block_data *bd = block->bd;
+       unsigned bitset_words = BITSET_WORDS(ctx->impl->num_blocks);
+
+       if (!bd)
+               return;
+
+       /* TODO use nir dom_frontier to help us with this? */
+
+       for (unsigned i = 1; i <= ctx->num_arrays; i++) {
+               struct ir3_array_value *av = bd->arrs[i];
+               BITSET_WORD visited[bitset_words];
+               struct set_entry *entry;
+
+               if (!(av && av->phis))
+                       continue;
+
+               memset(visited, 0, sizeof(visited));
+               set_foreach(block->nblock->predecessors, entry) {
+                       add_array_phi_srcs(ctx, (nir_block *)entry->key, av, visited);
+               }
+       }
 }
 
 /* allocate a n element value array (to be populated by caller) and
@@ -393,7 +569,8 @@ create_addr(struct ir3_block *block, struct ir3_instruction *src)
        instr->regs[1]->flags |= IR3_REG_HALF;
 
        instr = ir3_MOV(block, instr, TYPE_S16);
-       instr->regs[0]->flags |= IR3_REG_ADDR | IR3_REG_HALF;
+       instr->regs[0]->num = regid(REG_A0, 0);
+       instr->regs[0]->flags |= IR3_REG_HALF;
        instr->regs[1]->flags |= IR3_REG_HALF;
 
        return instr;
@@ -418,6 +595,22 @@ get_addr(struct ir3_compile *ctx, struct ir3_instruction *src)
        return addr;
 }
 
+static struct ir3_instruction *
+get_predicate(struct ir3_compile *ctx, struct ir3_instruction *src)
+{
+       struct ir3_block *b = ctx->block;
+       struct ir3_instruction *cond;
+
+       /* NOTE: only cmps.*.* can write p0.x: */
+       cond = ir3_CMPS_S(b, src, 0, create_immed(b, 0), 0);
+       cond->cat2.condition = IR3_COND_NE;
+
+       /* condition always goes in predicate register: */
+       cond->regs[0]->num = regid(REG_P0, 0);
+
+       return cond;
+}
+
 static struct ir3_instruction *
 create_uniform(struct ir3_compile *ctx, unsigned n)
 {
@@ -461,7 +654,7 @@ create_collect(struct ir3_block *block, struct ir3_instruction **arr,
                return NULL;
 
        collect = ir3_instr_create2(block, -1, OPC_META_FI, 1 + arrsz);
-       ir3_reg_create(collect, 0, 0);
+       ir3_reg_create(collect, 0, 0);     /* dst */
        for (unsigned i = 0; i < arrsz; i++)
                ir3_reg_create(collect, 0, IR3_REG_SSA)->instr = arr[i];
 
@@ -597,6 +790,7 @@ create_frag_face(struct ir3_compile *ctx, unsigned comp)
                compile_assert(ctx, !ctx->frag_face);
 
                ctx->frag_face = create_input(block, NULL, 0);
+               ctx->frag_face->regs[0]->flags |= IR3_REG_HALF;
 
                /* for faceness, we always get -1 or 0 (int).. but TGSI expects
                 * positive vs negative float.. and piglit further seems to
@@ -628,10 +822,10 @@ create_frag_face(struct ir3_compile *ctx, unsigned comp)
  */
 static void
 split_dest(struct ir3_block *block, struct ir3_instruction **dst,
-               struct ir3_instruction *src)
+               struct ir3_instruction *src, unsigned n)
 {
        struct ir3_instruction *prev = NULL;
-       for (int i = 0, j = 0; i < 4; i++) {
+       for (int i = 0, j = 0; i < n; i++) {
                struct ir3_instruction *split =
                                ir3_instr_create(block, -1, OPC_META_FO);
                ir3_reg_create(split, 0, IR3_REG_SSA);
@@ -882,9 +1076,15 @@ emit_alu(struct ir3_compile *ctx, nir_alu_instr *alu)
        case nir_op_imax:
                dst[0] = ir3_MAX_S(b, src[0], 0, src[1], 0);
                break;
+       case nir_op_umax:
+               dst[0] = ir3_MAX_U(b, src[0], 0, src[1], 0);
+               break;
        case nir_op_imin:
                dst[0] = ir3_MIN_S(b, src[0], 0, src[1], 0);
                break;
+       case nir_op_umin:
+               dst[0] = ir3_MIN_U(b, src[0], 0, src[1], 0);
+               break;
        case nir_op_imul:
                /*
                 * dst = (al * bl) + (ah * bl << 16) + (al * bh << 16)
@@ -1030,7 +1230,7 @@ emit_intrinisic_load_var(struct ir3_compile *ctx, nir_intrinsic_instr *intr,
 {
        nir_deref_var *dvar = intr->variables[0];
        nir_deref_array *darr = nir_deref_as_array(dvar->deref.child);
-       struct ir3_array *arr = get_var(ctx, dvar->var);
+       struct ir3_array_value *arr = get_var(ctx, dvar->var);
 
        compile_assert(ctx, dvar->deref.child &&
                (dvar->deref.child->deref_type == nir_deref_type_array));
@@ -1070,7 +1270,7 @@ emit_intrinisic_store_var(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
 {
        nir_deref_var *dvar = intr->variables[0];
        nir_deref_array *darr = nir_deref_as_array(dvar->deref.child);
-       struct ir3_array *arr = get_var(ctx, dvar->var);
+       struct ir3_array_value *arr = get_var(ctx, dvar->var);
        struct ir3_instruction **src;
 
        compile_assert(ctx, dvar->deref.child &&
@@ -1140,8 +1340,8 @@ static void add_sysval_input(struct ir3_compile *ctx, unsigned name,
        so->inputs[n].interpolate = TGSI_INTERPOLATE_CONSTANT;
        so->total_in++;
 
-       ctx->block->ninputs = MAX2(ctx->block->ninputs, r + 1);
-       ctx->block->inputs[r] = instr;
+       ctx->ir->ninputs = MAX2(ctx->ir->ninputs, r + 1);
+       ctx->ir->inputs[r] = instr;
 }
 
 static void
@@ -1154,18 +1354,18 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
 
        if (info->has_dest) {
                dst = get_dst(ctx, &intr->dest, intr->num_components);
+       } else {
+               dst = NULL;
        }
 
        switch (intr->intrinsic) {
        case nir_intrinsic_load_uniform:
-               compile_assert(ctx, intr->const_index[1] == 1);
                for (int i = 0; i < intr->num_components; i++) {
                        unsigned n = idx * 4 + i;
                        dst[i] = create_uniform(ctx, n);
                }
                break;
        case nir_intrinsic_load_uniform_indirect:
-               compile_assert(ctx, intr->const_index[1] == 1);
                src = get_src(ctx, &intr->src[0]);
                for (int i = 0; i < intr->num_components; i++) {
                        unsigned n = idx * 4 + i;
@@ -1178,21 +1378,20 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
                emit_intrinsic_load_ubo(ctx, intr, dst);
                break;
        case nir_intrinsic_load_input:
-               compile_assert(ctx, intr->const_index[1] == 1);
                for (int i = 0; i < intr->num_components; i++) {
                        unsigned n = idx * 4 + i;
-                       dst[i] = b->inputs[n];
+                       dst[i] = ctx->ir->inputs[n];
                }
                break;
        case nir_intrinsic_load_input_indirect:
-               compile_assert(ctx, intr->const_index[1] == 1);
                src = get_src(ctx, &intr->src[0]);
                struct ir3_instruction *collect =
-                               create_collect(b, b->inputs, b->ninputs);
+                               create_collect(b, ctx->ir->inputs, ctx->ir->ninputs);
                struct ir3_instruction *addr = get_addr(ctx, src[0]);
                for (int i = 0; i < intr->num_components; i++) {
                        unsigned n = idx * 4 + i;
-                       dst[i] = create_indirect_load(ctx, b->ninputs, n, addr, collect);
+                       dst[i] = create_indirect_load(ctx, ctx->ir->ninputs,
+                                       n, addr, collect);
                }
                break;
        case nir_intrinsic_load_var:
@@ -1202,11 +1401,10 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
                emit_intrinisic_store_var(ctx, intr);
                break;
        case nir_intrinsic_store_output:
-               compile_assert(ctx, intr->const_index[1] == 1);
                src = get_src(ctx, &intr->src[0]);
                for (int i = 0; i < intr->num_components; i++) {
                        unsigned n = idx * 4 + i;
-                       b->outputs[n] = src[i];
+                       ctx->ir->outputs[n] = src[i];
                }
                break;
        case nir_intrinsic_load_base_vertex:
@@ -1248,6 +1446,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
                        cond = create_immed(b, 1);
                }
 
+               /* NOTE: only cmps.*.* can write p0.x: */
                cond = ir3_CMPS_S(b, cond, 0, create_immed(b, 0), 0);
                cond->cat2.condition = IR3_COND_NE;
 
@@ -1255,6 +1454,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
                cond->regs[0]->num = regid(REG_P0, 0);
 
                kill = ir3_KILL(b, cond, 0);
+               array_insert(ctx->ir->predicates, kill);
 
                ctx->kill[ctx->kill_count++] = kill;
                ctx->so->has_kill = true;
@@ -1318,6 +1518,8 @@ tex_info(nir_tex_instr *tex, unsigned *flagsp, unsigned *coordsp)
                coords = 3;
                flags |= IR3_INSTR_3D;
                break;
+       default:
+               unreachable("bad sampler_dim");
        }
 
        if (tex->is_shadow)
@@ -1340,7 +1542,10 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
        unsigned i, coords, flags;
        unsigned nsrc0 = 0, nsrc1 = 0;
        type_t type;
-       opc_t opc;
+       opc_t opc = 0;
+
+       coord = off = ddx = ddy = NULL;
+       lod = proj = compare = NULL;
 
        /* TODO: might just be one component for gathers? */
        dst = get_dst(ctx, &tex->dest, 4);
@@ -1400,11 +1605,12 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
        tex_info(tex, &flags, &coords);
 
        /* scale up integer coords for TXF based on the LOD */
-       if (opc == OPC_ISAML) {
+       if (ctx->unminify_coords && (opc == OPC_ISAML)) {
                assert(has_lod);
                for (i = 0; i < coords; i++)
                        coord[i] = ir3_SHL_B(b, coord[i], 0, lod, 0);
        }
+
        /*
         * lay out the first argument in the proper order:
         *  - actual coordinates first
@@ -1484,6 +1690,8 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
        case nir_type_bool:
                type = TYPE_U32;
                break;
+       default:
+               unreachable("bad dest_type");
        }
 
        sam = ir3_SAM(b, opc, type, TGSI_WRITEMASK_XYZW,
@@ -1491,7 +1699,7 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
                        create_collect(b, src0, nsrc0),
                        create_collect(b, src1, nsrc1));
 
-       split_dest(b, dst, sam);
+       split_dest(b, dst, sam, 4);
 }
 
 static void
@@ -1508,7 +1716,7 @@ emit_tex_query_levels(struct ir3_compile *ctx, nir_tex_instr *tex)
        /* even though there is only one component, since it ends
         * up in .z rather than .x, we need a split_dest()
         */
-       split_dest(b, dst, sam);
+       split_dest(b, dst, sam, 3);
 
        /* The # of levels comes from getinfo.z. We need to add 1 to it, since
         * the value in TEX_CONST_0 is zero-based.
@@ -1536,7 +1744,7 @@ emit_tex_txs(struct ir3_compile *ctx, nir_tex_instr *tex)
        sam = ir3_SAM(b, OPC_GETSIZE, TYPE_U32, TGSI_WRITEMASK_XYZW, flags,
                        tex->sampler_index, tex->sampler_index, lod, NULL);
 
-       split_dest(b, dst, sam);
+       split_dest(b, dst, sam, 4);
 
        /* Array size actually ends up in .w rather than .z. This doesn't
         * matter for miplevel 0, but for higher mips the value in z is
@@ -1552,6 +1760,71 @@ emit_tex_txs(struct ir3_compile *ctx, nir_tex_instr *tex)
        }
 }
 
+static void
+emit_phi(struct ir3_compile *ctx, nir_phi_instr *nphi)
+{
+       struct ir3_instruction *phi, **dst;
+
+       /* NOTE: phi's should be lowered to scalar at this point */
+       compile_assert(ctx, nphi->dest.ssa.num_components == 1);
+
+       dst = get_dst(ctx, &nphi->dest, 1);
+
+       phi = ir3_instr_create2(ctx->block, -1, OPC_META_PHI,
+                       1 + exec_list_length(&nphi->srcs));
+       ir3_reg_create(phi, 0, 0);         /* dst */
+       phi->phi.nphi = nphi;
+
+       dst[0] = phi;
+}
+
+/* phi instructions are left partially constructed.  We don't resolve
+ * their srcs until the end of the block, since (eg. loops) one of
+ * the phi's srcs might be defined after the phi due to back edges in
+ * the CFG.
+ */
+static void
+resolve_phis(struct ir3_compile *ctx, struct ir3_block *block)
+{
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+               nir_phi_instr *nphi;
+
+               /* phi's only come at start of block: */
+               if (!(is_meta(instr) && (instr->opc == OPC_META_PHI)))
+                       break;
+
+               if (!instr->phi.nphi)
+                       break;
+
+               nphi = instr->phi.nphi;
+               instr->phi.nphi = NULL;
+
+               foreach_list_typed(nir_phi_src, nsrc, node, &nphi->srcs) {
+                       struct ir3_instruction *src = get_src(ctx, &nsrc->src)[0];
+                       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
+               }
+       }
+
+       resolve_array_phis(ctx, block);
+}
+
+static void
+emit_jump(struct ir3_compile *ctx, nir_jump_instr *jump)
+{
+       switch (jump->type) {
+       case nir_jump_break:
+       case nir_jump_continue:
+               /* I *think* we can simply just ignore this, and use the
+                * successor block link to figure out where we need to
+                * jump to for break/continue
+                */
+               break;
+       default:
+               compile_error(ctx, "Unhandled NIR jump type: %d\n", jump->type);
+               break;
+       }
+}
+
 static void
 emit_instr(struct ir3_compile *ctx, nir_instr *instr)
 {
@@ -1585,44 +1858,111 @@ emit_instr(struct ir3_compile *ctx, nir_instr *instr)
                }
                break;
        }
-       case nir_instr_type_call:
-       case nir_instr_type_jump:
        case nir_instr_type_phi:
+               emit_phi(ctx, nir_instr_as_phi(instr));
+               break;
+       case nir_instr_type_jump:
+               emit_jump(ctx, nir_instr_as_jump(instr));
+               break;
+       case nir_instr_type_call:
        case nir_instr_type_parallel_copy:
                compile_error(ctx, "Unhandled NIR instruction type: %d\n", instr->type);
                break;
        }
 }
 
+static struct ir3_block *
+get_block(struct ir3_compile *ctx, nir_block *nblock)
+{
+       struct ir3_block *block;
+       struct hash_entry *entry;
+       entry = _mesa_hash_table_search(ctx->block_ht, nblock);
+       if (entry)
+               return entry->data;
+
+       block = ir3_block_create(ctx->ir);
+       block->nblock = nblock;
+       _mesa_hash_table_insert(ctx->block_ht, nblock, block);
+
+       return block;
+}
+
 static void
-emit_block(struct ir3_compile *ctx, nir_block *block)
+emit_block(struct ir3_compile *ctx, nir_block *nblock)
 {
-       nir_foreach_instr(block, instr) {
+       struct ir3_block *block = get_block(ctx, nblock);
+
+       for (int i = 0; i < ARRAY_SIZE(block->successors); i++) {
+               if (nblock->successors[i]) {
+                       block->successors[i] =
+                               get_block(ctx, nblock->successors[i]);
+               }
+       }
+
+       ctx->block = block;
+       list_addtail(&block->node, &ctx->ir->block_list);
+
+       nir_foreach_instr(nblock, instr) {
                emit_instr(ctx, instr);
                if (ctx->error)
                        return;
        }
 }
 
+static void emit_cf_list(struct ir3_compile *ctx, struct exec_list *list);
+
 static void
-emit_function(struct ir3_compile *ctx, nir_function_impl *impl)
+emit_if(struct ir3_compile *ctx, nir_if *nif)
+{
+       struct ir3_instruction *condition = get_src(ctx, &nif->condition)[0];
+
+       ctx->block->condition =
+               get_predicate(ctx, ir3_b2n(condition->block, condition));
+
+       emit_cf_list(ctx, &nif->then_list);
+       emit_cf_list(ctx, &nif->else_list);
+}
+
+static void
+emit_loop(struct ir3_compile *ctx, nir_loop *nloop)
+{
+       emit_cf_list(ctx, &nloop->body);
+}
+
+static void
+emit_cf_list(struct ir3_compile *ctx, struct exec_list *list)
 {
-       foreach_list_typed(nir_cf_node, node, node, &impl->body) {
+       foreach_list_typed(nir_cf_node, node, node, list) {
                switch (node->type) {
                case nir_cf_node_block:
                        emit_block(ctx, nir_cf_node_as_block(node));
                        break;
                case nir_cf_node_if:
+                       emit_if(ctx, nir_cf_node_as_if(node));
+                       break;
                case nir_cf_node_loop:
+                       emit_loop(ctx, nir_cf_node_as_loop(node));
+                       break;
                case nir_cf_node_function:
                        compile_error(ctx, "TODO\n");
                        break;
                }
-               if (ctx->error)
-                       return;
        }
 }
 
+static void
+emit_function(struct ir3_compile *ctx, nir_function_impl *impl)
+{
+       emit_cf_list(ctx, &impl->body);
+       emit_block(ctx, impl->end_block);
+
+       /* at this point, we should have a single empty block,
+        * into which we emit the 'end' instruction.
+        */
+       compile_assert(ctx, list_empty(&ctx->block->instr_list));
+       ir3_END(ctx->block);
+}
+
 static void
 setup_input(struct ir3_compile *ctx, nir_variable *in)
 {
@@ -1708,7 +2048,7 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
                        instr = create_input(ctx->block, NULL, idx);
                }
 
-               ctx->block->inputs[idx] = instr;
+               ctx->ir->inputs[idx] = instr;
        }
 
        if (so->inputs[n].bary || (ctx->so->type == SHADER_VERTEX)) {
@@ -1775,15 +2115,26 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
        for (int i = 0; i < ncomp; i++) {
                unsigned idx = (n * 4) + i;
 
-               ctx->block->outputs[idx] = create_immed(ctx->block, fui(0.0));
+               ctx->ir->outputs[idx] = create_immed(ctx->block, fui(0.0));
        }
 }
 
 static void
 emit_instructions(struct ir3_compile *ctx)
 {
-       unsigned ninputs  = exec_list_length(&ctx->s->inputs) * 4;
-       unsigned noutputs = exec_list_length(&ctx->s->outputs) * 4;
+       unsigned ninputs, noutputs;
+       nir_function_impl *fxn = NULL;
+
+       /* Find the main function: */
+       nir_foreach_overload(ctx->s, overload) {
+               compile_assert(ctx, strcmp(overload->function->name, "main") == 0);
+               compile_assert(ctx, overload->impl);
+               fxn = overload->impl;
+               break;
+       }
+
+       ninputs  = exec_list_length(&ctx->s->inputs) * 4;
+       noutputs = exec_list_length(&ctx->s->outputs) * 4;
 
        /* we need to allocate big enough outputs array so that
         * we can stuff the kill's at the end.  Likewise for vtx
@@ -1795,12 +2146,17 @@ emit_instructions(struct ir3_compile *ctx)
                ninputs += 8;
        }
 
-       ctx->block = ir3_block_create(ctx->ir, 0, ninputs, noutputs);
+       ctx->ir = ir3_create(ctx->compiler, ninputs, noutputs);
+
+       /* Create inputs in first block: */
+       ctx->block = get_block(ctx, fxn->start_block);
+       ctx->in_block = ctx->block;
+       list_addtail(&ctx->block->node, &ctx->ir->block_list);
 
        if (ctx->so->type == SHADER_FRAGMENT) {
-               ctx->block->noutputs -= ARRAY_SIZE(ctx->kill);
+               ctx->ir->noutputs -= ARRAY_SIZE(ctx->kill);
        } else if (ctx->so->type == SHADER_VERTEX) {
-               ctx->block->ninputs -= 8;
+               ctx->ir->ninputs -= 8;
        }
 
        /* for fragment shader, we have a single input register (usually
@@ -1831,13 +2187,12 @@ emit_instructions(struct ir3_compile *ctx)
                declare_var(ctx, var);
        }
 
-       /* Find the main function and emit the body: */
-       nir_foreach_overload(ctx->s, overload) {
-               compile_assert(ctx, strcmp(overload->function->name, "main") == 0);
-               compile_assert(ctx, overload->impl);
-               emit_function(ctx, overload->impl);
-               if (ctx->error)
-                       return;
+       /* And emit the body: */
+       ctx->impl = fxn;
+       emit_function(ctx, fxn);
+
+       list_for_each_entry (struct ir3_block, block, &ctx->ir->block_list, node) {
+               resolve_phis(ctx, block);
        }
 }
 
@@ -1850,12 +2205,12 @@ static void
 fixup_frag_inputs(struct ir3_compile *ctx)
 {
        struct ir3_shader_variant *so = ctx->so;
-       struct ir3_block *block = ctx->block;
+       struct ir3 *ir = ctx->ir;
        struct ir3_instruction **inputs;
        struct ir3_instruction *instr;
        int n, regid = 0;
 
-       block->ninputs = 0;
+       ir->ninputs = 0;
 
        n  = 4;  /* always have frag_pos */
        n += COND(so->frag_face, 4);
@@ -1867,15 +2222,15 @@ fixup_frag_inputs(struct ir3_compile *ctx)
                /* this ultimately gets assigned to hr0.x so doesn't conflict
                 * with frag_coord/frag_pos..
                 */
-               inputs[block->ninputs++] = ctx->frag_face;
+               inputs[ir->ninputs++] = ctx->frag_face;
                ctx->frag_face->regs[0]->num = 0;
 
                /* remaining channels not used, but let's avoid confusing
                 * other parts that expect inputs to come in groups of vec4
                 */
-               inputs[block->ninputs++] = NULL;
-               inputs[block->ninputs++] = NULL;
-               inputs[block->ninputs++] = NULL;
+               inputs[ir->ninputs++] = NULL;
+               inputs[ir->ninputs++] = NULL;
+               inputs[ir->ninputs++] = NULL;
        }
 
        /* since we don't know where to set the regid for frag_coord,
@@ -1889,63 +2244,45 @@ fixup_frag_inputs(struct ir3_compile *ctx)
                ctx->frag_coord[2]->regs[0]->num = regid++;
                ctx->frag_coord[3]->regs[0]->num = regid++;
 
-               inputs[block->ninputs++] = ctx->frag_coord[0];
-               inputs[block->ninputs++] = ctx->frag_coord[1];
-               inputs[block->ninputs++] = ctx->frag_coord[2];
-               inputs[block->ninputs++] = ctx->frag_coord[3];
+               inputs[ir->ninputs++] = ctx->frag_coord[0];
+               inputs[ir->ninputs++] = ctx->frag_coord[1];
+               inputs[ir->ninputs++] = ctx->frag_coord[2];
+               inputs[ir->ninputs++] = ctx->frag_coord[3];
        }
 
        /* we always have frag_pos: */
        so->pos_regid = regid;
 
        /* r0.x */
-       instr = create_input(block, NULL, block->ninputs);
+       instr = create_input(ctx->in_block, NULL, ir->ninputs);
        instr->regs[0]->num = regid++;
-       inputs[block->ninputs++] = instr;
+       inputs[ir->ninputs++] = instr;
        ctx->frag_pos->regs[1]->instr = instr;
 
        /* r0.y */
-       instr = create_input(block, NULL, block->ninputs);
+       instr = create_input(ctx->in_block, NULL, ir->ninputs);
        instr->regs[0]->num = regid++;
-       inputs[block->ninputs++] = instr;
+       inputs[ir->ninputs++] = instr;
        ctx->frag_pos->regs[2]->instr = instr;
 
-       block->inputs = inputs;
-}
-
-static void
-compile_dump(struct ir3_compile *ctx)
-{
-       const char *name = (ctx->so->type == SHADER_VERTEX) ? "vert" : "frag";
-       static unsigned n = 0;
-       char fname[16];
-       FILE *f;
-       snprintf(fname, sizeof(fname), "%s-%04u.dot", name, n++);
-       f = fopen(fname, "w");
-       if (!f)
-               return;
-       ir3_block_depth(ctx->block);
-       ir3_dump(ctx->ir, name, ctx->block, f);
-       fclose(f);
+       ir->inputs = inputs;
 }
 
 int
-ir3_compile_shader_nir(struct ir3_shader_variant *so,
-               const struct tgsi_token *tokens, struct ir3_shader_key key)
+ir3_compile_shader_nir(struct ir3_compiler *compiler,
+               struct ir3_shader_variant *so,
+               const struct tgsi_token *tokens,
+               struct ir3_shader_key key)
 {
        struct ir3_compile *ctx;
-       struct ir3_block *block;
+       struct ir3 *ir;
        struct ir3_instruction **inputs;
        unsigned i, j, actual_in;
        int ret = 0, max_bary;
 
        assert(!so->ir);
 
-       so->ir = ir3_create();
-
-       assert(so->ir);
-
-       ctx = compile_init(so, tokens);
+       ctx = compile_init(compiler, so, tokens);
        if (!ctx) {
                DBG("INIT failed!");
                ret = -1;
@@ -1960,11 +2297,10 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
                goto out;
        }
 
-       block = ctx->block;
-       so->ir->block = block;
+       ir = so->ir = ctx->ir;
 
        /* keep track of the inputs from TGSI perspective.. */
-       inputs = block->inputs;
+       inputs = ir->inputs;
 
        /* but fixup actual inputs for frag shader: */
        if (so->type == SHADER_FRAGMENT)
@@ -1981,26 +2317,39 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
                                        (name == TGSI_SEMANTIC_PSIZE))) {
                                if (i != j) {
                                        so->outputs[j] = so->outputs[i];
-                                       block->outputs[(j*4)+0] = block->outputs[(i*4)+0];
-                                       block->outputs[(j*4)+1] = block->outputs[(i*4)+1];
-                                       block->outputs[(j*4)+2] = block->outputs[(i*4)+2];
-                                       block->outputs[(j*4)+3] = block->outputs[(i*4)+3];
+                                       ir->outputs[(j*4)+0] = ir->outputs[(i*4)+0];
+                                       ir->outputs[(j*4)+1] = ir->outputs[(i*4)+1];
+                                       ir->outputs[(j*4)+2] = ir->outputs[(i*4)+2];
+                                       ir->outputs[(j*4)+3] = ir->outputs[(i*4)+3];
                                }
                                j++;
                        }
                }
                so->outputs_count = j;
-               block->noutputs = j * 4;
+               ir->noutputs = j * 4;
        }
 
        /* if we want half-precision outputs, mark the output registers
         * as half:
         */
        if (key.half_precision) {
-               for (i = 0; i < block->noutputs; i++) {
-                       if (!block->outputs[i])
+               for (i = 0; i < ir->noutputs; i++) {
+                       struct ir3_instruction *out = ir->outputs[i];
+                       if (!out)
                                continue;
-                       block->outputs[i]->regs[0]->flags |= IR3_REG_HALF;
+                       out->regs[0]->flags |= IR3_REG_HALF;
+                       /* output could be a fanout (ie. texture fetch output)
+                        * in which case we need to propagate the half-reg flag
+                        * up to the definer so that RA sees it:
+                        */
+                       if (is_meta(out) && (out->opc == OPC_META_FO)) {
+                               out = out->regs[1]->instr;
+                               out->regs[0]->flags |= IR3_REG_HALF;
+                       }
+
+                       if (out->category == 1) {
+                               out->cat1.dst_type = half_type(out->cat1.dst_type);
+                       }
                }
        }
 
@@ -2010,42 +2359,34 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
         */
        if (so->type == SHADER_FRAGMENT) {
                for (i = 0; i < ctx->kill_count; i++)
-                       block->outputs[block->noutputs++] = ctx->kill[i];
+                       ir->outputs[ir->noutputs++] = ctx->kill[i];
        }
 
-       if (fd_mesa_debug & FD_DBG_OPTDUMP)
-               compile_dump(ctx);
-
        if (fd_mesa_debug & FD_DBG_OPTMSGS) {
                printf("BEFORE CP:\n");
-               ir3_dump_instr_list(block->head);
+               ir3_print(ir);
        }
 
-       ir3_block_depth(block);
-
-       ir3_block_cp(block);
+       ir3_cp(ir);
 
        if (fd_mesa_debug & FD_DBG_OPTMSGS) {
                printf("BEFORE GROUPING:\n");
-               ir3_dump_instr_list(block->head);
+               ir3_print(ir);
        }
 
        /* Group left/right neighbors, inserting mov's where needed to
         * solve conflicts:
         */
-       ir3_block_group(block);
-
-       if (fd_mesa_debug & FD_DBG_OPTDUMP)
-               compile_dump(ctx);
+       ir3_group(ir);
 
-       ir3_block_depth(block);
+       ir3_depth(ir);
 
        if (fd_mesa_debug & FD_DBG_OPTMSGS) {
                printf("AFTER DEPTH:\n");
-               ir3_dump_instr_list(block->head);
+               ir3_print(ir);
        }
 
-       ret = ir3_block_sched(block);
+       ret = ir3_sched(ir);
        if (ret) {
                DBG("SCHED failed!");
                goto out;
@@ -2053,10 +2394,10 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
 
        if (fd_mesa_debug & FD_DBG_OPTMSGS) {
                printf("AFTER SCHED:\n");
-               ir3_dump_instr_list(block->head);
+               ir3_print(ir);
        }
 
-       ret = ir3_block_ra(block, so->type, so->frag_coord, so->frag_face);
+       ret = ir3_ra(ir, so->type, so->frag_coord, so->frag_face);
        if (ret) {
                DBG("RA failed!");
                goto out;
@@ -2064,14 +2405,19 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
 
        if (fd_mesa_debug & FD_DBG_OPTMSGS) {
                printf("AFTER RA:\n");
-               ir3_dump_instr_list(block->head);
+               ir3_print(ir);
        }
 
-       ir3_block_legalize(block, &so->has_samp, &max_bary);
+       ir3_legalize(ir, &so->has_samp, &max_bary);
+
+       if (fd_mesa_debug & FD_DBG_OPTMSGS) {
+               printf("AFTER LEGALIZE:\n");
+               ir3_print(ir);
+       }
 
        /* fixup input/outputs: */
        for (i = 0; i < so->outputs_count; i++) {
-               so->outputs[i].regid = block->outputs[i*4]->regs[0]->num;
+               so->outputs[i].regid = ir->outputs[i*4]->regs[0]->num;
                /* preserve hack for depth output.. tgsi writes depth to .z,
                 * but what we give the hw is the scalar register:
                 */
@@ -2111,7 +2457,8 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
 
 out:
        if (ret) {
-               ir3_destroy(so->ir);
+               if (so->ir)
+                       ir3_destroy(so->ir);
                so->ir = NULL;
        }
        compile_free(ctx);
index fa7d363be7bfc81bd20b55406c36784f99bca04c..8c7c80f7aae37b97453663e816ee7954f02129a8 100644 (file)
@@ -41,7 +41,7 @@ static bool is_eligible_mov(struct ir3_instruction *instr, bool allow_flags)
                struct ir3_register *dst = instr->regs[0];
                struct ir3_register *src = instr->regs[1];
                struct ir3_instruction *src_instr = ssa(src);
-               if (dst->flags & (IR3_REG_ADDR | IR3_REG_RELATIV))
+               if (dst->flags & IR3_REG_RELATIV)
                        return false;
                if (src->flags & IR3_REG_RELATIV)
                        return false;
@@ -54,6 +54,13 @@ static bool is_eligible_mov(struct ir3_instruction *instr, bool allow_flags)
                /* TODO: remove this hack: */
                if (is_meta(src_instr) && (src_instr->opc == OPC_META_FO))
                        return false;
+               /* TODO: we currently don't handle left/right neighbors
+                * very well when inserting parallel-copies into phi..
+                * to avoid problems don't eliminate a mov coming out
+                * of phi..
+                */
+               if (is_meta(src_instr) && (src_instr->opc == OPC_META_PHI))
+                       return false;
                return true;
        }
        return false;
@@ -354,13 +361,6 @@ instr_cp(struct ir3_instruction *instr, unsigned *flags)
 {
        struct ir3_register *reg;
 
-       /* stay within the block.. don't try to operate across
-        * basic block boundaries or we'll have problems when
-        * dealing with multiple basic blocks:
-        */
-       if (is_meta(instr) && (instr->opc == OPC_META_INPUT))
-               return instr;
-
        if (is_eligible_mov(instr, !!flags)) {
                struct ir3_register *reg = instr->regs[1];
                struct ir3_instruction *src_instr = ssa(reg);
@@ -394,22 +394,22 @@ instr_cp(struct ir3_instruction *instr, unsigned *flags)
        return instr;
 }
 
-static void block_cp(struct ir3_block *block)
+void
+ir3_cp(struct ir3 *ir)
 {
-       unsigned i;
+       ir3_clear_mark(ir);
 
-       for (i = 0; i < block->noutputs; i++) {
-               if (block->outputs[i]) {
+       for (unsigned i = 0; i < ir->noutputs; i++) {
+               if (ir->outputs[i]) {
                        struct ir3_instruction *out =
-                                       instr_cp(block->outputs[i], NULL);
+                                       instr_cp(ir->outputs[i], NULL);
 
-                       block->outputs[i] = out;
+                       ir->outputs[i] = out;
                }
        }
-}
 
-void ir3_block_cp(struct ir3_block *block)
-{
-       ir3_clear_mark(block->shader);
-       block_cp(block);
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               if (block->condition)
+                       block->condition = instr_cp(block->condition, NULL);
+       }
 }
index b899c66b37e36fa04cca70e2b101b2d7babec158..3a108243479da0379f1b4eb4aa80828194bc8335 100644 (file)
@@ -84,25 +84,25 @@ int ir3_delayslots(struct ir3_instruction *assigner,
        }
 }
 
-static void insert_by_depth(struct ir3_instruction *instr)
+void
+ir3_insert_by_depth(struct ir3_instruction *instr, struct list_head *list)
 {
-       struct ir3_block *block = instr->block;
-       struct ir3_instruction *n = block->head;
-       struct ir3_instruction *p = NULL;
-
-       while (n && (n != instr) && (n->depth > instr->depth)) {
-               p = n;
-               n = n->next;
+       /* remove from existing spot in list: */
+       list_delinit(&instr->node);
+
+       /* find where to re-insert instruction: */
+       list_for_each_entry (struct ir3_instruction, pos, list, node) {
+               if (pos->depth > instr->depth) {
+                       list_add(&instr->node, &pos->node);
+                       return;
+               }
        }
-
-       instr->next = n;
-       if (p)
-               p->next = instr;
-       else
-               block->head = instr;
+       /* if we get here, we didn't find an insertion spot: */
+       list_addtail(&instr->node, list);
 }
 
-static void ir3_instr_depth(struct ir3_instruction *instr)
+static void
+ir3_instr_depth(struct ir3_instruction *instr)
 {
        struct ir3_instruction *src;
 
@@ -123,47 +123,54 @@ static void ir3_instr_depth(struct ir3_instruction *instr)
                instr->depth = MAX2(instr->depth, sd);
        }
 
-       /* meta-instructions don't add cycles, other than PHI.. which
-        * might translate to a real instruction..
-        *
-        * well, not entirely true, fan-in/out, etc might need to need
-        * to generate some extra mov's in edge cases, etc.. probably
-        * we might want to do depth calculation considering the worst
-        * case for these??
-        */
        if (!is_meta(instr))
                instr->depth++;
 
-       insert_by_depth(instr);
+       ir3_insert_by_depth(instr, &instr->block->instr_list);
+}
+
+static void
+remove_unused_by_block(struct ir3_block *block)
+{
+       list_for_each_entry_safe (struct ir3_instruction, instr, &block->instr_list, node) {
+               if (!ir3_instr_check_mark(instr)) {
+                       if (is_flow(instr) && (instr->opc == OPC_END))
+                               continue;
+                       /* mark it, in case it is input, so we can
+                        * remove unused inputs:
+                        */
+                       instr->depth = DEPTH_UNUSED;
+                       /* and remove from instruction list: */
+                       list_delinit(&instr->node);
+               }
+       }
 }
 
-void ir3_block_depth(struct ir3_block *block)
+void
+ir3_depth(struct ir3 *ir)
 {
        unsigned i;
 
-       block->head = NULL;
+       ir3_clear_mark(ir);
+       for (i = 0; i < ir->noutputs; i++)
+               if (ir->outputs[i])
+                       ir3_instr_depth(ir->outputs[i]);
 
-       ir3_clear_mark(block->shader);
-       for (i = 0; i < block->noutputs; i++)
-               if (block->outputs[i])
-                       ir3_instr_depth(block->outputs[i]);
+       /* We also need to account for if-condition: */
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               if (block->condition)
+                       ir3_instr_depth(block->condition);
+       }
 
        /* mark un-used instructions: */
-       for (i = 0; i < block->shader->instrs_count; i++) {
-               struct ir3_instruction *instr = block->shader->instrs[i];
-
-               /* just consider instructions within this block: */
-               if (instr->block != block)
-                       continue;
-
-               if (!ir3_instr_check_mark(instr))
-                       instr->depth = DEPTH_UNUSED;
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               remove_unused_by_block(block);
        }
 
        /* cleanup unused inputs: */
-       for (i = 0; i < block->ninputs; i++) {
-               struct ir3_instruction *in = block->inputs[i];
+       for (i = 0; i < ir->ninputs; i++) {
+               struct ir3_instruction *in = ir->inputs[i];
                if (in && (in->depth == DEPTH_UNUSED))
-                       block->inputs[i] = NULL;
+                       ir->inputs[i] = NULL;
        }
 }
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_dump.c b/src/gallium/drivers/freedreno/ir3/ir3_dump.c
deleted file mode 100644 (file)
index 1614d63..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Rob Clark <robclark@freedesktop.org>
- */
-
-#include <stdarg.h>
-
-#include "ir3.h"
-
-#define PTRID(x) ((unsigned long)(x))
-
-struct ir3_dump_ctx {
-       FILE *f;
-       bool verbose;
-};
-
-static void dump_instr_name(struct ir3_dump_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       /* for debugging: */
-       if (ctx->verbose) {
-#ifdef DEBUG
-               fprintf(ctx->f, "%04u:", instr->serialno);
-#endif
-               fprintf(ctx->f, "%03u: ", instr->depth);
-       }
-
-       if (instr->flags & IR3_INSTR_SY)
-               fprintf(ctx->f, "(sy)");
-       if (instr->flags & IR3_INSTR_SS)
-               fprintf(ctx->f, "(ss)");
-
-       if (is_meta(instr)) {
-               switch(instr->opc) {
-               case OPC_META_PHI:
-                       fprintf(ctx->f, "&#934;");
-                       break;
-               default:
-                       /* shouldn't hit here.. just for debugging: */
-                       switch (instr->opc) {
-                       case OPC_META_INPUT:  fprintf(ctx->f, "_meta:in");   break;
-                       case OPC_META_OUTPUT: fprintf(ctx->f, "_meta:out");  break;
-                       case OPC_META_FO:     fprintf(ctx->f, "_meta:fo");   break;
-                       case OPC_META_FI:     fprintf(ctx->f, "_meta:fi");   break;
-                       case OPC_META_FLOW:   fprintf(ctx->f, "_meta:flow"); break;
-
-                       default: fprintf(ctx->f, "_meta:%d", instr->opc); break;
-                       }
-                       break;
-               }
-       } else if (instr->category == 1) {
-               static const char *type[] = {
-                               [TYPE_F16] = "f16",
-                               [TYPE_F32] = "f32",
-                               [TYPE_U16] = "u16",
-                               [TYPE_U32] = "u32",
-                               [TYPE_S16] = "s16",
-                               [TYPE_S32] = "s32",
-                               [TYPE_U8]  = "u8",
-                               [TYPE_S8]  = "s8",
-               };
-               if (instr->cat1.src_type == instr->cat1.dst_type)
-                       fprintf(ctx->f, "mov");
-               else
-                       fprintf(ctx->f, "cov");
-               fprintf(ctx->f, ".%s%s", type[instr->cat1.src_type], type[instr->cat1.dst_type]);
-       } else {
-               fprintf(ctx->f, "%s", ir3_instr_name(instr));
-               if (instr->flags & IR3_INSTR_3D)
-                       fprintf(ctx->f, ".3d");
-               if (instr->flags & IR3_INSTR_A)
-                       fprintf(ctx->f, ".a");
-               if (instr->flags & IR3_INSTR_O)
-                       fprintf(ctx->f, ".o");
-               if (instr->flags & IR3_INSTR_P)
-                       fprintf(ctx->f, ".p");
-               if (instr->flags & IR3_INSTR_S)
-                       fprintf(ctx->f, ".s");
-               if (instr->flags & IR3_INSTR_S2EN)
-                       fprintf(ctx->f, ".s2en");
-       }
-}
-
-static void dump_reg_name(struct ir3_dump_ctx *ctx,
-               struct ir3_register *reg, bool followssa)
-{
-       if ((reg->flags & (IR3_REG_FABS | IR3_REG_SABS)) &&
-                       (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT)))
-               fprintf(ctx->f, "(absneg)");
-       else if (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT))
-               fprintf(ctx->f, "(neg)");
-       else if (reg->flags & (IR3_REG_FABS | IR3_REG_SABS))
-               fprintf(ctx->f, "(abs)");
-
-       if (reg->flags & IR3_REG_IMMED) {
-               fprintf(ctx->f, "imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val);
-       } else if (reg->flags & IR3_REG_SSA) {
-               if (ctx->verbose) {
-                       fprintf(ctx->f, "_");
-                       if (followssa) {
-                               fprintf(ctx->f, "[");
-                               dump_instr_name(ctx, reg->instr);
-                               fprintf(ctx->f, "]");
-                       }
-               }
-       } else if (reg->flags & IR3_REG_RELATIV) {
-               if (reg->flags & IR3_REG_HALF)
-                       fprintf(ctx->f, "h");
-               if (reg->flags & IR3_REG_CONST)
-                       fprintf(ctx->f, "c<a0.x + %u>", reg->num);
-               else
-                       fprintf(ctx->f, "\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->num, reg->size);
-       } else {
-               if (reg->flags & IR3_REG_HALF)
-                       fprintf(ctx->f, "h");
-               if (reg->flags & IR3_REG_CONST)
-                       fprintf(ctx->f, "c%u.%c", reg_num(reg), "xyzw"[reg_comp(reg)]);
-               else
-                       fprintf(ctx->f, "\x1b[0;31mr%u.%c\x1b[0m", reg_num(reg), "xyzw"[reg_comp(reg)]);
-       }
-}
-
-static void ir3_instr_dump(struct ir3_dump_ctx *ctx,
-               struct ir3_instruction *instr);
-static void ir3_block_dump(struct ir3_dump_ctx *ctx,
-               struct ir3_block *block, const char *name);
-
-static void dump_instr(struct ir3_dump_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       /* if we've already visited this instruction, bail now: */
-       if (ir3_instr_check_mark(instr))
-               return;
-
-       /* some meta-instructions need to be handled specially: */
-       if (is_meta(instr)) {
-               if ((instr->opc == OPC_META_FO) ||
-                               (instr->opc == OPC_META_FI)) {
-                       struct ir3_instruction *src;
-                       foreach_ssa_src(src, instr)
-                               dump_instr(ctx, src);
-               } else if (instr->opc == OPC_META_FLOW) {
-                       struct ir3_register *reg = instr->regs[1];
-                       ir3_block_dump(ctx, instr->flow.if_block, "if");
-                       if (instr->flow.else_block)
-                               ir3_block_dump(ctx, instr->flow.else_block, "else");
-                       if (reg->flags & IR3_REG_SSA)
-                               dump_instr(ctx, reg->instr);
-               } else if (instr->opc == OPC_META_PHI) {
-                       /* treat like a normal instruction: */
-                       ir3_instr_dump(ctx, instr);
-               }
-       } else {
-               ir3_instr_dump(ctx, instr);
-       }
-}
-
-/* arrarraggh!  if link is to something outside of the current block, we
- * need to defer emitting the link until the end of the block, since the
- * edge triggers pre-creation of the node it links to inside the cluster,
- * even though it is meant to be outside..
- */
-static struct {
-       char buf[40960];
-       unsigned n;
-} edge_buf;
-
-/* helper to print or defer: */
-static void printdef(struct ir3_dump_ctx *ctx,
-               bool defer, const char *fmt, ...)
-{
-       va_list ap;
-       va_start(ap, fmt);
-       if (defer) {
-               unsigned n = edge_buf.n;
-               n += vsnprintf(&edge_buf.buf[n], sizeof(edge_buf.buf) - n,
-                               fmt, ap);
-               edge_buf.n = n;
-       } else {
-               vfprintf(ctx->f, fmt, ap);
-       }
-       va_end(ap);
-}
-
-static void dump_link2(struct ir3_dump_ctx *ctx,
-               struct ir3_instruction *instr, const char *target, bool defer)
-{
-       /* some meta-instructions need to be handled specially: */
-       if (is_meta(instr)) {
-               if (instr->opc == OPC_META_INPUT) {
-                       printdef(ctx, defer, "input%lx:<in%u>:w -> %s",
-                                       PTRID(instr->inout.block),
-                                       instr->regs[0]->num, target);
-               } else if (instr->opc == OPC_META_FO) {
-                       struct ir3_register *reg = instr->regs[1];
-                       dump_link2(ctx, reg->instr, target, defer);
-                       printdef(ctx, defer, "[label=\".%c\"]",
-                                       "xyzw"[instr->fo.off & 0x3]);
-               } else if (instr->opc == OPC_META_FI) {
-                       struct ir3_instruction *src;
-
-                       foreach_ssa_src_n(src, i, instr) {
-                               dump_link2(ctx, src, target, defer);
-                               printdef(ctx, defer, "[label=\".%c\"]",
-                                               "xyzw"[i & 0x3]);
-                       }
-               } else if (instr->opc == OPC_META_OUTPUT) {
-                       printdef(ctx, defer, "output%lx:<out%u>:w -> %s",
-                                       PTRID(instr->inout.block),
-                                       instr->regs[0]->num, target);
-               } else if (instr->opc == OPC_META_PHI) {
-                       /* treat like a normal instruction: */
-                       printdef(ctx, defer, "instr%lx:<dst0> -> %s", PTRID(instr), target);
-               }
-       } else {
-               printdef(ctx, defer, "instr%lx:<dst0> -> %s", PTRID(instr), target);
-       }
-}
-
-static void dump_link(struct ir3_dump_ctx *ctx,
-               struct ir3_instruction *instr,
-               struct ir3_block *block, const char *target)
-{
-       bool defer = instr->block != block;
-       dump_link2(ctx, instr, target, defer);
-       printdef(ctx, defer, "\n");
-}
-
-static struct ir3_register *follow_flow(struct ir3_register *reg)
-{
-       if (reg->flags & IR3_REG_SSA) {
-               struct ir3_instruction *instr = reg->instr;
-               /* go with the flow.. */
-               if (is_meta(instr) && (instr->opc == OPC_META_FLOW))
-                       return instr->regs[1];
-       }
-       return reg;
-}
-
-static void ir3_instr_dump(struct ir3_dump_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       struct ir3_register *src;
-
-       fprintf(ctx->f, "instr%lx [shape=record,style=filled,fillcolor=lightgrey,label=\"{",
-                       PTRID(instr));
-       dump_instr_name(ctx, instr);
-
-       /* destination register: */
-       fprintf(ctx->f, "|<dst0>");
-
-       /* source register(s): */
-       foreach_src_n(src, i, instr) {
-               struct ir3_register *reg = follow_flow(src);
-
-               fprintf(ctx->f, "|");
-
-               if (reg->flags & IR3_REG_SSA)
-                       fprintf(ctx->f, "<src%u> ", i);
-
-               dump_reg_name(ctx, reg, true);
-       }
-
-       fprintf(ctx->f, "}\"];\n");
-
-       /* and recursively dump dependent instructions: */
-       foreach_src_n(src, i, instr) {
-               struct ir3_register *reg = follow_flow(src);
-               char target[32];  /* link target */
-
-               if (!(reg->flags & IR3_REG_SSA))
-                       continue;
-
-               snprintf(target, sizeof(target), "instr%lx:<src%u>",
-                               PTRID(instr), i);
-
-               dump_instr(ctx, reg->instr);
-               dump_link(ctx, reg->instr, instr->block, target);
-       }
-}
-
-static void ir3_block_dump(struct ir3_dump_ctx *ctx,
-               struct ir3_block *block, const char *name)
-{
-       unsigned i, n;
-
-       n = edge_buf.n;
-
-       fprintf(ctx->f, "subgraph cluster%lx {\n", PTRID(block));
-       fprintf(ctx->f, "label=\"%s\";\n", name);
-
-       /* draw inputs: */
-       fprintf(ctx->f, "input%lx [shape=record,label=\"inputs", PTRID(block));
-       for (i = 0; i < block->ninputs; i++)
-               if (block->inputs[i])
-                       fprintf(ctx->f, "|<in%u> i%u.%c", i, (i >> 2), "xyzw"[i & 0x3]);
-       fprintf(ctx->f, "\"];\n");
-
-       /* draw instruction graph: */
-       for (i = 0; i < block->noutputs; i++)
-               if (block->outputs[i])
-                       dump_instr(ctx, block->outputs[i]);
-
-       /* draw outputs: */
-       fprintf(ctx->f, "output%lx [shape=record,label=\"outputs", PTRID(block));
-       for (i = 0; i < block->noutputs; i++)
-               fprintf(ctx->f, "|<out%u> o%u.%c", i, (i >> 2), "xyzw"[i & 0x3]);
-       fprintf(ctx->f, "\"];\n");
-
-       /* and links to outputs: */
-       for (i = 0; i < block->noutputs; i++) {
-               char target[32];  /* link target */
-
-               /* NOTE: there could be outputs that are never assigned,
-                * so skip them
-                */
-               if (!block->outputs[i])
-                       continue;
-
-               snprintf(target, sizeof(target), "output%lx:<out%u>:e",
-                               PTRID(block), i);
-
-               dump_link(ctx, block->outputs[i], block, target);
-       }
-
-       fprintf(ctx->f, "}\n");
-
-       /* and links to inputs: */
-       if (block->parent) {
-               for (i = 0; i < block->ninputs; i++) {
-                       char target[32];  /* link target */
-
-                       if (!block->inputs[i])
-                               continue;
-
-                       dump_instr(ctx, block->inputs[i]);
-
-                       snprintf(target, sizeof(target), "input%lx:<in%u>:e",
-                                       PTRID(block), i);
-
-                       dump_link(ctx, block->inputs[i], block, target);
-               }
-       }
-
-       /* dump deferred edges: */
-       if (edge_buf.n > n) {
-               fprintf(ctx->f, "%*s", edge_buf.n - n, &edge_buf.buf[n]);
-               edge_buf.n = n;
-       }
-}
-
-void ir3_dump(struct ir3 *shader, const char *name,
-               struct ir3_block *block /* XXX maybe 'block' ptr should move to ir3? */,
-               FILE *f)
-{
-       struct ir3_dump_ctx ctx = {
-                       .f = f,
-       };
-       ir3_clear_mark(shader);
-       fprintf(ctx.f, "digraph G {\n");
-       fprintf(ctx.f, "rankdir=RL;\n");
-       fprintf(ctx.f, "nodesep=0.25;\n");
-       fprintf(ctx.f, "ranksep=1.5;\n");
-       ir3_block_dump(&ctx, block, name);
-       fprintf(ctx.f, "}\n");
-}
-
-/*
- * For Debugging:
- */
-
-void
-ir3_dump_instr_single(struct ir3_instruction *instr)
-{
-       struct ir3_dump_ctx ctx = {
-                       .f = stdout,
-                       .verbose = true,
-       };
-       unsigned i;
-
-       dump_instr_name(&ctx, instr);
-       for (i = 0; i < instr->regs_count; i++) {
-               struct ir3_register *reg = instr->regs[i];
-               printf(i ? ", " : " ");
-               dump_reg_name(&ctx, reg, !!i);
-       }
-
-       if (instr->address) {
-               fprintf(ctx.f, ", address=_");
-               fprintf(ctx.f, "[");
-               dump_instr_name(&ctx, instr->address);
-               fprintf(ctx.f, "]");
-       }
-
-       if (instr->fanin) {
-               fprintf(ctx.f, ", fanin=_");
-               fprintf(ctx.f, "[");
-               dump_instr_name(&ctx, instr->fanin);
-               fprintf(ctx.f, "]");
-       }
-
-       if (is_meta(instr)) {
-               if (instr->opc == OPC_META_FO) {
-                       printf(", off=%d", instr->fo.off);
-               } else if ((instr->opc == OPC_META_FI) && instr->fi.aid) {
-                       printf(", aid=%d", instr->fi.aid);
-               }
-       }
-
-       printf("\n");
-}
-
-void
-ir3_dump_instr_list(struct ir3_instruction *instr)
-{
-       struct ir3_block *block = instr->block;
-       unsigned n = 0;
-
-       while (instr) {
-               ir3_dump_instr_single(instr);
-               if (!is_meta(instr))
-                       n++;
-               instr = instr->next;
-       }
-       printf("%u instructions\n", n);
-
-       for (n = 0; n < block->noutputs; n++) {
-               if (!block->outputs[n])
-                       continue;
-               printf("out%d: ", n);
-               ir3_dump_instr_single(block->outputs[n]);
-       }
-}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_flatten.c b/src/gallium/drivers/freedreno/ir3/ir3_flatten.c
deleted file mode 100644 (file)
index 419cd9d..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Rob Clark <robclark@freedesktop.org>
- */
-
-#include <stdarg.h>
-
-#include "ir3.h"
-
-/*
- * Flatten: flatten out legs of if/else, etc
- *
- * TODO probably should use some heuristic to decide to not flatten
- * if one side of the other is too large / deeply nested / whatever?
- */
-
-struct ir3_flatten_ctx {
-       struct ir3_block *block;
-       unsigned cnt;
-};
-
-static struct ir3_register *unwrap(struct ir3_register *reg)
-{
-
-       if (reg->flags & IR3_REG_SSA) {
-               struct ir3_instruction *instr = reg->instr;
-               if (is_meta(instr)) {
-                       switch (instr->opc) {
-                       case OPC_META_OUTPUT:
-                       case OPC_META_FLOW:
-                               if (instr->regs_count > 1)
-                                       return instr->regs[1];
-                               return NULL;
-                       default:
-                               break;
-                       }
-               }
-       }
-       return reg;
-}
-
-static void ir3_instr_flatten(struct ir3_flatten_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       struct ir3_instruction *src;
-
-       /* if we've already visited this instruction, bail now: */
-       if (ir3_instr_check_mark(instr))
-               return;
-
-       instr->block = ctx->block;
-
-       /* TODO: maybe some threshold to decide whether to
-        * flatten or not??
-        */
-       if (is_meta(instr)) {
-               if (instr->opc == OPC_META_PHI) {
-                       struct ir3_register *cond, *t, *f;
-
-                       cond = unwrap(instr->regs[1]);
-                       t    = unwrap(instr->regs[2]);  /* true val */
-                       f    = unwrap(instr->regs[3]);  /* false val */
-
-                       /* must have cond, but t or f may be null if only written
-                        * one one side of the if/else (in which case we can just
-                        * convert the PHI to a simple move).
-                        */
-                       assert(cond);
-                       assert(t || f);
-
-                       if (t && f) {
-                               /* convert the PHI instruction to sel.{b16,b32} */
-                               instr->category = 3;
-
-                               /* instruction type based on dst size: */
-                               if (instr->regs[0]->flags & IR3_REG_HALF)
-                                       instr->opc = OPC_SEL_B16;
-                               else
-                                       instr->opc = OPC_SEL_B32;
-
-                               instr->regs[1] = t;
-                               instr->regs[2] = cond;
-                               instr->regs[3] = f;
-                       } else {
-                               /* convert to simple mov: */
-                               instr->category = 1;
-                               instr->cat1.dst_type = TYPE_F32;
-                               instr->cat1.src_type = TYPE_F32;
-                               instr->regs_count = 2;
-                               instr->regs[1] = t ? t : f;
-                       }
-
-                       ctx->cnt++;
-               } else if ((instr->opc == OPC_META_INPUT) &&
-                               (instr->regs_count == 2)) {
-                       type_t ftype;
-
-                       if (instr->regs[0]->flags & IR3_REG_HALF)
-                               ftype = TYPE_F16;
-                       else
-                               ftype = TYPE_F32;
-
-                       /* convert meta:input to mov: */
-                       instr->category = 1;
-                       instr->cat1.src_type = ftype;
-                       instr->cat1.dst_type = ftype;
-               }
-       }
-
-       /* recursively visit children: */
-       foreach_ssa_src(src, instr)
-               ir3_instr_flatten(ctx, src);
-}
-
-/* return >= 0 is # of phi's flattened, < 0 is error */
-int ir3_block_flatten(struct ir3_block *block)
-{
-       struct ir3_flatten_ctx ctx = {
-                       .block = block,
-       };
-       unsigned i;
-
-       ir3_clear_mark(block->shader);
-       for(i = 0; i < block->noutputs; i++)
-               if (block->outputs[i])
-                       ir3_instr_flatten(&ctx, block->outputs[i]);
-
-       return ctx.cnt;
-}
index 782f6e87e5651762c026e4c63ab3507e2373a783..70d9b08e01934c7db93ac4743d75aedd0f1078bb 100644 (file)
  * Find/group instruction neighbors:
  */
 
-/* stop condition for iteration: */
-static bool check_stop(struct ir3_instruction *instr)
-{
-       if (ir3_instr_check_mark(instr))
-               return true;
-
-       /* stay within the block.. don't try to operate across
-        * basic block boundaries or we'll have problems when
-        * dealing with multiple basic blocks:
-        */
-       if (is_meta(instr) && (instr->opc == OPC_META_INPUT))
-               return true;
-
-       return false;
-}
-
-static struct ir3_instruction * create_mov(struct ir3_instruction *instr)
-{
-       struct ir3_instruction *mov;
-
-       mov = ir3_instr_create(instr->block, 1, 0);
-       mov->cat1.src_type = TYPE_F32;
-       mov->cat1.dst_type = TYPE_F32;
-       ir3_reg_create(mov, 0, 0);    /* dst */
-       ir3_reg_create(mov, 0, IR3_REG_SSA)->instr = instr;
-
-       return mov;
-}
-
 /* bleh.. we need to do the same group_n() thing for both inputs/outputs
  * (where we have a simple instr[] array), and fanin nodes (where we have
  * an extra indirection via reg->instr).
@@ -78,7 +49,8 @@ static struct ir3_instruction *arr_get(void *arr, int idx)
 }
 static void arr_insert_mov_out(void *arr, int idx, struct ir3_instruction *instr)
 {
-       ((struct ir3_instruction **)arr)[idx] = create_mov(instr);
+       ((struct ir3_instruction **)arr)[idx] =
+                       ir3_MOV(instr->block, instr, TYPE_F32);
 }
 static void arr_insert_mov_in(void *arr, int idx, struct ir3_instruction *instr)
 {
@@ -111,14 +83,17 @@ static struct ir3_instruction *instr_get(void *arr, int idx)
 {
        return ssa(((struct ir3_instruction *)arr)->regs[idx+1]);
 }
-static void instr_insert_mov(void *arr, int idx, struct ir3_instruction *instr)
+static void
+instr_insert_mov(void *arr, int idx, struct ir3_instruction *instr)
 {
-       ((struct ir3_instruction *)arr)->regs[idx+1]->instr = create_mov(instr);
+       ((struct ir3_instruction *)arr)->regs[idx+1]->instr =
+                       ir3_MOV(instr->block, instr, TYPE_F32);
 }
 static struct group_ops instr_ops = { instr_get, instr_insert_mov };
 
 
-static void group_n(struct group_ops *ops, void *arr, unsigned n)
+static void
+group_n(struct group_ops *ops, void *arr, unsigned n)
 {
        unsigned i, j;
 
@@ -141,6 +116,10 @@ restart:
                        conflict = conflicts(instr->cp.left, left) ||
                                conflicts(instr->cp.right, right);
 
+                       /* RA can't yet deal very well w/ group'd phi's: */
+                       if (is_meta(instr) && (instr->opc == OPC_META_PHI))
+                               conflict = true;
+
                        /* we also can't have an instr twice in the group: */
                        for (j = i + 1; (j < n) && !conflict; j++)
                                if (ops->get(arr, j) == instr)
@@ -181,11 +160,12 @@ restart:
        }
 }
 
-static void instr_find_neighbors(struct ir3_instruction *instr)
+static void
+instr_find_neighbors(struct ir3_instruction *instr)
 {
        struct ir3_instruction *src;
 
-       if (check_stop(instr))
+       if (ir3_instr_check_mark(instr))
                return;
 
        if (is_meta(instr) && (instr->opc == OPC_META_FI))
@@ -200,7 +180,8 @@ static void instr_find_neighbors(struct ir3_instruction *instr)
  * we need to insert dummy/padding instruction for grouping, and
  * then take it back out again before anyone notices.
  */
-static void pad_and_group_input(struct ir3_instruction **input, unsigned n)
+static void
+pad_and_group_input(struct ir3_instruction **input, unsigned n)
 {
        int i, mask = 0;
        struct ir3_block *block = NULL;
@@ -210,8 +191,8 @@ static void pad_and_group_input(struct ir3_instruction **input, unsigned n)
                if (instr) {
                        block = instr->block;
                } else if (block) {
-                       instr = ir3_instr_create(block, 0, OPC_NOP);
-                       ir3_reg_create(instr, 0, IR3_REG_SSA);    /* dst */
+                       instr = ir3_NOP(block);
+                       ir3_reg_create(instr, 0, IR3_REG_SSA);    /* dummy dst */
                        input[i] = instr;
                        mask |= (1 << i);
                }
@@ -225,42 +206,41 @@ static void pad_and_group_input(struct ir3_instruction **input, unsigned n)
        }
 }
 
-static void block_find_neighbors(struct ir3_block *block)
+static void
+find_neighbors(struct ir3 *ir)
 {
        unsigned i;
 
-       for (i = 0; i < block->noutputs; i++) {
-               if (block->outputs[i]) {
-                       struct ir3_instruction *instr = block->outputs[i];
-                       instr_find_neighbors(instr);
-               }
-       }
-
        /* shader inputs/outputs themselves must be contiguous as well:
+        *
+        * NOTE: group inputs first, since we only insert mov's
+        * *before* the conflicted instr (and that would go badly
+        * for inputs).  By doing inputs first, we should never
+        * have a conflict on inputs.. pushing any conflict to
+        * resolve to the outputs, for stuff like:
+        *
+        *     MOV OUT[n], IN[m].wzyx
+        *
+        * NOTE: we assume here inputs/outputs are grouped in vec4.
+        * This logic won't quite cut it if we don't align smaller
+        * on vec4 boundaries
         */
-       if (!block->parent) {
-               /* NOTE: group inputs first, since we only insert mov's
-                * *before* the conflicted instr (and that would go badly
-                * for inputs).  By doing inputs first, we should never
-                * have a conflict on inputs.. pushing any conflict to
-                * resolve to the outputs, for stuff like:
-                *
-                *     MOV OUT[n], IN[m].wzyx
-                *
-                * NOTE: we assume here inputs/outputs are grouped in vec4.
-                * This logic won't quite cut it if we don't align smaller
-                * on vec4 boundaries
-                */
-               for (i = 0; i < block->ninputs; i += 4)
-                       pad_and_group_input(&block->inputs[i], 4);
-               for (i = 0; i < block->noutputs; i += 4)
-                       group_n(&arr_ops_out, &block->outputs[i], 4);
-
+       for (i = 0; i < ir->ninputs; i += 4)
+               pad_and_group_input(&ir->inputs[i], 4);
+       for (i = 0; i < ir->noutputs; i += 4)
+               group_n(&arr_ops_out, &ir->outputs[i], 4);
+
+       for (i = 0; i < ir->noutputs; i++) {
+               if (ir->outputs[i]) {
+                       struct ir3_instruction *instr = ir->outputs[i];
+                       instr_find_neighbors(instr);
+               }
        }
 }
 
-void ir3_block_group(struct ir3_block *block)
+void
+ir3_group(struct ir3 *ir)
 {
-       ir3_clear_mark(block->shader);
-       block_find_neighbors(block);
+       ir3_clear_mark(ir);
+       find_neighbors(ir);
 }
index 2455f7e4efc513b0ba337f0f8c7baf83ea7ed5e2..f4a4223ae1736f88db66e7b98b4223725576bbb6 100644 (file)
@@ -26,7 +26,6 @@
  *    Rob Clark <robclark@freedesktop.org>
  */
 
-#include "pipe/p_shader_tokens.h"
 #include "util/u_math.h"
 
 #include "freedreno_util.h"
  */
 
 struct ir3_legalize_ctx {
-       struct ir3_block *block;
        bool has_samp;
        int max_bary;
 };
 
-static void legalize(struct ir3_legalize_ctx *ctx)
+/* We want to evaluate each block from the position of any other
+ * predecessor block, in order that the flags set are the union
+ * of all possible program paths.  For stopping condition, we
+ * want to stop when the pair of <pred-block, current-block> has
+ * been visited already.
+ *
+ * XXX is that completely true?  We could have different needs_xyz
+ * flags set depending on path leading to pred-block.. we could
+ * do *most* of this based on chasing src instructions ptrs (and
+ * following all phi srcs).. except the write-after-read hazzard.
+ *
+ * For now we just set ss/sy flag on first instruction on block,
+ * and handle everything within the block as before.
+ */
+
+static void
+legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
 {
-       struct ir3_block *block = ctx->block;
-       struct ir3_instruction *n;
-       struct ir3 *shader = block->shader;
-       struct ir3_instruction *end =
-                       ir3_instr_create(block, 0, OPC_END);
        struct ir3_instruction *last_input = NULL;
        struct ir3_instruction *last_rel = NULL;
+       struct list_head instr_list;
        regmask_t needs_ss_war;       /* write after read */
        regmask_t needs_ss;
        regmask_t needs_sy;
@@ -65,9 +75,13 @@ static void legalize(struct ir3_legalize_ctx *ctx)
        regmask_init(&needs_ss);
        regmask_init(&needs_sy);
 
-       shader->instrs_count = 0;
+       /* remove all the instructions from the list, we'll be adding
+        * them back in as we go
+        */
+       list_replace(&block->instr_list, &instr_list);
+       list_inithead(&block->instr_list);
 
-       for (n = block->head; n; n = n->next) {
+       list_for_each_entry_safe (struct ir3_instruction, n, &instr_list, node) {
                struct ir3_register *reg;
                unsigned i;
 
@@ -134,18 +148,18 @@ static void legalize(struct ir3_legalize_ctx *ctx)
                 */
                if ((n->flags & IR3_INSTR_SS) && (n->category >= 5)) {
                        struct ir3_instruction *nop;
-                       nop = ir3_instr_create(block, 0, OPC_NOP);
+                       nop = ir3_NOP(block);
                        nop->flags |= IR3_INSTR_SS;
                        n->flags &= ~IR3_INSTR_SS;
                }
 
                /* need to be able to set (ss) on first instruction: */
-               if ((shader->instrs_count == 0) && (n->category >= 5))
-                       ir3_instr_create(block, 0, OPC_NOP);
+               if (list_empty(&block->instr_list) && (n->category >= 5))
+                       ir3_NOP(block);
 
-               if (is_nop(n) && shader->instrs_count) {
-                       struct ir3_instruction *last =
-                                       shader->instrs[shader->instrs_count-1];
+               if (is_nop(n) && !list_empty(&block->instr_list)) {
+                       struct ir3_instruction *last = list_last_entry(&block->instr_list,
+                                       struct ir3_instruction, node);
                        if (is_nop(last) && (last->repeat < 5)) {
                                last->repeat++;
                                last->flags |= n->flags;
@@ -153,7 +167,7 @@ static void legalize(struct ir3_legalize_ctx *ctx)
                        }
                }
 
-               shader->instrs[shader->instrs_count++] = n;
+               list_addtail(&n->node, &block->instr_list);
 
                if (is_sfu(n))
                        regmask_set(&needs_ss, n->regs[0]);
@@ -192,35 +206,20 @@ static void legalize(struct ir3_legalize_ctx *ctx)
                 * the (ei) flag:
                 */
                if (is_mem(last_input) && (last_input->opc == OPC_LDLV)) {
-                       int i, cnt;
-
-                       /* note that ir3_instr_create() inserts into
-                        * shader->instrs[] and increments the count..
-                        * so we need to bump up the cnt initially (to
-                        * avoid it clobbering the last real instr) and
-                        * restore it after.
-                        */
-                       cnt = ++shader->instrs_count;
+                       struct ir3_instruction *baryf;
 
-                       /* inserting instructions would be a bit nicer if list.. */
-                       for (i = cnt - 2; i >= 0; i--) {
-                               if (shader->instrs[i] == last_input) {
+                       /* (ss)bary.f (ei)r63.x, 0, r0.x */
+                       baryf = ir3_instr_create(block, 2, OPC_BARY_F);
+                       baryf->flags |= IR3_INSTR_SS;
+                       ir3_reg_create(baryf, regid(63, 0), 0);
+                       ir3_reg_create(baryf, 0, IR3_REG_IMMED)->iim_val = 0;
+                       ir3_reg_create(baryf, regid(0, 0), 0);
 
-                                       /* (ss)bary.f (ei)r63.x, 0, r0.x */
-                                       last_input = ir3_instr_create(block, 2, OPC_BARY_F);
-                                       last_input->flags |= IR3_INSTR_SS;
-                                       ir3_reg_create(last_input, regid(63, 0), 0);
-                                       ir3_reg_create(last_input, 0, IR3_REG_IMMED)->iim_val = 0;
-                                       ir3_reg_create(last_input, regid(0, 0), 0);
+                       /* insert the dummy bary.f after last_input: */
+                       list_delinit(&baryf->node);
+                       list_add(&baryf->node, &last_input->node);
 
-                                       shader->instrs[i + 1] = last_input;
-
-                                       break;
-                               }
-                               shader->instrs[i + 1] = shader->instrs[i];
-                       }
-
-                       shader->instrs_count = cnt;
+                       last_input = baryf;
                }
                last_input->regs[0]->flags |= IR3_REG_EI;
        }
@@ -228,21 +227,177 @@ static void legalize(struct ir3_legalize_ctx *ctx)
        if (last_rel)
                last_rel->flags |= IR3_INSTR_UL;
 
-       shader->instrs[shader->instrs_count++] = end;
+       list_first_entry(&block->instr_list, struct ir3_instruction, node)
+               ->flags |= IR3_INSTR_SS | IR3_INSTR_SY;
+}
+
+/* NOTE: branch instructions are always the last instruction(s)
+ * in the block.  We take advantage of this as we resolve the
+ * branches, since "if (foo) break;" constructs turn into
+ * something like:
+ *
+ *   block3 {
+ *     ...
+ *     0029:021: mov.s32s32 r62.x, r1.y
+ *     0082:022: br !p0.x, target=block5
+ *     0083:023: br p0.x, target=block4
+ *     // succs: if _[0029:021: mov.s32s32] block4; else block5;
+ *   }
+ *   block4 {
+ *     0084:024: jump, target=block6
+ *     // succs: block6;
+ *   }
+ *   block5 {
+ *     0085:025: jump, target=block7
+ *     // succs: block7;
+ *   }
+ *
+ * ie. only instruction in block4/block5 is a jump, so when
+ * resolving branches we can easily detect this by checking
+ * that the first instruction in the target block is itself
+ * a jump, and setup the br directly to the jump's target
+ * (and strip back out the now unreached jump)
+ *
+ * TODO sometimes we end up with things like:
+ *
+ *    br !p0.x, #2
+ *    br p0.x, #12
+ *    add.u r0.y, r0.y, 1
+ *
+ * If we swapped the order of the branches, we could drop one.
+ */
+static struct ir3_block *
+resolve_dest_block(struct ir3_block *block)
+{
+       /* special case for last block: */
+       if (!block->successors[0])
+               return block;
+
+       /* NOTE that we may or may not have inserted the jump
+        * in the target block yet, so conditions to resolve
+        * the dest to the dest block's successor are:
+        *
+        *   (1) successor[1] == NULL &&
+        *   (2) (block-is-empty || only-instr-is-jump)
+        */
+       if (block->successors[1] == NULL) {
+               if (list_empty(&block->instr_list)) {
+                       return block->successors[0];
+               } else if (list_length(&block->instr_list) == 1) {
+                       struct ir3_instruction *instr = list_first_entry(
+                                       &block->instr_list, struct ir3_instruction, node);
+                       if (is_flow(instr) && (instr->opc == OPC_JUMP))
+                               return block->successors[0];
+               }
+       }
+       return block;
+}
+
+static bool
+resolve_jump(struct ir3_instruction *instr)
+{
+       struct ir3_block *tblock =
+               resolve_dest_block(instr->cat0.target);
+       struct ir3_instruction *target;
+
+       if (tblock != instr->cat0.target) {
+               list_delinit(&instr->cat0.target->node);
+               instr->cat0.target = tblock;
+               return true;
+       }
+
+       target = list_first_entry(&tblock->instr_list,
+                               struct ir3_instruction, node);
+
+       if ((!target) || (target->ip == (instr->ip + 1))) {
+               list_delinit(&instr->node);
+               return true;
+       } else {
+               instr->cat0.immed =
+                       (int)target->ip - (int)instr->ip;
+       }
+       return false;
+}
+
+/* resolve jumps, removing jumps/branches to immediately following
+ * instruction which we end up with from earlier stages.  Since
+ * removing an instruction can invalidate earlier instruction's
+ * branch offsets, we need to do this iteratively until no more
+ * branches are removed.
+ */
+static bool
+resolve_jumps(struct ir3 *ir)
+{
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node)
+               list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node)
+                       if (is_flow(instr) && instr->cat0.target)
+                               if (resolve_jump(instr))
+                                       return true;
+
+       return false;
+}
 
-       shader->instrs[0]->flags |= IR3_INSTR_SS | IR3_INSTR_SY;
+/* we want to mark points where divergent flow control re-converges
+ * with (jp) flags.  For now, since we don't do any optimization for
+ * things that start out as a 'do {} while()', re-convergence points
+ * will always be a branch or jump target.  Note that this is overly
+ * conservative, since unconditional jump targets are not convergence
+ * points, we are just assuming that the other path to reach the jump
+ * target was divergent.  If we were clever enough to optimize the
+ * jump at end of a loop back to a conditional branch into a single
+ * conditional branch, ie. like:
+ *
+ *    add.f r1.w, r0.x, (neg)(r)c2.x   <= loop start
+ *    mul.f r1.z, r1.z, r0.x
+ *    mul.f r1.y, r1.y, r0.x
+ *    mul.f r0.z, r1.x, r0.x
+ *    mul.f r0.w, r0.y, r0.x
+ *    cmps.f.ge r0.x, (r)c2.y, (r)r1.w
+ *    add.s r0.x, (r)r0.x, (r)-1
+ *    sel.f32 r0.x, (r)c3.y, (r)r0.x, c3.x
+ *    cmps.f.eq p0.x, r0.x, c3.y
+ *    mov.f32f32 r0.x, r1.w
+ *    mov.f32f32 r0.y, r0.w
+ *    mov.f32f32 r1.x, r0.z
+ *    (rpt2)nop
+ *    br !p0.x, #-13
+ *    (jp)mul.f r0.x, c263.y, r1.y
+ *
+ * Then we'd have to be more clever, as the convergence point is no
+ * longer a branch or jump target.
+ */
+static void
+mark_convergence_points(struct ir3 *ir)
+{
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+                       if (is_flow(instr) && instr->cat0.target) {
+                               struct ir3_instruction *target =
+                                       list_first_entry(&instr->cat0.target->instr_list,
+                                                       struct ir3_instruction, node);
+                               target->flags |= IR3_INSTR_JP;
+                       }
+               }
+       }
 }
 
-void ir3_block_legalize(struct ir3_block *block,
-               bool *has_samp, int *max_bary)
+void
+ir3_legalize(struct ir3 *ir, bool *has_samp, int *max_bary)
 {
        struct ir3_legalize_ctx ctx = {
-                       .block = block,
                        .max_bary = -1,
        };
 
-       legalize(&ctx);
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               legalize_block(&ctx, block);
+       }
 
        *has_samp = ctx.has_samp;
        *max_bary = ctx.max_bary;
+
+       do {
+               ir3_count_instructions(ir);
+       } while(resolve_jumps(ir));
+
+       mark_convergence_points(ir);
 }
index ae36019ed5f9d380133b51b32e1b97c6945799fc..dc9e4626f27099909493e1b2b9a112d06654c381 100644 (file)
@@ -74,14 +74,13 @@ valid_dest(nir_block *block, nir_dest *dest)
         * (so this is run iteratively in a loop).  Therefore if
         * we get this far, it should not have any if_uses:
         */
-       assert(dest->ssa.if_uses->entries == 0);
+       assert(list_empty(&dest->ssa.if_uses));
 
        /* The only uses of this definition must be phi's in the
         * successor or in the current block
         */
-       struct set_entry *entry;
-       set_foreach(dest->ssa.uses, entry) {
-               const nir_instr *dest_instr = entry->key;
+       nir_foreach_use(&dest->ssa, use) {
+               nir_instr *dest_instr = use->parent_instr;
                if (dest_instr->block == block)
                        continue;
                if ((dest_instr->type == nir_instr_type_phi) &&
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_print.c b/src/gallium/drivers/freedreno/ir3/ir3_print.c
new file mode 100644 (file)
index 0000000..f377982
--- /dev/null
@@ -0,0 +1,237 @@
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Rob Clark <robclark@freedesktop.org>
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "ir3.h"
+
+#define PTRID(x) ((unsigned long)(x))
+
+static void print_instr_name(struct ir3_instruction *instr)
+{
+#ifdef DEBUG
+       printf("%04u:", instr->serialno);
+#endif
+       printf("%03u: ", instr->depth);
+
+       if (instr->flags & IR3_INSTR_SY)
+               printf("(sy)");
+       if (instr->flags & IR3_INSTR_SS)
+               printf("(ss)");
+
+       if (is_meta(instr)) {
+               switch(instr->opc) {
+               case OPC_META_PHI:
+                       printf("&#934;");
+                       break;
+               default:
+                       /* shouldn't hit here.. just for debugging: */
+                       switch (instr->opc) {
+                       case OPC_META_INPUT:  printf("_meta:in");   break;
+                       case OPC_META_FO:     printf("_meta:fo");   break;
+                       case OPC_META_FI:     printf("_meta:fi");   break;
+
+                       default: printf("_meta:%d", instr->opc); break;
+                       }
+                       break;
+               }
+       } else if (instr->category == 1) {
+               static const char *type[] = {
+                               [TYPE_F16] = "f16",
+                               [TYPE_F32] = "f32",
+                               [TYPE_U16] = "u16",
+                               [TYPE_U32] = "u32",
+                               [TYPE_S16] = "s16",
+                               [TYPE_S32] = "s32",
+                               [TYPE_U8]  = "u8",
+                               [TYPE_S8]  = "s8",
+               };
+               if (instr->cat1.src_type == instr->cat1.dst_type)
+                       printf("mov");
+               else
+                       printf("cov");
+               printf(".%s%s", type[instr->cat1.src_type], type[instr->cat1.dst_type]);
+       } else {
+               printf("%s", ir3_instr_name(instr));
+               if (instr->flags & IR3_INSTR_3D)
+                       printf(".3d");
+               if (instr->flags & IR3_INSTR_A)
+                       printf(".a");
+               if (instr->flags & IR3_INSTR_O)
+                       printf(".o");
+               if (instr->flags & IR3_INSTR_P)
+                       printf(".p");
+               if (instr->flags & IR3_INSTR_S)
+                       printf(".s");
+               if (instr->flags & IR3_INSTR_S2EN)
+                       printf(".s2en");
+       }
+}
+
+static void print_reg_name(struct ir3_register *reg, bool followssa)
+{
+       if ((reg->flags & (IR3_REG_FABS | IR3_REG_SABS)) &&
+                       (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT)))
+               printf("(absneg)");
+       else if (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT))
+               printf("(neg)");
+       else if (reg->flags & (IR3_REG_FABS | IR3_REG_SABS))
+               printf("(abs)");
+
+       if (reg->flags & IR3_REG_IMMED) {
+               printf("imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val);
+       } else if (reg->flags & IR3_REG_SSA) {
+               printf("_");
+               if (followssa) {
+                       printf("[");
+                       print_instr_name(reg->instr);
+                       printf("]");
+               }
+       } else if (reg->flags & IR3_REG_RELATIV) {
+               if (reg->flags & IR3_REG_HALF)
+                       printf("h");
+               if (reg->flags & IR3_REG_CONST)
+                       printf("c<a0.x + %u>", reg->num);
+               else
+                       printf("\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->num, reg->size);
+       } else {
+               if (reg->flags & IR3_REG_HALF)
+                       printf("h");
+               if (reg->flags & IR3_REG_CONST)
+                       printf("c%u.%c", reg_num(reg), "xyzw"[reg_comp(reg)]);
+               else
+                       printf("\x1b[0;31mr%u.%c\x1b[0m", reg_num(reg), "xyzw"[reg_comp(reg)]);
+       }
+}
+
+static void
+tab(int lvl)
+{
+       for (int i = 0; i < lvl; i++)
+               printf("\t");
+}
+
+static uint32_t
+block_id(struct ir3_block *block)
+{
+#ifdef DEBUG
+       return block->serialno;
+#else
+       return (uint32_t)(uint64_t)block;
+#endif
+}
+
+static void
+print_instr(struct ir3_instruction *instr, int lvl)
+{
+       unsigned i;
+
+       tab(lvl);
+
+       print_instr_name(instr);
+       for (i = 0; i < instr->regs_count; i++) {
+               struct ir3_register *reg = instr->regs[i];
+               printf(i ? ", " : " ");
+               print_reg_name(reg, !!i);
+       }
+
+       if (instr->address) {
+               printf(", address=_");
+               printf("[");
+               print_instr_name(instr->address);
+               printf("]");
+       }
+
+       if (instr->fanin) {
+               printf(", fanin=_");
+               printf("[");
+               print_instr_name(instr->fanin);
+               printf("]");
+       }
+
+       if (is_meta(instr)) {
+               if (instr->opc == OPC_META_FO) {
+                       printf(", off=%d", instr->fo.off);
+               } else if ((instr->opc == OPC_META_FI) && instr->fi.aid) {
+                       printf(", aid=%d", instr->fi.aid);
+               }
+       }
+
+       if (is_flow(instr) && instr->cat0.target) {
+               /* the predicate register src is implied: */
+               if (instr->opc == OPC_BR) {
+                       printf(" %sp0.x", instr->cat0.inv ? "!" : "");
+               }
+               printf(", target=block%u", block_id(instr->cat0.target));
+       }
+
+       printf("\n");
+}
+
+void ir3_print_instr(struct ir3_instruction *instr)
+{
+       print_instr(instr, 0);
+}
+
+static void
+print_block(struct ir3_block *block, int lvl)
+{
+       tab(lvl); printf("block%u {\n", block_id(block));
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+               print_instr(instr, lvl+1);
+       }
+       if (block->successors[1]) {
+               /* leading into if/else: */
+               tab(lvl+1);
+               printf("/* succs: if _[");
+               print_instr_name(block->condition);
+               printf("] block%u; else block%u; */\n",
+                               block_id(block->successors[0]),
+                               block_id(block->successors[1]));
+       } else if (block->successors[0]) {
+               tab(lvl+1);
+               printf("/* succs: block%u; */\n",
+                               block_id(block->successors[0]));
+       }
+       tab(lvl); printf("}\n");
+}
+
+void
+ir3_print(struct ir3 *ir)
+{
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node)
+               print_block(block, 0);
+
+       for (unsigned i = 0; i < ir->noutputs; i++) {
+               if (!ir->outputs[i])
+                       continue;
+               printf("out%d: ", i);
+               print_instr(ir->outputs[i], 0);
+       }
+}
index a4235a77a15227a86f5b5c35cfc4b785c2ad2317..e5aba859fabdcf834e2e413543a3b50c08fe6cb7 100644 (file)
  *    Rob Clark <robclark@freedesktop.org>
  */
 
-#include "pipe/p_shader_tokens.h"
 #include "util/u_math.h"
+#include "util/register_allocate.h"
+#include "util/ralloc.h"
+#include "util/bitset.h"
 
 #include "ir3.h"
+#include "ir3_compiler.h"
 
 /*
  * Register Assignment:
  *
- * NOTE: currently only works on a single basic block.. need to think
- * about how multiple basic blocks are going to get scheduled.  But
- * I think I want to re-arrange how blocks work, ie. get rid of the
- * block nesting thing..
+ * Uses the register_allocate util, which implements graph coloring
+ * algo with interference classes.  To handle the cases where we need
+ * consecutive registers (for example, texture sample instructions),
+ * we model these as larger (double/quad/etc) registers which conflict
+ * with the corresponding registers in other classes.
  *
- * NOTE: we could do register coalescing (eliminate moves) as part of
- * the RA step.. OTOH I think we need to do scheduling before register
- * assignment.  And if we remove a mov that effects scheduling (unless
- * we leave a placeholder nop, which seems lame), so I'm not really
- * sure how practical this is to do both in a single stage.  But OTOH
- * I'm not really sure a sane way for the CP stage to realize when it
- * cannot remove a mov due to multi-register constraints..
+ * Additionally we create additional classes for half-regs, which
+ * do not conflict with the full-reg classes.  We do need at least
+ * sizes 1-4 (to deal w/ texture sample instructions output to half-
+ * reg).  At the moment we don't create the higher order half-reg
+ * classes as half-reg frequently does not have enough precision
+ * for texture coords at higher resolutions.
  *
- * NOTE: http://scopesconf.org/scopes-01/paper/session1_2.ps.gz has
- * some ideas to handle array allocation with a more conventional
- * graph coloring algorithm for register assignment, which might be
- * a good alternative to the current algo.  However afaict it cannot
- * handle overlapping arrays, which is a scenario that we have to
- * deal with
+ * There are some additional cases that we need to handle specially,
+ * as the graph coloring algo doesn't understand "partial writes".
+ * For example, a sequence like:
+ *
+ *   add r0.z, ...
+ *   sam (f32)(xy)r0.x, ...
+ *   ...
+ *   sam (f32)(xyzw)r0.w, r0.x, ...  ; 3d texture, so r0.xyz are coord
+ *
+ * In this scenario, we treat r0.xyz as class size 3, which is written
+ * (from a use/def perspective) at the 'add' instruction and ignore the
+ * subsequent partial writes to r0.xy.  So the 'add r0.z, ...' is the
+ * defining instruction, as it is the first to partially write r0.xyz.
+ *
+ * Note i965 has a similar scenario, which they solve with a virtual
+ * LOAD_PAYLOAD instruction which gets turned into multiple MOV's after
+ * register assignment.  But for us that is horrible from a scheduling
+ * standpoint.  Instead what we do is use idea of 'definer' instruction.
+ * Ie. the first instruction (lowest ip) to write to the array is the
+ * one we consider from use/def perspective when building interference
+ * graph.  (Other instructions which write other array elements just
+ * define the variable some more.)
+ */
+
+static const unsigned class_sizes[] = {
+       1, 2, 3, 4,
+       4 + 4, /* txd + 1d/2d */
+       4 + 6, /* txd + 3d */
+       /* temporary: until we can assign arrays, create classes so we
+        * can round up array to fit.  NOTE with tgsi arrays should
+        * really all be multiples of four:
+        */
+       4 * 4,
+       4 * 8,
+       4 * 16,
+       4 * 32,
+
+};
+#define class_count ARRAY_SIZE(class_sizes)
+
+static const unsigned half_class_sizes[] = {
+       1, 2, 3, 4,
+};
+#define half_class_count  ARRAY_SIZE(half_class_sizes)
+#define total_class_count (class_count + half_class_count)
+
+/* Below a0.x are normal regs.  RA doesn't need to assign a0.x/p0.x. */
+#define NUM_REGS             (4 * (REG_A0 - 1))
+/* Number of virtual regs in a given class: */
+#define CLASS_REGS(i)        (NUM_REGS - (class_sizes[i] - 1))
+#define HALF_CLASS_REGS(i)   (NUM_REGS - (half_class_sizes[i] - 1))
+
+/* register-set, created one time, used for all shaders: */
+struct ir3_ra_reg_set {
+       struct ra_regs *regs;
+       unsigned int classes[class_count];
+       unsigned int half_classes[half_class_count];
+       /* maps flat virtual register space to base gpr: */
+       uint16_t *ra_reg_to_gpr;
+       /* maps cls,gpr to flat virtual register space: */
+       uint16_t **gpr_to_ra_reg;
+};
+
+/* One-time setup of RA register-set, which describes all the possible
+ * "virtual" registers and their interferences.  Ie. double register
+ * occupies (and conflicts with) two single registers, and so forth.
+ * Since registers do not need to be aligned to their class size, they
+ * can conflict with other registers in the same class too.  Ie:
+ *
+ *    Single (base) |  Double
+ *    --------------+---------------
+ *       R0         |  D0
+ *       R1         |  D0 D1
+ *       R2         |     D1 D2
+ *       R3         |        D2
+ *           .. and so on..
+ *
+ * (NOTE the disassembler uses notation like r0.x/y/z/w but those are
+ * really just four scalar registers.  Don't let that confuse you.)
  */
+struct ir3_ra_reg_set *
+ir3_ra_alloc_reg_set(void *memctx)
+{
+       struct ir3_ra_reg_set *set = rzalloc(memctx, struct ir3_ra_reg_set);
+       unsigned ra_reg_count, reg, first_half_reg;
+       unsigned int **q_values;
+
+       /* calculate # of regs across all classes: */
+       ra_reg_count = 0;
+       for (unsigned i = 0; i < class_count; i++)
+               ra_reg_count += CLASS_REGS(i);
+       for (unsigned i = 0; i < half_class_count; i++)
+               ra_reg_count += HALF_CLASS_REGS(i);
+
+       /* allocate and populate q_values: */
+       q_values = ralloc_array(set, unsigned *, total_class_count);
+       for (unsigned i = 0; i < class_count; i++) {
+               q_values[i] = rzalloc_array(q_values, unsigned, total_class_count);
+
+               /* From register_allocate.c:
+                *
+                * q(B,C) (indexed by C, B is this register class) in
+                * Runeson/Nyström paper.  This is "how many registers of B could
+                * the worst choice register from C conflict with".
+                *
+                * If we just let the register allocation algorithm compute these
+                * values, is extremely expensive.  However, since all of our
+                * registers are laid out, we can very easily compute them
+                * ourselves.  View the register from C as fixed starting at GRF n
+                * somewhere in the middle, and the register from B as sliding back
+                * and forth.  Then the first register to conflict from B is the
+                * one starting at n - class_size[B] + 1 and the last register to
+                * conflict will start at n + class_size[B] - 1.  Therefore, the
+                * number of conflicts from B is class_size[B] + class_size[C] - 1.
+                *
+                *   +-+-+-+-+-+-+     +-+-+-+-+-+-+
+                * B | | | | | |n| --> | | | | | | |
+                *   +-+-+-+-+-+-+     +-+-+-+-+-+-+
+                *             +-+-+-+-+-+
+                * C           |n| | | | |
+                *             +-+-+-+-+-+
+                *
+                * (Idea copied from brw_fs_reg_allocate.cpp)
+                */
+               for (unsigned j = 0; j < class_count; j++)
+                       q_values[i][j] = class_sizes[i] + class_sizes[j] - 1;
+       }
+
+       for (unsigned i = class_count; i < total_class_count; i++) {
+               q_values[i] = ralloc_array(q_values, unsigned, total_class_count);
+
+               /* see comment above: */
+               for (unsigned j = class_count; j < total_class_count; j++) {
+                       q_values[i][j] = half_class_sizes[i - class_count] +
+                                       half_class_sizes[j - class_count] - 1;
+               }
+       }
 
+       /* allocate the reg-set.. */
+       set->regs = ra_alloc_reg_set(set, ra_reg_count);
+       set->ra_reg_to_gpr = ralloc_array(set, uint16_t, ra_reg_count);
+       set->gpr_to_ra_reg = ralloc_array(set, uint16_t *, total_class_count);
+
+       /* .. and classes */
+       reg = 0;
+       for (unsigned i = 0; i < class_count; i++) {
+               set->classes[i] = ra_alloc_reg_class(set->regs);
+
+               set->gpr_to_ra_reg[i] = ralloc_array(set, uint16_t, CLASS_REGS(i));
+
+               for (unsigned j = 0; j < CLASS_REGS(i); j++) {
+                       ra_class_add_reg(set->regs, set->classes[i], reg);
+
+                       set->ra_reg_to_gpr[reg] = j;
+                       set->gpr_to_ra_reg[i][j] = reg;
+
+                       for (unsigned br = j; br < j + class_sizes[i]; br++)
+                               ra_add_transitive_reg_conflict(set->regs, br, reg);
+
+                       reg++;
+               }
+       }
+
+       first_half_reg = reg;
+
+       for (unsigned i = 0; i < half_class_count; i++) {
+               set->half_classes[i] = ra_alloc_reg_class(set->regs);
+
+               set->gpr_to_ra_reg[class_count + i] =
+                               ralloc_array(set, uint16_t, CLASS_REGS(i));
+
+               for (unsigned j = 0; j < HALF_CLASS_REGS(i); j++) {
+                       ra_class_add_reg(set->regs, set->half_classes[i], reg);
+
+                       set->ra_reg_to_gpr[reg] = j;
+                       set->gpr_to_ra_reg[class_count + i][j] = reg;
+
+                       for (unsigned br = j; br < j + half_class_sizes[i]; br++)
+                               ra_add_transitive_reg_conflict(set->regs, br + first_half_reg, reg);
+
+                       reg++;
+               }
+       }
+
+       ra_set_finalize(set->regs, q_values);
+
+       ralloc_free(q_values);
+
+       return set;
+}
+
+/* register-assign context, per-shader */
 struct ir3_ra_ctx {
-       struct ir3_block *block;
+       struct ir3 *ir;
        enum shader_t type;
-       bool frag_coord;
        bool frag_face;
-       int cnt;
-       bool error;
-       struct {
-               unsigned base;
-               unsigned size;
-       } arrays[MAX_ARRAYS];
+
+       struct ir3_ra_reg_set *set;
+       struct ra_graph *g;
+       unsigned alloc_count;
+       unsigned class_alloc_count[total_class_count];
+       unsigned class_base[total_class_count];
+       unsigned instr_cnt;
+       unsigned *def, *use;     /* def/use table */
 };
 
-#ifdef DEBUG
-#  include "freedreno_util.h"
-#  define ra_debug (fd_mesa_debug & FD_DBG_OPTMSGS)
-#else
-#  define ra_debug 0
-#endif
-
-#define ra_dump_list(msg, n) do { \
-               if (ra_debug) { \
-                       debug_printf("-- " msg); \
-                       ir3_dump_instr_list(n); \
-               } \
-       } while (0)
-
-#define ra_dump_instr(msg, n) do { \
-               if (ra_debug) { \
-                       debug_printf(">> " msg); \
-                       ir3_dump_instr_single(n); \
-               } \
-       } while (0)
-
-#define ra_assert(ctx, x) do { \
-               debug_assert(x); \
-               if (!(x)) { \
-                       debug_printf("RA: failed assert: %s\n", #x); \
-                       (ctx)->error = true; \
-               }; \
-       } while (0)
-
-
-/* sorta ugly way to retrofit half-precision support.. rather than
- * passing extra param around, just OR in a high bit.  All the low
- * value arithmetic (ie. +/- offset within a contiguous vec4, etc)
- * will continue to work as long as you don't underflow (and that
- * would go badly anyways).
- */
-#define REG_HALF  0x8000
+/* additional block-data (per-block) */
+struct ir3_ra_block_data {
+       BITSET_WORD *def;        /* variables defined before used in block */
+       BITSET_WORD *use;        /* variables used before defined in block */
+       BITSET_WORD *livein;     /* which defs reach entry point of block */
+       BITSET_WORD *liveout;    /* which defs reach exit point of block */
+};
+
+static bool
+is_half(struct ir3_instruction *instr)
+{
+       return !!(instr->regs[0]->flags & IR3_REG_HALF);
+}
 
-#define REG(n, wm, f) (struct ir3_register){ \
-               .flags  = (f), \
-               .num    = (n), \
-               .wrmask = TGSI_WRITEMASK_ ## wm, \
+static int
+size_to_class(unsigned sz, bool half)
+{
+       if (half) {
+               for (unsigned i = 0; i < half_class_count; i++)
+                       if (half_class_sizes[i] >= sz)
+                               return i + class_count;
+       } else {
+               for (unsigned i = 0; i < class_count; i++)
+                       if (class_sizes[i] >= sz)
+                               return i;
        }
+       debug_assert(0);
+       return -1;
+}
 
-/* check that the register exists, is a GPR and is not special (a0/p0) */
-static struct ir3_register * reg_check(struct ir3_instruction *instr, unsigned n)
+static bool
+is_temp(struct ir3_register *reg)
 {
-       if ((n < instr->regs_count) && reg_gpr(instr->regs[n]) &&
-                       !(instr->regs[n]->flags & IR3_REG_SSA))
-               return instr->regs[n];
-       return NULL;
+       if (reg->flags & (IR3_REG_CONST | IR3_REG_IMMED))
+               return false;
+       if (reg->flags & IR3_REG_RELATIV) // TODO
+               return false;
+       if ((reg->num == regid(REG_A0, 0)) ||
+                       (reg->num == regid(REG_P0, 0)))
+               return false;
+       return true;
 }
 
-/* figure out if an unassigned src register points back to the instr we
- * are assigning:
- */
-static bool instr_used_by(struct ir3_instruction *instr,
-               struct ir3_register *src)
+static bool
+writes_gpr(struct ir3_instruction *instr)
 {
-       struct ir3_instruction *src_instr = ssa(src);
-       unsigned i;
-       if (instr == src_instr)
-               return true;
-       if (src_instr && is_meta(src_instr))
-               for (i = 1; i < src_instr->regs_count; i++)
-                       if (instr_used_by(instr, src_instr->regs[i]))
-                               return true;
-
-       return false;
+       if (is_store(instr))
+               return false;
+       /* is dest a normal temp register: */
+       return is_temp(instr->regs[0]);
 }
 
-static bool instr_is_output(struct ir3_instruction *instr)
+static struct ir3_instruction *
+get_definer(struct ir3_instruction *instr, int *sz, int *off)
 {
-       struct ir3_block *block = instr->block;
-       unsigned i;
+       struct ir3_instruction *d = NULL;
+       if (is_meta(instr) && (instr->opc == OPC_META_FI)) {
+               /* What about the case where collect is subset of array, we
+                * need to find the distance between where actual array starts
+                * and fanin..  that probably doesn't happen currently.
+                */
+               struct ir3_register *src;
 
-       for (i = 0; i < block->noutputs; i++)
-               if (instr == block->outputs[i])
-                       return true;
+               /* note: don't use foreach_ssa_src as this gets called once
+                * while assigning regs (which clears SSA flag)
+                */
+               foreach_src(src, instr) {
+                       if (!src->instr)
+                               continue;
+                       if ((!d) || (src->instr->ip < d->ip))
+                               d = src->instr;
+               }
 
-       return false;
-}
+               *sz = instr->regs_count - 1;
+               *off = 0;
 
-static void mark_sources(struct ir3_instruction *instr,
-               struct ir3_instruction *n, regmask_t *liveregs, regmask_t *written)
-{
-       unsigned i;
+       } else if (instr->cp.right || instr->cp.left) {
+               /* covers also the meta:fo case, which ends up w/ single
+                * scalar instructions for each component:
+                */
+               struct ir3_instruction *f = ir3_neighbor_first(instr);
+
+               /* by definition, the entire sequence forms one linked list
+                * of single scalar register nodes (even if some of them may
+                * be fanouts from a texture sample (for example) instr.  We
+                * just need to walk the list finding the first element of
+                * the group defined (lowest ip)
+                */
+               int cnt = 0;
+
+               d = f;
+               while (f) {
+                       if (f->ip < d->ip)
+                               d = f;
+                       if (f == instr)
+                               *off = cnt;
+                       f = f->cp.right;
+                       cnt++;
+               }
+
+               *sz = cnt;
+
+       } else {
+               /* second case is looking directly at the instruction which
+                * produces multiple values (eg, texture sample), rather
+                * than the fanout nodes that point back to that instruction.
+                * This isn't quite right, because it may be part of a larger
+                * group, such as:
+                *
+                *     sam (f32)(xyzw)r0.x, ...
+                *     add r1.x, ...
+                *     add r1.y, ...
+                *     sam (f32)(xyzw)r2.x, r0.w  <-- (r0.w, r1.x, r1.y)
+                *
+                * need to come up with a better way to handle that case.
+                */
+               if (instr->address) {
+                       *sz = instr->regs[0]->size;
+               } else {
+                       *sz = util_last_bit(instr->regs[0]->wrmask);
+               }
+               *off = 0;
+               d = instr;
+       }
+
+       if (d->regs[0]->flags & IR3_REG_PHI_SRC) {
+               struct ir3_instruction *phi = d->regs[0]->instr;
+               struct ir3_instruction *dd;
+               int dsz, doff;
+
+               dd = get_definer(phi, &dsz, &doff);
+
+               *sz = MAX2(*sz, dsz);
+               *off = doff;
+
+               if (dd->ip < d->ip) {
+                       d = dd;
+               }
+       }
 
-       for (i = 1; i < n->regs_count; i++) {
-               struct ir3_register *r = reg_check(n, i);
-               if (r)
-                       regmask_set_if_not(liveregs, r, written);
+       if (is_meta(d) && (d->opc == OPC_META_PHI)) {
+               /* we have already inserted parallel-copies into
+                * the phi, so we don't need to chase definers
+                */
+               struct ir3_register *src;
 
-               /* if any src points back to the instruction(s) in
-                * the block of neighbors that we are assigning then
-                * mark any written (clobbered) registers as live:
+               /* note: don't use foreach_ssa_src as this gets called once
+                * while assigning regs (which clears SSA flag)
                 */
-               if (instr_used_by(instr, n->regs[i]))
-                       regmask_or(liveregs, liveregs, written);
+               foreach_src(src, d) {
+                       if (!src->instr)
+                               continue;
+                       if (src->instr->ip < d->ip)
+                               d = src->instr;
+               }
        }
 
+       if (is_meta(d) && (d->opc == OPC_META_FO)) {
+               struct ir3_instruction *dd;
+               int dsz, doff;
+
+               dd = get_definer(d->regs[1]->instr, &dsz, &doff);
+
+               /* by definition, should come before: */
+               debug_assert(dd->ip < d->ip);
+
+               *sz = MAX2(*sz, dsz);
+
+               /* Fanout's are grouped, so *off should already valid */
+
+               d = dd;
+       }
+
+       return d;
 }
 
-/* live means read before written */
-static void compute_liveregs(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr, regmask_t *liveregs)
+/* give each instruction a name (and ip), and count up the # of names
+ * of each class
+ */
+static void
+ra_block_name_instructions(struct ir3_ra_ctx *ctx, struct ir3_block *block)
 {
-       struct ir3_block *block = instr->block;
-       struct ir3_instruction *n;
-       regmask_t written;
-       unsigned i;
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+               struct ir3_instruction *defn;
+               int cls, sz, off;
 
-       regmask_init(&written);
+               ctx->instr_cnt++;
 
-       for (n = instr->next; n; n = n->next) {
-               struct ir3_register *r;
-
-               if (is_meta(n))
+               if (instr->regs_count == 0)
                        continue;
 
-               /* check first src's read: */
-               mark_sources(instr, n, liveregs, &written);
+               if (!writes_gpr(instr))
+                       continue;
 
-               /* for instructions that write to an array, we need to
-                * capture the dependency on the array elements:
-                */
-               if (n->fanin)
-                       mark_sources(instr, n->fanin, liveregs, &written);
+               defn = get_definer(instr, &sz, &off);
 
-               /* meta-instructions don't actually get scheduled,
-                * so don't let it's write confuse us.. what we
-                * really care about is when the src to the meta
-                * instr was written:
-                */
-               if (is_meta(n))
+               if (defn != instr)
                        continue;
 
-               /* then dst written (if assigned already): */
-               r = reg_check(n, 0);
-               if (r) {
-                       /* if an instruction *is* an output, then it is live */
-                       if (!instr_is_output(n))
-                               regmask_set(&written, r);
+               /* arrays which don't fit in one of the pre-defined class
+                * sizes are pre-colored:
+                *
+                * TODO but we still need to allocate names for them, don't we??
+                */
+               cls = size_to_class(sz, is_half(defn));
+               if (cls >= 0) {
+                       instr->name = ctx->class_alloc_count[cls]++;
+                       ctx->alloc_count++;
                }
-
        }
+}
 
-       /* be sure to account for output registers too: */
-       for (i = 0; i < block->noutputs; i++) {
-               struct ir3_register *r;
-               if (!block->outputs[i])
-                       continue;
-               r = reg_check(block->outputs[i], 0);
-               if (r)
-                       regmask_set_if_not(liveregs, r, &written);
+static void
+ra_init(struct ir3_ra_ctx *ctx)
+{
+       ir3_clear_mark(ctx->ir);
+       ir3_count_instructions(ctx->ir);
+
+       list_for_each_entry (struct ir3_block, block, &ctx->ir->block_list, node) {
+               ra_block_name_instructions(ctx, block);
        }
 
-       /* if instruction is output, we need a reg that isn't written
-        * before the end.. equiv to the instr_used_by() check above
-        * in the loop body
-        * TODO maybe should follow fanin/fanout?
+       /* figure out the base register name for each class.  The
+        * actual ra name is class_base[cls] + instr->name;
         */
-       if (instr_is_output(instr))
-               regmask_or(liveregs, liveregs, &written);
+       ctx->class_base[0] = 0;
+       for (unsigned i = 1; i < total_class_count; i++) {
+               ctx->class_base[i] = ctx->class_base[i-1] +
+                               ctx->class_alloc_count[i-1];
+       }
+
+       ctx->g = ra_alloc_interference_graph(ctx->set->regs, ctx->alloc_count);
+       ctx->def = rzalloc_array(ctx->g, unsigned, ctx->alloc_count);
+       ctx->use = rzalloc_array(ctx->g, unsigned, ctx->alloc_count);
+}
+
+static unsigned
+ra_name(struct ir3_ra_ctx *ctx, int cls, struct ir3_instruction *defn)
+{
+       unsigned name;
+       debug_assert(cls >= 0);
+       name = ctx->class_base[cls] + defn->name;
+       debug_assert(name < ctx->alloc_count);
+       return name;
 }
 
-static int find_available(regmask_t *liveregs, int size, bool half)
+static void
+ra_destroy(struct ir3_ra_ctx *ctx)
 {
-       unsigned i;
-       unsigned f = half ? IR3_REG_HALF : 0;
-       for (i = 0; i < MAX_REG - size; i++) {
-               if (!regmask_get(liveregs, &REG(i, X, f))) {
-                       unsigned start = i++;
-                       for (; (i < MAX_REG) && ((i - start) < size); i++)
-                               if (regmask_get(liveregs, &REG(i, X, f)))
-                                       break;
-                       if ((i - start) >= size)
-                               return start;
+       ralloc_free(ctx->g);
+}
+
+static void
+ra_block_compute_live_ranges(struct ir3_ra_ctx *ctx, struct ir3_block *block)
+{
+       struct ir3_ra_block_data *bd;
+       unsigned bitset_words = BITSET_WORDS(ctx->alloc_count);
+
+       bd = rzalloc(ctx->g, struct ir3_ra_block_data);
+
+       bd->def     = rzalloc_array(bd, BITSET_WORD, bitset_words);
+       bd->use     = rzalloc_array(bd, BITSET_WORD, bitset_words);
+       bd->livein  = rzalloc_array(bd, BITSET_WORD, bitset_words);
+       bd->liveout = rzalloc_array(bd, BITSET_WORD, bitset_words);
+
+       block->bd = bd;
+
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+               struct ir3_instruction *src;
+
+               if (instr->regs_count == 0)
+                       continue;
+
+               /* There are a couple special cases to deal with here:
+                *
+                * fanout: used to split values from a higher class to a lower
+                *     class, for example split the results of a texture fetch
+                *     into individual scalar values;  We skip over these from
+                *     a 'def' perspective, and for a 'use' we walk the chain
+                *     up to the defining instruction.
+                *
+                * fanin: used to collect values from lower class and assemble
+                *     them together into a higher class, for example arguments
+                *     to texture sample instructions;  We consider these to be
+                *     defined at the earliest fanin source.
+                *
+                * phi: used to merge values from different flow control paths
+                *     to the same reg.  Consider defined at earliest phi src,
+                *     and update all the other phi src's (which may come later
+                *     in the program) as users to extend the var's live range.
+                *
+                * Most of this, other than phi, is completely handled in the
+                * get_definer() helper.
+                *
+                * In either case, we trace the instruction back to the original
+                * definer and consider that as the def/use ip.
+                */
+
+               if (writes_gpr(instr)) {
+                       struct ir3_instruction *defn;
+                       int cls, sz, off;
+
+                       defn = get_definer(instr, &sz, &off);
+                       if (defn == instr) {
+                               /* arrays which don't fit in one of the pre-defined class
+                                * sizes are pre-colored:
+                                */
+                               cls = size_to_class(sz, is_half(defn));
+                               if (cls >= 0) {
+                                       unsigned name = ra_name(ctx, cls, defn);
+
+                                       ctx->def[name] = defn->ip;
+                                       ctx->use[name] = defn->ip;
+
+                                       /* since we are in SSA at this point: */
+                                       debug_assert(!BITSET_TEST(bd->use, name));
+
+                                       BITSET_SET(bd->def, name);
+
+                                       if (is_half(defn)) {
+                                               ra_set_node_class(ctx->g, name,
+                                                               ctx->set->half_classes[cls - class_count]);
+                                       } else {
+                                               ra_set_node_class(ctx->g, name,
+                                                               ctx->set->classes[cls]);
+                                       }
+
+                                       /* extend the live range for phi srcs, which may come
+                                        * from the bottom of the loop
+                                        */
+                                       if (defn->regs[0]->flags & IR3_REG_PHI_SRC) {
+                                               struct ir3_instruction *phi = defn->regs[0]->instr;
+                                               foreach_ssa_src(src, phi) {
+                                                       /* if src is after phi, then we need to extend
+                                                        * the liverange to the end of src's block:
+                                                        */
+                                                       if (src->ip > phi->ip) {
+                                                               struct ir3_instruction *last =
+                                                                       list_last_entry(&src->block->instr_list,
+                                                                               struct ir3_instruction, node);
+                                                               ctx->use[name] = MAX2(ctx->use[name], last->ip);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               foreach_ssa_src(src, instr) {
+                       if (writes_gpr(src)) {
+                               struct ir3_instruction *srcdefn;
+                               int cls, sz, off;
+
+                               srcdefn = get_definer(src, &sz, &off);
+                               cls = size_to_class(sz, is_half(srcdefn));
+                               if (cls >= 0) {
+                                       unsigned name = ra_name(ctx, cls, srcdefn);
+                                       ctx->use[name] = MAX2(ctx->use[name], instr->ip);
+                                       if (!BITSET_TEST(bd->def, name))
+                                               BITSET_SET(bd->use, name);
+                               }
+                       }
                }
        }
-       assert(0);
-       return -1;
 }
 
-static int alloc_block(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr, int size)
+static bool
+ra_compute_livein_liveout(struct ir3_ra_ctx *ctx)
 {
-       struct ir3_register *dst = instr->regs[0];
-       struct ir3_instruction *n;
-       regmask_t liveregs;
-       unsigned name;
+       unsigned bitset_words = BITSET_WORDS(ctx->alloc_count);
+       bool progress = false;
 
-       /* should only ever be called w/ head of neighbor list: */
-       debug_assert(!instr->cp.left);
+       list_for_each_entry (struct ir3_block, block, &ctx->ir->block_list, node) {
+               struct ir3_ra_block_data *bd = block->bd;
 
-       regmask_init(&liveregs);
+               /* update livein: */
+               for (unsigned i = 0; i < bitset_words; i++) {
+                       BITSET_WORD new_livein =
+                               (bd->use[i] | (bd->liveout[i] & ~bd->def[i]));
 
-       for (n = instr; n; n = n->cp.right)
-               compute_liveregs(ctx, n, &liveregs);
+                       if (new_livein & ~bd->livein[i]) {
+                               bd->livein[i] |= new_livein;
+                               progress = true;
+                       }
+               }
 
-       /* because we do assignment on fanout nodes for wrmask!=0x1, we
-        * need to handle this special case, where the fanout nodes all
-        * appear after one or more of the consumers of the src node:
-        *
-        *   0098:009: sam _, r2.x
-        *   0028:010: mul.f r3.z, r4.x, c13.x
-        *   ; we start assigning here for '0098:009: sam'.. but
-        *   ; would miss the usage at '0028:010: mul.f'
-        *   0101:009: _meta:fo _, _[0098:009: sam], off=2
-        */
-       if (is_meta(instr) && (instr->opc == OPC_META_FO))
-               compute_liveregs(ctx, instr->regs[1]->instr, &liveregs);
+               /* update liveout: */
+               for (unsigned j = 0; j < ARRAY_SIZE(block->successors); j++) {
+                       struct ir3_block *succ = block->successors[j];
+                       struct ir3_ra_block_data *succ_bd;
+
+                       if (!succ)
+                               continue;
 
-       name = find_available(&liveregs, size,
-                       !!(dst->flags & IR3_REG_HALF));
+                       succ_bd = succ->bd;
 
-       if (dst->flags & IR3_REG_HALF)
-               name |= REG_HALF;
+                       for (unsigned i = 0; i < bitset_words; i++) {
+                               BITSET_WORD new_liveout =
+                                       (succ_bd->livein[i] & ~bd->liveout[i]);
 
-       return name;
+                               if (new_liveout) {
+                                       bd->liveout[i] |= new_liveout;
+                                       progress = true;
+                               }
+                       }
+               }
+       }
+
+       return progress;
 }
 
-static type_t half_type(type_t type)
+static void
+ra_add_interference(struct ir3_ra_ctx *ctx)
 {
-       switch (type) {
-       case TYPE_F32: return TYPE_F16;
-       case TYPE_U32: return TYPE_U16;
-       case TYPE_S32: return TYPE_S16;
-       /* instructions may already be fixed up: */
-       case TYPE_F16:
-       case TYPE_U16:
-       case TYPE_S16:
-               return type;
-       default:
-               assert(0);
-               return ~0;
+       struct ir3 *ir = ctx->ir;
+
+       /* compute live ranges (use/def) on a block level, also updating
+        * block's def/use bitmasks (used below to calculate per-block
+        * livein/liveout):
+        */
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               ra_block_compute_live_ranges(ctx, block);
+       }
+
+       /* update per-block livein/liveout: */
+       while (ra_compute_livein_liveout(ctx)) {}
+
+       /* extend start/end ranges based on livein/liveout info from cfg: */
+       unsigned bitset_words = BITSET_WORDS(ctx->alloc_count);
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               struct ir3_ra_block_data *bd = block->bd;
+
+               for (unsigned i = 0; i < bitset_words; i++) {
+                       if (BITSET_TEST(bd->livein, i)) {
+                               ctx->def[i] = MIN2(ctx->def[i], block->start_ip);
+                               ctx->use[i] = MAX2(ctx->use[i], block->start_ip);
+                       }
+
+                       if (BITSET_TEST(bd->liveout, i)) {
+                               ctx->def[i] = MIN2(ctx->def[i], block->end_ip);
+                               ctx->use[i] = MAX2(ctx->use[i], block->end_ip);
+                       }
+               }
+       }
+
+       /* need to fix things up to keep outputs live: */
+       for (unsigned i = 0; i < ir->noutputs; i++) {
+               struct ir3_instruction *instr = ir->outputs[i];
+               struct ir3_instruction *defn;
+               int cls, sz, off;
+
+               defn = get_definer(instr, &sz, &off);
+               cls = size_to_class(sz, is_half(defn));
+               if (cls >= 0) {
+                       unsigned name = ra_name(ctx, cls, defn);
+                       ctx->use[name] = ctx->instr_cnt;
+               }
+       }
+
+       for (unsigned i = 0; i < ctx->alloc_count; i++) {
+               for (unsigned j = 0; j < ctx->alloc_count; j++) {
+                       if (!((ctx->def[i] >= ctx->use[j]) ||
+                                       (ctx->def[j] >= ctx->use[i]))) {
+                               ra_add_node_interference(ctx->g, i, j);
+                       }
+               }
        }
 }
 
@@ -358,302 +776,124 @@ static void fixup_half_instr_src(struct ir3_instruction *instr)
        }
 }
 
-static void reg_assign(struct ir3_instruction *instr,
-               unsigned r, unsigned name)
+static void
+reg_assign(struct ir3_ra_ctx *ctx, struct ir3_register *reg,
+               struct ir3_instruction *instr)
 {
-       struct ir3_register *reg = instr->regs[r];
-
-       reg->flags &= ~IR3_REG_SSA;
-       reg->num = name & ~REG_HALF;
-
-       if (name & REG_HALF) {
-               reg->flags |= IR3_REG_HALF;
-               /* if dst reg being assigned, patch up the instr: */
-               if (reg == instr->regs[0])
-                       fixup_half_instr_dst(instr);
-               else
-                       fixup_half_instr_src(instr);
-       }
-}
-
-static void instr_assign(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr, unsigned name);
+       struct ir3_instruction *defn;
+       int cls, sz, off;
 
-static void instr_assign_src(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr, unsigned r, unsigned name)
-{
-       struct ir3_register *reg = instr->regs[r];
+       defn = get_definer(instr, &sz, &off);
+       cls = size_to_class(sz, is_half(defn));
+       if (cls >= 0) {
+               unsigned name = ra_name(ctx, cls, defn);
+               unsigned r = ra_get_node_reg(ctx->g, name);
+               unsigned num = ctx->set->ra_reg_to_gpr[r] + off;
 
-       if (reg->flags & IR3_REG_RELATIV)
-               name += reg->offset;
+               if (reg->flags & IR3_REG_RELATIV)
+                       num += reg->offset;
 
-       reg_assign(instr, r, name);
+               reg->num = num;
+               reg->flags &= ~(IR3_REG_SSA | IR3_REG_PHI_SRC);
 
-       if (is_meta(instr)) {
-               switch (instr->opc) {
-               case OPC_META_INPUT:
-                       /* shader-input does not have a src, only block input: */
-                       debug_assert(instr->regs_count == 2);
-                       instr_assign(ctx, instr, name);
-                       return;
-               case OPC_META_FO:
-                       instr_assign(ctx, instr, name + instr->fo.off);
-                       return;
-               case OPC_META_FI:
-                       instr_assign(ctx, instr, name - (r - 1));
-                       return;
-               default:
-                       break;
-               }
+               if (is_half(defn))
+                       reg->flags |= IR3_REG_HALF;
        }
 }
 
-static void instr_assign_srcs(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr, unsigned name)
+static void
+ra_block_alloc(struct ir3_ra_ctx *ctx, struct ir3_block *block)
 {
-       struct ir3_instruction *n, *src;
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+               struct ir3_register *reg;
 
-       for (n = instr->next; n && !ctx->error; n = n->next) {
-               foreach_ssa_src_n(src, i, n) {
-                       unsigned r = i + 1;
-
-                       /* skip address / etc (non real sources): */
-                       if (r >= n->regs_count)
-                               continue;
+               if (instr->regs_count == 0)
+                       continue;
 
-                       if (src == instr)
-                               instr_assign_src(ctx, n, r, name);
+               if (writes_gpr(instr)) {
+                       reg_assign(ctx, instr->regs[0], instr);
+                       if (instr->regs[0]->flags & IR3_REG_HALF)
+                               fixup_half_instr_dst(instr);
                }
-       }
-}
-
-static void instr_assign(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr, unsigned name)
-{
-       struct ir3_register *reg = instr->regs[0];
-
-       if (reg->flags & IR3_REG_RELATIV)
-               return;
-
-       /* check if already assigned: */
-       if (!(reg->flags & IR3_REG_SSA)) {
-               /* ... and if so, sanity check: */
-               ra_assert(ctx, reg->num == (name & ~REG_HALF));
-               return;
-       }
-
-       /* rename this instructions dst register: */
-       reg_assign(instr, 0, name);
-
-       /* and rename any subsequent use of result of this instr: */
-       instr_assign_srcs(ctx, instr, name);
-
-       /* To simplify the neighbor logic, and to "avoid" dealing with
-        * instructions which write more than one output, we actually
-        * do register assignment for instructions that produce multiple
-        * outputs on the fanout nodes and propagate up the assignment
-        * to the actual instruction:
-        */
-       if (is_meta(instr) && (instr->opc == OPC_META_FO)) {
-               struct ir3_instruction *src;
 
-               debug_assert(name >= instr->fo.off);
-
-               foreach_ssa_src(src, instr)
-                       instr_assign(ctx, src, name - instr->fo.off);
-       }
-}
+               foreach_src_n(reg, n, instr) {
+                       struct ir3_instruction *src = reg->instr;
+                       if (!src)
+                               continue;
 
-/* check neighbor list to see if it is already partially (or completely)
- * assigned, in which case register block is already allocated and we
- * just need to complete the assignment:
- */
-static int check_partial_assignment(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       struct ir3_instruction *n;
-       int off = 0;
-
-       debug_assert(!instr->cp.left);
-
-       for (n = instr; n; n = n->cp.right) {
-               struct ir3_register *dst = n->regs[0];
-               if ((n->depth != DEPTH_UNUSED) &&
-                               !(dst->flags & IR3_REG_SSA)) {
-                       int name = dst->num - off;
-                       debug_assert(name >= 0);
-                       return name;
+                       reg_assign(ctx, instr->regs[n+1], src);
+                       if (instr->regs[n+1]->flags & IR3_REG_HALF)
+                               fixup_half_instr_src(instr);
                }
-               off++;
        }
-
-       return -1;
 }
 
-/* allocate register name(s) for a list of neighboring instructions;
- * instr should point to leftmost neighbor (head of list)
- */
-static void instr_alloc_and_assign(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr)
+static int
+ra_alloc(struct ir3_ra_ctx *ctx)
 {
-       struct ir3_instruction *n;
-       struct ir3_register *dst;
-       int name;
-
-       debug_assert(!instr->cp.left);
-
-       if (instr->regs_count == 0)
-               return;
-
-       dst = instr->regs[0];
-
-       /* For indirect dst, take the register assignment from the
-        * fanin and propagate it forward.
-        */
-       if (dst->flags & IR3_REG_RELATIV) {
-               /* NOTE can be grouped, if for example outputs:
-                * for now disable cp if indirect writes
-                */
-               instr_alloc_and_assign(ctx, instr->fanin);
-
-               dst->num += instr->fanin->regs[0]->num;
-               dst->flags &= ~IR3_REG_SSA;
-
-               instr_assign_srcs(ctx, instr, instr->fanin->regs[0]->num);
-
-               return;
-       }
-
-       /* for instructions w/ fanouts, do the actual register assignment
-        * on the group of fanout neighbor nodes and propagate the reg
-        * name back up to the texture instruction.
-        */
-       if (dst->wrmask != 0x1)
-               return;
-
-       name = check_partial_assignment(ctx, instr);
-
-       /* allocate register(s): */
-       if (name >= 0) {
-               /* already partially assigned, just finish the job */
-       } else if (reg_gpr(dst)) {
-               int size;
-               /* number of consecutive registers to assign: */
-               size = ir3_neighbor_count(instr);
-               if (dst->wrmask != 0x1)
-                       size = MAX2(size, ffs(~dst->wrmask) - 1);
-               name = alloc_block(ctx, instr, size);
-       } else if (dst->flags & IR3_REG_ADDR) {
-               debug_assert(!instr->cp.right);
-               dst->flags &= ~IR3_REG_ADDR;
-               name = regid(REG_A0, 0) | REG_HALF;
-       } else {
-               debug_assert(!instr->cp.right);
-               /* predicate register (p0).. etc */
-               name = regid(REG_P0, 0);
-               debug_assert(dst->num == name);
-       }
-
-       ra_assert(ctx, name >= 0);
-
-       for (n = instr; n && !ctx->error; n = n->cp.right) {
-               instr_assign(ctx, n, name);
-               name++;
-       }
-}
-
-static void instr_assign_array(struct ir3_ra_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       struct ir3_instruction *src;
-       int name, aid = instr->fi.aid;
-
-       if (ctx->arrays[aid].base == ~0) {
-               int size = instr->regs_count - 1;
-               ctx->arrays[aid].base = alloc_block(ctx, instr, size);
-               ctx->arrays[aid].size = size;
-       }
-
-       name = ctx->arrays[aid].base;
-
-       foreach_ssa_src_n(src, i, instr) {
-               unsigned r = i + 1;
-
-               /* skip address / etc (non real sources): */
-               if (r >= instr->regs_count)
-                       break;
-
-               instr_assign(ctx, src, name);
-               name++;
-       }
-
-}
-
-static int block_ra(struct ir3_ra_ctx *ctx, struct ir3_block *block)
-{
-       struct ir3_instruction *n;
-
        /* frag shader inputs get pre-assigned, since we have some
         * constraints/unknowns about setup for some of these regs:
         */
-       if ((ctx->type == SHADER_FRAGMENT) && !block->parent) {
+       if (ctx->type == SHADER_FRAGMENT) {
+               struct ir3 *ir = ctx->ir;
                unsigned i = 0, j;
-               if (ctx->frag_face && (i < block->ninputs) && block->inputs[i]) {
+               if (ctx->frag_face && (i < ir->ninputs) && ir->inputs[i]) {
+                       struct ir3_instruction *instr = ir->inputs[i];
+                       int cls = size_to_class(1, true);
+                       unsigned name = ra_name(ctx, cls, instr);
+                       unsigned reg = ctx->set->gpr_to_ra_reg[cls][0];
+
                        /* if we have frag_face, it gets hr0.x */
-                       instr_assign(ctx, block->inputs[i], REG_HALF | 0);
+                       ra_set_node_reg(ctx->g, name, reg);
                        i += 4;
                }
-               for (j = 0; i < block->ninputs; i++, j++)
-                       if (block->inputs[i])
-                               instr_assign(ctx, block->inputs[i], j);
-       }
 
-       ra_dump_list("-------\n", block->head);
+               for (j = 0; i < ir->ninputs; i++) {
+                       struct ir3_instruction *instr = ir->inputs[i];
+                       if (instr) {
+                               struct ir3_instruction *defn;
+                               int cls, sz, off;
 
-       /* first pass, assign arrays: */
-       for (n = block->head; n && !ctx->error; n = n->next) {
-               if (is_meta(n) && (n->opc == OPC_META_FI) && n->fi.aid) {
-                       debug_assert(!n->cp.left);  /* don't think this should happen */
-                       ra_dump_instr("ASSIGN ARRAY: ", n);
-                       instr_assign_array(ctx, n);
-                       ra_dump_list("-------\n", block->head);
+                               defn = get_definer(instr, &sz, &off);
+                               if (defn == instr) {
+                                       unsigned name, reg;
+
+                                       cls = size_to_class(sz, is_half(defn));
+                                       name = ra_name(ctx, cls, defn);
+                                       reg = ctx->set->gpr_to_ra_reg[cls][j];
+
+                                       ra_set_node_reg(ctx->g, name, reg);
+                                       j += sz;
+                               }
+                       }
                }
        }
 
-       for (n = block->head; n && !ctx->error; n = n->next) {
-               ra_dump_instr("ASSIGN: ", n);
-               instr_alloc_and_assign(ctx, ir3_neighbor_first(n));
-               ra_dump_list("-------\n", block->head);
+       if (!ra_allocate(ctx->g))
+               return -1;
+
+       list_for_each_entry (struct ir3_block, block, &ctx->ir->block_list, node) {
+               ra_block_alloc(ctx, block);
        }
 
-       return ctx->error ? -1 : 0;
+       return 0;
 }
 
-int ir3_block_ra(struct ir3_block *block, enum shader_t type,
+int ir3_ra(struct ir3 *ir, enum shader_t type,
                bool frag_coord, bool frag_face)
 {
-       struct ir3_instruction *n;
        struct ir3_ra_ctx ctx = {
-                       .block = block,
+                       .ir = ir,
                        .type = type,
-                       .frag_coord = frag_coord,
                        .frag_face = frag_face,
+                       .set = ir->compiler->set,
        };
        int ret;
 
-       memset(&ctx.arrays, ~0, sizeof(ctx.arrays));
-
-       /* mark dst registers w/ SSA flag so we can see which
-        * have been assigned so far:
-        * NOTE: we really should set SSA flag consistently on
-        * every dst register in the frontend.
-        */
-       for (n = block->head; n; n = n->next)
-               if (n->regs_count > 0)
-                       n->regs[0]->flags |= IR3_REG_SSA;
-
-       ir3_clear_mark(block->shader);
-       ret = block_ra(&ctx, block);
+       ra_init(&ctx);
+       ra_add_interference(&ctx);
+       ret = ra_alloc(&ctx);
+       ra_destroy(&ctx);
 
        return ret;
 }
index a790cba129be06a0c32fba5b8ba1b102446dcc3a..49a4426d163cf9d8aea6b24e3eef3fa13df8ab77 100644 (file)
 
 #include "ir3.h"
 
-enum {
-       SCHEDULED = -1,
-       DELAYED = -2,
-};
-
 /*
  * Instruction Scheduling:
  *
- * Using the depth sorted list from depth pass, attempt to recursively
- * schedule deepest unscheduled path.  The first instruction that cannot
- * be scheduled, returns the required delay slots it needs, at which
- * point we return back up to the top and attempt to schedule by next
- * highest depth.  After a sufficient number of instructions have been
- * scheduled, return back to beginning of list and start again.  If you
- * reach the end of depth sorted list without being able to insert any
- * instruction, insert nop's.  Repeat until no more unscheduled
- * instructions.
+ * A priority-queue based scheduling algo.  Add eligible instructions,
+ * ie. ones with all their dependencies scheduled, to the priority
+ * (depth) sorted queue (list).  Pop highest priority instruction off
+ * the queue and schedule it, add newly eligible instructions to the
+ * priority queue, rinse, repeat.
  *
  * There are a few special cases that need to be handled, since sched
  * is currently independent of register allocation.  Usages of address
@@ -60,90 +51,33 @@ enum {
  */
 
 struct ir3_sched_ctx {
-       struct ir3_instruction *scheduled; /* last scheduled instr */
+       struct ir3_block *block;           /* the current block */
+       struct ir3_instruction *scheduled; /* last scheduled instr XXX remove*/
        struct ir3_instruction *addr;      /* current a0.x user, if any */
        struct ir3_instruction *pred;      /* current p0.x user, if any */
-       unsigned cnt;
        bool error;
 };
 
-static struct ir3_instruction *
-deepest(struct ir3_instruction **srcs, unsigned nsrcs)
-{
-       struct ir3_instruction *d = NULL;
-       unsigned i = 0, id = 0;
-
-       while ((i < nsrcs) && !(d = srcs[id = i]))
-               i++;
-
-       if (!d)
-               return NULL;
-
-       for (; i < nsrcs; i++)
-               if (srcs[i] && (srcs[i]->depth > d->depth))
-                       d = srcs[id = i];
-
-       srcs[id] = NULL;
-
-       return d;
-}
-
-static unsigned distance(struct ir3_sched_ctx *ctx,
-               struct ir3_instruction *instr, unsigned maxd)
-{
-       struct ir3_instruction *n = ctx->scheduled;
-       unsigned d = 0;
-       while (n && (n != instr) && (d < maxd)) {
-               if (is_alu(n) || is_flow(n))
-                       d++;
-               n = n->next;
-       }
-       return d;
-}
-
-/* TODO maybe we want double linked list? */
-static struct ir3_instruction * prev(struct ir3_instruction *instr)
-{
-       struct ir3_instruction *p = instr->block->head;
-       while (p && (p->next != instr))
-               p = p->next;
-       return p;
-}
-
 static bool is_sfu_or_mem(struct ir3_instruction *instr)
 {
        return is_sfu(instr) || is_mem(instr);
 }
 
-static void schedule(struct ir3_sched_ctx *ctx,
-               struct ir3_instruction *instr, bool remove)
+static void
+schedule(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
 {
-       struct ir3_block *block = instr->block;
+       debug_assert(ctx->block == instr->block);
 
        /* maybe there is a better way to handle this than just stuffing
         * a nop.. ideally we'd know about this constraint in the
         * scheduling and depth calculation..
         */
        if (ctx->scheduled && is_sfu_or_mem(ctx->scheduled) && is_sfu_or_mem(instr))
-               schedule(ctx, ir3_instr_create(block, 0, OPC_NOP), false);
+               ir3_NOP(ctx->block);
 
        /* remove from depth list:
         */
-       if (remove) {
-               struct ir3_instruction *p = prev(instr);
-
-               /* NOTE: this can happen for inputs which are not
-                * read.. in that case there is no need to schedule
-                * the input, so just bail:
-                */
-               if (instr != (p ? p->next : block->head))
-                       return;
-
-               if (p)
-                       p->next = instr->next;
-               else
-                       block->head = instr->next;
-       }
+       list_delinit(&instr->node);
 
        if (writes_addr(instr)) {
                assert(ctx->addr == NULL);
@@ -157,18 +91,30 @@ static void schedule(struct ir3_sched_ctx *ctx,
 
        instr->flags |= IR3_INSTR_MARK;
 
-       instr->next = ctx->scheduled;
+       list_addtail(&instr->node, &instr->block->instr_list);
        ctx->scheduled = instr;
-
-       ctx->cnt++;
 }
 
-/*
- * Delay-slot calculation.  Follows fanin/fanout.
- */
+static unsigned
+distance(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr,
+               unsigned maxd)
+{
+       struct list_head *instr_list = &ctx->block->instr_list;
+       unsigned d = 0;
+
+       list_for_each_entry_rev (struct ir3_instruction, n, instr_list, node) {
+               if ((n == instr) || (d >= maxd))
+                       break;
+               if (is_alu(n) || is_flow(n))
+                       d++;
+       }
+
+       return d;
+}
 
 /* calculate delay for specified src: */
-static unsigned delay_calc_srcn(struct ir3_sched_ctx *ctx,
+static unsigned
+delay_calc_srcn(struct ir3_sched_ctx *ctx,
                struct ir3_instruction *assigner,
                struct ir3_instruction *consumer, unsigned srcn)
 {
@@ -177,7 +123,10 @@ static unsigned delay_calc_srcn(struct ir3_sched_ctx *ctx,
        if (is_meta(assigner)) {
                struct ir3_instruction *src;
                foreach_ssa_src(src, assigner) {
-                       unsigned d = delay_calc_srcn(ctx, src, consumer, srcn);
+                       unsigned d;
+                       if (src->block != assigner->block)
+                               break;
+                       d = delay_calc_srcn(ctx, src, consumer, srcn);
                        delay = MAX2(delay, d);
                }
        } else {
@@ -189,48 +138,87 @@ static unsigned delay_calc_srcn(struct ir3_sched_ctx *ctx,
 }
 
 /* calculate delay for instruction (maximum of delay for all srcs): */
-static unsigned delay_calc(struct ir3_sched_ctx *ctx,
-               struct ir3_instruction *instr)
+static unsigned
+delay_calc(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
 {
        unsigned delay = 0;
        struct ir3_instruction *src;
 
        foreach_ssa_src_n(src, i, instr) {
-               unsigned d = delay_calc_srcn(ctx, src, instr, i);
+               unsigned d;
+               if (src->block != instr->block)
+                       continue;
+               d = delay_calc_srcn(ctx, src, instr, i);
                delay = MAX2(delay, d);
        }
 
        return delay;
 }
 
-/* A negative return value signals that an instruction has been newly
- * SCHEDULED (or DELAYED due to address or predicate register already
- * in use), return back up to the top of the stack (to block_sched())
+struct ir3_sched_notes {
+       /* there is at least one kill which could be scheduled, except
+        * for unscheduled bary.f's:
+        */
+       bool blocked_kill;
+       /* there is at least one instruction that could be scheduled,
+        * except for conflicting address/predicate register usage:
+        */
+       bool addr_conflict, pred_conflict;
+};
+
+static bool is_scheduled(struct ir3_instruction *instr)
+{
+       return !!(instr->flags & IR3_INSTR_MARK);
+}
+
+static bool
+check_conflict(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
+               struct ir3_instruction *instr)
+{
+       /* if this is a write to address/predicate register, and that
+        * register is currently in use, we need to defer until it is
+        * free:
+        */
+       if (writes_addr(instr) && ctx->addr) {
+               assert(ctx->addr != instr);
+               notes->addr_conflict = true;
+               return true;
+       }
+
+       if (writes_pred(instr) && ctx->pred) {
+               assert(ctx->pred != instr);
+               notes->pred_conflict = true;
+               return true;
+       }
+
+       return false;
+}
+
+/* is this instruction ready to be scheduled?  Return negative for not
+ * ready (updating notes if needed), or >= 0 to indicate number of
+ * delay slots needed.
  */
-static int trysched(struct ir3_sched_ctx *ctx,
+static int
+instr_eligibility(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
                struct ir3_instruction *instr)
 {
-       struct ir3_instruction *srcs[64];
        struct ir3_instruction *src;
-       unsigned delay, nsrcs = 0;
+       unsigned delay = 0;
 
-       /* if already scheduled: */
-       if (instr->flags & IR3_INSTR_MARK)
+       /* Phi instructions can have a dependency on something not
+        * scheduled yet (for ex, loops).  But OTOH we don't really
+        * care.  By definition phi's should appear at the top of
+        * the block, and it's sources should be values from the
+        * previously executing block, so they are always ready to
+        * be scheduled:
+        */
+       if (is_meta(instr) && (instr->opc == OPC_META_PHI))
                return 0;
 
-       /* figure out our src's, copy 'em out into an array for sorting: */
        foreach_ssa_src(src, instr) {
-               debug_assert(nsrcs < ARRAY_SIZE(srcs));
-               srcs[nsrcs++] = src;
-       }
-
-       /* for each src register in sorted order:
-        */
-       delay = 0;
-       while ((src = deepest(srcs, nsrcs))) {
-               delay = trysched(ctx, src);
-               if (delay)
-                       return delay;
+               /* if dependency not scheduled, we aren't ready yet: */
+               if (!is_scheduled(src))
+                       return -1;
        }
 
        /* all our dependents are scheduled, figure out if
@@ -255,216 +243,276 @@ static int trysched(struct ir3_sched_ctx *ctx,
         */
        if (is_kill(instr)) {
                struct ir3 *ir = instr->block->shader;
-               unsigned i;
 
-               for (i = 0; i < ir->baryfs_count; i++) {
+               for (unsigned i = 0; i < ir->baryfs_count; i++) {
                        struct ir3_instruction *baryf = ir->baryfs[i];
                        if (baryf->depth == DEPTH_UNUSED)
                                continue;
-                       delay = trysched(ctx, baryf);
-                       if (delay)
-                               return delay;
+                       if (!is_scheduled(baryf)) {
+                               notes->blocked_kill = true;
+                               return -1;
+                       }
                }
        }
 
-       /* if this is a write to address/predicate register, and that
-        * register is currently in use, we need to defer until it is
-        * free:
-        */
-       if (writes_addr(instr) && ctx->addr) {
-               assert(ctx->addr != instr);
-               return DELAYED;
-       }
-       if (writes_pred(instr) && ctx->pred) {
-               assert(ctx->pred != instr);
-               return DELAYED;
-       }
+       if (check_conflict(ctx, notes, instr))
+               return -1;
 
-       schedule(ctx, instr, true);
-       return SCHEDULED;
+       return 0;
 }
 
-static struct ir3_instruction * reverse(struct ir3_instruction *instr)
+/* move eligible instructions to the priority list: */
+static unsigned
+add_eligible_instrs(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
+               struct list_head *prio_queue, struct list_head *unscheduled_list)
 {
-       struct ir3_instruction *reversed = NULL;
-       while (instr) {
-               struct ir3_instruction *next = instr->next;
-               instr->next = reversed;
-               reversed = instr;
-               instr = next;
+       unsigned min_delay = ~0;
+
+       list_for_each_entry_safe (struct ir3_instruction, instr, unscheduled_list, node) {
+               int e = instr_eligibility(ctx, notes, instr);
+               if (e < 0)
+                       continue;
+               min_delay = MIN2(min_delay, e);
+               if (e == 0) {
+                       /* remove from unscheduled list and into priority queue: */
+                       list_delinit(&instr->node);
+                       ir3_insert_by_depth(instr, prio_queue);
+               }
        }
-       return reversed;
-}
 
-static bool uses_current_addr(struct ir3_sched_ctx *ctx,
-               struct ir3_instruction *instr)
-{
-       return instr->address && (ctx->addr == instr->address);
+       return min_delay;
 }
 
-static bool uses_current_pred(struct ir3_sched_ctx *ctx,
-               struct ir3_instruction *instr)
+/* "spill" the address register by remapping any unscheduled
+ * instructions which depend on the current address register
+ * to a clone of the instruction which wrote the address reg.
+ */
+static void
+split_addr(struct ir3_sched_ctx *ctx)
 {
-       struct ir3_instruction *src;
-       foreach_ssa_src(src, instr)
-               if (ctx->pred == src)
-                       return true;
-       return false;
+       struct ir3 *ir = ctx->addr->block->shader;
+       struct ir3_instruction *new_addr = NULL;
+       unsigned i;
+
+       debug_assert(ctx->addr);
+
+       for (i = 0; i < ir->indirects_count; i++) {
+               struct ir3_instruction *indirect = ir->indirects[i];
+
+               /* skip instructions already scheduled: */
+               if (indirect->flags & IR3_INSTR_MARK)
+                       continue;
+
+               /* remap remaining instructions using current addr
+                * to new addr:
+                */
+               if (indirect->address == ctx->addr) {
+                       if (!new_addr) {
+                               new_addr = ir3_instr_clone(ctx->addr);
+                               /* original addr is scheduled, but new one isn't: */
+                               new_addr->flags &= ~IR3_INSTR_MARK;
+                       }
+                       indirect->address = new_addr;
+               }
+       }
+
+       /* all remaining indirects remapped to new addr: */
+       ctx->addr = NULL;
 }
 
-/* when we encounter an instruction that writes to the address register
- * when it is in use, we delay that instruction and try to schedule all
- * other instructions using the current address register:
+/* "spill" the predicate register by remapping any unscheduled
+ * instructions which depend on the current predicate register
+ * to a clone of the instruction which wrote the address reg.
  */
-static int block_sched_undelayed(struct ir3_sched_ctx *ctx,
-               struct ir3_block *block)
+static void
+split_pred(struct ir3_sched_ctx *ctx)
 {
-       struct ir3_instruction *instr = block->head;
-       bool addr_in_use = false;
-       bool pred_in_use = false;
-       bool all_delayed = true;
-       unsigned cnt = ~0, attempted = 0;
-
-       while (instr) {
-               struct ir3_instruction *next = instr->next;
-               bool addr = uses_current_addr(ctx, instr);
-               bool pred = uses_current_pred(ctx, instr);
-
-               if (addr || pred) {
-                       int ret = trysched(ctx, instr);
-
-                       if (ret != DELAYED)
-                               all_delayed = false;
-
-                       if (ret == SCHEDULED)
-                               cnt = 0;
-                       else if (ret > 0)
-                               cnt = MIN2(cnt, ret);
-                       if (addr)
-                               addr_in_use = true;
-                       if (pred)
-                               pred_in_use = true;
-
-                       attempted++;
-               }
+       struct ir3 *ir = ctx->pred->block->shader;
+       struct ir3_instruction *new_pred = NULL;
+       unsigned i;
 
-               instr = next;
-       }
+       debug_assert(ctx->pred);
 
-       if (!addr_in_use)
-               ctx->addr = NULL;
+       for (i = 0; i < ir->predicates_count; i++) {
+               struct ir3_instruction *predicated = ir->predicates[i];
 
-       if (!pred_in_use)
-               ctx->pred = NULL;
+               /* skip instructions already scheduled: */
+               if (predicated->flags & IR3_INSTR_MARK)
+                       continue;
 
-       /* detect if we've gotten ourselves into an impossible situation
-        * and bail if needed
-        */
-       if (all_delayed && (attempted > 0)) {
-               if (pred_in_use) {
-                       /* TODO we probably need to keep a list of instructions
-                        * that reference predicate, similar to indirects
-                        */
-                       ctx->error = true;
-                       return DELAYED;
-               }
-               if (addr_in_use) {
-                       struct ir3 *ir = ctx->addr->block->shader;
-                       struct ir3_instruction *new_addr =
-                                       ir3_instr_clone(ctx->addr);
-                       unsigned i;
-
-                       /* original addr is scheduled, but new one isn't: */
-                       new_addr->flags &= ~IR3_INSTR_MARK;
-
-                       for (i = 0; i < ir->indirects_count; i++) {
-                               struct ir3_instruction *indirect = ir->indirects[i];
-
-                               /* skip instructions already scheduled: */
-                               if (indirect->flags & IR3_INSTR_MARK)
-                                       continue;
-
-                               /* remap remaining instructions using current addr
-                                * to new addr:
-                                */
-                               if (indirect->address == ctx->addr)
-                                       indirect->address = new_addr;
+               /* remap remaining instructions using current pred
+                * to new pred:
+                *
+                * TODO is there ever a case when pred isn't first
+                * (and only) src?
+                */
+               if (ssa(predicated->regs[1]) == ctx->pred) {
+                       if (!new_pred) {
+                               new_pred = ir3_instr_clone(ctx->pred);
+                               /* original pred is scheduled, but new one isn't: */
+                               new_pred->flags &= ~IR3_INSTR_MARK;
                        }
-
-                       /* all remaining indirects remapped to new addr: */
-                       ctx->addr = NULL;
-
-                       /* not really, but this will trigger us to go back to
-                        * main trysched() loop now that we've resolved the
-                        * conflict by duplicating the instr that writes to
-                        * the address register.
-                        */
-                       return SCHEDULED;
+                       predicated->regs[1]->instr = new_pred;
                }
        }
 
-       return cnt;
+       /* all remaining predicated remapped to new pred: */
+       ctx->pred = NULL;
 }
 
-static void block_sched(struct ir3_sched_ctx *ctx, struct ir3_block *block)
+static void
+sched_block(struct ir3_sched_ctx *ctx, struct ir3_block *block)
 {
-       struct ir3_instruction *instr;
+       struct list_head unscheduled_list, prio_queue;
 
-       /* schedule all the shader input's (meta-instr) first so that
-        * the RA step sees that the input registers contain a value
-        * from the start of the shader:
+       ctx->block = block;
+
+       /* move all instructions to the unscheduled list, and
+        * empty the block's instruction list (to which we will
+        * be inserting.
         */
-       if (!block->parent) {
-               unsigned i;
-               for (i = 0; i < block->ninputs; i++) {
-                       struct ir3_instruction *in = block->inputs[i];
-                       if (in)
-                               schedule(ctx, in, true);
+       list_replace(&block->instr_list, &unscheduled_list);
+       list_inithead(&block->instr_list);
+       list_inithead(&prio_queue);
+
+       /* first a pre-pass to schedule all meta:input/phi instructions
+        * (which need to appear first so that RA knows the register is
+        * occupied:
+        */
+       list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node) {
+               if (is_meta(instr) && ((instr->opc == OPC_META_INPUT) ||
+                               (instr->opc == OPC_META_PHI)))
+                       schedule(ctx, instr);
+       }
+
+       while (!(list_empty(&unscheduled_list) &&
+                       list_empty(&prio_queue))) {
+               struct ir3_sched_notes notes = {0};
+               unsigned delay;
+
+               delay = add_eligible_instrs(ctx, &notes, &prio_queue, &unscheduled_list);
+
+               if (!list_empty(&prio_queue)) {
+                       struct ir3_instruction *instr = list_last_entry(&prio_queue,
+                                       struct ir3_instruction, node);
+                       /* ugg, this is a bit ugly, but between the time when
+                        * the instruction became eligible and now, a new
+                        * conflict may have arose..
+                        */
+                       if (check_conflict(ctx, &notes, instr)) {
+                               list_del(&instr->node);
+                               list_addtail(&instr->node, &unscheduled_list);
+                               continue;
+                       }
+
+                       schedule(ctx, instr);
+               } else if (delay == ~0) {
+                       /* nothing available to schedule.. if we are blocked on
+                        * address/predicate register conflict, then break the
+                        * deadlock by cloning the instruction that wrote that
+                        * reg:
+                        */
+                       if (notes.addr_conflict) {
+                               split_addr(ctx);
+                       } else if (notes.pred_conflict) {
+                               split_pred(ctx);
+                       } else {
+                               debug_assert(0);
+                               ctx->error = true;
+                               return;
+                       }
+               } else {
+                       /* and if we run out of instructions that can be scheduled,
+                        * then it is time for nop's:
+                        */
+                       debug_assert(delay <= 6);
+                       while (delay > 0) {
+                               ir3_NOP(block);
+                               delay--;
+                       }
                }
        }
 
-       while ((instr = block->head) && !ctx->error) {
-               /* NOTE: always grab next *before* trysched(), in case the
-                * instruction is actually scheduled (and therefore moved
-                * from depth list into scheduled list)
-                */
-               struct ir3_instruction *next = instr->next;
-               int cnt = trysched(ctx, instr);
+       /* And lastly, insert branch/jump instructions to take us to
+        * the next block.  Later we'll strip back out the branches
+        * that simply jump to next instruction.
+        */
+       if (block->successors[1]) {
+               /* if/else, conditional branches to "then" or "else": */
+               struct ir3_instruction *br;
+               unsigned delay = 6;
 
-               if (cnt == DELAYED)
-                       cnt = block_sched_undelayed(ctx, block);
+               debug_assert(ctx->pred);
+               debug_assert(block->condition);
 
-               /* -1 is signal to return up stack, but to us means same as 0: */
-               cnt = MAX2(0, cnt);
-               cnt += ctx->cnt;
-               instr = next;
+               delay -= distance(ctx, ctx->pred, delay);
 
-               /* if deepest remaining instruction cannot be scheduled, try
-                * the increasingly more shallow instructions until needed
-                * number of delay slots is filled:
-                */
-               while (instr && (cnt > ctx->cnt)) {
-                       next = instr->next;
-                       trysched(ctx, instr);
-                       instr = next;
+               while (delay > 0) {
+                       ir3_NOP(block);
+                       delay--;
                }
 
-               /* and if we run out of instructions that can be scheduled,
-                * then it is time for nop's:
+               /* create "else" branch first (since "then" block should
+                * frequently/always end up being a fall-thru):
+                */
+               br = ir3_BR(block);
+               br->cat0.inv = true;
+               br->cat0.target = block->successors[1];
+
+               /* NOTE: we have to hard code delay of 6 above, since
+                * we want to insert the nop's before constructing the
+                * branch.  Throw in an assert so we notice if this
+                * ever breaks on future generation:
                 */
-               while (cnt > ctx->cnt)
-                       schedule(ctx, ir3_instr_create(block, 0, OPC_NOP), false);
+               debug_assert(ir3_delayslots(ctx->pred, br, 0) == 6);
+
+               br = ir3_BR(block);
+               br->cat0.target = block->successors[0];
+
+       } else if (block->successors[0]) {
+               /* otherwise unconditional jump to next block: */
+               struct ir3_instruction *jmp;
+
+               jmp = ir3_JUMP(block);
+               jmp->cat0.target = block->successors[0];
        }
 
-       /* at this point, scheduled list is in reverse order, so fix that: */
-       block->head = reverse(ctx->scheduled);
+       /* NOTE: if we kept track of the predecessors, we could do a better
+        * job w/ (jp) flags.. every node w/ > predecessor is a join point.
+        * Note that as we eliminate blocks which contain only an unconditional
+        * jump we probably need to propagate (jp) flag..
+        */
 }
 
-int ir3_block_sched(struct ir3_block *block)
+/* this is needed to ensure later RA stage succeeds: */
+static void
+sched_insert_parallel_copies(struct ir3_block *block)
+{
+       list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+               if (is_meta(instr) && (instr->opc == OPC_META_PHI)) {
+                       struct ir3_register *reg;
+                       foreach_src(reg, instr) {
+                               struct ir3_instruction *src = reg->instr;
+                               struct ir3_instruction *mov =
+                                       ir3_MOV(src->block, src, TYPE_U32);
+                               mov->regs[0]->flags |= IR3_REG_PHI_SRC;
+                               mov->regs[0]->instr = instr;
+                               reg->instr = mov;
+                       }
+               }
+       }
+}
+
+int ir3_sched(struct ir3 *ir)
 {
        struct ir3_sched_ctx ctx = {0};
-       ir3_clear_mark(block->shader);
-       block_sched(&ctx, block);
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               sched_insert_parallel_copies(block);
+       }
+       ir3_clear_mark(ir);
+       list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+               sched_block(&ctx, block);
+       }
        if (ctx.error)
                return -1;
        return 0;
index 9bf4e64c7f1f42650306ff003c12aedb66ca3d67..b5b038100cce8c9a3f02ac5b0ad95d1ff2f6736b 100644 (file)
@@ -127,7 +127,7 @@ static void
 assemble_variant(struct ir3_shader_variant *v)
 {
        struct fd_context *ctx = fd_context(v->shader->pctx);
-       uint32_t gpu_id = ir3_shader_gpuid(v->shader);
+       uint32_t gpu_id = v->shader->compiler->gpu_id;
        uint32_t sz, *bin;
 
        bin = ir3_shader_assemble(v, gpu_id);
@@ -146,17 +146,6 @@ assemble_variant(struct ir3_shader_variant *v)
        v->ir = NULL;
 }
 
-/* reset before attempting to compile again.. */
-static void reset_variant(struct ir3_shader_variant *v, const char *msg)
-{
-       debug_error(msg);
-       v->inputs_count = 0;
-       v->outputs_count = 0;
-       v->total_in = 0;
-       v->has_samp = false;
-       v->immediates_count = 0;
-}
-
 static struct ir3_shader_variant *
 create_variant(struct ir3_shader *shader, struct ir3_shader_key key)
 {
@@ -177,22 +166,7 @@ create_variant(struct ir3_shader *shader, struct ir3_shader_key key)
                tgsi_dump(tokens, 0);
        }
 
-       if (fd_mesa_debug & FD_DBG_NIR) {
-               ret = ir3_compile_shader_nir(v, tokens, key);
-               if (ret)
-                       reset_variant(v, "NIR compiler failed, fallback to TGSI!");
-       } else {
-               ret = -1;
-       }
-
-       if (ret) {
-               ret = ir3_compile_shader(v, tokens, key, true);
-               if (ret) {
-                       reset_variant(v, "new compiler failed, trying without copy propagation!");
-                       ret = ir3_compile_shader(v, tokens, key, false);
-               }
-       }
-
+       ret = ir3_compile_shader_nir(shader->compiler, v, tokens, key);
        if (ret) {
                debug_error("compile failed!");
                goto fail;
@@ -217,13 +191,6 @@ fail:
        return NULL;
 }
 
-uint32_t
-ir3_shader_gpuid(struct ir3_shader *shader)
-{
-       struct fd_context *ctx = fd_context(shader->pctx);
-       return ctx->screen->gpu_id;
-}
-
 struct ir3_shader_variant *
 ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
 {
@@ -286,6 +253,7 @@ ir3_shader_create(struct pipe_context *pctx, const struct tgsi_token *tokens,
                enum shader_t type)
 {
        struct ir3_shader *shader = CALLOC_STRUCT(ir3_shader);
+       shader->compiler = fd_context(pctx)->screen->compiler;
        shader->pctx = pctx;
        shader->type = type;
        shader->tokens = tgsi_dup_tokens(tokens);
index e5410bf88b292da228ef8c2a0f62207a95b14d21..9f1b076918080a4b7dec025ad56f6d118e051f7a 100644 (file)
@@ -86,10 +86,6 @@ struct ir3_shader_key {
         * shader:
         */
        uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
-
-       /* bitmask of sampler which produces integer outputs:
-        */
-       uint16_t vinteger_s, finteger_s;
 };
 
 static inline bool
@@ -196,6 +192,8 @@ struct ir3_shader_variant {
 struct ir3_shader {
        enum shader_t type;
 
+       struct ir3_compiler *compiler;
+
        struct pipe_context *pctx;
        const struct tgsi_token *tokens;
 
@@ -212,7 +210,6 @@ void * ir3_shader_assemble(struct ir3_shader_variant *v, uint32_t gpu_id);
 struct ir3_shader * ir3_shader_create(struct pipe_context *pctx,
                const struct tgsi_token *tokens, enum shader_t type);
 void ir3_shader_destroy(struct ir3_shader *shader);
-uint32_t ir3_shader_gpuid(struct ir3_shader *shader);
 struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
                struct ir3_shader_key key);
 
@@ -220,6 +217,8 @@ struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
  * Helper/util:
  */
 
+#include "pipe/p_shader_tokens.h"
+
 static inline int
 ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
 {
index e0134a7c4ee4ed3cf3153349a5010c31d5c8eaf3..83bb64918d4f92aa55adf277696aaf16cbf6a0bf 100644 (file)
@@ -552,7 +552,7 @@ static boolean i915_fpc_useless_mov(union tgsi_full_token *tgsi_current)
    if ( current.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION  &&
         current.FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV &&
         op_has_dst(current.FullInstruction.Instruction.Opcode) &&
-        current.FullInstruction.Instruction.Saturate == TGSI_SAT_NONE &&
+        !current.FullInstruction.Instruction.Saturate &&
         current.FullInstruction.Src[0].Register.Absolute == 0 &&
         current.FullInstruction.Src[0].Register.Negate == 0 &&
         is_unswizzled(&current.FullInstruction.Src[0], current.FullInstruction.Dst[0].Register.WriteMask) &&
@@ -582,7 +582,7 @@ static void i915_fpc_optimize_useless_mov_after_inst(struct i915_optimize_contex
         next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION  &&
         next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV &&
         op_has_dst(current->FullInstruction.Instruction.Opcode) &&
-        next->FullInstruction.Instruction.Saturate == TGSI_SAT_NONE &&
+        !next->FullInstruction.Instruction.Saturate &&
         next->FullInstruction.Src[0].Register.Absolute == 0 &&
         next->FullInstruction.Src[0].Register.Negate == 0 &&
         unused_from(ctx, &current->FullInstruction.Dst[0], index) &&
index b74f8239bb4d8b5c4e2c3b31363a4b83d680b48c..38a3388816673f67e0290bcd1b5406e819bdb6dc 100644 (file)
@@ -329,7 +329,7 @@ get_result_flags(const struct i915_full_instruction *inst)
       = inst->Dst[0].Register.WriteMask;
    uint flags = 0x0;
 
-   if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE)
+   if (inst->Instruction.Saturate)
       flags |= A0_DEST_SATURATE;
 
    if (writeMask & TGSI_WRITEMASK_X)
index 7216160bb22674a825d33f3d0d9da0ab7e47f09e..0590da07b9a71ba5317a7640eac0e5c24d660acf 100644 (file)
@@ -165,6 +165,7 @@ i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_sha
       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
          return 0;
       default:
          debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
@@ -241,6 +242,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
 
    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
index 91a6f65f2e9d269855795f226f548795e0804d47..e1bbb9a0781db7ccb8cd931e138269d61b68f7f3 100644 (file)
@@ -15,14 +15,34 @@ C_SOURCES := \
        core/ilo_debug.h \
        core/ilo_dev.c \
        core/ilo_dev.h \
-       core/ilo_format.c \
-       core/ilo_format.h \
-       core/ilo_fence.h \
        core/ilo_image.c \
        core/ilo_image.h \
-       core/ilo_state_3d.h \
-       core/ilo_state_3d_bottom.c \
-       core/ilo_state_3d_top.c \
+       core/ilo_state_cc.c \
+       core/ilo_state_cc.h \
+       core/ilo_state_compute.c \
+       core/ilo_state_compute.h \
+       core/ilo_state_raster.c \
+       core/ilo_state_raster.h \
+       core/ilo_state_sampler.c \
+       core/ilo_state_sampler.h \
+       core/ilo_state_sbe.c \
+       core/ilo_state_sbe.h \
+       core/ilo_state_shader.c \
+       core/ilo_state_shader_ps.c \
+       core/ilo_state_shader.h \
+       core/ilo_state_sol.c \
+       core/ilo_state_sol.h \
+       core/ilo_state_surface.c \
+       core/ilo_state_surface_format.c \
+       core/ilo_state_surface.h \
+       core/ilo_state_urb.c \
+       core/ilo_state_urb.h \
+       core/ilo_state_vf.c \
+       core/ilo_state_vf.h \
+       core/ilo_state_viewport.c \
+       core/ilo_state_viewport.h \
+       core/ilo_state_zs.c \
+       core/ilo_state_zs.h \
        core/intel_winsys.h \
        ilo_blit.c \
        ilo_blit.h \
@@ -38,6 +58,8 @@ C_SOURCES := \
        ilo_cp.h \
        ilo_draw.c \
        ilo_draw.h \
+       ilo_format.c \
+       ilo_format.h \
        ilo_gpgpu.c \
        ilo_gpgpu.h \
        ilo_public.h \
index 50f97d10bd71345e8015ab212eac560b495d2e24..ca3c61ff89026dbcf603360ee5b4186f1d1fe6b0 100644 (file)
 #include "intel_winsys.h"
 
 #include "ilo_core.h"
+#include "ilo_debug.h"
 #include "ilo_dev.h"
 
 struct ilo_buffer {
    unsigned bo_size;
 
+   /* managed by users */
    struct intel_bo *bo;
 };
 
@@ -43,6 +45,8 @@ static inline void
 ilo_buffer_init(struct ilo_buffer *buf, const struct ilo_dev *dev,
                 unsigned size, uint32_t bind, uint32_t flags)
 {
+   assert(ilo_is_zeroed(buf, sizeof(*buf)));
+
    buf->bo_size = size;
 
    /*
@@ -55,36 +59,6 @@ ilo_buffer_init(struct ilo_buffer *buf, const struct ilo_dev *dev,
     */
    if (bind & PIPE_BIND_SAMPLER_VIEW)
       buf->bo_size = align(buf->bo_size, 256) + 16;
-
-   if ((bind & PIPE_BIND_VERTEX_BUFFER) && ilo_dev_gen(dev) < ILO_GEN(7.5)) {
-      /*
-       * As noted in ilo_format_translate(), we treat some 3-component formats
-       * as 4-component formats to work around hardware limitations.  Imagine
-       * the case where the vertex buffer holds a single
-       * PIPE_FORMAT_R16G16B16_FLOAT vertex, and buf->bo_size is 6.  The
-       * hardware would fail to fetch it at boundary check because the vertex
-       * buffer is expected to hold a PIPE_FORMAT_R16G16B16A16_FLOAT vertex
-       * and that takes at least 8 bytes.
-       *
-       * For the workaround to work, we should add 2 to the bo size.  But that
-       * would waste a page when the bo size is already page aligned.  Let's
-       * round it to page size for now and revisit this when needed.
-       */
-      buf->bo_size = align(buf->bo_size, 4096);
-   }
-}
-
-static inline void
-ilo_buffer_cleanup(struct ilo_buffer *buf)
-{
-   intel_bo_unref(buf->bo);
-}
-
-static inline void
-ilo_buffer_set_bo(struct ilo_buffer *buf, struct intel_bo *bo)
-{
-   intel_bo_unref(buf->bo);
-   buf->bo = intel_bo_ref(bo);
 }
 
 #endif /* ILO_BUFFER_H */
index 3c5eef9bcbc5b24d0cc746453f17662670362a10..4e05a3aca1e6e6fb154662943b25cc4db75ba47b 100644 (file)
@@ -333,7 +333,7 @@ ilo_builder_init(struct ilo_builder *builder,
 {
    int i;
 
-   memset(builder, 0, sizeof(*builder));
+   assert(ilo_is_zeroed(builder, sizeof(*builder)));
 
    builder->dev = dev;
    builder->winsys = winsys;
index 6cf1732ee1cd7a14c56678b4a6e006418502e8b5..fb8b53cbe230dd22e45b6148da07569790a50df5 100644 (file)
 #include "ilo_builder_3d_top.h"
 #include "ilo_builder_3d_bottom.h"
 
+struct gen6_3dprimitive_info {
+   enum gen_3dprim_type topology;
+   bool indexed;
+
+   uint32_t vertex_count;
+   uint32_t vertex_start;
+   uint32_t instance_count;
+   uint32_t instance_start;
+   int32_t vertex_base;
+};
+
 static inline void
 gen6_3DPRIMITIVE(struct ilo_builder *builder,
-                 const struct pipe_draw_info *info,
-                 const struct ilo_ib_state *ib)
+                 const struct gen6_3dprimitive_info *info)
 {
    const uint8_t cmd_len = 6;
-   const int prim = gen6_3d_translate_pipe_prim(info->mode);
-   const int vb_access = (info->indexed) ?
-      GEN6_3DPRIM_DW0_ACCESS_RANDOM : GEN6_3DPRIM_DW0_ACCESS_SEQUENTIAL;
-   const uint32_t vb_start = info->start +
-      ((info->indexed) ? ib->draw_start_offset : 0);
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 6);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) |
-           vb_access |
-           prim << GEN6_3DPRIM_DW0_TYPE__SHIFT |
-           (cmd_len - 2);
-   dw[1] = info->count;
-   dw[2] = vb_start;
+   dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) | (cmd_len - 2) |
+           info->topology << GEN6_3DPRIM_DW0_TYPE__SHIFT;
+   if (info->indexed)
+      dw[0] |= GEN6_3DPRIM_DW0_ACCESS_RANDOM;
+
+   dw[1] = info->vertex_count;
+   dw[2] = info->vertex_start;
    dw[3] = info->instance_count;
-   dw[4] = info->start_instance;
-   dw[5] = info->index_bias;
+   dw[4] = info->instance_start;
+   dw[5] = info->vertex_base;
 }
 
 static inline void
 gen7_3DPRIMITIVE(struct ilo_builder *builder,
-                 const struct pipe_draw_info *info,
-                 const struct ilo_ib_state *ib)
+                 const struct gen6_3dprimitive_info *info)
 {
    const uint8_t cmd_len = 7;
-   const int prim = gen6_3d_translate_pipe_prim(info->mode);
-   const int vb_access = (info->indexed) ?
-      GEN7_3DPRIM_DW1_ACCESS_RANDOM : GEN7_3DPRIM_DW1_ACCESS_SEQUENTIAL;
-   const uint32_t vb_start = info->start +
-      ((info->indexed) ? ib->draw_start_offset : 0);
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 7, 8);
@@ -81,12 +81,16 @@ gen7_3DPRIMITIVE(struct ilo_builder *builder,
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) | (cmd_len - 2);
-   dw[1] = vb_access | prim;
-   dw[2] = info->count;
-   dw[3] = vb_start;
+
+   dw[1] = info->topology << GEN7_3DPRIM_DW1_TYPE__SHIFT;
+   if (info->indexed)
+      dw[1] |= GEN7_3DPRIM_DW1_ACCESS_RANDOM;
+
+   dw[2] = info->vertex_count;
+   dw[3] = info->vertex_start;
    dw[4] = info->instance_count;
-   dw[5] = info->start_instance;
-   dw[6] = info->index_bias;
+   dw[5] = info->instance_start;
+   dw[6] = info->vertex_base;
 }
 
 #endif /* ILO_BUILDER_3D_H */
index 16ec4afd15b76767bf6a9956ed6d5949e30464c3..6d9e369912562788c8d28046f33cf667485b1c4c 100644 (file)
 #define ILO_BUILDER_3D_BOTTOM_H
 
 #include "genhw/genhw.h"
-#include "../ilo_shader.h"
 #include "intel_winsys.h"
 
 #include "ilo_core.h"
 #include "ilo_dev.h"
-#include "ilo_format.h"
+#include "ilo_state_cc.h"
+#include "ilo_state_raster.h"
+#include "ilo_state_sbe.h"
+#include "ilo_state_shader.h"
+#include "ilo_state_viewport.h"
+#include "ilo_state_zs.h"
 #include "ilo_builder.h"
 #include "ilo_builder_3d_top.h"
 
 static inline void
 gen6_3DSTATE_CLIP(struct ilo_builder *builder,
-                  const struct ilo_rasterizer_state *rasterizer,
-                  const struct ilo_shader_state *fs,
-                  bool enable_guardband,
-                  int num_viewports)
-{
-   const uint8_t cmd_len = 4;
-   uint32_t dw1, dw2, dw3, *dw;
-   int interps;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 8);
-
-   dw1 = rasterizer->clip.payload[0];
-   dw2 = rasterizer->clip.payload[1];
-   dw3 = rasterizer->clip.payload[2];
-
-   if (enable_guardband && rasterizer->clip.can_enable_guardband)
-      dw2 |= GEN6_CLIP_DW2_GB_TEST_ENABLE;
-
-   interps = (fs) ?  ilo_shader_get_kernel_param(fs,
-         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) : 0;
-
-   if (interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
-                  GEN6_INTERP_NONPERSPECTIVE_CENTROID |
-                  GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
-      dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
-
-   dw3 |= GEN6_CLIP_DW3_RTAINDEX_FORCED_ZERO |
-          (num_viewports - 1);
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) | (cmd_len - 2);
-   dw[1] = dw1;
-   dw[2] = dw2;
-   dw[3] = dw3;
-}
-
-static inline void
-gen6_disable_3DSTATE_CLIP(struct ilo_builder *builder)
+                  const struct ilo_state_raster *rs)
 {
    const uint8_t cmd_len = 4;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+   ILO_DEV_ASSERT(builder->dev, 6, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
-}
-
-static inline void
-gen7_internal_3dstate_sf(struct ilo_builder *builder,
-                         uint8_t cmd_len, uint32_t *dw,
-                         const struct ilo_rasterizer_sf *sf,
-                         int num_samples)
-{
-   ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
-   assert(cmd_len == 7);
-
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
-
-   if (!sf) {
-      dw[1] = 0;
-      dw[2] = (num_samples > 1) ? GEN7_SF_DW2_MSRASTMODE_ON_PATTERN : 0;
-      dw[3] = 0;
-      dw[4] = 0;
-      dw[5] = 0;
-      dw[6] = 0;
-
-      return;
-   }
-
-   /* see rasterizer_init_sf_gen6() */
-   STATIC_ASSERT(Elements(sf->payload) >= 3);
-   dw[1] = sf->payload[0];
-   dw[2] = sf->payload[1];
-   dw[3] = sf->payload[2];
-
-   if (num_samples > 1)
-      dw[2] |= sf->dw_msaa;
-
-   dw[4] = sf->dw_depth_offset_const;
-   dw[5] = sf->dw_depth_offset_scale;
-   dw[6] = sf->dw_depth_offset_clamp;
-}
-
-static inline void
-gen8_internal_3dstate_sbe(struct ilo_builder *builder,
-                          uint8_t cmd_len, uint32_t *dw,
-                          const struct ilo_shader_state *fs,
-                          int sprite_coord_mode)
-{
-   const struct ilo_kernel_routing *routing;
-   int vue_offset, vue_len, out_count;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 8);
-
-   assert(cmd_len == 4);
-
-   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
-
-   if (!fs) {
-      dw[1] = 1 << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
-      dw[2] = 0;
-      dw[3] = 0;
-      return;
-   }
-
-   routing = ilo_shader_get_kernel_routing(fs);
-
-   vue_offset = routing->source_skip;
-   assert(vue_offset % 2 == 0);
-   vue_offset /= 2;
-
-   vue_len = (routing->source_len + 1) / 2;
-   if (!vue_len)
-      vue_len = 1;
-
-   out_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT);
-   assert(out_count <= 32);
-
-   dw[1] = out_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
-           vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
-
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[1] |= GEN8_SBE_DW1_USE_URB_READ_LEN |
-               GEN8_SBE_DW1_USE_URB_READ_OFFSET |
-               vue_offset << GEN8_SBE_DW1_URB_READ_OFFSET__SHIFT;
-   } else {
-      dw[1] |= vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
-   }
-
-   if (routing->swizzle_enable)
-      dw[1] |= GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE;
-
-   switch (sprite_coord_mode) {
-   case PIPE_SPRITE_COORD_UPPER_LEFT:
-      dw[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_UPPERLEFT;
-      break;
-   case PIPE_SPRITE_COORD_LOWER_LEFT:
-      dw[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_LOWERLEFT;
-      break;
-   }
-
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 268:
-    *
-    *     "This field (Point Sprite Texture Coordinate Enable) must be
-    *      programmed to 0 when non-point primitives are rendered."
-    *
-    * TODO We do not check that yet.
-    */
-   dw[2] = routing->point_sprite_enable;
-
-   dw[3] = routing->const_interp_enable;
-}
-
-static inline void
-gen8_internal_3dstate_sbe_swiz(struct ilo_builder *builder,
-                               uint8_t cmd_len, uint32_t *dw,
-                               const struct ilo_shader_state *fs)
-{
-   const struct ilo_kernel_routing *routing;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 8);
-
-   assert(cmd_len == 11);
-
-   dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SBE_SWIZ) | (cmd_len - 2);
-
-   if (!fs) {
-      memset(&dw[1], 0, sizeof(*dw) * (cmd_len - 1));
-      return;
-   }
-
-   routing = ilo_shader_get_kernel_routing(fs);
-
-   STATIC_ASSERT(sizeof(routing->swizzles) >= sizeof(*dw) * 8);
-   memcpy(&dw[1], routing->swizzles, sizeof(*dw) * 8);
-
-   /* WrapShortest enables */
-   dw[9] = 0;
-   dw[10] = 0;
+   /* see raster_set_gen6_3DSTATE_CLIP() */
+   dw[1] = rs->clip[0];
+   dw[2] = rs->clip[1];
+   dw[3] = rs->clip[2];
 }
 
 static inline void
 gen6_3DSTATE_SF(struct ilo_builder *builder,
-                const struct ilo_rasterizer_state *rasterizer,
-                const struct ilo_shader_state *fs,
-                int sample_count)
+                const struct ilo_state_raster *rs,
+                const struct ilo_state_sbe *sbe)
 {
    const uint8_t cmd_len = 20;
-   uint32_t gen8_3dstate_sbe[4], gen8_3dstate_sbe_swiz[11];
-   uint32_t gen7_3dstate_sf[7];
-   const struct ilo_rasterizer_sf *sf;
-   int sprite_coord_mode;
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 6);
 
-   sf = (rasterizer) ? &rasterizer->sf : NULL;
-   sprite_coord_mode = (rasterizer) ? rasterizer->state.sprite_coord_mode : 0;
-
-   gen8_internal_3dstate_sbe(builder, Elements(gen8_3dstate_sbe),
-         gen8_3dstate_sbe, fs, sprite_coord_mode);
-   gen8_internal_3dstate_sbe_swiz(builder, Elements(gen8_3dstate_sbe_swiz),
-         gen8_3dstate_sbe_swiz, fs);
-   gen7_internal_3dstate_sf(builder, Elements(gen7_3dstate_sf),
-         gen7_3dstate_sf, sf, sample_count);
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
-   dw[1] = gen8_3dstate_sbe[1];
-   memcpy(&dw[2], &gen7_3dstate_sf[1], sizeof(*dw) * 6);
-   memcpy(&dw[8], &gen8_3dstate_sbe_swiz[1], sizeof(*dw) * 8);
-   dw[16] = gen8_3dstate_sbe[2];
-   dw[17] = gen8_3dstate_sbe[3];
-   dw[18] = gen8_3dstate_sbe_swiz[9];
-   dw[19] = gen8_3dstate_sbe_swiz[10];
+   /* see sbe_set_gen8_3DSTATE_SBE() */
+   dw[1] = sbe->sbe[0];
+
+   /* see raster_set_gen7_3DSTATE_SF() */
+   dw[2] = rs->sf[0];
+   dw[3] = rs->sf[1];
+   dw[4] = rs->sf[2];
+   dw[5] = rs->raster[1];
+   dw[6] = rs->raster[2];
+   dw[7] = rs->raster[3];
+
+   /* see sbe_set_gen8_3DSTATE_SBE_SWIZ() */
+   memcpy(&dw[8], sbe->swiz, sizeof(*dw) * 8);
+
+   dw[16] = sbe->sbe[1];
+   dw[17] = sbe->sbe[2];
+   /* WrapShortest enables */
+   dw[18] = 0;
+   dw[19] = 0;
 }
 
 static inline void
 gen7_3DSTATE_SF(struct ilo_builder *builder,
-                const struct ilo_rasterizer_sf *sf,
-                enum pipe_format zs_format,
-                int sample_count)
+                const struct ilo_state_raster *rs)
 {
-   const uint8_t cmd_len = 7;
+   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 7;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
-   gen7_internal_3dstate_sf(builder, cmd_len, dw, sf, sample_count);
-
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
-      int hw_format;
-
-      /* separate stencil */
-      switch (zs_format) {
-      case PIPE_FORMAT_Z16_UNORM:
-         hw_format = GEN6_ZFORMAT_D16_UNORM;
-         break;
-      case PIPE_FORMAT_Z32_FLOAT:
-      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-         hw_format = GEN6_ZFORMAT_D32_FLOAT;
-         break;
-      case PIPE_FORMAT_Z24X8_UNORM:
-      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-         hw_format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
-         break;
-      default:
-         /* FLOAT surface is assumed when there is no depth buffer */
-         hw_format = GEN6_ZFORMAT_D32_FLOAT;
-         break;
-      }
-
-      dw[1] |= hw_format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT;
-   }
-}
-
-static inline void
-gen8_3DSTATE_SF(struct ilo_builder *builder,
-                const struct ilo_rasterizer_sf *sf)
-{
-   const uint8_t cmd_len = 4;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 8, 8);
+   ILO_DEV_ASSERT(builder->dev, 7, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
 
-   /* see rasterizer_init_sf_gen8() */
-   STATIC_ASSERT(Elements(sf->payload) >= 3);
-   dw[1] = sf->payload[0];
-   dw[2] = sf->payload[1];
-   dw[3] = sf->payload[2];
+   /* see raster_set_gen7_3DSTATE_SF() or raster_set_gen8_3DSTATE_SF() */
+   dw[1] = rs->sf[0];
+   dw[2] = rs->sf[1];
+   dw[3] = rs->sf[2];
+   if (ilo_dev_gen(builder->dev) < ILO_GEN(8)) {
+      dw[4] = rs->raster[1];
+      dw[5] = rs->raster[2];
+      dw[6] = rs->raster[3];
+   }
 }
 
 static inline void
 gen7_3DSTATE_SBE(struct ilo_builder *builder,
-                 const struct ilo_shader_state *fs,
-                 int sprite_coord_mode)
+                 const struct ilo_state_sbe *sbe)
 {
    const uint8_t cmd_len = 14;
-   uint32_t gen8_3dstate_sbe[4], gen8_3dstate_sbe_swiz[11];
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
-   gen8_internal_3dstate_sbe(builder, Elements(gen8_3dstate_sbe),
-         gen8_3dstate_sbe, fs, sprite_coord_mode);
-   gen8_internal_3dstate_sbe_swiz(builder, Elements(gen8_3dstate_sbe_swiz),
-         gen8_3dstate_sbe_swiz, fs);
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
-   dw[1] = gen8_3dstate_sbe[1];
-   memcpy(&dw[2], &gen8_3dstate_sbe_swiz[1], sizeof(*dw) * 8);
-   dw[10] = gen8_3dstate_sbe[2];
-   dw[11] = gen8_3dstate_sbe[3];
-   dw[12] = gen8_3dstate_sbe_swiz[9];
-   dw[13] = gen8_3dstate_sbe_swiz[10];
+   /* see sbe_set_gen8_3DSTATE_SBE() and sbe_set_gen8_3DSTATE_SBE_SWIZ() */
+   dw[1] = sbe->sbe[0];
+   memcpy(&dw[2], sbe->swiz, sizeof(*dw) * 8);
+   dw[10] = sbe->sbe[1];
+   dw[11] = sbe->sbe[2];
+
+   /* WrapShortest enables */
+   dw[12] = 0;
+   dw[13] = 0;
 }
 
 static inline void
 gen8_3DSTATE_SBE(struct ilo_builder *builder,
-                 const struct ilo_shader_state *fs,
-                 int sprite_coord_mode)
+                 const struct ilo_state_sbe *sbe)
 {
    const uint8_t cmd_len = 4;
    uint32_t *dw;
@@ -366,12 +152,16 @@ gen8_3DSTATE_SBE(struct ilo_builder *builder,
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   gen8_internal_3dstate_sbe(builder, cmd_len, dw, fs, sprite_coord_mode);
+   /* see sbe_set_gen8_3DSTATE_SBE() */
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
+   dw[1] = sbe->sbe[0];
+   dw[2] = sbe->sbe[1];
+   dw[3] = sbe->sbe[2];
 }
 
 static inline void
 gen8_3DSTATE_SBE_SWIZ(struct ilo_builder *builder,
-                      const struct ilo_shader_state *fs)
+                      const struct ilo_state_sbe *sbe)
 {
    const uint8_t cmd_len = 11;
    uint32_t *dw;
@@ -380,12 +170,17 @@ gen8_3DSTATE_SBE_SWIZ(struct ilo_builder *builder,
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   gen8_internal_3dstate_sbe_swiz(builder, cmd_len, dw, fs);
+   dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SBE_SWIZ) | (cmd_len - 2);
+   /* see sbe_set_gen8_3DSTATE_SBE_SWIZ() */
+   memcpy(&dw[1], sbe->swiz, sizeof(*dw) * 8);
+   /* WrapShortest enables */
+   dw[9] = 0;
+   dw[10] = 0;
 }
 
 static inline void
 gen8_3DSTATE_RASTER(struct ilo_builder *builder,
-                    const struct ilo_rasterizer_sf *sf)
+                    const struct ilo_state_raster *rs)
 {
    const uint8_t cmd_len = 5;
    uint32_t *dw;
@@ -395,232 +190,108 @@ gen8_3DSTATE_RASTER(struct ilo_builder *builder,
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_RASTER) | (cmd_len - 2);
-   dw[1] = sf->dw_raster;
-   dw[2] = sf->dw_depth_offset_const;
-   dw[3] = sf->dw_depth_offset_scale;
-   dw[4] = sf->dw_depth_offset_clamp;
+   /* see raster_set_gen8_3DSTATE_RASTER() */
+   dw[1] = rs->raster[0];
+   dw[2] = rs->raster[1];
+   dw[3] = rs->raster[2];
+   dw[4] = rs->raster[3];
 }
 
 static inline void
 gen6_3DSTATE_WM(struct ilo_builder *builder,
-                const struct ilo_shader_state *fs,
-                const struct ilo_rasterizer_state *rasterizer,
-                bool dual_blend, bool cc_may_kill)
+                const struct ilo_state_raster *rs,
+                const struct ilo_state_ps *ps,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 9;
-   const int num_samples = 1;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw2, dw4, dw5, dw6, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 6);
 
-   cso = ilo_shader_get_kernel_cso(fs);
-   dw2 = cso->payload[0];
-   dw4 = cso->payload[1];
-   dw5 = cso->payload[2];
-   dw6 = cso->payload[3];
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 248:
-    *
-    *     "This bit (Statistics Enable) must be disabled if either of these
-    *      bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve
-    *      Enable or Depth Buffer Resolve Enable."
-    */
-   dw4 |= GEN6_WM_DW4_STATISTICS;
-
-   if (cc_may_kill)
-      dw5 |= GEN6_WM_DW5_PS_KILL_PIXEL | GEN6_WM_DW5_PS_DISPATCH_ENABLE;
-
-   if (dual_blend)
-      dw5 |= GEN6_WM_DW5_PS_DUAL_SOURCE_BLEND;
-
-   dw5 |= rasterizer->wm.payload[0];
-
-   dw6 |= rasterizer->wm.payload[1];
-
-   if (num_samples > 1) {
-      dw6 |= rasterizer->wm.dw_msaa_rast |
-             rasterizer->wm.dw_msaa_disp;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(fs);
-   dw[2] = dw2;
-   dw[3] = 0; /* scratch */
-   dw[4] = dw4;
-   dw[5] = dw5;
-   dw[6] = dw6;
+   dw[1] = kernel_offset;
+   /* see raster_set_gen6_3dstate_wm() and ps_set_gen6_3dstate_wm() */
+   dw[2] = ps->ps[0];
+   dw[3] = ps->ps[1];
+   dw[4] = rs->wm[0] | ps->ps[2];
+   dw[5] = rs->wm[1] | ps->ps[3];
+   dw[6] = rs->wm[2] | ps->ps[4];
    dw[7] = 0; /* kernel 1 */
    dw[8] = 0; /* kernel 2 */
 }
 
-static inline void
-gen6_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
-{
-   const uint8_t cmd_len = 9;
-   const int max_threads = (builder->dev->gt == 2) ? 80 : 40;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 6);
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
-   dw[4] = hiz_op;
-   /* honor the valid range even if dispatching is disabled */
-   dw[5] = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT;
-   dw[6] = 0;
-   dw[7] = 0;
-   dw[8] = 0;
-}
-
 static inline void
 gen7_3DSTATE_WM(struct ilo_builder *builder,
-                const struct ilo_shader_state *fs,
-                const struct ilo_rasterizer_state *rasterizer,
-                bool cc_may_kill)
+                const struct ilo_state_raster *rs,
+                const struct ilo_state_ps *ps)
 {
    const uint8_t cmd_len = 3;
-   const int num_samples = 1;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw1, dw2, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
-   /* see rasterizer_init_wm_gen7() */
-   dw1 = rasterizer->wm.payload[0];
-   dw2 = rasterizer->wm.payload[1];
-
-   /* see fs_init_cso_gen7() */
-   cso = ilo_shader_get_kernel_cso(fs);
-   dw1 |= cso->payload[3];
-
-   dw1 |= GEN7_WM_DW1_STATISTICS;
-
-   if (cc_may_kill)
-      dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE | GEN7_WM_DW1_PS_KILL_PIXEL;
-
-   if (num_samples > 1) {
-      dw1 |= rasterizer->wm.dw_msaa_rast;
-      dw2 |= rasterizer->wm.dw_msaa_disp;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
-   dw[1] = dw1;
-   dw[2] = dw2;
+   /* see raster_set_gen8_3DSTATE_WM() and ps_set_gen7_3dstate_wm() */
+   dw[1] = rs->wm[0] | ps->ps[0];
+   dw[2] = ps->ps[1];
 }
 
 static inline void
 gen8_3DSTATE_WM(struct ilo_builder *builder,
-                const struct ilo_shader_state *fs,
-                const struct ilo_rasterizer_state *rasterizer)
+                const struct ilo_state_raster *rs)
 {
    const uint8_t cmd_len = 2;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw1, interps, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   /* see rasterizer_get_wm_gen8() */
-   dw1 = rasterizer->wm.payload[0];
-   dw1 |= GEN7_WM_DW1_STATISTICS;
-
-   /* see fs_init_cso_gen8() */
-   cso = ilo_shader_get_kernel_cso(fs);
-   interps = cso->payload[4];
-
-   assert(!(dw1 & interps));
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
-   dw[1] = dw1 | interps;
-}
-
-static inline void
-gen7_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
-{
-   const uint8_t cmd_len = 3;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
-   dw[1] = hiz_op;
-   dw[2] = 0;
+   /* see raster_set_gen8_3DSTATE_WM() */
+   dw[1] = rs->wm[0];
 }
 
 static inline void
 gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_builder *builder,
-                              const struct ilo_dsa_state *dsa)
+                              const struct ilo_state_cc *cc)
 {
    const uint8_t cmd_len = 3;
-   uint32_t dw1, dw2, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   dw1 = dsa->payload[0];
-   dw2 = dsa->payload[1];
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_DEPTH_STENCIL) | (cmd_len - 2);
-   dw[1] = dw1;
-   dw[2] = dw2;
+   /* see cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL() */
+   dw[1] = cc->ds[0];
+   dw[2] = cc->ds[1];
 }
 
 static inline void
-gen8_3DSTATE_WM_HZ_OP(struct ilo_builder *builder, uint32_t op,
-                      uint16_t width, uint16_t height, int sample_count)
+gen8_3DSTATE_WM_HZ_OP(struct ilo_builder *builder,
+                      const struct ilo_state_raster *rs,
+                      uint16_t width, uint16_t height)
 {
    const uint8_t cmd_len = 5;
-   const uint32_t sample_mask = ((1 << sample_count) - 1) | 0x1;
-   uint32_t dw1, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   dw1 = op;
-
-   switch (sample_count) {
-   case 0:
-   case 1:
-      dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_1;
-      break;
-   case 2:
-      dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_2;
-      break;
-   case 4:
-      dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_4;
-      break;
-   case 8:
-      dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_8;
-      break;
-   case 16:
-      dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_16;
-      break;
-   default:
-      assert(!"unsupported sample count");
-      dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_1;
-      break;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_HZ_OP) | (cmd_len - 2);
-   dw[1] = dw1;
+   /* see raster_set_gen8_3dstate_wm_hz_op() */
+   dw[1] = rs->wm[1];
    dw[2] = 0;
-   /* exclusive? */
+   /* exclusive */
    dw[3] = height << 16 | width;
-   dw[4] = sample_mask;
+   dw[4] = rs->wm[2];
 }
 
 static inline void
@@ -656,100 +327,48 @@ gen8_3DSTATE_WM_CHROMAKEY(struct ilo_builder *builder)
 
 static inline void
 gen7_3DSTATE_PS(struct ilo_builder *builder,
-                const struct ilo_shader_state *fs,
-                bool dual_blend)
+                const struct ilo_state_ps *ps,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 8;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw2, dw4, dw5, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
-   /* see fs_init_cso_gen7() */
-   cso = ilo_shader_get_kernel_cso(fs);
-   dw2 = cso->payload[0];
-   dw4 = cso->payload[1];
-   dw5 = cso->payload[2];
-
-   if (dual_blend)
-      dw4 |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(fs);
-   dw[2] = dw2;
-   dw[3] = 0; /* scratch */
-   dw[4] = dw4;
-   dw[5] = dw5;
+   dw[1] = kernel_offset;
+   /* see ps_set_gen7_3DSTATE_PS() */
+   dw[2] = ps->ps[2];
+   dw[3] = ps->ps[3];
+   dw[4] = ps->ps[4];
+   dw[5] = ps->ps[5];
    dw[6] = 0; /* kernel 1 */
    dw[7] = 0; /* kernel 2 */
 }
 
-static inline void
-gen7_disable_3DSTATE_PS(struct ilo_builder *builder)
-{
-   const uint8_t cmd_len = 8;
-   int max_threads;
-   uint32_t dw4, *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
-   /* GPU hangs if none of the dispatch enable bits is set */
-   dw4 = GEN6_PS_DISPATCH_8 << GEN7_PS_DW4_DISPATCH_MODE__SHIFT;
-
-   /* see brwCreateContext() */
-   switch (ilo_dev_gen(builder->dev)) {
-   case ILO_GEN(7.5):
-      max_threads = (builder->dev->gt == 3) ? 408 :
-                    (builder->dev->gt == 2) ? 204 : 102;
-      dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
-      break;
-   case ILO_GEN(7):
-   default:
-      max_threads = (builder->dev->gt == 2) ? 172 : 48;
-      dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
-      break;
-   }
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
-   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
-   dw[4] = dw4;
-   dw[5] = 0;
-   dw[6] = 0;
-   dw[7] = 0;
-}
-
 static inline void
 gen8_3DSTATE_PS(struct ilo_builder *builder,
-                const struct ilo_shader_state *fs)
+                const struct ilo_state_ps *ps,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 12;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw3, dw6, dw7, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   /* see fs_init_cso_gen8() */
-   cso = ilo_shader_get_kernel_cso(fs);
-   dw3 = cso->payload[0];
-   dw6 = cso->payload[1];
-   dw7 = cso->payload[2];
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(fs);
+   dw[1] = kernel_offset;
    dw[2] = 0;
-   dw[3] = dw3;
-   dw[4] = 0; /* scratch */
+   /* see ps_set_gen8_3DSTATE_PS() */
+   dw[3] = ps->ps[0];
+   dw[4] = ps->ps[1];
    dw[5] = 0;
-   dw[6] = dw6;
-   dw[7] = dw7;
+   dw[6] = ps->ps[2];
+   dw[7] = ps->ps[3];
    dw[8] = 0; /* kernel 1 */
    dw[9] = 0;
    dw[10] = 0; /* kernel 2 */
@@ -758,66 +377,34 @@ gen8_3DSTATE_PS(struct ilo_builder *builder,
 
 static inline void
 gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
-                      const struct ilo_shader_state *fs,
-                      bool cc_may_kill, bool per_sample)
+                      const struct ilo_state_ps *ps)
 {
    const uint8_t cmd_len = 2;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw1, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   /* see fs_init_cso_gen8() */
-   cso = ilo_shader_get_kernel_cso(fs);
-   dw1 = cso->payload[3];
-
-   if (cc_may_kill)
-      dw1 |= GEN8_PSX_DW1_DISPATCH_ENABLE | GEN8_PSX_DW1_KILL_PIXEL;
-   if (per_sample)
-      dw1 |= GEN8_PSX_DW1_PER_SAMPLE;
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_EXTRA) | (cmd_len - 2);
-   dw[1] = dw1;
+   /* see ps_set_gen8_3DSTATE_PS_EXTRA() */
+   dw[1] = ps->ps[4];
 }
 
 static inline void
 gen8_3DSTATE_PS_BLEND(struct ilo_builder *builder,
-                      const struct ilo_blend_state *blend,
-                      const struct ilo_fb_state *fb,
-                      const struct ilo_dsa_state *dsa)
+                      const struct ilo_state_cc *cc)
 {
    const uint8_t cmd_len = 2;
-   uint32_t dw1, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   dw1 = 0;
-   if (blend->alpha_to_coverage && fb->num_samples > 1)
-      dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE;
-
-   if (fb->state.nr_cbufs && fb->state.cbufs[0]) {
-      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[0];
-
-      dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT;
-      if (caps->can_blend) {
-         if (caps->dst_alpha_forced_one)
-            dw1 |= blend->dw_ps_blend_dst_alpha_forced_one;
-         else
-            dw1 |= blend->dw_ps_blend;
-      }
-
-      if (caps->can_alpha_test)
-         dw1 |= dsa->dw_ps_blend_alpha;
-   } else {
-      dw1 |= dsa->dw_ps_blend_alpha;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_BLEND) | (cmd_len - 2);
-   dw[1] = dw1;
+   /* see cc_set_gen8_3DSTATE_PS_BLEND() */
+   dw[1] = cc->blend[0];
 }
 
 static inline void
@@ -862,101 +449,49 @@ gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(struct ilo_builder *builder,
 
 static inline void
 gen6_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
-                         int num_samples, const uint32_t *pattern,
-                         bool pixel_location_center)
+                         const struct ilo_state_raster *rs,
+                         const struct ilo_state_sample_pattern *pattern,
+                         uint8_t sample_count)
 {
    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 3;
-   uint32_t dw1, dw2, dw3, *dw;
+   const uint32_t *packed = (const uint32_t *)
+      ilo_state_sample_pattern_get_packed_offsets(pattern,
+            builder->dev, sample_count);
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   dw1 = (pixel_location_center) ? GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER :
-      GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER;
-
-   switch (num_samples) {
-   case 0:
-   case 1:
-      dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
-      dw2 = 0;
-      dw3 = 0;
-      break;
-   case 4:
-      dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
-      dw2 = pattern[0];
-      dw3 = 0;
-      break;
-   case 8:
-      assert(ilo_dev_gen(builder->dev) >= ILO_GEN(7));
-      dw1 |= GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
-      dw2 = pattern[0];
-      dw3 = pattern[1];
-      break;
-   default:
-      assert(!"unsupported sample count");
-      dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
-      dw2 = 0;
-      dw3 = 0;
-      break;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE) | (cmd_len - 2);
-   dw[1] = dw1;
-   dw[2] = dw2;
+   /* see raster_set_gen8_3DSTATE_MULTISAMPLE() */
+   dw[1] = rs->sample[0];
+
+   /* see sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN() */
+   dw[2] = (sample_count >= 4) ? packed[0] : 0;
    if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
-      dw[3] = dw3;
+      dw[3] = (sample_count >= 8) ? packed[1] : 0;
 }
 
 static inline void
 gen8_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
-                         int num_samples,
-                         bool pixel_location_center)
+                         const struct ilo_state_raster *rs)
 {
    const uint8_t cmd_len = 2;
-   uint32_t dw1, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   dw1 = (pixel_location_center) ? GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER :
-      GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER;
-
-   switch (num_samples) {
-   case 0:
-   case 1:
-      dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
-      break;
-   case 2:
-      dw1 |= GEN8_MULTISAMPLE_DW1_NUMSAMPLES_2;
-      break;
-   case 4:
-      dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
-      break;
-   case 8:
-      dw1 |= GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
-      break;
-   case 16:
-      dw1 |= GEN8_MULTISAMPLE_DW1_NUMSAMPLES_16;
-      break;
-   default:
-      assert(!"unsupported sample count");
-      dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
-      break;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE) | (cmd_len - 2);
-   dw[1] = dw1;
+   /* see raster_set_gen8_3DSTATE_MULTISAMPLE() */
+   dw[1] = rs->sample[0];
 }
 
 static inline void
 gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_builder *builder,
-                            const uint32_t *pattern_1x,
-                            const uint32_t *pattern_2x,
-                            const uint32_t *pattern_4x,
-                            const uint32_t *pattern_8x,
-                            const uint32_t *pattern_16x)
+                            const struct ilo_state_sample_pattern *pattern)
 {
    const uint8_t cmd_len = 9;
    uint32_t *dw;
@@ -966,61 +501,32 @@ gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_builder *builder,
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SAMPLE_PATTERN) | (cmd_len - 2);
-   dw[1] = pattern_16x[3];
-   dw[2] = pattern_16x[2];
-   dw[3] = pattern_16x[1];
-   dw[4] = pattern_16x[0];
-   dw[5] = pattern_8x[1];
-   dw[6] = pattern_8x[0];
-   dw[7] = pattern_4x[0];
-   dw[8] = pattern_1x[0] << 16 |
-           pattern_2x[0];
+   dw[1] = 0;
+   dw[2] = 0;
+   dw[3] = 0;
+   dw[4] = 0;
+   /* see sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN() */
+   dw[5] = ((const uint32_t *) pattern->pattern_8x)[1];
+   dw[6] = ((const uint32_t *) pattern->pattern_8x)[0];
+   dw[7] = ((const uint32_t *) pattern->pattern_4x)[0];
+   dw[8] = pattern->pattern_1x[0] << 16 |
+           ((const uint16_t *) pattern->pattern_2x)[0];
 }
 
 static inline void
 gen6_3DSTATE_SAMPLE_MASK(struct ilo_builder *builder,
-                         unsigned sample_mask)
+                         const struct ilo_state_raster *rs)
 {
    const uint8_t cmd_len = 2;
-   const unsigned valid_mask = 0xf;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 6, 6);
-
-   sample_mask &= valid_mask;
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK) | (cmd_len - 2);
-   dw[1] = sample_mask;
-}
-
-static inline void
-gen7_3DSTATE_SAMPLE_MASK(struct ilo_builder *builder,
-                         unsigned sample_mask,
-                         int num_samples)
-{
-   const uint8_t cmd_len = 2;
-   const unsigned valid_mask = ((1 << num_samples) - 1) | 0x1;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
-
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 294:
-    *
-    *     "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field
-    *      (Sample Mask) must be zero.
-    *
-    *      If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field
-    *      must be zero."
-    */
-   sample_mask &= valid_mask;
+   ILO_DEV_ASSERT(builder->dev, 6, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK) | (cmd_len - 2);
-   dw[1] = sample_mask;
+   /* see raster_set_gen6_3DSTATE_SAMPLE_MASK() */
+   dw[1] = rs->sample[1];
 }
 
 static inline void
@@ -1070,95 +576,75 @@ gen6_3DSTATE_DRAWING_RECTANGLE(struct ilo_builder *builder,
 
 static inline void
 gen6_3DSTATE_POLY_STIPPLE_OFFSET(struct ilo_builder *builder,
-                                 int x_offset, int y_offset)
+                                 const struct ilo_state_poly_stipple *stipple)
 {
    const uint8_t cmd_len = 2;
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   assert(x_offset >= 0 && x_offset <= 31);
-   assert(y_offset >= 0 && y_offset <= 31);
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_POLY_STIPPLE_OFFSET) | (cmd_len - 2);
-   dw[1] = x_offset << 8 | y_offset;
+   /* constant */
+   dw[1] = 0;
 }
 
 static inline void
 gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_builder *builder,
-                                  const struct pipe_poly_stipple *pattern)
+                                  const struct ilo_state_poly_stipple *stipple)
 {
    const uint8_t cmd_len = 33;
    uint32_t *dw;
-   int i;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_POLY_STIPPLE_PATTERN) | (cmd_len - 2);
-   dw++;
-
-   STATIC_ASSERT(Elements(pattern->stipple) == 32);
-   for (i = 0; i < 32; i++)
-      dw[i] = pattern->stipple[i];
+   /* see poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN() */
+   memcpy(&dw[1], stipple->stipple, sizeof(stipple->stipple));
 }
 
 static inline void
 gen6_3DSTATE_LINE_STIPPLE(struct ilo_builder *builder,
-                          unsigned pattern, unsigned factor)
+                          const struct ilo_state_line_stipple *stipple)
 {
    const uint8_t cmd_len = 3;
-   unsigned inverse;
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   assert((pattern & 0xffff) == pattern);
-   assert(factor >= 1 && factor <= 256);
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_LINE_STIPPLE) | (cmd_len - 2);
-   dw[1] = pattern;
-
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
-      /* in U1.16 */
-      inverse = 65536 / factor;
-
-      dw[2] = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
-              factor;
-   }
-   else {
-      /* in U1.13 */
-      inverse = 8192 / factor;
-
-      dw[2] = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
-              factor;
-   }
+   /* see line_stipple_set_gen6_3DSTATE_LINE_STIPPLE() */
+   dw[1] = stipple->stipple[0];
+   dw[2] = stipple->stipple[1];
 }
 
 static inline void
-gen6_3DSTATE_AA_LINE_PARAMETERS(struct ilo_builder *builder)
+gen6_3DSTATE_AA_LINE_PARAMETERS(struct ilo_builder *builder,
+                                const struct ilo_state_raster *rs)
 {
    const uint8_t cmd_len = 3;
-   const uint32_t dw[3] = {
-      GEN6_RENDER_CMD(3D, 3DSTATE_AA_LINE_PARAMETERS) | (cmd_len - 2),
-      0 << GEN6_AA_LINE_DW1_BIAS__SHIFT | 0,
-      0 << GEN6_AA_LINE_DW2_CAP_BIAS__SHIFT | 0,
-   };
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   ilo_builder_batch_write(builder, cmd_len, dw);
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_AA_LINE_PARAMETERS) | (cmd_len - 2);
+   /* constant */
+   dw[1] = 0 << GEN6_AA_LINE_DW1_BIAS__SHIFT |
+           0 << GEN6_AA_LINE_DW1_SLOPE__SHIFT;
+   dw[2] = 0 << GEN6_AA_LINE_DW2_CAP_BIAS__SHIFT |
+           0 << GEN6_AA_LINE_DW2_CAP_SLOPE__SHIFT;
 }
 
 static inline void
 gen6_3DSTATE_DEPTH_BUFFER(struct ilo_builder *builder,
-                          const struct ilo_zs_surface *zs,
-                          bool aligned_8x4)
+                          const struct ilo_state_zs *zs)
 {
    const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
       GEN7_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER) :
@@ -1172,44 +658,49 @@ gen6_3DSTATE_DEPTH_BUFFER(struct ilo_builder *builder,
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = cmd | (cmd_len - 2);
-   dw[1] = zs->payload[0];
-   dw[2] = 0;
 
-   /* see ilo_gpe_init_zs_surface() */
+   /*
+    * see zs_set_gen6_3DSTATE_DEPTH_BUFFER() and
+    * zs_set_gen7_3DSTATE_DEPTH_BUFFER()
+    */
    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+      dw[1] = zs->depth[0];
+      dw[2] = 0;
       dw[3] = 0;
-      dw[4] = (aligned_8x4) ? zs->dw_aligned_8x4 : zs->payload[2];
-      dw[5] = zs->payload[3];
-      dw[6] = zs->payload[4];
-      dw[7] = zs->payload[5];
+      dw[4] = zs->depth[2];
+      dw[5] = zs->depth[3];
+      dw[6] = 0;
+      dw[7] = zs->depth[4];
 
       dw[5] |= builder->mocs << GEN8_DEPTH_DW5_MOCS__SHIFT;
 
-      if (zs->bo) {
-         ilo_builder_batch_reloc64(builder, pos + 2, zs->bo,
-               zs->payload[1], INTEL_RELOC_WRITE);
+      if (zs->depth_bo) {
+         ilo_builder_batch_reloc64(builder, pos + 2, zs->depth_bo,
+               zs->depth[1], (zs->z_readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    } else {
-      dw[3] = (aligned_8x4) ? zs->dw_aligned_8x4 : zs->payload[2];
-      dw[4] = zs->payload[3];
-      dw[5] = zs->payload[4];
-      dw[6] = zs->payload[5];
+      dw[1] = zs->depth[0];
+      dw[2] = 0;
+      dw[3] = zs->depth[2];
+      dw[4] = zs->depth[3];
+      dw[5] = 0;
+      dw[6] = zs->depth[4];
 
       if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
          dw[4] |= builder->mocs << GEN7_DEPTH_DW4_MOCS__SHIFT;
       else
          dw[6] |= builder->mocs << GEN6_DEPTH_DW6_MOCS__SHIFT;
 
-      if (zs->bo) {
-         ilo_builder_batch_reloc(builder, pos + 2, zs->bo,
-               zs->payload[1], INTEL_RELOC_WRITE);
+      if (zs->depth_bo) {
+         ilo_builder_batch_reloc(builder, pos + 2, zs->depth_bo,
+               zs->depth[1], (zs->z_readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    }
 }
 
 static inline void
 gen6_3DSTATE_STENCIL_BUFFER(struct ilo_builder *builder,
-                            const struct ilo_zs_surface *zs)
+                            const struct ilo_state_zs *zs)
 {
    const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
       GEN7_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER) :
@@ -1223,33 +714,36 @@ gen6_3DSTATE_STENCIL_BUFFER(struct ilo_builder *builder,
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = cmd | (cmd_len - 2);
-   /* see ilo_gpe_init_zs_surface() */
-   dw[1] = zs->payload[6];
-   dw[2] = 0;
 
+   /* see zs_set_gen6_3DSTATE_STENCIL_BUFFER() */
    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[1] |= builder->mocs << GEN8_STENCIL_DW1_MOCS__SHIFT;
-
+      dw[1] = zs->stencil[0];
+      dw[2] = 0;
       dw[3] = 0;
-      dw[4] = zs->payload[8];
+      dw[4] = zs->stencil[2];
 
-      if (zs->separate_s8_bo) {
-         ilo_builder_batch_reloc64(builder, pos + 2,
-               zs->separate_s8_bo, zs->payload[7], INTEL_RELOC_WRITE);
+      dw[1] |= builder->mocs << GEN8_STENCIL_DW1_MOCS__SHIFT;
+
+      if (zs->stencil_bo) {
+         ilo_builder_batch_reloc64(builder, pos + 2, zs->stencil_bo,
+               zs->stencil[1], (zs->s_readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    } else {
+      dw[1] = zs->stencil[0];
+      dw[2] = 0;
+
       dw[1] |= builder->mocs << GEN6_STENCIL_DW1_MOCS__SHIFT;
 
-      if (zs->separate_s8_bo) {
-         ilo_builder_batch_reloc(builder, pos + 2,
-               zs->separate_s8_bo, zs->payload[7], INTEL_RELOC_WRITE);
+      if (zs->stencil_bo) {
+         ilo_builder_batch_reloc(builder, pos + 2, zs->stencil_bo,
+               zs->stencil[1], (zs->s_readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    }
 }
 
 static inline void
 gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_builder *builder,
-                               const struct ilo_zs_surface *zs)
+                               const struct ilo_state_zs *zs)
 {
    const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
       GEN7_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER) :
@@ -1263,26 +757,29 @@ gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_builder *builder,
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = cmd | (cmd_len - 2);
-   /* see ilo_gpe_init_zs_surface() */
-   dw[1] = zs->payload[9];
-   dw[2] = 0;
 
+   /* see zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER() */
    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[1] |= builder->mocs << GEN8_HIZ_DW1_MOCS__SHIFT;
-
+      dw[1] = zs->hiz[0];
+      dw[2] = 0;
       dw[3] = 0;
-      dw[4] = zs->payload[11];
+      dw[4] = zs->hiz[2];
+
+      dw[1] |= builder->mocs << GEN8_HIZ_DW1_MOCS__SHIFT;
 
       if (zs->hiz_bo) {
-         ilo_builder_batch_reloc64(builder, pos + 2,
-               zs->hiz_bo, zs->payload[10], INTEL_RELOC_WRITE);
+         ilo_builder_batch_reloc64(builder, pos + 2, zs->hiz_bo,
+               zs->hiz[1], (zs->z_readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    } else {
+      dw[1] = zs->hiz[0];
+      dw[2] = 0;
+
       dw[1] |= builder->mocs << GEN6_HIZ_DW1_MOCS__SHIFT;
 
       if (zs->hiz_bo) {
-         ilo_builder_batch_reloc(builder, pos + 2,
-               zs->hiz_bo, zs->payload[10], INTEL_RELOC_WRITE);
+         ilo_builder_batch_reloc(builder, pos + 2, zs->hiz_bo,
+               zs->hiz[1], (zs->z_readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    }
 }
@@ -1440,34 +937,24 @@ gen7_3DSTATE_BLEND_STATE_POINTERS(struct ilo_builder *builder,
 
 static inline uint32_t
 gen6_CLIP_VIEWPORT(struct ilo_builder *builder,
-                   const struct ilo_viewport_cso *viewports,
-                   unsigned num_viewports)
+                   const struct ilo_state_viewport *vp)
 {
    const int state_align = 32;
-   const int state_len = 4 * num_viewports;
+   const int state_len = 4 * vp->count;
    uint32_t state_offset, *dw;
-   unsigned i;
+   int i;
 
    ILO_DEV_ASSERT(builder->dev, 6, 6);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 193:
-    *
-    *     "The viewport-related state is stored as an array of up to 16
-    *      elements..."
-    */
-   assert(num_viewports && num_viewports <= 16);
-
    state_offset = ilo_builder_dynamic_pointer(builder,
          ILO_BUILDER_ITEM_CLIP_VIEWPORT, state_align, state_len, &dw);
 
-   for (i = 0; i < num_viewports; i++) {
-      const struct ilo_viewport_cso *vp = &viewports[i];
-
-      dw[0] = fui(vp->min_gbx);
-      dw[1] = fui(vp->max_gbx);
-      dw[2] = fui(vp->min_gby);
-      dw[3] = fui(vp->max_gby);
+   for (i = 0; i < vp->count; i++) {
+      /* see viewport_matrix_set_gen7_SF_CLIP_VIEWPORT() */
+      dw[0] = vp->sf_clip[i][8];
+      dw[1] = vp->sf_clip[i][9];
+      dw[2] = vp->sf_clip[i][10];
+      dw[3] = vp->sf_clip[i][11];
 
       dw += 4;
    }
@@ -1477,38 +964,21 @@ gen6_CLIP_VIEWPORT(struct ilo_builder *builder,
 
 static inline uint32_t
 gen6_SF_VIEWPORT(struct ilo_builder *builder,
-                 const struct ilo_viewport_cso *viewports,
-                 unsigned num_viewports)
+                 const struct ilo_state_viewport *vp)
 {
    const int state_align = 32;
-   const int state_len = 8 * num_viewports;
+   const int state_len = 8 * vp->count;
    uint32_t state_offset, *dw;
-   unsigned i;
+   int i;
 
    ILO_DEV_ASSERT(builder->dev, 6, 6);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 262:
-    *
-    *     "The viewport-specific state used by the SF unit (SF_VIEWPORT) is
-    *      stored as an array of up to 16 elements..."
-    */
-   assert(num_viewports && num_viewports <= 16);
-
    state_offset = ilo_builder_dynamic_pointer(builder,
          ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw);
 
-   for (i = 0; i < num_viewports; i++) {
-      const struct ilo_viewport_cso *vp = &viewports[i];
-
-      dw[0] = fui(vp->m00);
-      dw[1] = fui(vp->m11);
-      dw[2] = fui(vp->m22);
-      dw[3] = fui(vp->m30);
-      dw[4] = fui(vp->m31);
-      dw[5] = fui(vp->m32);
-      dw[6] = 0;
-      dw[7] = 0;
+   for (i = 0; i < vp->count; i++) {
+      /* see viewport_matrix_set_gen7_SF_CLIP_VIEWPORT() */
+      memcpy(dw, vp->sf_clip[i], sizeof(*dw) * 8);
 
       dw += 8;
    }
@@ -1518,298 +988,103 @@ gen6_SF_VIEWPORT(struct ilo_builder *builder,
 
 static inline uint32_t
 gen7_SF_CLIP_VIEWPORT(struct ilo_builder *builder,
-                      const struct ilo_viewport_cso *viewports,
-                      unsigned num_viewports)
+                      const struct ilo_state_viewport *vp)
 {
    const int state_align = 64;
-   const int state_len = 16 * num_viewports;
-   uint32_t state_offset, *dw;
-   unsigned i;
+   const int state_len = 16 * vp->count;
 
    ILO_DEV_ASSERT(builder->dev, 7, 8);
 
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 270:
-    *
-    *     "The viewport-specific state used by both the SF and CL units
-    *      (SF_CLIP_VIEWPORT) is stored as an array of up to 16 elements, each
-    *      of which contains the DWords described below. The start of each
-    *      element is spaced 16 DWords apart. The location of first element of
-    *      the array, as specified by both Pointer to SF_VIEWPORT and Pointer
-    *      to CLIP_VIEWPORT, is aligned to a 64-byte boundary."
-    */
-   assert(num_viewports && num_viewports <= 16);
-
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw);
-
-   for (i = 0; i < num_viewports; i++) {
-      const struct ilo_viewport_cso *vp = &viewports[i];
-
-      dw[0] = fui(vp->m00);
-      dw[1] = fui(vp->m11);
-      dw[2] = fui(vp->m22);
-      dw[3] = fui(vp->m30);
-      dw[4] = fui(vp->m31);
-      dw[5] = fui(vp->m32);
-      dw[6] = 0;
-      dw[7] = 0;
-
-      dw[8] = fui(vp->min_gbx);
-      dw[9] = fui(vp->max_gbx);
-      dw[10] = fui(vp->min_gby);
-      dw[11] = fui(vp->max_gby);
-
-      if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-         dw[12] = fui(vp->min_x);
-         dw[13] = fui(vp->max_x - 1.0f);
-         dw[14] = fui(vp->min_y);
-         dw[15] = fui(vp->max_y - 1.0f);
-      } else {
-         dw[12] = 0;
-         dw[13] = 0;
-         dw[14] = 0;
-         dw[15] = 0;
-      }
-
-      dw += 16;
-   }
-
-   return state_offset;
+   /* see viewport_matrix_set_gen7_SF_CLIP_VIEWPORT() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_SF_VIEWPORT,
+         state_align, state_len, (const uint32_t *) vp->sf_clip);
 }
 
 static inline uint32_t
 gen6_CC_VIEWPORT(struct ilo_builder *builder,
-                 const struct ilo_viewport_cso *viewports,
-                 unsigned num_viewports)
+                 const struct ilo_state_viewport *vp)
 {
    const int state_align = 32;
-   const int state_len = 2 * num_viewports;
-   uint32_t state_offset, *dw;
-   unsigned i;
+   const int state_len = 2 * vp->count;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 385:
-    *
-    *     "The viewport state is stored as an array of up to 16 elements..."
-    */
-   assert(num_viewports && num_viewports <= 16);
-
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_CC_VIEWPORT, state_align, state_len, &dw);
-
-   for (i = 0; i < num_viewports; i++) {
-      const struct ilo_viewport_cso *vp = &viewports[i];
-
-      dw[0] = fui(vp->min_z);
-      dw[1] = fui(vp->max_z);
-
-      dw += 2;
-   }
-
-   return state_offset;
+   /* see viewport_matrix_set_gen6_CC_VIEWPORT() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_CC_VIEWPORT,
+         state_align, state_len, (const uint32_t *) vp->cc);
 }
 
 static inline uint32_t
 gen6_SCISSOR_RECT(struct ilo_builder *builder,
-                  const struct ilo_scissor_state *scissor,
-                  unsigned num_viewports)
+                  const struct ilo_state_viewport *vp)
 {
    const int state_align = 32;
-   const int state_len = 2 * num_viewports;
+   const int state_len = 2 * vp->count;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 263:
-    *
-    *     "The viewport-specific state used by the SF unit (SCISSOR_RECT) is
-    *      stored as an array of up to 16 elements..."
-    */
-   assert(num_viewports && num_viewports <= 16);
-   assert(Elements(scissor->payload) >= state_len);
-
+   /* see viewport_scissor_set_gen6_SCISSOR_RECT() */
    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_SCISSOR_RECT,
-         state_align, state_len, scissor->payload);
+         state_align, state_len, (const uint32_t *) vp->scissor);
 }
 
 static inline uint32_t
 gen6_COLOR_CALC_STATE(struct ilo_builder *builder,
-                      const struct pipe_stencil_ref *stencil_ref,
-                      ubyte alpha_ref,
-                      const struct pipe_blend_color *blend_color)
+                      const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
    const int state_len = 6;
-   uint32_t state_offset, *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_COLOR_CALC, state_align, state_len, &dw);
-
-   dw[0] = stencil_ref->ref_value[0] << 24 |
-           stencil_ref->ref_value[1] << 16 |
-           GEN6_CC_DW0_ALPHATEST_UNORM8;
-   dw[1] = alpha_ref;
-   dw[2] = fui(blend_color->color[0]);
-   dw[3] = fui(blend_color->color[1]);
-   dw[4] = fui(blend_color->color[2]);
-   dw[5] = fui(blend_color->color[3]);
-
-   return state_offset;
+   /* see cc_params_set_gen6_COLOR_CALC_STATE() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_COLOR_CALC,
+         state_align, state_len, cc->cc);
 }
 
 static inline uint32_t
 gen6_DEPTH_STENCIL_STATE(struct ilo_builder *builder,
-                         const struct ilo_dsa_state *dsa)
+                         const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
    const int state_len = 3;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   STATIC_ASSERT(Elements(dsa->payload) >= state_len);
-
+   /* see cc_set_gen6_DEPTH_STENCIL_STATE() */
    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_DEPTH_STENCIL,
-         state_align, state_len, dsa->payload);
+         state_align, state_len, cc->ds);
 }
 
 static inline uint32_t
 gen6_BLEND_STATE(struct ilo_builder *builder,
-                 const struct ilo_blend_state *blend,
-                 const struct ilo_fb_state *fb,
-                 const struct ilo_dsa_state *dsa)
+                 const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
-   int state_len;
-   uint32_t state_offset, *dw;
-   unsigned num_targets, i;
+   const int state_len = 2 * cc->blend_state_count;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 376:
-    *
-    *     "The blend state is stored as an array of up to 8 elements..."
-    */
-   num_targets = fb->state.nr_cbufs;
-   assert(num_targets <= 8);
-
-   if (!num_targets) {
-      if (!dsa->dw_blend_alpha)
-         return 0;
-      /* to be able to reference alpha func */
-      num_targets = 1;
-   }
-
-   state_len = 2 * num_targets;
-
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
-
-   for (i = 0; i < num_targets; i++) {
-      const struct ilo_blend_cso *cso = &blend->cso[i];
-
-      dw[0] = cso->payload[0];
-      dw[1] = cso->payload[1] | blend->dw_shared;
-
-      if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
-         const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
-
-         if (caps->can_blend) {
-            if (caps->dst_alpha_forced_one)
-               dw[0] |= cso->dw_blend_dst_alpha_forced_one;
-            else
-               dw[0] |= cso->dw_blend;
-         }
-
-         if (caps->can_logicop)
-            dw[1] |= blend->dw_logicop;
-
-         if (caps->can_alpha_test)
-            dw[1] |= dsa->dw_blend_alpha;
-      } else {
-         dw[1] |= GEN6_RT_DW1_WRITE_DISABLE_A |
-                  GEN6_RT_DW1_WRITE_DISABLE_R |
-                  GEN6_RT_DW1_WRITE_DISABLE_G |
-                  GEN6_RT_DW1_WRITE_DISABLE_B |
-                  dsa->dw_blend_alpha;
-      }
+   if (!state_len)
+      return 0;
 
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 356:
-       *
-       *     "When NumSamples = 1, AlphaToCoverage and AlphaToCoverage
-       *      Dither both must be disabled."
-       *
-       * There is no such limitation on GEN7, or for AlphaToOne.  But GL
-       * requires that anyway.
-       */
-      if (fb->num_samples > 1)
-         dw[1] |= blend->dw_alpha_mod;
-
-      dw += 2;
-   }
-
-   return state_offset;
+   /* see cc_set_gen6_BLEND_STATE() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLEND,
+         state_align, state_len, cc->blend);
 }
 
 static inline uint32_t
 gen8_BLEND_STATE(struct ilo_builder *builder,
-                 const struct ilo_blend_state *blend,
-                 const struct ilo_fb_state *fb,
-                 const struct ilo_dsa_state *dsa)
+                 const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
-   const int state_len = 1 + 2 * fb->state.nr_cbufs;
-   uint32_t state_offset, *dw;
-   unsigned i;
+   const int state_len = 1 + 2 * cc->blend_state_count;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   assert(fb->state.nr_cbufs <= 8);
-
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
-
-   dw[0] = blend->dw_shared;
-   if (fb->num_samples > 1)
-      dw[0] |= blend->dw_alpha_mod;
-   if (!fb->state.nr_cbufs || fb->blend_caps[0].can_alpha_test)
-      dw[0] |= dsa->dw_blend_alpha;
-   dw++;
-
-   for (i = 0; i < fb->state.nr_cbufs; i++) {
-      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
-      const struct ilo_blend_cso *cso = &blend->cso[i];
-
-      dw[0] = cso->payload[0];
-      dw[1] = cso->payload[1];
-
-      if (fb->state.cbufs[i]) {
-         if (caps->can_blend) {
-            if (caps->dst_alpha_forced_one)
-               dw[0] |= cso->dw_blend_dst_alpha_forced_one;
-            else
-               dw[0] |= cso->dw_blend;
-         }
-
-         if (caps->can_logicop)
-            dw[1] |= blend->dw_logicop;
-      } else {
-         dw[0] |= GEN8_RT_DW0_WRITE_DISABLE_A |
-                  GEN8_RT_DW0_WRITE_DISABLE_R |
-                  GEN8_RT_DW0_WRITE_DISABLE_G |
-                  GEN8_RT_DW0_WRITE_DISABLE_B;
-      }
-
-      dw += 2;
-   }
-
-   return state_offset;
+   /* see cc_set_gen8_BLEND_STATE() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLEND,
+         state_align, state_len, &cc->blend[1]);
 }
 
 #endif /* ILO_BUILDER_3D_BOTTOM_H */
index 05dbce7c905133c7284416a0a49335250fbd0b5e..8d30095e6f6ef9f4b0d660469516b2f67181f0a2 100644 (file)
 #define ILO_BUILDER_3D_TOP_H
 
 #include "genhw/genhw.h"
-#include "../ilo_resource.h"
-#include "../ilo_shader.h"
 #include "intel_winsys.h"
 
 #include "ilo_core.h"
 #include "ilo_dev.h"
-#include "ilo_state_3d.h"
+#include "ilo_state_sampler.h"
+#include "ilo_state_shader.h"
+#include "ilo_state_sol.h"
+#include "ilo_state_surface.h"
+#include "ilo_state_urb.h"
+#include "ilo_state_vf.h"
 #include "ilo_builder.h"
 
 static inline void
 gen6_3DSTATE_URB(struct ilo_builder *builder,
-                 int vs_total_size, int gs_total_size,
-                 int vs_entry_size, int gs_entry_size)
+                 const struct ilo_state_urb *urb)
 {
    const uint8_t cmd_len = 3;
-   const int row_size = 128; /* 1024 bits */
-   int vs_alloc_size, gs_alloc_size;
-   int vs_num_entries, gs_num_entries;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 6, 6);
-
-   /* in 1024-bit URB rows */
-   vs_alloc_size = (vs_entry_size + row_size - 1) / row_size;
-   gs_alloc_size = (gs_entry_size + row_size - 1) / row_size;
-
-   /* the valid range is [1, 5] */
-   if (!vs_alloc_size)
-      vs_alloc_size = 1;
-   if (!gs_alloc_size)
-      gs_alloc_size = 1;
-   assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
-
-   /* the valid range is [24, 256] in multiples of 4 */
-   vs_num_entries = (vs_total_size / row_size / vs_alloc_size) & ~3;
-   if (vs_num_entries > 256)
-      vs_num_entries = 256;
-   assert(vs_num_entries >= 24);
-
-   /* the valid range is [0, 256] in multiples of 4 */
-   gs_num_entries = (gs_total_size / row_size / gs_alloc_size) & ~3;
-   if (gs_num_entries > 256)
-      gs_num_entries = 256;
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_URB) | (cmd_len - 2);
-   dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
-           vs_num_entries << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
-   dw[2] = gs_num_entries << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
-           (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
+   /* see urb_set_gen6_3DSTATE_URB() */
+   dw[1] = urb->urb[0];
+   dw[2] = urb->urb[1];
 }
 
 static inline void
-gen7_3dstate_push_constant_alloc(struct ilo_builder *builder,
-                                 int subop, int offset, int size)
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
+                                    const struct ilo_state_urb *urb)
 {
-   const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
-                        GEN6_RENDER_SUBTYPE_3D |
-                        subop;
    const uint8_t cmd_len = 2;
-   const int slice_count = ((ilo_dev_gen(builder->dev) == ILO_GEN(7.5) &&
-                             builder->dev->gt == 3) ||
-                            ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 2 : 1;
    uint32_t *dw;
-   int end;
-
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
-
-   /* VS, HS, DS, GS, and PS variants */
-   assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS &&
-          subop <= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS);
-
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 68:
-    *
-    *     "(A table that says the maximum size of each constant buffer is
-    *      16KB")
-    *
-    * From the Ivy Bridge PRM, volume 2 part 1, page 115:
-    *
-    *     "The sum of the Constant Buffer Offset and the Constant Buffer Size
-    *      may not exceed the maximum value of the Constant Buffer Size."
-    *
-    * Thus, the valid range of buffer end is [0KB, 16KB].
-    */
-   end = (offset + size) / 1024;
-   if (end > 16 * slice_count) {
-      assert(!"invalid constant buffer end");
-      end = 16 * slice_count;
-   }
-
-   /* the valid range of buffer offset is [0KB, 15KB] */
-   offset = (offset + 1023) / 1024;
-   if (offset > 15 * slice_count) {
-      assert(!"invalid constant buffer offset");
-      offset = 15 * slice_count;
-   }
-
-   if (offset > end) {
-      assert(!size);
-      offset = end;
-   }
-
-   /* the valid range of buffer size is [0KB, 15KB] */
-   size = end - offset;
-   if (size > 15 * slice_count) {
-      assert(!"invalid constant buffer size");
-      size = 15 * slice_count;
-   }
-
-   assert(offset % slice_count == 0 && size % slice_count == 0);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = cmd | (cmd_len - 2);
-   dw[1] = offset << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
-           size;
-}
-
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
-                                    int offset, int size)
-{
-   gen7_3dstate_push_constant_alloc(builder,
-         GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS, offset, size);
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) |
+           (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->pcb[0];
 }
 
 static inline void
 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder *builder,
-                                    int offset, int size)
+                                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_push_constant_alloc(builder,
-         GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_HS, offset, size);
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) |
+           (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->pcb[1];
 }
 
 static inline void
 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder *builder,
-                                    int offset, int size)
+                                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_push_constant_alloc(builder,
-         GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_DS, offset, size);
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) |
+           (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->pcb[2];
 }
 
 static inline void
 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder *builder,
-                                    int offset, int size)
+                                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_push_constant_alloc(builder,
-         GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_GS, offset, size);
-}
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
 
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
-                                    int offset, int size)
-{
-   gen7_3dstate_push_constant_alloc(builder,
-         GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS, offset, size);
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) |
+           (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->pcb[3];
 }
 
 static inline void
-gen7_3dstate_urb(struct ilo_builder *builder,
-                 int subop, int offset, int size,
-                 int entry_size)
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
+                                    const struct ilo_state_urb *urb)
 {
-   const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
-                        GEN6_RENDER_SUBTYPE_3D |
-                        subop;
    const uint8_t cmd_len = 2;
-   const int row_size = 64; /* 512 bits */
-   int alloc_size, num_entries, min_entries, max_entries;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
-
-   /* VS, HS, DS, and GS variants */
-   assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_URB_VS &&
-          subop <= GEN7_RENDER_OPCODE_3DSTATE_URB_GS);
-
-   /* in multiples of 8KB */
-   assert(offset % 8192 == 0);
-   offset /= 8192;
-
-   /* in multiple of 512-bit rows */
-   alloc_size = (entry_size + row_size - 1) / row_size;
-   if (!alloc_size)
-      alloc_size = 1;
-
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 34:
-    *
-    *     "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may
-    *      cause performance to decrease due to banking in the URB. Element
-    *      sizes of 16 to 20 should be programmed with six 512-bit URB rows."
-    */
-   if (subop == GEN7_RENDER_OPCODE_3DSTATE_URB_VS && alloc_size == 5)
-      alloc_size = 6;
-
-   /* in multiples of 8 */
-   num_entries = (size / row_size / alloc_size) & ~7;
-
-   switch (subop) {
-   case GEN7_RENDER_OPCODE_3DSTATE_URB_VS:
-      switch (ilo_dev_gen(builder->dev)) {
-      case ILO_GEN(8):
-         max_entries = 2560;
-         min_entries = 64;
-         break;
-      case ILO_GEN(7.5):
-         max_entries = (builder->dev->gt >= 2) ? 1664 : 640;
-         min_entries = (builder->dev->gt >= 2) ? 64 : 32;
-         break;
-      case ILO_GEN(7):
-      default:
-         max_entries = (builder->dev->gt == 2) ? 704 : 512;
-         min_entries = 32;
-         break;
-      }
-
-      assert(num_entries >= min_entries);
-      if (num_entries > max_entries)
-         num_entries = max_entries;
-      break;
-   case GEN7_RENDER_OPCODE_3DSTATE_URB_HS:
-      max_entries = (builder->dev->gt == 2) ? 64 : 32;
-      if (num_entries > max_entries)
-         num_entries = max_entries;
-      break;
-   case GEN7_RENDER_OPCODE_3DSTATE_URB_DS:
-      if (num_entries)
-         assert(num_entries >= 138);
-      break;
-   case GEN7_RENDER_OPCODE_3DSTATE_URB_GS:
-      switch (ilo_dev_gen(builder->dev)) {
-      case ILO_GEN(8):
-         max_entries = 960;
-         break;
-      case ILO_GEN(7.5):
-         max_entries = (builder->dev->gt >= 2) ? 640 : 256;
-         break;
-      case ILO_GEN(7):
-      default:
-         max_entries = (builder->dev->gt == 2) ? 320 : 192;
-         break;
-      }
-
-      if (num_entries > max_entries)
-         num_entries = max_entries;
-      break;
-   default:
-      break;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = cmd | (cmd_len - 2);
-   dw[1] = offset << GEN7_URB_DW1_OFFSET__SHIFT |
-           (alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
-           num_entries;
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) |
+           (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->pcb[4];
 }
 
 static inline void
 gen7_3DSTATE_URB_VS(struct ilo_builder *builder,
-                    int offset, int size, int entry_size)
+                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_VS,
-         offset, size, entry_size);
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->urb[0];
 }
 
 static inline void
 gen7_3DSTATE_URB_HS(struct ilo_builder *builder,
-                    int offset, int size, int entry_size)
+                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_HS,
-         offset, size, entry_size);
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->urb[1];
 }
 
 static inline void
 gen7_3DSTATE_URB_DS(struct ilo_builder *builder,
-                    int offset, int size, int entry_size)
+                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_DS,
-         offset, size, entry_size);
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->urb[2];
 }
 
 static inline void
 gen7_3DSTATE_URB_GS(struct ilo_builder *builder,
-                    int offset, int size, int entry_size)
+                    const struct ilo_state_urb *urb)
 {
-   gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_GS,
-         offset, size, entry_size);
+   const uint8_t cmd_len = 2;
+   uint32_t *dw;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
+   /* see urb_set_gen7_3dstate_push_constant_alloc() */
+   dw[1] = urb->urb[3];
 }
 
 static inline void
 gen75_3DSTATE_VF(struct ilo_builder *builder,
-                 bool enable_cut_index,
-                 uint32_t cut_index)
+                 const struct ilo_state_vf *vf)
 {
    const uint8_t cmd_len = 2;
    uint32_t *dw;
@@ -334,11 +198,10 @@ gen75_3DSTATE_VF(struct ilo_builder *builder,
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2);
-   if (enable_cut_index)
-      dw[0] |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
-
-   dw[1] = cut_index;
+   /* see vf_params_set_gen75_3DSTATE_VF() */
+   dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2) |
+           vf->cut[0];
+   dw[1] = vf->cut[1];
 }
 
 static inline void
@@ -354,40 +217,11 @@ gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
    ilo_builder_batch_write(builder, cmd_len, &dw0);
 }
 
-/**
- * Translate a pipe primitive type to the matching hardware primitive type.
- */
-static inline int
-gen6_3d_translate_pipe_prim(unsigned prim)
-{
-   static const int prim_mapping[ILO_PRIM_MAX] = {
-      [PIPE_PRIM_POINTS]                     = GEN6_3DPRIM_POINTLIST,
-      [PIPE_PRIM_LINES]                      = GEN6_3DPRIM_LINELIST,
-      [PIPE_PRIM_LINE_LOOP]                  = GEN6_3DPRIM_LINELOOP,
-      [PIPE_PRIM_LINE_STRIP]                 = GEN6_3DPRIM_LINESTRIP,
-      [PIPE_PRIM_TRIANGLES]                  = GEN6_3DPRIM_TRILIST,
-      [PIPE_PRIM_TRIANGLE_STRIP]             = GEN6_3DPRIM_TRISTRIP,
-      [PIPE_PRIM_TRIANGLE_FAN]               = GEN6_3DPRIM_TRIFAN,
-      [PIPE_PRIM_QUADS]                      = GEN6_3DPRIM_QUADLIST,
-      [PIPE_PRIM_QUAD_STRIP]                 = GEN6_3DPRIM_QUADSTRIP,
-      [PIPE_PRIM_POLYGON]                    = GEN6_3DPRIM_POLYGON,
-      [PIPE_PRIM_LINES_ADJACENCY]            = GEN6_3DPRIM_LINELIST_ADJ,
-      [PIPE_PRIM_LINE_STRIP_ADJACENCY]       = GEN6_3DPRIM_LINESTRIP_ADJ,
-      [PIPE_PRIM_TRIANGLES_ADJACENCY]        = GEN6_3DPRIM_TRILIST_ADJ,
-      [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]   = GEN6_3DPRIM_TRISTRIP_ADJ,
-      [ILO_PRIM_RECTANGLES]                  = GEN6_3DPRIM_RECTLIST,
-   };
-
-   assert(prim_mapping[prim]);
-
-   return prim_mapping[prim];
-}
-
 static inline void
-gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim)
+gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder,
+                         enum gen_3dprim_type topology)
 {
    const uint8_t cmd_len = 2;
-   const int prim = gen6_3d_translate_pipe_prim(pipe_prim);
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
@@ -395,12 +229,13 @@ gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim)
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
-   dw[1] = prim;
+   dw[1] = topology << GEN8_TOPOLOGY_DW1_TYPE__SHIFT;
 }
 
 static inline void
 gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
-                           int vb_index, uint32_t step_rate)
+                           const struct ilo_state_vf *vf,
+                           uint32_t attr)
 {
    const uint8_t cmd_len = 3;
    uint32_t *dw;
@@ -410,16 +245,20 @@ gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
-   dw[1] = vb_index;
-   if (step_rate)
-      dw[1] |= GEN8_INSTANCING_DW1_ENABLE;
-   dw[2] = step_rate;
+   dw[1] = attr << GEN8_INSTANCING_DW1_VE_INDEX__SHIFT;
+   dw[2] = 0;
+   /* see vf_set_gen8_3DSTATE_VF_INSTANCING() */
+   if (attr >= vf->internal_ve_count) {
+      attr -= vf->internal_ve_count;
+
+      dw[1] |= vf->user_instancing[attr][0];
+      dw[2] |= vf->user_instancing[attr][1];
+   }
 }
 
 static inline void
 gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
-                     bool vid_enable, int vid_ve, int vid_comp,
-                     bool iid_enable, int iid_ve, int iid_comp)
+                     const struct ilo_state_vf *vf)
 {
    const uint8_t cmd_len = 2;
    uint32_t *dw;
@@ -429,29 +268,19 @@ gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
-   dw[1] = 0;
-
-   if (iid_enable) {
-      dw[1] |= GEN8_SGVS_DW1_IID_ENABLE |
-               vid_comp << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT |
-               vid_ve << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT;
-   }
-
-   if (vid_enable) {
-      dw[1] |= GEN8_SGVS_DW1_VID_ENABLE |
-               vid_comp << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT |
-               vid_ve << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT;
-   }
+   /* see vf_params_set_gen8_3DSTATE_VF_SGVS() */
+   dw[1] = vf->sgvs[0];
 }
 
 static inline void
 gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
-                            const struct ilo_ve_state *ve,
-                            const struct ilo_vb_state *vb)
+                            const struct ilo_state_vf *vf,
+                            const struct ilo_state_vertex_buffer *vb,
+                            unsigned vb_count)
 {
    uint8_t cmd_len;
    uint32_t *dw;
-   unsigned pos, hw_idx;
+   unsigned pos, i;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
@@ -460,67 +289,52 @@ gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
     *
     *     "From 1 to 33 VBs can be specified..."
     */
-   assert(ve->vb_count <= 33);
+   assert(vb_count <= 33);
 
-   if (!ve->vb_count)
+   if (!vb_count)
       return;
 
-   cmd_len = 1 + 4 * ve->vb_count;
+   cmd_len = 1 + 4 * vb_count;
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
    dw++;
    pos++;
 
-   for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
-      const unsigned instance_divisor = ve->instance_divisors[hw_idx];
-      const unsigned pipe_idx = ve->vb_mapping[hw_idx];
-      const struct pipe_vertex_buffer *cso = &vb->states[pipe_idx];
+   for (i = 0; i < vb_count; i++) {
+      const struct ilo_state_vertex_buffer *b = &vb[i];
 
-      dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT;
+      /* see vertex_buffer_set_gen8_vertex_buffer_state() */
+      dw[0] = b->vb[0] |
+              i << GEN6_VB_DW0_INDEX__SHIFT;
 
       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
          dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
       else
          dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
 
-      if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
-         dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
-
-      if (instance_divisor)
-         dw[0] |= GEN6_VB_DW0_ACCESS_INSTANCEDATA;
-      else
-         dw[0] |= GEN6_VB_DW0_ACCESS_VERTEXDATA;
-
-      /* use null vb if there is no buffer or the stride is out of range */
-      if (!cso->buffer || cso->stride > 2048) {
-         dw[0] |= GEN6_VB_DW0_IS_NULL;
-         dw[1] = 0;
-         dw[2] = 0;
-         dw[3] = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ?
-            0 : instance_divisor;
-
-         continue;
-      }
-
-      dw[0] |= cso->stride << GEN6_VB_DW0_PITCH__SHIFT;
+      dw[1] = 0;
+      dw[2] = 0;
+      dw[3] = 0;
 
       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-         const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
-         const uint32_t start_offset = cso->buffer_offset;
+         if (b->need_bo)
+            ilo_builder_batch_reloc64(builder, pos + 1, b->bo, b->vb[1], 0);
 
-         ilo_builder_batch_reloc64(builder, pos + 1,
-               buf->bo, start_offset, 0);
-         dw[3] = buf->bo_size;
+         dw[3] |= b->vb[2];
       } else {
-         const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
-         const uint32_t start_offset = cso->buffer_offset;
-         const uint32_t end_offset = buf->bo_size - 1;
+         const int8_t elem = vf->vb_to_first_elem[i];
 
-         dw[3] = instance_divisor;
+         /* see vf_set_gen6_vertex_buffer_state() */
+         if (elem >= 0) {
+            dw[0] |= vf->user_instancing[elem][0];
+            dw[3] |= vf->user_instancing[elem][1];
+         }
 
-         ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
-         ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
+         if (b->need_bo) {
+            ilo_builder_batch_reloc(builder, pos + 1, b->bo, b->vb[1], 0);
+            ilo_builder_batch_reloc(builder, pos + 2, b->bo, b->vb[2], 0);
+         }
       }
 
       dw += 4;
@@ -563,248 +377,189 @@ gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
 
 static inline void
 gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
-                             const struct ilo_ve_state *ve)
+                             const struct ilo_state_vf *vf)
 {
    uint8_t cmd_len;
    uint32_t *dw;
-   unsigned i;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 92:
-    *
-    *    "At least one VERTEX_ELEMENT_STATE structure must be included."
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 93:
-    *
-    *     "Up to 34 (DevSNB+) vertex elements are supported."
-    */
-   assert(ve->count + ve->prepend_nosrc_cso >= 1);
-   assert(ve->count + ve->prepend_nosrc_cso <= 34);
-
-   STATIC_ASSERT(Elements(ve->cso[0].payload) == 2);
+   cmd_len = 1 + 2 * (vf->internal_ve_count + vf->user_ve_count);
 
-   cmd_len = 1 + 2 * (ve->count + ve->prepend_nosrc_cso);
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
    dw++;
 
-   if (ve->prepend_nosrc_cso) {
-      memcpy(dw, ve->nosrc_cso.payload, sizeof(ve->nosrc_cso.payload));
-      dw += 2;
-   }
-
-   for (i = 0; i < ve->count - ve->last_cso_edgeflag; i++) {
-      memcpy(dw, ve->cso[i].payload, sizeof(ve->cso[i].payload));
-      dw += 2;
+   /*
+    * see vf_params_set_gen6_internal_ve() and
+    * vf_set_gen6_3DSTATE_VERTEX_ELEMENTS()
+    */
+   if (vf->internal_ve_count) {
+      memcpy(dw, vf->internal_ve,
+            sizeof(vf->internal_ve[0]) * vf->internal_ve_count);
+      dw += 2 * vf->internal_ve_count;
    }
 
-   if (ve->last_cso_edgeflag)
-      memcpy(dw, ve->edgeflag_cso.payload, sizeof(ve->edgeflag_cso.payload));
+   memcpy(dw, vf->user_ve, sizeof(vf->user_ve[0]) * vf->user_ve_count);
 }
 
 static inline void
 gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
-                          const struct ilo_ib_state *ib,
-                          bool enable_cut_index)
+                          const struct ilo_state_vf *vf,
+                          const struct ilo_state_index_buffer *ib)
 {
    const uint8_t cmd_len = 3;
-   struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
-   uint32_t start_offset, end_offset;
-   int format;
-   uint32_t *dw;
+   uint32_t dw0, *dw;
    unsigned pos;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   if (!buf)
-      return;
-
-   /* this is moved to the new 3DSTATE_VF */
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5))
-      assert(!enable_cut_index);
-
-   switch (ib->hw_index_size) {
-   case 4:
-      format = GEN6_IB_DW0_FORMAT_DWORD;
-      break;
-   case 2:
-      format = GEN6_IB_DW0_FORMAT_WORD;
-      break;
-   case 1:
-      format = GEN6_IB_DW0_FORMAT_BYTE;
-      break;
-   default:
-      assert(!"unknown index size");
-      format = GEN6_IB_DW0_FORMAT_BYTE;
-      break;
-   }
+   dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
+         builder->mocs << GEN6_IB_DW0_MOCS__SHIFT;
 
    /*
-    * set start_offset to 0 here and adjust pipe_draw_info::start with
-    * ib->draw_start_offset in 3DPRIMITIVE
+    * see index_buffer_set_gen8_3DSTATE_INDEX_BUFFER() and
+    * vf_params_set_gen6_3dstate_index_buffer()
     */
-   start_offset = 0;
-   end_offset = buf->bo_size;
-
-   /* end_offset must also be aligned and is inclusive */
-   end_offset -= (end_offset % ib->hw_index_size);
-   end_offset--;
+   dw0 |= ib->ib[0];
+   if (ilo_dev_gen(builder->dev) <= ILO_GEN(7))
+      dw0 |= vf->cut[0];
 
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
-           builder->mocs << GEN6_IB_DW0_MOCS__SHIFT |
-           format;
-   if (enable_cut_index)
-      dw[0] |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
-
-   ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
-   ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
+   dw[0] = dw0;
+   if (ib->need_bo) {
+      ilo_builder_batch_reloc(builder, pos + 1, ib->bo, ib->ib[1], 0);
+      ilo_builder_batch_reloc(builder, pos + 2, ib->bo, ib->ib[2], 0);
+   } else {
+      dw[1] = 0;
+      dw[2] = 0;
+   }
 }
 
 static inline void
 gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
-                          const struct ilo_ib_state *ib)
+                          const struct ilo_state_vf *vf,
+                          const struct ilo_state_index_buffer *ib)
 {
    const uint8_t cmd_len = 5;
-   struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
-   int format;
    uint32_t *dw;
    unsigned pos;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   if (!buf)
-      return;
-
-   switch (ib->hw_index_size) {
-   case 4:
-      format = GEN8_IB_DW1_FORMAT_DWORD;
-      break;
-   case 2:
-      format = GEN8_IB_DW1_FORMAT_WORD;
-      break;
-   case 1:
-      format = GEN8_IB_DW1_FORMAT_BYTE;
-      break;
-   default:
-      assert(!"unknown index size");
-      format = GEN8_IB_DW1_FORMAT_BYTE;
-      break;
-   }
-
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
-   dw[1] = format |
+   /* see index_buffer_set_gen8_3DSTATE_INDEX_BUFFER() */
+   dw[1] = ib->ib[0] |
            builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
-   dw[4] = buf->bo_size;
 
-   /* ignore ib->offset here in favor of adjusting 3DPRIMITIVE */
-   ilo_builder_batch_reloc64(builder, pos + 2, buf->bo, 0, 0);
+   if (ib->need_bo) {
+      ilo_builder_batch_reloc64(builder, pos + 2, ib->bo, ib->ib[1], 0);
+   } else {
+      dw[2] = 0;
+      dw[3] = 0;
+   }
+
+   dw[4] = ib->ib[2];
 }
 
 static inline void
 gen6_3DSTATE_VS(struct ilo_builder *builder,
-                const struct ilo_shader_state *vs)
+                const struct ilo_state_vs *vs,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 6;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw2, dw4, dw5, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   cso = ilo_shader_get_kernel_cso(vs);
-   dw2 = cso->payload[0];
-   dw4 = cso->payload[1];
-   dw5 = cso->payload[2];
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(vs);
-   dw[2] = dw2;
-   dw[3] = 0; /* scratch */
-   dw[4] = dw4;
-   dw[5] = dw5;
+   dw[1] = kernel_offset;
+   /* see vs_set_gen6_3DSTATE_VS() */
+   dw[2] = vs->vs[0];
+   dw[3] = vs->vs[1];
+   dw[4] = vs->vs[2];
+   dw[5] = vs->vs[3];
 }
 
 static inline void
 gen8_3DSTATE_VS(struct ilo_builder *builder,
-                const struct ilo_shader_state *vs,
-                uint32_t clip_plane_enable)
+                const struct ilo_state_vs *vs,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 9;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw3, dw6, dw7, dw8, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   cso = ilo_shader_get_kernel_cso(vs);
-   dw3 = cso->payload[0];
-   dw6 = cso->payload[1];
-   dw7 = cso->payload[2];
-   dw8 = clip_plane_enable << GEN8_VS_DW8_UCP_CLIP_ENABLES__SHIFT;
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(vs);
+   dw[1] = kernel_offset;
    dw[2] = 0;
-   dw[3] = dw3;
-   dw[4] = 0; /* scratch */
+   /* see vs_set_gen6_3DSTATE_VS() */
+   dw[3] = vs->vs[0];
+   dw[4] = vs->vs[1];
    dw[5] = 0;
-   dw[6] = dw6;
-   dw[7] = dw7;
-   dw[8] = dw8;
+   dw[6] = vs->vs[2];
+   dw[7] = vs->vs[3];
+   dw[8] = vs->vs[4];
 }
 
 static inline void
-gen6_disable_3DSTATE_VS(struct ilo_builder *builder)
+gen7_3DSTATE_HS(struct ilo_builder *builder,
+                const struct ilo_state_hs *hs,
+                uint32_t kernel_offset)
 {
-   const uint8_t cmd_len = 6;
+   const uint8_t cmd_len = 7;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
-   dw[4] = 0;
-   dw[5] = 0;
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
+   /* see hs_set_gen7_3DSTATE_HS() */
+   dw[1] = hs->hs[0];
+   dw[2] = hs->hs[1];
+   dw[3] = kernel_offset;
+   dw[4] = hs->hs[2];
+   dw[5] = hs->hs[3];
+   dw[6] = 0;
 }
 
 static inline void
-gen7_disable_3DSTATE_HS(struct ilo_builder *builder)
+gen8_3DSTATE_HS(struct ilo_builder *builder,
+                const struct ilo_state_hs *hs,
+                uint32_t kernel_offset)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 7;
+   const uint8_t cmd_len = 9;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
+   /* see hs_set_gen7_3DSTATE_HS() */
+   dw[1] = hs->hs[0];
+   dw[2] = hs->hs[1];
+   dw[3] = kernel_offset;
    dw[4] = 0;
-   dw[5] = 0;
+   dw[5] = hs->hs[2];
    dw[6] = 0;
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[7] = 0;
-      dw[8] = 0;
-   }
+   dw[7] = hs->hs[3];
+   dw[8] = 0;
 }
 
 static inline void
-gen7_3DSTATE_TE(struct ilo_builder *builder)
+gen7_3DSTATE_TE(struct ilo_builder *builder,
+                const struct ilo_state_ds *ds)
 {
    const uint8_t cmd_len = 4;
    uint32_t *dw;
@@ -814,108 +569,61 @@ gen7_3DSTATE_TE(struct ilo_builder *builder)
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
+   /* see ds_set_gen7_3DSTATE_TE() */
+   dw[1] = ds->te[0];
+   dw[2] = ds->te[1];
+   dw[3] = ds->te[2];
 }
 
 static inline void
-gen7_disable_3DSTATE_DS(struct ilo_builder *builder)
+gen7_3DSTATE_DS(struct ilo_builder *builder,
+                const struct ilo_state_ds *ds,
+                uint32_t kernel_offset)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 6;
+   const uint8_t cmd_len = 6;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
+   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
-   dw[4] = 0;
-   dw[5] = 0;
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[6] = 0;
-      dw[7] = 0;
-      dw[8] = 0;
-   }
-}
-
-static inline void
-gen6_3DSTATE_GS(struct ilo_builder *builder,
-                const struct ilo_shader_state *gs)
-{
-   const uint8_t cmd_len = 7;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw2, dw4, dw5, dw6, *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 6);
-
-   cso = ilo_shader_get_kernel_cso(gs);
-   dw2 = cso->payload[0];
-   dw4 = cso->payload[1];
-   dw5 = cso->payload[2];
-   dw6 = cso->payload[3];
-
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(gs);
-   dw[2] = dw2;
-   dw[3] = 0; /* scratch */
-   dw[4] = dw4;
-   dw[5] = dw5;
-   dw[6] = dw6;
+   /* see ds_set_gen7_3DSTATE_DS() */
+   dw[1] = kernel_offset;
+   dw[2] = ds->ds[0];
+   dw[3] = ds->ds[1];
+   dw[4] = ds->ds[2];
+   dw[5] = ds->ds[3];
 }
 
 static inline void
-gen6_so_3DSTATE_GS(struct ilo_builder *builder,
-                   const struct ilo_shader_state *vs,
-                   int verts_per_prim)
+gen8_3DSTATE_DS(struct ilo_builder *builder,
+                const struct ilo_state_ds *ds,
+                uint32_t kernel_offset)
 {
-   const uint8_t cmd_len = 7;
-   struct ilo_shader_cso cso;
-   enum ilo_kernel_param param;
-   uint32_t dw2, dw4, dw5, dw6, *dw;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 6);
-
-   assert(ilo_shader_get_kernel_param(vs, ILO_KERNEL_VS_GEN6_SO));
-
-   switch (verts_per_prim) {
-   case 1:
-      param = ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET;
-      break;
-   case 2:
-      param = ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET;
-      break;
-   default:
-      param = ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET;
-      break;
-   }
+   const uint8_t cmd_len = 9;
+   uint32_t *dw;
 
-   /* cannot use VS's CSO */
-   ilo_gpe_init_gs_cso(builder->dev, vs, &cso);
-   dw2 = cso.payload[0];
-   dw4 = cso.payload[1];
-   dw5 = cso.payload[2];
-   dw6 = cso.payload[3];
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
-   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(vs) +
-           ilo_shader_get_kernel_param(vs, param);
-   dw[2] = dw2;
-   dw[3] = 0;
-   dw[4] = dw4;
-   dw[5] = dw5;
-   dw[6] = dw6;
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
+   /* see ds_set_gen7_3DSTATE_DS() */
+   dw[1] = kernel_offset;
+   dw[2] = 0;
+   dw[3] = ds->ds[0];
+   dw[4] = ds->ds[1];
+   dw[5] = 0;
+   dw[6] = ds->ds[2];
+   dw[7] = ds->ds[3];
+   dw[8] = ds->ds[4];
 }
 
 static inline void
-gen6_disable_3DSTATE_GS(struct ilo_builder *builder)
+gen6_3DSTATE_GS(struct ilo_builder *builder,
+                const struct ilo_state_gs *gs,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 7;
    uint32_t *dw;
@@ -925,13 +633,13 @@ gen6_disable_3DSTATE_GS(struct ilo_builder *builder)
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
-   dw[1] = 0;
-   dw[2] = 0;
-   dw[3] = 0;
-   /* honor the valid range of URB read length */
-   dw[4] = 1 << GEN6_GS_DW4_URB_READ_LEN__SHIFT;
-   dw[5] = GEN6_GS_DW5_STATISTICS;
-   dw[6] = 0;
+   dw[1] = kernel_offset;
+   /* see gs_set_gen6_3DSTATE_GS() */
+   dw[2] = gs->gs[0];
+   dw[3] = gs->gs[1];
+   dw[4] = gs->gs[2];
+   dw[5] = gs->gs[3];
+   dw[6] = gs->gs[4];
 }
 
 static inline void
@@ -960,183 +668,90 @@ gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
 
 static inline void
 gen7_3DSTATE_GS(struct ilo_builder *builder,
-                const struct ilo_shader_state *gs)
+                const struct ilo_state_gs *gs,
+                uint32_t kernel_offset)
 {
    const uint8_t cmd_len = 7;
-   const struct ilo_shader_cso *cso;
-   uint32_t dw2, dw4, dw5, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
-   cso = ilo_shader_get_kernel_cso(gs);
-   dw2 = cso->payload[0];
-   dw4 = cso->payload[1];
-   dw5 = cso->payload[2];
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
-   dw[1] = ilo_shader_get_kernel_offset(gs);
-   dw[2] = dw2;
-   dw[3] = 0; /* scratch */
-   dw[4] = dw4;
-   dw[5] = dw5;
+   dw[1] = kernel_offset;
+   /* see gs_set_gen7_3DSTATE_GS() */
+   dw[2] = gs->gs[0];
+   dw[3] = gs->gs[1];
+   dw[4] = gs->gs[2];
+   dw[5] = gs->gs[3];
    dw[6] = 0;
 }
 
 static inline void
-gen7_disable_3DSTATE_GS(struct ilo_builder *builder)
+gen8_3DSTATE_GS(struct ilo_builder *builder,
+                const struct ilo_state_gs *gs,
+                uint32_t kernel_offset)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 7;
+   const uint8_t cmd_len = 10;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
-   dw[1] = 0;
+   dw[1] = kernel_offset;
    dw[2] = 0;
-   dw[3] = 0;
-   dw[4] = 0;
-
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[7] = GEN8_GS_DW7_STATISTICS;
-      dw[8] = 0;
-      dw[9] = 0;
-   } else {
-      dw[5] = GEN7_GS_DW5_STATISTICS;
-      dw[6] = 0;
-   }
+   /* see gs_set_gen7_3DSTATE_GS() */
+   dw[3] = gs->gs[0];
+   dw[4] = gs->gs[1];
+   dw[5] = 0;
+   dw[6] = gs->gs[2];
+   dw[7] = gs->gs[3];
+   dw[8] = 0;
+   dw[9] = gs->gs[4];
 }
 
 static inline void
 gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
-                       int render_stream,
-                       bool render_disable,
-                       int vertex_attrib_count,
-                       const int *buf_strides)
+                       const struct ilo_state_sol *sol)
 {
    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
    uint32_t *dw;
-   int buf_mask;
 
    ILO_DEV_ASSERT(builder->dev, 7, 8);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
-
-   dw[1] = render_stream << GEN7_SO_DW1_RENDER_STREAM_SELECT__SHIFT;
-   if (render_disable)
-      dw[1] |= GEN7_SO_DW1_RENDER_DISABLE;
-
-   if (buf_strides) {
-      buf_mask = ((bool) buf_strides[3]) << 3 |
-                 ((bool) buf_strides[2]) << 2 |
-                 ((bool) buf_strides[1]) << 1 |
-                 ((bool) buf_strides[0]);
-      if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-         dw[3] = buf_strides[1] << 16 | buf_strides[0];
-         dw[4] = buf_strides[3] << 16 | buf_strides[1];
-      }
-   } else {
-      buf_mask = 0;
-   }
-
-   if (buf_mask) {
-      int read_len;
-
-      dw[1] |= GEN7_SO_DW1_SO_ENABLE |
-               GEN7_SO_DW1_STATISTICS;
-      /* API_OPENGL */
-      if (true)
-         dw[1] |= GEN7_SO_DW1_REORDER_TRAILING;
-      if (ilo_dev_gen(builder->dev) < ILO_GEN(8))
-         dw[1] |= buf_mask << GEN7_SO_DW1_BUFFER_ENABLES__SHIFT;
-
-      read_len = (vertex_attrib_count + 1) / 2;
-      if (!read_len)
-         read_len = 1;
-
-      dw[2] = 0 << GEN7_SO_DW2_STREAM3_READ_OFFSET__SHIFT |
-              (read_len - 1) << GEN7_SO_DW2_STREAM3_READ_LEN__SHIFT |
-              0 << GEN7_SO_DW2_STREAM2_READ_OFFSET__SHIFT |
-              (read_len - 1) << GEN7_SO_DW2_STREAM2_READ_LEN__SHIFT |
-              0 << GEN7_SO_DW2_STREAM1_READ_OFFSET__SHIFT |
-              (read_len - 1) << GEN7_SO_DW2_STREAM1_READ_LEN__SHIFT |
-              0 << GEN7_SO_DW2_STREAM0_READ_OFFSET__SHIFT |
-              (read_len - 1) << GEN7_SO_DW2_STREAM0_READ_LEN__SHIFT;
-   } else {
-      dw[2] = 0;
+   /* see sol_set_gen7_3DSTATE_STREAMOUT() */
+   dw[1] = sol->streamout[0];
+   dw[2] = sol->streamout[1];
+   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+      dw[3] = sol->strides[1] << GEN8_SO_DW3_BUFFER1_PITCH__SHIFT |
+              sol->strides[0] << GEN8_SO_DW3_BUFFER0_PITCH__SHIFT;
+      dw[4] = sol->strides[3] << GEN8_SO_DW4_BUFFER3_PITCH__SHIFT |
+              sol->strides[2] << GEN8_SO_DW4_BUFFER2_PITCH__SHIFT;
    }
 }
 
 static inline void
 gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
-                          const struct pipe_stream_output_info *so_info)
+                          const struct ilo_state_sol *sol)
 {
    /*
     * Note that "DWord Length" has 9 bits for this command and the type of
     * cmd_len cannot be uint8_t.
     */
    uint16_t cmd_len;
-   struct {
-      int buf_selects;
-      int decl_count;
-      uint16_t decls[128];
-   } streams[4];
-   unsigned buf_offsets[PIPE_MAX_SO_BUFFERS];
-   int hw_decl_count, i;
+   int cmd_decl_count;
    uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 7, 8);
 
-   memset(streams, 0, sizeof(streams));
-   memset(buf_offsets, 0, sizeof(buf_offsets));
-
-   for (i = 0; i < so_info->num_outputs; i++) {
-      unsigned decl, st, buf, reg, mask;
-
-      st = so_info->output[i].stream;
-      buf = so_info->output[i].output_buffer;
-
-      /* pad with holes */
-      while (buf_offsets[buf] < so_info->output[i].dst_offset) {
-         int num_dwords;
-
-         num_dwords = so_info->output[i].dst_offset - buf_offsets[buf];
-         if (num_dwords > 4)
-            num_dwords = 4;
-
-         decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
-                GEN7_SO_DECL_HOLE_FLAG |
-                ((1 << num_dwords) - 1) << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
-
-         assert(streams[st].decl_count < Elements(streams[st].decls));
-         streams[st].decls[streams[st].decl_count++] = decl;
-         buf_offsets[buf] += num_dwords;
-      }
-      assert(buf_offsets[buf] == so_info->output[i].dst_offset);
-
-      reg = so_info->output[i].register_index;
-      mask = ((1 << so_info->output[i].num_components) - 1) <<
-         so_info->output[i].start_component;
-
-      decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
-             reg << GEN7_SO_DECL_REG_INDEX__SHIFT |
-             mask << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
-
-      assert(streams[st].decl_count < Elements(streams[st].decls));
-
-      streams[st].buf_selects |= 1 << buf;
-      streams[st].decls[streams[st].decl_count++] = decl;
-      buf_offsets[buf] += so_info->output[i].num_components;
-   }
-
    if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
-      hw_decl_count = MAX4(streams[0].decl_count, streams[1].decl_count,
-                           streams[2].decl_count, streams[3].decl_count);
+      cmd_decl_count = sol->decl_count;
    } else {
       /*
        * From the Ivy Bridge PRM, volume 2 part 1, page 201:
@@ -1145,100 +760,97 @@ gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
        *      whenever this command is issued. The "Num Entries [n]" fields
        *      still contain the actual numbers of valid decls."
        */
-      hw_decl_count = 128;
+      cmd_decl_count = 128;
    }
 
-   cmd_len = 3 + 2 * hw_decl_count;
+   cmd_len = 3 + 2 * cmd_decl_count;
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
-   dw[1] = streams[3].buf_selects << GEN7_SO_DECL_DW1_STREAM3_BUFFER_SELECTS__SHIFT |
-           streams[2].buf_selects << GEN7_SO_DECL_DW1_STREAM2_BUFFER_SELECTS__SHIFT |
-           streams[1].buf_selects << GEN7_SO_DECL_DW1_STREAM1_BUFFER_SELECTS__SHIFT |
-           streams[0].buf_selects << GEN7_SO_DECL_DW1_STREAM0_BUFFER_SELECTS__SHIFT;
-   dw[2] = streams[3].decl_count << GEN7_SO_DECL_DW2_STREAM3_ENTRY_COUNT__SHIFT |
-           streams[2].decl_count << GEN7_SO_DECL_DW2_STREAM2_ENTRY_COUNT__SHIFT |
-           streams[1].decl_count << GEN7_SO_DECL_DW2_STREAM1_ENTRY_COUNT__SHIFT |
-           streams[0].decl_count << GEN7_SO_DECL_DW2_STREAM0_ENTRY_COUNT__SHIFT;
-   dw += 3;
-
-   for (i = 0; i < hw_decl_count; i++) {
-      dw[0] = streams[1].decls[i] << 16 | streams[0].decls[i];
-      dw[1] = streams[3].decls[i] << 16 | streams[2].decls[i];
-      dw += 2;
+   /* see sol_set_gen7_3DSTATE_SO_DECL_LIST() */
+   dw[1] = sol->so_decl[0];
+   dw[2] = sol->so_decl[1];
+   memcpy(&dw[3], sol->decl, sizeof(sol->decl[0]) * sol->decl_count);
+
+   if (sol->decl_count < cmd_decl_count) {
+      memset(&dw[3 + 2 * sol->decl_count], 0, sizeof(sol->decl[0]) *
+            cmd_decl_count - sol->decl_count);
    }
 }
 
 static inline void
-gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index, int stride,
-                       const struct pipe_stream_output_target *so_target)
+gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
+                       const struct ilo_state_sol *sol,
+                       const struct ilo_state_sol_buffer *sb,
+                       uint8_t buffer)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
-   struct ilo_buffer *buf;
-   int start, end;
+   const uint8_t cmd_len = 4;
    uint32_t *dw;
    unsigned pos;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
-
-   buf = ilo_buffer(so_target->buffer);
-
-   /* DWord-aligned */
-   assert(stride % 4 == 0);
-   assert(so_target->buffer_offset % 4 == 0);
+   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
-   stride &= ~3;
-   start = so_target->buffer_offset & ~3;
-   end = (start + so_target->buffer_size) & ~3;
+   assert(buffer < ILO_STATE_SOL_MAX_BUFFER_COUNT);
 
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
-   dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT |
-           stride;
-
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[1] |= builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
-
-      dw[4] = end - start;
-      dw[5] = 0;
-      dw[6] = 0;
-      dw[7] = 0;
-
-      ilo_builder_batch_reloc64(builder, pos + 2,
-            buf->bo, start, INTEL_RELOC_WRITE);
+   /* see sol_buffer_set_gen7_3dstate_so_buffer() */
+   dw[1] = buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
+           builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT |
+           sol->strides[buffer] << GEN7_SO_BUF_DW1_PITCH__SHIFT;
+
+   if (sb->need_bo) {
+      ilo_builder_batch_reloc(builder, pos + 2, sb->bo,
+            sb->so_buf[0], INTEL_RELOC_WRITE);
+      ilo_builder_batch_reloc(builder, pos + 3, sb->bo,
+            sb->so_buf[1], INTEL_RELOC_WRITE);
    } else {
-      dw[1] |= builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT;
-
-      ilo_builder_batch_reloc(builder, pos + 2,
-            buf->bo, start, INTEL_RELOC_WRITE);
-      ilo_builder_batch_reloc(builder, pos + 3,
-            buf->bo, end, INTEL_RELOC_WRITE);
+      dw[2] = 0;
+      dw[3] = 0;
    }
 }
 
 static inline void
-gen7_disable_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index)
+gen8_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
+                       const struct ilo_state_sol *sol,
+                       const struct ilo_state_sol_buffer *sb,
+                       uint8_t buffer)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
+   const uint8_t cmd_len = 8;
    uint32_t *dw;
+   unsigned pos;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+   pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
-   dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT;
-   dw[2] = 0;
-   dw[3] = 0;
+   /* see sol_buffer_set_gen8_3dstate_so_buffer() */
+   dw[1] = sb->so_buf[0] |
+           buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
+           builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
+
+   if (sb->need_bo) {
+      ilo_builder_batch_reloc64(builder, pos + 2, sb->bo,
+            sb->so_buf[1], INTEL_RELOC_WRITE);
+   } else {
+      dw[2] = 0;
+      dw[3] = 0;
+   }
 
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[4] = 0;
+   dw[4] = sb->so_buf[2];
+
+   if (sb->need_write_offset_bo) {
+      ilo_builder_batch_reloc64(builder, pos + 5, sb->write_offset_bo,
+            sizeof(uint32_t) * buffer, INTEL_RELOC_WRITE);
+   } else {
       dw[5] = 0;
       dw[6] = 0;
-      dw[7] = 0;
    }
+
+   dw[7] = sb->so_buf[3];
 }
 
 static inline void
@@ -1627,8 +1239,7 @@ gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
 
 static inline uint32_t
 gen6_SURFACE_STATE(struct ilo_builder *builder,
-                   const struct ilo_view_surface *surf,
-                   bool for_render)
+                   const struct ilo_state_surface *surf)
 {
    int state_align, state_len;
    uint32_t state_offset, *dw;
@@ -1641,7 +1252,7 @@ gen6_SURFACE_STATE(struct ilo_builder *builder,
 
       state_offset = ilo_builder_surface_pointer(builder,
             ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
-      memcpy(dw, surf->payload, state_len << 2);
+      memcpy(dw, surf->surface, state_len << 2);
 
       if (surf->bo) {
          const uint32_t mocs = (surf->scanout) ?
@@ -1650,7 +1261,7 @@ gen6_SURFACE_STATE(struct ilo_builder *builder,
          dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
 
          ilo_builder_surface_reloc64(builder, state_offset, 8, surf->bo,
-               surf->payload[8], (for_render) ? INTEL_RELOC_WRITE : 0);
+               surf->surface[8], (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    } else {
       state_align = 32;
@@ -1658,7 +1269,7 @@ gen6_SURFACE_STATE(struct ilo_builder *builder,
 
       state_offset = ilo_builder_surface_pointer(builder,
             ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
-      memcpy(dw, surf->payload, state_len << 2);
+      memcpy(dw, surf->surface, state_len << 2);
 
       if (surf->bo) {
          /*
@@ -1668,63 +1279,21 @@ gen6_SURFACE_STATE(struct ilo_builder *builder,
          dw[5] |= builder->mocs << GEN6_SURFACE_DW5_MOCS__SHIFT;
 
          ilo_builder_surface_reloc(builder, state_offset, 1, surf->bo,
-               surf->payload[1], (for_render) ? INTEL_RELOC_WRITE : 0);
+               surf->surface[1], (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
       }
    }
 
    return state_offset;
 }
 
-static inline uint32_t
-gen6_so_SURFACE_STATE(struct ilo_builder *builder,
-                      const struct pipe_stream_output_target *so,
-                      const struct pipe_stream_output_info *so_info,
-                      int so_index)
-{
-   struct ilo_buffer *buf = ilo_buffer(so->buffer);
-   unsigned bo_offset, struct_size;
-   enum pipe_format elem_format;
-   struct ilo_view_surface surf;
-
-   ILO_DEV_ASSERT(builder->dev, 6, 6);
-
-   bo_offset = so->buffer_offset + so_info->output[so_index].dst_offset * 4;
-   struct_size = so_info->stride[so_info->output[so_index].output_buffer] * 4;
-
-   switch (so_info->output[so_index].num_components) {
-   case 1:
-      elem_format = PIPE_FORMAT_R32_FLOAT;
-      break;
-   case 2:
-      elem_format = PIPE_FORMAT_R32G32_FLOAT;
-      break;
-   case 3:
-      elem_format = PIPE_FORMAT_R32G32B32_FLOAT;
-      break;
-   case 4:
-      elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-      break;
-   default:
-      assert(!"unexpected SO components length");
-      elem_format = PIPE_FORMAT_R32_FLOAT;
-      break;
-   }
-
-   ilo_gpe_init_view_surface_for_buffer(builder->dev, buf, bo_offset,
-         so->buffer_size, struct_size, elem_format, false, true, &surf);
-
-   return gen6_SURFACE_STATE(builder, &surf, false);
-}
-
 static inline uint32_t
 gen6_SAMPLER_STATE(struct ilo_builder *builder,
-                   const struct ilo_sampler_cso * const *samplers,
-                   const struct pipe_sampler_view * const *views,
+                   const struct ilo_state_sampler *samplers,
                    const uint32_t *sampler_border_colors,
-                   int num_samplers)
+                   int sampler_count)
 {
    const int state_align = 32;
-   const int state_len = 4 * num_samplers;
+   const int state_len = 4 * sampler_count;
    uint32_t state_offset, *dw;
    int i;
 
@@ -1735,9 +1304,9 @@ gen6_SAMPLER_STATE(struct ilo_builder *builder,
     *
     *     "The sampler state is stored as an array of up to 16 elements..."
     */
-   assert(num_samplers <= 16);
+   assert(sampler_count <= 16);
 
-   if (!num_samplers)
+   if (!sampler_count)
       return 0;
 
    /*
@@ -1749,86 +1318,19 @@ gen6_SAMPLER_STATE(struct ilo_builder *builder,
     *
     * It also applies to other shader stages.
     */
-   ilo_builder_dynamic_pad_top(builder, 4 * (4 - (num_samplers % 4)));
+   ilo_builder_dynamic_pad_top(builder, 4 * (4 - (sampler_count % 4)));
 
    state_offset = ilo_builder_dynamic_pointer(builder,
          ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
 
-   for (i = 0; i < num_samplers; i++) {
-      const struct ilo_sampler_cso *sampler = samplers[i];
-      const struct pipe_sampler_view *view = views[i];
-      const uint32_t border_color = sampler_border_colors[i];
-      uint32_t dw_filter, dw_wrap;
-
-      /* there may be holes */
-      if (!sampler || !view) {
-         /* disabled sampler */
-         dw[0] = 1 << 31;
-         dw[1] = 0;
-         dw[2] = 0;
-         dw[3] = 0;
-         dw += 4;
-
-         continue;
-      }
-
-      /* determine filter and wrap modes */
-      switch (view->texture->target) {
-      case PIPE_TEXTURE_1D:
-         dw_filter = (sampler->anisotropic) ?
-            sampler->dw_filter_aniso : sampler->dw_filter;
-         dw_wrap = sampler->dw_wrap_1d;
-         break;
-      case PIPE_TEXTURE_3D:
-         /*
-          * From the Sandy Bridge PRM, volume 4 part 1, page 103:
-          *
-          *     "Only MAPFILTER_NEAREST and MAPFILTER_LINEAR are supported for
-          *      surfaces of type SURFTYPE_3D."
-          */
-         dw_filter = sampler->dw_filter;
-         dw_wrap = sampler->dw_wrap;
-         break;
-      case PIPE_TEXTURE_CUBE:
-         dw_filter = (sampler->anisotropic) ?
-            sampler->dw_filter_aniso : sampler->dw_filter;
-         dw_wrap = sampler->dw_wrap_cube;
-         break;
-      default:
-         dw_filter = (sampler->anisotropic) ?
-            sampler->dw_filter_aniso : sampler->dw_filter;
-         dw_wrap = sampler->dw_wrap;
-         break;
-      }
+   for (i = 0; i < sampler_count; i++) {
+      /* see sampler_set_gen6_SAMPLER_STATE() */
+      dw[0] = samplers[i].sampler[0];
+      dw[1] = samplers[i].sampler[1];
+      dw[3] = samplers[i].sampler[2];
 
-      dw[0] = sampler->payload[0];
-      dw[1] = sampler->payload[1];
-      assert(!(border_color & 0x1f));
-      dw[2] = border_color;
-      dw[3] = sampler->payload[2];
-
-      dw[0] |= dw_filter;
-
-      if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
-         dw[3] |= dw_wrap;
-      }
-      else {
-         /*
-          * From the Sandy Bridge PRM, volume 4 part 1, page 21:
-          *
-          *     "[DevSNB] Errata: Incorrect behavior is observed in cases
-          *      where the min and mag mode filters are different and
-          *      SurfMinLOD is nonzero. The determination of MagMode uses the
-          *      following equation instead of the one in the above
-          *      pseudocode: MagMode = (LOD + SurfMinLOD - Base <= 0)"
-          *
-          * As a way to work around that, we set Base to
-          * view->u.tex.first_level.
-          */
-         dw[0] |= view->u.tex.first_level << 22;
-
-         dw[1] |= dw_wrap;
-      }
+      assert(!(sampler_border_colors[i] & 0x1f));
+      dw[2] = sampler_border_colors[i];
 
       dw += 4;
    }
@@ -1838,7 +1340,7 @@ gen6_SAMPLER_STATE(struct ilo_builder *builder,
 
 static inline uint32_t
 gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
-                                const struct ilo_sampler_cso *sampler)
+                                const struct ilo_state_sampler_border *border)
 {
    const int state_align =
       (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
@@ -1846,11 +1348,12 @@ gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   assert(Elements(sampler->payload) >= 3 + state_len);
-
-   /* see ilo_gpe_init_sampler_cso() */
+   /*
+    * see border_set_gen6_SAMPLER_BORDER_COLOR_STATE() and
+    * border_set_gen7_SAMPLER_BORDER_COLOR_STATE()
+    */
    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
-         state_align, state_len, &sampler->payload[3]);
+         state_align, state_len, border->color);
 }
 
 static inline uint32_t
index cedaab1559d151430da0fff64ca71a6a13931cb3..c5a98c91204406f51faf42af98b15fc511261253 100644 (file)
@@ -319,7 +319,7 @@ writer_decode_color_calc(const struct ilo_builder *builder,
               "stencil ref %d, bf stencil ref %d\n",
              GEN_EXTRACT(dw, GEN6_CC_DW0_ALPHATEST) ? "FLOAT32" : "UNORM8",
              (bool) (dw & GEN6_CC_DW0_ROUND_DISABLE_DISABLE),
-             GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL0_REF),
+             GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL_REF),
              GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL1_REF));
 
    writer_dw(builder, which, item->offset, 1, "CC\n");
@@ -347,13 +347,13 @@ writer_decode_depth_stencil(const struct ilo_builder *builder,
    dw = writer_dw(builder, which, item->offset, 0, "D_S");
    ilo_printf("stencil %sable, func %d, write %sable\n",
          (dw & GEN6_ZS_DW0_STENCIL_TEST_ENABLE) ? "en" : "dis",
-         GEN_EXTRACT(dw, GEN6_ZS_DW0_STENCIL0_FUNC),
+         GEN_EXTRACT(dw, GEN6_ZS_DW0_STENCIL_FUNC),
          (dw & GEN6_ZS_DW0_STENCIL_WRITE_ENABLE) ? "en" : "dis");
 
    dw = writer_dw(builder, which, item->offset, 1, "D_S");
    ilo_printf("stencil test mask 0x%x, write mask 0x%x\n",
-         GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL0_VALUEMASK),
-         GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL0_WRITEMASK));
+         GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL_TEST_MASK),
+         GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL_WRITE_MASK));
 
    dw = writer_dw(builder, which, item->offset, 2, "D_S");
    ilo_printf("depth test %sable, func %d, write %sable\n",
index 7fbe6d41635f2bdf15031eea620b748d410e26ef..7197104a23e930f0337ff6ce5933acf73cbd5282 100644 (file)
 #define ILO_BUILDER_MEDIA_H
 
 #include "genhw/genhw.h"
-#include "../ilo_shader.h"
 #include "intel_winsys.h"
 
 #include "ilo_core.h"
 #include "ilo_dev.h"
+#include "ilo_state_compute.h"
 #include "ilo_builder.h"
 
-struct gen6_idrt_data {
-   const struct ilo_shader_state *cs;
-
-   uint32_t sampler_offset;
-   uint32_t binding_table_offset;
-
-   unsigned curbe_size;
-   unsigned thread_group_size;
-};
-
 static inline void
 gen6_MEDIA_VFE_STATE(struct ilo_builder *builder,
-                     unsigned curbe_alloc, bool use_slm)
+                     const struct ilo_state_compute *compute)
 {
    const uint8_t cmd_len = 8;
-   const unsigned idrt_alloc =
-      ((ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) ? 64 : 32) * 32;
-   int max_threads;
    uint32_t *dw;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
-   max_threads = builder->dev->thread_count;
-
-   curbe_alloc = align(curbe_alloc, 32);
-   assert(idrt_alloc + curbe_alloc <= builder->dev->urb_size / (use_slm + 1));
+   ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_VFE_STATE) | (cmd_len - 2);
-   dw[1] = 0; /* scratch */
-
-   dw[2] = (max_threads - 1) << GEN6_VFE_DW2_MAX_THREADS__SHIFT |
-           0 << GEN6_VFE_DW2_URB_ENTRY_COUNT__SHIFT |
-           GEN6_VFE_DW2_RESET_GATEWAY_TIMER |
-           GEN6_VFE_DW2_BYPASS_GATEWAY_CONTROL;
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
-      dw[2] |= GEN7_VFE_DW2_GPGPU_MODE;
-
+   /* see compute_set_gen6_MEDIA_VFE_STATE() */
+   dw[1] = compute->vfe[0];
+   dw[2] = compute->vfe[1];
    dw[3] = 0;
-
-   dw[4] = 0 << GEN6_VFE_DW4_URB_ENTRY_SIZE__SHIFT |
-           (curbe_alloc / 32);
-
+   dw[4] = compute->vfe[2];
    dw[5] = 0;
    dw[6] = 0;
    dw[7] = 0;
@@ -194,8 +167,10 @@ gen7_GPGPU_WALKER(struct ilo_builder *builder,
 
 static inline uint32_t
 gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_builder *builder,
-                               const struct gen6_idrt_data *data,
-                               int idrt_count)
+                               const struct ilo_state_compute *compute,
+                               const uint32_t *kernel_offsets,
+                               const uint32_t *sampler_offsets,
+                               const uint32_t *binding_table_offsets)
 {
    /*
     * From the Sandy Bridge PRM, volume 2 part 2, page 34:
@@ -211,61 +186,26 @@ gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_builder *builder,
     *      aligned address of the Interface Descriptor data."
     */
    const int state_align = 32;
-   const int state_len = (32 / 4) * idrt_count;
+   const int state_len = (32 / 4) * compute->idrt_count;
    uint32_t state_offset, *dw;
    int i;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+   ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
    state_offset = ilo_builder_dynamic_pointer(builder,
          ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR, state_align, state_len, &dw);
 
-   for (i = 0; i < idrt_count; i++) {
-      const struct gen6_idrt_data *idrt = &data[i];
-      const struct ilo_shader_state *cs = idrt->cs;
-      unsigned sampler_count, bt_size, slm_size;
-
-      sampler_count =
-         ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);
-      assert(sampler_count <= 16);
-      sampler_count = (sampler_count + 3) / 4;
-
-      bt_size =
-         ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
-      if (bt_size > 31)
-         bt_size = 31;
-
-      slm_size = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_LOCAL_SIZE);
-
-      assert(idrt->curbe_size / 32 <= 63);
-
-      dw[0] = ilo_shader_get_kernel_offset(idrt->cs);
+   for (i = 0; i < compute->idrt_count; i++) {
+      /* see compute_set_gen6_INTERFACE_DESCRIPTOR_DATA() */
+      dw[0] = compute->idrt[i][0] + kernel_offsets[i];
       dw[1] = 0;
-      dw[2] = idrt->sampler_offset |
-              sampler_count << GEN6_IDRT_DW2_SAMPLER_COUNT__SHIFT;
-      dw[3] = idrt->binding_table_offset |
-              bt_size << GEN6_IDRT_DW3_BINDING_TABLE_SIZE__SHIFT;
-
-      dw[4] = (idrt->curbe_size / 32) << GEN6_IDRT_DW4_CURBE_READ_LEN__SHIFT |
-              0 << GEN6_IDRT_DW4_CURBE_READ_OFFSET__SHIFT;
-
-      if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
-         dw[5] = GEN7_IDRT_DW5_ROUNDING_MODE_RTNE;
-
-         if (slm_size) {
-            assert(slm_size <= 64 * 1024);
-            slm_size = util_next_power_of_two((slm_size + 4095) / 4096);
-
-            dw[5] |= GEN7_IDRT_DW5_BARRIER_ENABLE |
-                     slm_size << GEN7_IDRT_DW5_SLM_SIZE__SHIFT |
-                     idrt->thread_group_size <<
-                        GEN7_IDRT_DW5_THREAD_GROUP_SIZE__SHIFT;
-         }
-      } else {
-         dw[5] = 0;
-      }
-
-      dw[6] = 0;
+      dw[2] = compute->idrt[i][1] |
+              sampler_offsets[i];
+      dw[3] = compute->idrt[i][2] |
+              binding_table_offsets[i];
+      dw[4] = compute->idrt[i][3];
+      dw[5] = compute->idrt[i][4];
+      dw[6] = compute->idrt[i][5];
       dw[7] = 0;
 
       dw += 8;
index 3587d3930f3757feb15612507aa2c5ccd71b277d..0a7f7d9d3feeefc98a057c15399907f516843c69 100644 (file)
@@ -40,7 +40,4 @@
 #include "util/u_memory.h"
 #include "util/u_pointer.h"
 
-#define ILO_PRIM_RECTANGLES PIPE_PRIM_MAX
-#define ILO_PRIM_MAX (PIPE_PRIM_MAX + 1)
-
 #endif /* ILO_CORE_H */
index d9c460498ff1fd656fe75a1c114398112b1e2fde..9833233d7964b75beae5a7eb1ffc0d57b7f8bf90 100644 (file)
@@ -100,4 +100,21 @@ ilo_warn(const char *format, ...)
 #endif
 }
 
+static inline bool
+ilo_is_zeroed(const void *ptr, size_t size)
+{
+#ifdef DEBUG
+   size_t i;
+
+   for (i = 0; i < size; i++) {
+      if (*((const char *) ptr) != 0)
+         return false;
+   }
+
+   return true;
+#else
+   return true;
+#endif
+}
+
 #endif /* ILO_DEBUG_H */
index 7a774fa1591a07e0c7ac4631c0aa5f886dcbc751..925322abba4cf820df2c95e720f7ee5f034ddbdc 100644 (file)
 #include "ilo_dev.h"
 
 /**
- * Initialize the \p dev from \p winsys.  \p winsys is considered owned by \p
- * dev and will be destroyed in \p ilo_dev_cleanup().
+ * Initialize the \p dev from \p winsys.
  */
 bool
 ilo_dev_init(struct ilo_dev *dev, struct intel_winsys *winsys)
 {
    const struct intel_winsys_info *info;
 
+   assert(ilo_is_zeroed(dev, sizeof(*dev)));
+
    info = intel_winsys_get_info(winsys);
 
    dev->winsys = winsys;
@@ -178,9 +179,3 @@ ilo_dev_init(struct ilo_dev *dev, struct intel_winsys *winsys)
 
    return true;
 }
-
-void
-ilo_dev_cleanup(struct ilo_dev *dev)
-{
-   intel_winsys_destroy(dev->winsys);
-}
index 4eb5d59dc86222ecf26fd200cc30822f560594d2..a9f9b176e1676677719db20f84b091c5cc5a37ac 100644 (file)
@@ -63,9 +63,6 @@ struct ilo_dev {
 bool
 ilo_dev_init(struct ilo_dev *dev, struct intel_winsys *winsys);
 
-void
-ilo_dev_cleanup(struct ilo_dev *dev);
-
 static inline int
 ilo_dev_gen(const struct ilo_dev *dev)
 {
diff --git a/src/gallium/drivers/ilo/core/ilo_fence.h b/src/gallium/drivers/ilo/core/ilo_fence.h
deleted file mode 100644 (file)
index 00d555a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2013 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_FENCE_H
-#define ILO_FENCE_H
-
-#include "intel_winsys.h"
-
-#include "ilo_core.h"
-#include "ilo_dev.h"
-
-struct ilo_fence {
-   struct intel_bo *seq_bo;
-};
-
-static inline void
-ilo_fence_init(struct ilo_fence *fence, const struct ilo_dev *dev)
-{
-   /* no-op */
-}
-
-static inline void
-ilo_fence_cleanup(struct ilo_fence *fence)
-{
-   intel_bo_unref(fence->seq_bo);
-}
-
-/**
- * Set the sequence bo for waiting.  The fence is considered signaled when
- * there is no sequence bo.
- */
-static inline void
-ilo_fence_set_seq_bo(struct ilo_fence *fence, struct intel_bo *seq_bo)
-{
-   intel_bo_unref(fence->seq_bo);
-   fence->seq_bo = intel_bo_ref(seq_bo);
-}
-
-/**
- * Wait for the fence to be signaled or until \p timeout nanoseconds has
- * passed.  It will wait indefinitely when \p timeout is negative.
- */
-static inline bool
-ilo_fence_wait(struct ilo_fence *fence, int64_t timeout)
-{
-   return (!fence->seq_bo || intel_bo_wait(fence->seq_bo, timeout) == 0);
-}
-
-#endif /* ILO_FENCE_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_format.c b/src/gallium/drivers/ilo/core/ilo_format.c
deleted file mode 100644 (file)
index 280e499..0000000
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2013 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#include "genhw/genhw.h"
-#include "ilo_format.h"
-
-struct ilo_vf_cap {
-   int vertex_element;
-};
-
-struct ilo_sol_cap {
-   int buffer;
-};
-
-struct ilo_sampler_cap {
-   int sampling;
-   int filtering;
-   int shadow_map;
-   int chroma_key;
-};
-
-struct ilo_dp_cap {
-   int rt_write;
-   int rt_write_blending;
-   int typed_write;
-   int media_color_processing;
-};
-
-/*
- * This table is based on:
- *
- *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
- *  - the Ivy Bridge PRM, volume 2 part 1, page 97-99
- *  - the Haswell PRM, volume 7, page 467-470
- */
-static const struct ilo_vf_cap ilo_vf_caps[] = {
-#define CAP(vertex_element) { ILO_GEN(vertex_element) }
-   [GEN6_FORMAT_R32G32B32A32_FLOAT]       = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_SINT]        = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_UINT]        = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_UNORM]       = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_SNORM]       = CAP(  1),
-   [GEN6_FORMAT_R64G64_FLOAT]             = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_SSCALED]     = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_USCALED]     = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_SFIXED]      = CAP(7.5),
-   [GEN6_FORMAT_R32G32B32_FLOAT]          = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_SINT]           = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_UINT]           = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_UNORM]          = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_SNORM]          = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_SSCALED]        = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_USCALED]        = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_SFIXED]         = CAP(7.5),
-   [GEN6_FORMAT_R16G16B16A16_UNORM]       = CAP(  1),
-   [GEN6_FORMAT_R16G16B16A16_SNORM]       = CAP(  1),
-   [GEN6_FORMAT_R16G16B16A16_SINT]        = CAP(  1),
-   [GEN6_FORMAT_R16G16B16A16_UINT]        = CAP(  1),
-   [GEN6_FORMAT_R16G16B16A16_FLOAT]       = CAP(  1),
-   [GEN6_FORMAT_R32G32_FLOAT]             = CAP(  1),
-   [GEN6_FORMAT_R32G32_SINT]              = CAP(  1),
-   [GEN6_FORMAT_R32G32_UINT]              = CAP(  1),
-   [GEN6_FORMAT_R32G32_UNORM]             = CAP(  1),
-   [GEN6_FORMAT_R32G32_SNORM]             = CAP(  1),
-   [GEN6_FORMAT_R64_FLOAT]                = CAP(  1),
-   [GEN6_FORMAT_R16G16B16A16_SSCALED]     = CAP(  1),
-   [GEN6_FORMAT_R16G16B16A16_USCALED]     = CAP(  1),
-   [GEN6_FORMAT_R32G32_SSCALED]           = CAP(  1),
-   [GEN6_FORMAT_R32G32_USCALED]           = CAP(  1),
-   [GEN6_FORMAT_R32G32_SFIXED]            = CAP(7.5),
-   [GEN6_FORMAT_B8G8R8A8_UNORM]           = CAP(  1),
-   [GEN6_FORMAT_R10G10B10A2_UNORM]        = CAP(  1),
-   [GEN6_FORMAT_R10G10B10A2_UINT]         = CAP(  1),
-   [GEN6_FORMAT_R10G10B10_SNORM_A2_UNORM] = CAP(  1),
-   [GEN6_FORMAT_R8G8B8A8_UNORM]           = CAP(  1),
-   [GEN6_FORMAT_R8G8B8A8_SNORM]           = CAP(  1),
-   [GEN6_FORMAT_R8G8B8A8_SINT]            = CAP(  1),
-   [GEN6_FORMAT_R8G8B8A8_UINT]            = CAP(  1),
-   [GEN6_FORMAT_R16G16_UNORM]             = CAP(  1),
-   [GEN6_FORMAT_R16G16_SNORM]             = CAP(  1),
-   [GEN6_FORMAT_R16G16_SINT]              = CAP(  1),
-   [GEN6_FORMAT_R16G16_UINT]              = CAP(  1),
-   [GEN6_FORMAT_R16G16_FLOAT]             = CAP(  1),
-   [GEN6_FORMAT_B10G10R10A2_UNORM]        = CAP(7.5),
-   [GEN6_FORMAT_R11G11B10_FLOAT]          = CAP(  1),
-   [GEN6_FORMAT_R32_SINT]                 = CAP(  1),
-   [GEN6_FORMAT_R32_UINT]                 = CAP(  1),
-   [GEN6_FORMAT_R32_FLOAT]                = CAP(  1),
-   [GEN6_FORMAT_R32_UNORM]                = CAP(  1),
-   [GEN6_FORMAT_R32_SNORM]                = CAP(  1),
-   [GEN6_FORMAT_R10G10B10X2_USCALED]      = CAP(  1),
-   [GEN6_FORMAT_R8G8B8A8_SSCALED]         = CAP(  1),
-   [GEN6_FORMAT_R8G8B8A8_USCALED]         = CAP(  1),
-   [GEN6_FORMAT_R16G16_SSCALED]           = CAP(  1),
-   [GEN6_FORMAT_R16G16_USCALED]           = CAP(  1),
-   [GEN6_FORMAT_R32_SSCALED]              = CAP(  1),
-   [GEN6_FORMAT_R32_USCALED]              = CAP(  1),
-   [GEN6_FORMAT_R8G8_UNORM]               = CAP(  1),
-   [GEN6_FORMAT_R8G8_SNORM]               = CAP(  1),
-   [GEN6_FORMAT_R8G8_SINT]                = CAP(  1),
-   [GEN6_FORMAT_R8G8_UINT]                = CAP(  1),
-   [GEN6_FORMAT_R16_UNORM]                = CAP(  1),
-   [GEN6_FORMAT_R16_SNORM]                = CAP(  1),
-   [GEN6_FORMAT_R16_SINT]                 = CAP(  1),
-   [GEN6_FORMAT_R16_UINT]                 = CAP(  1),
-   [GEN6_FORMAT_R16_FLOAT]                = CAP(  1),
-   [GEN6_FORMAT_R8G8_SSCALED]             = CAP(  1),
-   [GEN6_FORMAT_R8G8_USCALED]             = CAP(  1),
-   [GEN6_FORMAT_R16_SSCALED]              = CAP(  1),
-   [GEN6_FORMAT_R16_USCALED]              = CAP(  1),
-   [GEN6_FORMAT_R8_UNORM]                 = CAP(  1),
-   [GEN6_FORMAT_R8_SNORM]                 = CAP(  1),
-   [GEN6_FORMAT_R8_SINT]                  = CAP(  1),
-   [GEN6_FORMAT_R8_UINT]                  = CAP(  1),
-   [GEN6_FORMAT_R8_SSCALED]               = CAP(  1),
-   [GEN6_FORMAT_R8_USCALED]               = CAP(  1),
-   [GEN6_FORMAT_R8G8B8_UNORM]             = CAP(  1),
-   [GEN6_FORMAT_R8G8B8_SNORM]             = CAP(  1),
-   [GEN6_FORMAT_R8G8B8_SSCALED]           = CAP(  1),
-   [GEN6_FORMAT_R8G8B8_USCALED]           = CAP(  1),
-   [GEN6_FORMAT_R64G64B64A64_FLOAT]       = CAP(  1),
-   [GEN6_FORMAT_R64G64B64_FLOAT]          = CAP(  1),
-   [GEN6_FORMAT_R16G16B16_FLOAT]          = CAP(  6),
-   [GEN6_FORMAT_R16G16B16_UNORM]          = CAP(  1),
-   [GEN6_FORMAT_R16G16B16_SNORM]          = CAP(  1),
-   [GEN6_FORMAT_R16G16B16_SSCALED]        = CAP(  1),
-   [GEN6_FORMAT_R16G16B16_USCALED]        = CAP(  1),
-   [GEN6_FORMAT_R16G16B16_UINT]           = CAP(7.5),
-   [GEN6_FORMAT_R16G16B16_SINT]           = CAP(7.5),
-   [GEN6_FORMAT_R32_SFIXED]               = CAP(7.5),
-   [GEN6_FORMAT_R10G10B10A2_SNORM]        = CAP(7.5),
-   [GEN6_FORMAT_R10G10B10A2_USCALED]      = CAP(7.5),
-   [GEN6_FORMAT_R10G10B10A2_SSCALED]      = CAP(7.5),
-   [GEN6_FORMAT_R10G10B10A2_SINT]         = CAP(7.5),
-   [GEN6_FORMAT_B10G10R10A2_SNORM]        = CAP(7.5),
-   [GEN6_FORMAT_B10G10R10A2_USCALED]      = CAP(7.5),
-   [GEN6_FORMAT_B10G10R10A2_SSCALED]      = CAP(7.5),
-   [GEN6_FORMAT_B10G10R10A2_UINT]         = CAP(7.5),
-   [GEN6_FORMAT_B10G10R10A2_SINT]         = CAP(7.5),
-   [GEN6_FORMAT_R8G8B8_UINT]              = CAP(7.5),
-   [GEN6_FORMAT_R8G8B8_SINT]              = CAP(7.5),
-#undef CAP
-};
-
-/*
- * This table is based on:
- *
- *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
- *  - the Ivy Bridge PRM, volume 2 part 1, page 195
- *  - the Haswell PRM, volume 7, page 535
- */
-static const struct ilo_sol_cap ilo_sol_caps[] = {
-#define CAP(buffer) { ILO_GEN(buffer) }
-   [GEN6_FORMAT_R32G32B32A32_FLOAT]       = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_SINT]        = CAP(  1),
-   [GEN6_FORMAT_R32G32B32A32_UINT]        = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_FLOAT]          = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_SINT]           = CAP(  1),
-   [GEN6_FORMAT_R32G32B32_UINT]           = CAP(  1),
-   [GEN6_FORMAT_R32G32_FLOAT]             = CAP(  1),
-   [GEN6_FORMAT_R32G32_SINT]              = CAP(  1),
-   [GEN6_FORMAT_R32G32_UINT]              = CAP(  1),
-   [GEN6_FORMAT_R32_SINT]                 = CAP(  1),
-   [GEN6_FORMAT_R32_UINT]                 = CAP(  1),
-   [GEN6_FORMAT_R32_FLOAT]                = CAP(  1),
-#undef CAP
-};
-
-/*
- * This table is based on:
- *
- *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
- *  - the Ivy Bridge PRM, volume 4 part 1, page 84-87
- */
-static const struct ilo_sampler_cap ilo_sampler_caps[] = {
-#define CAP(sampling, filtering, shadow_map, chroma_key) \
-   { ILO_GEN(sampling), ILO_GEN(filtering), ILO_GEN(shadow_map), ILO_GEN(chroma_key) }
-   [GEN6_FORMAT_R32G32B32A32_FLOAT]       = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_R32G32B32A32_SINT]        = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32G32B32A32_UINT]        = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32G32B32X32_FLOAT]       = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_R32G32B32_FLOAT]          = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_R32G32B32_SINT]           = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32G32B32_UINT]           = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16G16B16A16_UNORM]       = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16G16B16A16_SNORM]       = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16G16B16A16_SINT]        = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16G16B16A16_UINT]        = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16G16B16A16_FLOAT]       = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R32G32_FLOAT]             = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_R32G32_SINT]              = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32G32_UINT]              = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32_FLOAT_X8X24_TYPELESS] = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_X32_TYPELESS_G8X24_UINT]  = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_L32A32_FLOAT]             = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_R16G16B16X16_UNORM]       = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16G16B16X16_FLOAT]       = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_A32X32_FLOAT]             = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_L32X32_FLOAT]             = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_I32X32_FLOAT]             = CAP(  1,   5,   0,   0),
-   [GEN6_FORMAT_B8G8R8A8_UNORM]           = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_B8G8R8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R10G10B10A2_UNORM]        = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R10G10B10A2_UNORM_SRGB]   = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R10G10B10A2_UINT]         = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R10G10B10_SNORM_A2_UNORM] = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8B8A8_UNORM]           = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8B8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8B8A8_SNORM]           = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8B8A8_SINT]            = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R8G8B8A8_UINT]            = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16G16_UNORM]             = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16G16_SNORM]             = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16G16_SINT]              = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16G16_UINT]              = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16G16_FLOAT]             = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B10G10R10A2_UNORM]        = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B10G10R10A2_UNORM_SRGB]   = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R11G11B10_FLOAT]          = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R32_SINT]                 = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32_UINT]                 = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R32_FLOAT]                = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_R24_UNORM_X8_TYPELESS]    = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_X24_TYPELESS_G8_UINT]     = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_L16A16_UNORM]             = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_I24X8_UNORM]              = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_L24X8_UNORM]              = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_A24X8_UNORM]              = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_I32_FLOAT]                = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_L32_FLOAT]                = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_A32_FLOAT]                = CAP(  1,   5,   1,   0),
-   [GEN6_FORMAT_B8G8R8X8_UNORM]           = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_B8G8R8X8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8B8X8_UNORM]           = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8B8X8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R9G9B9E5_SHAREDEXP]       = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B10G10R10X2_UNORM]        = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_L16A16_FLOAT]             = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B5G6R5_UNORM]             = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_B5G6R5_UNORM_SRGB]        = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B5G5R5A1_UNORM]           = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_B5G5R5A1_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B4G4R4A4_UNORM]           = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_B4G4R4A4_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8_UNORM]               = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8_SNORM]               = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_R8G8_SINT]                = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R8G8_UINT]                = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16_UNORM]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_R16_SNORM]                = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16_SINT]                 = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16_UINT]                 = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R16_FLOAT]                = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_A8P8_UNORM_PALETTE0]      = CAP(  5,   5,   0,   0),
-   [GEN6_FORMAT_A8P8_UNORM_PALETTE1]      = CAP(  5,   5,   0,   0),
-   [GEN6_FORMAT_I16_UNORM]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_L16_UNORM]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_A16_UNORM]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_L8A8_UNORM]               = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_I16_FLOAT]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_L16_FLOAT]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_A16_FLOAT]                = CAP(  1,   1,   1,   0),
-   [GEN6_FORMAT_L8A8_UNORM_SRGB]          = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_R5G5_SNORM_B6_UNORM]      = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_P8A8_UNORM_PALETTE0]      = CAP(  5,   5,   0,   0),
-   [GEN6_FORMAT_P8A8_UNORM_PALETTE1]      = CAP(  5,   5,   0,   0),
-   [GEN6_FORMAT_R8_UNORM]                 = CAP(  1,   1,   0, 4.5),
-   [GEN6_FORMAT_R8_SNORM]                 = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8_SINT]                  = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_R8_UINT]                  = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_A8_UNORM]                 = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_I8_UNORM]                 = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_L8_UNORM]                 = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_P4A4_UNORM_PALETTE0]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_A4P4_UNORM_PALETTE0]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_P8_UNORM_PALETTE0]        = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_L8_UNORM_SRGB]            = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_P8_UNORM_PALETTE1]        = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_P4A4_UNORM_PALETTE1]      = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_A4P4_UNORM_PALETTE1]      = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_DXT1_RGB_SRGB]            = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_R1_UNORM]                 = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_YCRCB_NORMAL]             = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_YCRCB_SWAPUVY]            = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_P2_UNORM_PALETTE0]        = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_P2_UNORM_PALETTE1]        = CAP(4.5, 4.5,   0,   0),
-   [GEN6_FORMAT_BC1_UNORM]                = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_BC2_UNORM]                = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_BC3_UNORM]                = CAP(  1,   1,   0,   1),
-   [GEN6_FORMAT_BC4_UNORM]                = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_BC5_UNORM]                = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_BC1_UNORM_SRGB]           = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_BC2_UNORM_SRGB]           = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_BC3_UNORM_SRGB]           = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_MONO8]                    = CAP(  1,   0,   0,   0),
-   [GEN6_FORMAT_YCRCB_SWAPUV]             = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_YCRCB_SWAPY]              = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_DXT1_RGB]                 = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_FXT1]                     = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_BC4_SNORM]                = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_BC5_SNORM]                = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R16G16B16_FLOAT]          = CAP(  5,   5,   0,   0),
-   [GEN6_FORMAT_BC6H_SF16]                = CAP(  7,   7,   0,   0),
-   [GEN6_FORMAT_BC7_UNORM]                = CAP(  7,   7,   0,   0),
-   [GEN6_FORMAT_BC7_UNORM_SRGB]           = CAP(  7,   7,   0,   0),
-   [GEN6_FORMAT_BC6H_UF16]                = CAP(  7,   7,   0,   0),
-#undef CAP
-};
-
-/*
- * This table is based on:
- *
- *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
- *  - the Ivy Bridge PRM, volume 4 part 1, page 172, 252-253, and 277-278
- *  - the Haswell PRM, volume 7, page 262-264
- */
-static const struct ilo_dp_cap ilo_dp_caps[] = {
-#define CAP(rt_write, rt_write_blending, typed_write, media_color_processing) \
-   { ILO_GEN(rt_write), ILO_GEN(rt_write_blending), ILO_GEN(typed_write), ILO_GEN(media_color_processing) }
-   [GEN6_FORMAT_R32G32B32A32_FLOAT]       = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_R32G32B32A32_SINT]        = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R32G32B32A32_UINT]        = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16G16B16A16_UNORM]       = CAP(  1, 4.5,   7,   6),
-   [GEN6_FORMAT_R16G16B16A16_SNORM]       = CAP(  1,   6,   7,   0),
-   [GEN6_FORMAT_R16G16B16A16_SINT]        = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16G16B16A16_UINT]        = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16G16B16A16_FLOAT]       = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_R32G32_FLOAT]             = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_R32G32_SINT]              = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R32G32_UINT]              = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_B8G8R8A8_UNORM]           = CAP(  1,   1,   7,   6),
-   [GEN6_FORMAT_B8G8R8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R10G10B10A2_UNORM]        = CAP(  1,   1,   7,   6),
-   [GEN6_FORMAT_R10G10B10A2_UNORM_SRGB]   = CAP(  0,   0,   0,   6),
-   [GEN6_FORMAT_R10G10B10A2_UINT]         = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R8G8B8A8_UNORM]           = CAP(  1,   1,   7,   6),
-   [GEN6_FORMAT_R8G8B8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   6),
-   [GEN6_FORMAT_R8G8B8A8_SNORM]           = CAP(  1,   6,   7,   0),
-   [GEN6_FORMAT_R8G8B8A8_SINT]            = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R8G8B8A8_UINT]            = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16G16_UNORM]             = CAP(  1, 4.5,   7,   0),
-   [GEN6_FORMAT_R16G16_SNORM]             = CAP(  1,   6,   7,   0),
-   [GEN6_FORMAT_R16G16_SINT]              = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16G16_UINT]              = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16G16_FLOAT]             = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B10G10R10A2_UNORM]        = CAP(  1,   1,   7,   6),
-   [GEN6_FORMAT_B10G10R10A2_UNORM_SRGB]   = CAP(  1,   1,   0,   6),
-   [GEN6_FORMAT_R11G11B10_FLOAT]          = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_R32_SINT]                 = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R32_UINT]                 = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R32_FLOAT]                = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B8G8R8X8_UNORM]           = CAP(  0,   0,   0,   6),
-   [GEN6_FORMAT_B5G6R5_UNORM]             = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B5G6R5_UNORM_SRGB]        = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B5G5R5A1_UNORM]           = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B5G5R5A1_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_B4G4R4A4_UNORM]           = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B4G4R4A4_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8G8_UNORM]               = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_R8G8_SNORM]               = CAP(  1,   6,   7,   0),
-   [GEN6_FORMAT_R8G8_SINT]                = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R8G8_UINT]                = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16_UNORM]                = CAP(  1, 4.5,   7,   7),
-   [GEN6_FORMAT_R16_SNORM]                = CAP(  1,   6,   7,   0),
-   [GEN6_FORMAT_R16_SINT]                 = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16_UINT]                 = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R16_FLOAT]                = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B5G5R5X1_UNORM]           = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_B5G5R5X1_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
-   [GEN6_FORMAT_R8_UNORM]                 = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_R8_SNORM]                 = CAP(  1,   6,   7,   0),
-   [GEN6_FORMAT_R8_SINT]                  = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_R8_UINT]                  = CAP(  1,   0,   7,   0),
-   [GEN6_FORMAT_A8_UNORM]                 = CAP(  1,   1,   7,   0),
-   [GEN6_FORMAT_YCRCB_NORMAL]             = CAP(  1,   0,   0,   6),
-   [GEN6_FORMAT_YCRCB_SWAPUVY]            = CAP(  1,   0,   0,   6),
-   [GEN6_FORMAT_YCRCB_SWAPUV]             = CAP(  1,   0,   0,   6),
-   [GEN6_FORMAT_YCRCB_SWAPY]              = CAP(  1,   0,   0,   6),
-#undef CAP
-};
-
-bool
-ilo_format_support_vb(const struct ilo_dev *dev,
-                      enum pipe_format format)
-{
-   const int idx = ilo_format_translate(dev, format, PIPE_BIND_VERTEX_BUFFER);
-   const struct ilo_vf_cap *cap = (idx >= 0 && idx < Elements(ilo_vf_caps)) ?
-      &ilo_vf_caps[idx] : NULL;
-
-   return (cap && cap->vertex_element &&
-         ilo_dev_gen(dev) >= cap->vertex_element);
-}
-
-bool
-ilo_format_support_sol(const struct ilo_dev *dev,
-                       enum pipe_format format)
-{
-   const int idx = ilo_format_translate(dev, format, PIPE_BIND_STREAM_OUTPUT);
-   const struct ilo_sol_cap *cap = (idx >= 0 && idx < Elements(ilo_sol_caps)) ?
-      &ilo_sol_caps[idx] : NULL;
-
-   return (cap && cap->buffer && ilo_dev_gen(dev) >= cap->buffer);
-}
-
-bool
-ilo_format_support_sampler(const struct ilo_dev *dev,
-                           enum pipe_format format)
-{
-   const int idx = ilo_format_translate(dev, format, PIPE_BIND_SAMPLER_VIEW);
-   const struct ilo_sampler_cap *cap = (idx >= 0 &&
-         idx < Elements(ilo_sampler_caps)) ? &ilo_sampler_caps[idx] : NULL;
-
-   if (!cap || !cap->sampling)
-      return false;
-
-   assert(!cap->filtering || cap->filtering >= cap->sampling);
-
-   if (util_format_is_pure_integer(format))
-      return (ilo_dev_gen(dev) >= cap->sampling);
-   else if (cap->filtering)
-      return (ilo_dev_gen(dev) >= cap->filtering);
-   else
-      return false;
-}
-
-bool
-ilo_format_support_rt(const struct ilo_dev *dev,
-                      enum pipe_format format)
-{
-   const int idx = ilo_format_translate(dev, format, PIPE_BIND_RENDER_TARGET);
-   const struct ilo_dp_cap *cap = (idx >= 0 && idx < Elements(ilo_dp_caps)) ?
-      &ilo_dp_caps[idx] : NULL;
-
-   if (!cap || !cap->rt_write)
-      return false;
-
-   assert(!cap->rt_write_blending || cap->rt_write_blending >= cap->rt_write);
-
-   if (util_format_is_pure_integer(format))
-      return (ilo_dev_gen(dev) >= cap->rt_write);
-   else if (cap->rt_write_blending)
-      return (ilo_dev_gen(dev) >= cap->rt_write_blending);
-   else
-      return false;
-}
-
-bool
-ilo_format_support_zs(const struct ilo_dev *dev,
-                      enum pipe_format format)
-{
-   switch (format) {
-   case PIPE_FORMAT_Z16_UNORM:
-   case PIPE_FORMAT_Z24X8_UNORM:
-   case PIPE_FORMAT_Z32_FLOAT:
-   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-      return true;
-   case PIPE_FORMAT_S8_UINT:
-      /* TODO separate stencil */
-   default:
-      return false;
-   }
-}
-
-/**
- * Translate a color (non-depth/stencil) pipe format to the matching hardware
- * format.  Return -1 on errors.
- */
-int
-ilo_format_translate_color(const struct ilo_dev *dev,
-                           enum pipe_format format)
-{
-   static const int format_mapping[PIPE_FORMAT_COUNT] = {
-      [PIPE_FORMAT_NONE]                  = 0,
-      [PIPE_FORMAT_B8G8R8A8_UNORM]        = GEN6_FORMAT_B8G8R8A8_UNORM,
-      [PIPE_FORMAT_B8G8R8X8_UNORM]        = GEN6_FORMAT_B8G8R8X8_UNORM,
-      [PIPE_FORMAT_A8R8G8B8_UNORM]        = 0,
-      [PIPE_FORMAT_X8R8G8B8_UNORM]        = 0,
-      [PIPE_FORMAT_B5G5R5A1_UNORM]        = GEN6_FORMAT_B5G5R5A1_UNORM,
-      [PIPE_FORMAT_B4G4R4A4_UNORM]        = GEN6_FORMAT_B4G4R4A4_UNORM,
-      [PIPE_FORMAT_B5G6R5_UNORM]          = GEN6_FORMAT_B5G6R5_UNORM,
-      [PIPE_FORMAT_R10G10B10A2_UNORM]     = GEN6_FORMAT_R10G10B10A2_UNORM,
-      [PIPE_FORMAT_L8_UNORM]              = GEN6_FORMAT_L8_UNORM,
-      [PIPE_FORMAT_A8_UNORM]              = GEN6_FORMAT_A8_UNORM,
-      [PIPE_FORMAT_I8_UNORM]              = GEN6_FORMAT_I8_UNORM,
-      [PIPE_FORMAT_L8A8_UNORM]            = GEN6_FORMAT_L8A8_UNORM,
-      [PIPE_FORMAT_L16_UNORM]             = GEN6_FORMAT_L16_UNORM,
-      [PIPE_FORMAT_UYVY]                  = GEN6_FORMAT_YCRCB_SWAPUVY,
-      [PIPE_FORMAT_YUYV]                  = GEN6_FORMAT_YCRCB_NORMAL,
-      [PIPE_FORMAT_Z16_UNORM]             = 0,
-      [PIPE_FORMAT_Z32_UNORM]             = 0,
-      [PIPE_FORMAT_Z32_FLOAT]             = 0,
-      [PIPE_FORMAT_Z24_UNORM_S8_UINT]     = 0,
-      [PIPE_FORMAT_S8_UINT_Z24_UNORM]     = 0,
-      [PIPE_FORMAT_Z24X8_UNORM]           = 0,
-      [PIPE_FORMAT_X8Z24_UNORM]           = 0,
-      [PIPE_FORMAT_S8_UINT]               = 0,
-      [PIPE_FORMAT_R64_FLOAT]             = GEN6_FORMAT_R64_FLOAT,
-      [PIPE_FORMAT_R64G64_FLOAT]          = GEN6_FORMAT_R64G64_FLOAT,
-      [PIPE_FORMAT_R64G64B64_FLOAT]       = GEN6_FORMAT_R64G64B64_FLOAT,
-      [PIPE_FORMAT_R64G64B64A64_FLOAT]    = GEN6_FORMAT_R64G64B64A64_FLOAT,
-      [PIPE_FORMAT_R32_FLOAT]             = GEN6_FORMAT_R32_FLOAT,
-      [PIPE_FORMAT_R32G32_FLOAT]          = GEN6_FORMAT_R32G32_FLOAT,
-      [PIPE_FORMAT_R32G32B32_FLOAT]       = GEN6_FORMAT_R32G32B32_FLOAT,
-      [PIPE_FORMAT_R32G32B32A32_FLOAT]    = GEN6_FORMAT_R32G32B32A32_FLOAT,
-      [PIPE_FORMAT_R32_UNORM]             = GEN6_FORMAT_R32_UNORM,
-      [PIPE_FORMAT_R32G32_UNORM]          = GEN6_FORMAT_R32G32_UNORM,
-      [PIPE_FORMAT_R32G32B32_UNORM]       = GEN6_FORMAT_R32G32B32_UNORM,
-      [PIPE_FORMAT_R32G32B32A32_UNORM]    = GEN6_FORMAT_R32G32B32A32_UNORM,
-      [PIPE_FORMAT_R32_USCALED]           = GEN6_FORMAT_R32_USCALED,
-      [PIPE_FORMAT_R32G32_USCALED]        = GEN6_FORMAT_R32G32_USCALED,
-      [PIPE_FORMAT_R32G32B32_USCALED]     = GEN6_FORMAT_R32G32B32_USCALED,
-      [PIPE_FORMAT_R32G32B32A32_USCALED]  = GEN6_FORMAT_R32G32B32A32_USCALED,
-      [PIPE_FORMAT_R32_SNORM]             = GEN6_FORMAT_R32_SNORM,
-      [PIPE_FORMAT_R32G32_SNORM]          = GEN6_FORMAT_R32G32_SNORM,
-      [PIPE_FORMAT_R32G32B32_SNORM]       = GEN6_FORMAT_R32G32B32_SNORM,
-      [PIPE_FORMAT_R32G32B32A32_SNORM]    = GEN6_FORMAT_R32G32B32A32_SNORM,
-      [PIPE_FORMAT_R32_SSCALED]           = GEN6_FORMAT_R32_SSCALED,
-      [PIPE_FORMAT_R32G32_SSCALED]        = GEN6_FORMAT_R32G32_SSCALED,
-      [PIPE_FORMAT_R32G32B32_SSCALED]     = GEN6_FORMAT_R32G32B32_SSCALED,
-      [PIPE_FORMAT_R32G32B32A32_SSCALED]  = GEN6_FORMAT_R32G32B32A32_SSCALED,
-      [PIPE_FORMAT_R16_UNORM]             = GEN6_FORMAT_R16_UNORM,
-      [PIPE_FORMAT_R16G16_UNORM]          = GEN6_FORMAT_R16G16_UNORM,
-      [PIPE_FORMAT_R16G16B16_UNORM]       = GEN6_FORMAT_R16G16B16_UNORM,
-      [PIPE_FORMAT_R16G16B16A16_UNORM]    = GEN6_FORMAT_R16G16B16A16_UNORM,
-      [PIPE_FORMAT_R16_USCALED]           = GEN6_FORMAT_R16_USCALED,
-      [PIPE_FORMAT_R16G16_USCALED]        = GEN6_FORMAT_R16G16_USCALED,
-      [PIPE_FORMAT_R16G16B16_USCALED]     = GEN6_FORMAT_R16G16B16_USCALED,
-      [PIPE_FORMAT_R16G16B16A16_USCALED]  = GEN6_FORMAT_R16G16B16A16_USCALED,
-      [PIPE_FORMAT_R16_SNORM]             = GEN6_FORMAT_R16_SNORM,
-      [PIPE_FORMAT_R16G16_SNORM]          = GEN6_FORMAT_R16G16_SNORM,
-      [PIPE_FORMAT_R16G16B16_SNORM]       = GEN6_FORMAT_R16G16B16_SNORM,
-      [PIPE_FORMAT_R16G16B16A16_SNORM]    = GEN6_FORMAT_R16G16B16A16_SNORM,
-      [PIPE_FORMAT_R16_SSCALED]           = GEN6_FORMAT_R16_SSCALED,
-      [PIPE_FORMAT_R16G16_SSCALED]        = GEN6_FORMAT_R16G16_SSCALED,
-      [PIPE_FORMAT_R16G16B16_SSCALED]     = GEN6_FORMAT_R16G16B16_SSCALED,
-      [PIPE_FORMAT_R16G16B16A16_SSCALED]  = GEN6_FORMAT_R16G16B16A16_SSCALED,
-      [PIPE_FORMAT_R8_UNORM]              = GEN6_FORMAT_R8_UNORM,
-      [PIPE_FORMAT_R8G8_UNORM]            = GEN6_FORMAT_R8G8_UNORM,
-      [PIPE_FORMAT_R8G8B8_UNORM]          = GEN6_FORMAT_R8G8B8_UNORM,
-      [PIPE_FORMAT_R8G8B8A8_UNORM]        = GEN6_FORMAT_R8G8B8A8_UNORM,
-      [PIPE_FORMAT_X8B8G8R8_UNORM]        = 0,
-      [PIPE_FORMAT_R8_USCALED]            = GEN6_FORMAT_R8_USCALED,
-      [PIPE_FORMAT_R8G8_USCALED]          = GEN6_FORMAT_R8G8_USCALED,
-      [PIPE_FORMAT_R8G8B8_USCALED]        = GEN6_FORMAT_R8G8B8_USCALED,
-      [PIPE_FORMAT_R8G8B8A8_USCALED]      = GEN6_FORMAT_R8G8B8A8_USCALED,
-      [PIPE_FORMAT_R8_SNORM]              = GEN6_FORMAT_R8_SNORM,
-      [PIPE_FORMAT_R8G8_SNORM]            = GEN6_FORMAT_R8G8_SNORM,
-      [PIPE_FORMAT_R8G8B8_SNORM]          = GEN6_FORMAT_R8G8B8_SNORM,
-      [PIPE_FORMAT_R8G8B8A8_SNORM]        = GEN6_FORMAT_R8G8B8A8_SNORM,
-      [PIPE_FORMAT_R8_SSCALED]            = GEN6_FORMAT_R8_SSCALED,
-      [PIPE_FORMAT_R8G8_SSCALED]          = GEN6_FORMAT_R8G8_SSCALED,
-      [PIPE_FORMAT_R8G8B8_SSCALED]        = GEN6_FORMAT_R8G8B8_SSCALED,
-      [PIPE_FORMAT_R8G8B8A8_SSCALED]      = GEN6_FORMAT_R8G8B8A8_SSCALED,
-      [PIPE_FORMAT_R32_FIXED]             = GEN6_FORMAT_R32_SFIXED,
-      [PIPE_FORMAT_R32G32_FIXED]          = GEN6_FORMAT_R32G32_SFIXED,
-      [PIPE_FORMAT_R32G32B32_FIXED]       = GEN6_FORMAT_R32G32B32_SFIXED,
-      [PIPE_FORMAT_R32G32B32A32_FIXED]    = GEN6_FORMAT_R32G32B32A32_SFIXED,
-      [PIPE_FORMAT_R16_FLOAT]             = GEN6_FORMAT_R16_FLOAT,
-      [PIPE_FORMAT_R16G16_FLOAT]          = GEN6_FORMAT_R16G16_FLOAT,
-      [PIPE_FORMAT_R16G16B16_FLOAT]       = GEN6_FORMAT_R16G16B16_FLOAT,
-      [PIPE_FORMAT_R16G16B16A16_FLOAT]    = GEN6_FORMAT_R16G16B16A16_FLOAT,
-      [PIPE_FORMAT_L8_SRGB]               = GEN6_FORMAT_L8_UNORM_SRGB,
-      [PIPE_FORMAT_L8A8_SRGB]             = GEN6_FORMAT_L8A8_UNORM_SRGB,
-      [PIPE_FORMAT_R8G8B8_SRGB]           = GEN6_FORMAT_R8G8B8_UNORM_SRGB,
-      [PIPE_FORMAT_A8B8G8R8_SRGB]         = 0,
-      [PIPE_FORMAT_X8B8G8R8_SRGB]         = 0,
-      [PIPE_FORMAT_B8G8R8A8_SRGB]         = GEN6_FORMAT_B8G8R8A8_UNORM_SRGB,
-      [PIPE_FORMAT_B8G8R8X8_SRGB]         = GEN6_FORMAT_B8G8R8X8_UNORM_SRGB,
-      [PIPE_FORMAT_A8R8G8B8_SRGB]         = 0,
-      [PIPE_FORMAT_X8R8G8B8_SRGB]         = 0,
-      [PIPE_FORMAT_R8G8B8A8_SRGB]         = GEN6_FORMAT_R8G8B8A8_UNORM_SRGB,
-      [PIPE_FORMAT_DXT1_RGB]              = GEN6_FORMAT_DXT1_RGB,
-      [PIPE_FORMAT_DXT1_RGBA]             = GEN6_FORMAT_BC1_UNORM,
-      [PIPE_FORMAT_DXT3_RGBA]             = GEN6_FORMAT_BC2_UNORM,
-      [PIPE_FORMAT_DXT5_RGBA]             = GEN6_FORMAT_BC3_UNORM,
-      [PIPE_FORMAT_DXT1_SRGB]             = GEN6_FORMAT_DXT1_RGB_SRGB,
-      [PIPE_FORMAT_DXT1_SRGBA]            = GEN6_FORMAT_BC1_UNORM_SRGB,
-      [PIPE_FORMAT_DXT3_SRGBA]            = GEN6_FORMAT_BC2_UNORM_SRGB,
-      [PIPE_FORMAT_DXT5_SRGBA]            = GEN6_FORMAT_BC3_UNORM_SRGB,
-      [PIPE_FORMAT_RGTC1_UNORM]           = GEN6_FORMAT_BC4_UNORM,
-      [PIPE_FORMAT_RGTC1_SNORM]           = GEN6_FORMAT_BC4_SNORM,
-      [PIPE_FORMAT_RGTC2_UNORM]           = GEN6_FORMAT_BC5_UNORM,
-      [PIPE_FORMAT_RGTC2_SNORM]           = GEN6_FORMAT_BC5_SNORM,
-      [PIPE_FORMAT_R8G8_B8G8_UNORM]       = 0,
-      [PIPE_FORMAT_G8R8_G8B8_UNORM]       = 0,
-      [PIPE_FORMAT_R8SG8SB8UX8U_NORM]     = 0,
-      [PIPE_FORMAT_R5SG5SB6U_NORM]        = 0,
-      [PIPE_FORMAT_A8B8G8R8_UNORM]        = 0,
-      [PIPE_FORMAT_B5G5R5X1_UNORM]        = GEN6_FORMAT_B5G5R5X1_UNORM,
-      [PIPE_FORMAT_R10G10B10A2_USCALED]   = GEN6_FORMAT_R10G10B10A2_USCALED,
-      [PIPE_FORMAT_R11G11B10_FLOAT]       = GEN6_FORMAT_R11G11B10_FLOAT,
-      [PIPE_FORMAT_R9G9B9E5_FLOAT]        = GEN6_FORMAT_R9G9B9E5_SHAREDEXP,
-      [PIPE_FORMAT_Z32_FLOAT_S8X24_UINT]  = 0,
-      [PIPE_FORMAT_R1_UNORM]              = GEN6_FORMAT_R1_UNORM,
-      [PIPE_FORMAT_R10G10B10X2_USCALED]   = GEN6_FORMAT_R10G10B10X2_USCALED,
-      [PIPE_FORMAT_R10G10B10X2_SNORM]     = 0,
-      [PIPE_FORMAT_L4A4_UNORM]            = 0,
-      [PIPE_FORMAT_B10G10R10A2_UNORM]     = GEN6_FORMAT_B10G10R10A2_UNORM,
-      [PIPE_FORMAT_R10SG10SB10SA2U_NORM]  = 0,
-      [PIPE_FORMAT_R8G8Bx_SNORM]          = 0,
-      [PIPE_FORMAT_R8G8B8X8_UNORM]        = GEN6_FORMAT_R8G8B8X8_UNORM,
-      [PIPE_FORMAT_B4G4R4X4_UNORM]        = 0,
-      [PIPE_FORMAT_X24S8_UINT]            = 0,
-      [PIPE_FORMAT_S8X24_UINT]            = 0,
-      [PIPE_FORMAT_X32_S8X24_UINT]        = 0,
-      [PIPE_FORMAT_B2G3R3_UNORM]          = 0,
-      [PIPE_FORMAT_L16A16_UNORM]          = GEN6_FORMAT_L16A16_UNORM,
-      [PIPE_FORMAT_A16_UNORM]             = GEN6_FORMAT_A16_UNORM,
-      [PIPE_FORMAT_I16_UNORM]             = GEN6_FORMAT_I16_UNORM,
-      [PIPE_FORMAT_LATC1_UNORM]           = 0,
-      [PIPE_FORMAT_LATC1_SNORM]           = 0,
-      [PIPE_FORMAT_LATC2_UNORM]           = 0,
-      [PIPE_FORMAT_LATC2_SNORM]           = 0,
-      [PIPE_FORMAT_A8_SNORM]              = 0,
-      [PIPE_FORMAT_L8_SNORM]              = 0,
-      [PIPE_FORMAT_L8A8_SNORM]            = 0,
-      [PIPE_FORMAT_I8_SNORM]              = 0,
-      [PIPE_FORMAT_A16_SNORM]             = 0,
-      [PIPE_FORMAT_L16_SNORM]             = 0,
-      [PIPE_FORMAT_L16A16_SNORM]          = 0,
-      [PIPE_FORMAT_I16_SNORM]             = 0,
-      [PIPE_FORMAT_A16_FLOAT]             = GEN6_FORMAT_A16_FLOAT,
-      [PIPE_FORMAT_L16_FLOAT]             = GEN6_FORMAT_L16_FLOAT,
-      [PIPE_FORMAT_L16A16_FLOAT]          = GEN6_FORMAT_L16A16_FLOAT,
-      [PIPE_FORMAT_I16_FLOAT]             = GEN6_FORMAT_I16_FLOAT,
-      [PIPE_FORMAT_A32_FLOAT]             = GEN6_FORMAT_A32_FLOAT,
-      [PIPE_FORMAT_L32_FLOAT]             = GEN6_FORMAT_L32_FLOAT,
-      [PIPE_FORMAT_L32A32_FLOAT]          = GEN6_FORMAT_L32A32_FLOAT,
-      [PIPE_FORMAT_I32_FLOAT]             = GEN6_FORMAT_I32_FLOAT,
-      [PIPE_FORMAT_YV12]                  = 0,
-      [PIPE_FORMAT_YV16]                  = 0,
-      [PIPE_FORMAT_IYUV]                  = 0,
-      [PIPE_FORMAT_NV12]                  = 0,
-      [PIPE_FORMAT_NV21]                  = 0,
-      [PIPE_FORMAT_A4R4_UNORM]            = 0,
-      [PIPE_FORMAT_R4A4_UNORM]            = 0,
-      [PIPE_FORMAT_R8A8_UNORM]            = 0,
-      [PIPE_FORMAT_A8R8_UNORM]            = 0,
-      [PIPE_FORMAT_R10G10B10A2_SSCALED]   = GEN6_FORMAT_R10G10B10A2_SSCALED,
-      [PIPE_FORMAT_R10G10B10A2_SNORM]     = GEN6_FORMAT_R10G10B10A2_SNORM,
-      [PIPE_FORMAT_B10G10R10A2_USCALED]   = GEN6_FORMAT_B10G10R10A2_USCALED,
-      [PIPE_FORMAT_B10G10R10A2_SSCALED]   = GEN6_FORMAT_B10G10R10A2_SSCALED,
-      [PIPE_FORMAT_B10G10R10A2_SNORM]     = GEN6_FORMAT_B10G10R10A2_SNORM,
-      [PIPE_FORMAT_R8_UINT]               = GEN6_FORMAT_R8_UINT,
-      [PIPE_FORMAT_R8G8_UINT]             = GEN6_FORMAT_R8G8_UINT,
-      [PIPE_FORMAT_R8G8B8_UINT]           = GEN6_FORMAT_R8G8B8_UINT,
-      [PIPE_FORMAT_R8G8B8A8_UINT]         = GEN6_FORMAT_R8G8B8A8_UINT,
-      [PIPE_FORMAT_R8_SINT]               = GEN6_FORMAT_R8_SINT,
-      [PIPE_FORMAT_R8G8_SINT]             = GEN6_FORMAT_R8G8_SINT,
-      [PIPE_FORMAT_R8G8B8_SINT]           = GEN6_FORMAT_R8G8B8_SINT,
-      [PIPE_FORMAT_R8G8B8A8_SINT]         = GEN6_FORMAT_R8G8B8A8_SINT,
-      [PIPE_FORMAT_R16_UINT]              = GEN6_FORMAT_R16_UINT,
-      [PIPE_FORMAT_R16G16_UINT]           = GEN6_FORMAT_R16G16_UINT,
-      [PIPE_FORMAT_R16G16B16_UINT]        = GEN6_FORMAT_R16G16B16_UINT,
-      [PIPE_FORMAT_R16G16B16A16_UINT]     = GEN6_FORMAT_R16G16B16A16_UINT,
-      [PIPE_FORMAT_R16_SINT]              = GEN6_FORMAT_R16_SINT,
-      [PIPE_FORMAT_R16G16_SINT]           = GEN6_FORMAT_R16G16_SINT,
-      [PIPE_FORMAT_R16G16B16_SINT]        = GEN6_FORMAT_R16G16B16_SINT,
-      [PIPE_FORMAT_R16G16B16A16_SINT]     = GEN6_FORMAT_R16G16B16A16_SINT,
-      [PIPE_FORMAT_R32_UINT]              = GEN6_FORMAT_R32_UINT,
-      [PIPE_FORMAT_R32G32_UINT]           = GEN6_FORMAT_R32G32_UINT,
-      [PIPE_FORMAT_R32G32B32_UINT]        = GEN6_FORMAT_R32G32B32_UINT,
-      [PIPE_FORMAT_R32G32B32A32_UINT]     = GEN6_FORMAT_R32G32B32A32_UINT,
-      [PIPE_FORMAT_R32_SINT]              = GEN6_FORMAT_R32_SINT,
-      [PIPE_FORMAT_R32G32_SINT]           = GEN6_FORMAT_R32G32_SINT,
-      [PIPE_FORMAT_R32G32B32_SINT]        = GEN6_FORMAT_R32G32B32_SINT,
-      [PIPE_FORMAT_R32G32B32A32_SINT]     = GEN6_FORMAT_R32G32B32A32_SINT,
-      [PIPE_FORMAT_A8_UINT]               = 0,
-      [PIPE_FORMAT_I8_UINT]               = GEN6_FORMAT_I8_UINT,
-      [PIPE_FORMAT_L8_UINT]               = GEN6_FORMAT_L8_UINT,
-      [PIPE_FORMAT_L8A8_UINT]             = GEN6_FORMAT_L8A8_UINT,
-      [PIPE_FORMAT_A8_SINT]               = 0,
-      [PIPE_FORMAT_I8_SINT]               = GEN6_FORMAT_I8_SINT,
-      [PIPE_FORMAT_L8_SINT]               = GEN6_FORMAT_L8_SINT,
-      [PIPE_FORMAT_L8A8_SINT]             = GEN6_FORMAT_L8A8_SINT,
-      [PIPE_FORMAT_A16_UINT]              = 0,
-      [PIPE_FORMAT_I16_UINT]              = 0,
-      [PIPE_FORMAT_L16_UINT]              = 0,
-      [PIPE_FORMAT_L16A16_UINT]           = 0,
-      [PIPE_FORMAT_A16_SINT]              = 0,
-      [PIPE_FORMAT_I16_SINT]              = 0,
-      [PIPE_FORMAT_L16_SINT]              = 0,
-      [PIPE_FORMAT_L16A16_SINT]           = 0,
-      [PIPE_FORMAT_A32_UINT]              = 0,
-      [PIPE_FORMAT_I32_UINT]              = 0,
-      [PIPE_FORMAT_L32_UINT]              = 0,
-      [PIPE_FORMAT_L32A32_UINT]           = 0,
-      [PIPE_FORMAT_A32_SINT]              = 0,
-      [PIPE_FORMAT_I32_SINT]              = 0,
-      [PIPE_FORMAT_L32_SINT]              = 0,
-      [PIPE_FORMAT_L32A32_SINT]           = 0,
-      [PIPE_FORMAT_B10G10R10A2_UINT]      = GEN6_FORMAT_B10G10R10A2_UINT,
-      [PIPE_FORMAT_ETC1_RGB8]             = GEN6_FORMAT_ETC1_RGB8,
-      [PIPE_FORMAT_R8G8_R8B8_UNORM]       = 0,
-      [PIPE_FORMAT_G8R8_B8R8_UNORM]       = 0,
-      [PIPE_FORMAT_R8G8B8X8_SNORM]        = 0,
-      [PIPE_FORMAT_R8G8B8X8_SRGB]         = 0,
-      [PIPE_FORMAT_R8G8B8X8_UINT]         = 0,
-      [PIPE_FORMAT_R8G8B8X8_SINT]         = 0,
-      [PIPE_FORMAT_B10G10R10X2_UNORM]     = GEN6_FORMAT_B10G10R10X2_UNORM,
-      [PIPE_FORMAT_R16G16B16X16_UNORM]    = GEN6_FORMAT_R16G16B16X16_UNORM,
-      [PIPE_FORMAT_R16G16B16X16_SNORM]    = 0,
-      [PIPE_FORMAT_R16G16B16X16_FLOAT]    = GEN6_FORMAT_R16G16B16X16_FLOAT,
-      [PIPE_FORMAT_R16G16B16X16_UINT]     = 0,
-      [PIPE_FORMAT_R16G16B16X16_SINT]     = 0,
-      [PIPE_FORMAT_R32G32B32X32_FLOAT]    = GEN6_FORMAT_R32G32B32X32_FLOAT,
-      [PIPE_FORMAT_R32G32B32X32_UINT]     = 0,
-      [PIPE_FORMAT_R32G32B32X32_SINT]     = 0,
-      [PIPE_FORMAT_R8A8_SNORM]            = 0,
-      [PIPE_FORMAT_R16A16_UNORM]          = 0,
-      [PIPE_FORMAT_R16A16_SNORM]          = 0,
-      [PIPE_FORMAT_R16A16_FLOAT]          = 0,
-      [PIPE_FORMAT_R32A32_FLOAT]          = 0,
-      [PIPE_FORMAT_R8A8_UINT]             = 0,
-      [PIPE_FORMAT_R8A8_SINT]             = 0,
-      [PIPE_FORMAT_R16A16_UINT]           = 0,
-      [PIPE_FORMAT_R16A16_SINT]           = 0,
-      [PIPE_FORMAT_R32A32_UINT]           = 0,
-      [PIPE_FORMAT_R32A32_SINT]           = 0,
-      [PIPE_FORMAT_R10G10B10A2_UINT]      = GEN6_FORMAT_R10G10B10A2_UINT,
-      [PIPE_FORMAT_B5G6R5_SRGB]           = GEN6_FORMAT_B5G6R5_UNORM_SRGB,
-   };
-   int sfmt = format_mapping[format];
-
-   /* GEN6_FORMAT_R32G32B32A32_FLOAT happens to be 0 */
-   if (!sfmt && format != PIPE_FORMAT_R32G32B32A32_FLOAT)
-      sfmt = -1;
-
-   return sfmt;
-}
diff --git a/src/gallium/drivers/ilo/core/ilo_format.h b/src/gallium/drivers/ilo/core/ilo_format.h
deleted file mode 100644 (file)
index 6b73ea1..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2013 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_FORMAT_H
-#define ILO_FORMAT_H
-
-#include "genhw/genhw.h"
-#include "ilo_core.h"
-#include "ilo_dev.h"
-
-bool
-ilo_format_support_vb(const struct ilo_dev *dev,
-                      enum pipe_format format);
-
-bool
-ilo_format_support_sol(const struct ilo_dev *dev,
-                       enum pipe_format format);
-
-bool
-ilo_format_support_sampler(const struct ilo_dev *dev,
-                           enum pipe_format format);
-
-bool
-ilo_format_support_rt(const struct ilo_dev *dev,
-                      enum pipe_format format);
-
-bool
-ilo_format_support_zs(const struct ilo_dev *dev,
-                      enum pipe_format format);
-
-int
-ilo_format_translate_color(const struct ilo_dev *dev,
-                           enum pipe_format format);
-
-/**
- * Translate a pipe format to a hardware surface format suitable for
- * the given purpose.  Return -1 on errors.
- *
- * This is an inline function not only for performance reasons.  There are
- * caveats that the callers should be aware of before calling this function.
- */
-static inline int
-ilo_format_translate(const struct ilo_dev *dev,
-                     enum pipe_format format, unsigned bind)
-{
-   switch (bind) {
-   case PIPE_BIND_RENDER_TARGET:
-      /*
-       * Some RGBX formats are not supported as render target formats.  But we
-       * can use their RGBA counterparts and force the destination alpha to be
-       * one when blending is enabled.
-       */
-      switch (format) {
-      case PIPE_FORMAT_B8G8R8X8_UNORM:
-         return GEN6_FORMAT_B8G8R8A8_UNORM;
-      default:
-         return ilo_format_translate_color(dev, format);
-      }
-      break;
-   case PIPE_BIND_SAMPLER_VIEW:
-      /*
-       * For depth formats, we want the depth values to be returned as R
-       * values.  But we assume in many places that the depth values are
-       * returned as I values (util_make_fragment_tex_shader_writedepth() is
-       * one such example).  We have to live with that at least for now.
-       *
-       * For ETC1 format, the texture data will be decompressed before being
-       * written to the bo.  See tex_staging_sys_convert_write().
-       */
-      switch (format) {
-      case PIPE_FORMAT_Z16_UNORM:
-         return GEN6_FORMAT_I16_UNORM;
-      case PIPE_FORMAT_Z32_FLOAT:
-         return GEN6_FORMAT_I32_FLOAT;
-      case PIPE_FORMAT_Z24X8_UNORM:
-      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-         return GEN6_FORMAT_I24X8_UNORM;
-      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-         return GEN6_FORMAT_I32X32_FLOAT;
-      case PIPE_FORMAT_ETC1_RGB8:
-         return GEN6_FORMAT_R8G8B8X8_UNORM;
-      default:
-         return ilo_format_translate_color(dev, format);
-      }
-      break;
-   case PIPE_BIND_VERTEX_BUFFER:
-      if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
-         return ilo_format_translate_color(dev, format);
-
-      /*
-       * Some 3-component formats are not supported as vertex element formats.
-       * But since we move between vertices using vb->stride, we should be
-       * good to use their 4-component counterparts if we force the W
-       * component to be one.  The only exception is that the vb boundary
-       * check for the last vertex may fail.
-       */
-      switch (format) {
-      case PIPE_FORMAT_R16G16B16_FLOAT:
-         return GEN6_FORMAT_R16G16B16A16_FLOAT;
-      case PIPE_FORMAT_R16G16B16_UINT:
-         return GEN6_FORMAT_R16G16B16A16_UINT;
-      case PIPE_FORMAT_R16G16B16_SINT:
-         return GEN6_FORMAT_R16G16B16A16_SINT;
-      case PIPE_FORMAT_R8G8B8_UINT:
-         return GEN6_FORMAT_R8G8B8A8_UINT;
-      case PIPE_FORMAT_R8G8B8_SINT:
-         return GEN6_FORMAT_R8G8B8A8_SINT;
-      default:
-         return ilo_format_translate_color(dev, format);
-      }
-      break;
-   case PIPE_BIND_STREAM_OUTPUT:
-      return ilo_format_translate_color(dev, format);
-      break;
-   default:
-      assert(!"cannot translate format");
-      break;
-   }
-
-   return -1;
-}
-
-static inline int
-ilo_format_translate_render(const struct ilo_dev *dev,
-                            enum pipe_format format)
-{
-   return ilo_format_translate(dev, format, PIPE_BIND_RENDER_TARGET);
-}
-
-static inline int
-ilo_format_translate_texture(const struct ilo_dev *dev,
-                             enum pipe_format format)
-{
-   return ilo_format_translate(dev, format, PIPE_BIND_SAMPLER_VIEW);
-}
-
-static inline int
-ilo_format_translate_vertex(const struct ilo_dev *dev,
-                            enum pipe_format format)
-{
-   return ilo_format_translate(dev, format, PIPE_BIND_VERTEX_BUFFER);
-}
-
-#endif /* ILO_FORMAT_H */
index 22c8ef2620ad518928fa6d726bda2437bd712b2b..0d837d8a9d56dba2b41f1bc764c0ac4d0bb5971a 100644 (file)
@@ -675,9 +675,12 @@ img_init_size_and_format(struct ilo_image *img,
    enum pipe_format format = templ->format;
    bool require_separate_stencil = false;
 
+   img->target = templ->target;
    img->width0 = templ->width0;
    img->height0 = templ->height0;
    img->depth0 = templ->depth0;
+   img->array_size = templ->array_size;
+   img->level_count = templ->last_level + 1;
    img->sample_count = (templ->nr_samples) ? templ->nr_samples : 1;
 
    /*
@@ -794,6 +797,10 @@ img_want_hiz(const struct ilo_image *img,
    if (ilo_debug & ILO_DEBUG_NOHIZ)
       return false;
 
+   /* we want 8x4 aligned levels */
+   if (templ->target == PIPE_TEXTURE_1D)
+      return false;
+
    if (!(templ->bind & PIPE_BIND_DEPTH_STENCIL))
       return false;
 
@@ -1343,9 +1350,12 @@ img_init_for_transfer(struct ilo_image *img,
 
    img->aux.type = ILO_IMAGE_AUX_NONE;
 
+   img->target = templ->target;
    img->width0 = templ->width0;
    img->height0 = templ->height0;
    img->depth0 = templ->depth0;
+   img->array_size = templ->array_size;
+   img->level_count = 1;
    img->sample_count = 1;
 
    img->format = templ->format;
@@ -1386,6 +1396,8 @@ void ilo_image_init(struct ilo_image *img,
    struct ilo_image_params params;
    bool transfer_only;
 
+   assert(ilo_is_zeroed(img, sizeof(*img)));
+
    /* use transfer layout when the texture is never bound to GPU */
    transfer_only = !(templ->bind & ~(PIPE_BIND_TRANSFER_WRITE |
                                      PIPE_BIND_TRANSFER_READ));
@@ -1411,6 +1423,8 @@ ilo_image_init_for_imported(struct ilo_image *img,
 {
    struct ilo_image_params params;
 
+   assert(ilo_is_zeroed(img, sizeof(*img)));
+
    if ((tiling == GEN6_TILING_X && bo_stride % 512) ||
        (tiling == GEN6_TILING_Y && bo_stride % 128) ||
        (tiling == GEN8_TILING_W && bo_stride % 64))
@@ -1435,3 +1449,22 @@ ilo_image_init_for_imported(struct ilo_image *img,
 
    return true;
 }
+
+bool
+ilo_image_disable_aux(struct ilo_image *img, const struct ilo_dev *dev)
+{
+   /* HiZ is required for separate stencil on Gen6 */
+   if (ilo_dev_gen(dev) == ILO_GEN(6) &&
+       img->aux.type == ILO_IMAGE_AUX_HIZ &&
+       img->separate_stencil)
+      return false;
+
+   /* MCS is required for multisample images */
+   if (img->aux.type == ILO_IMAGE_AUX_MCS &&
+       img->sample_count > 1)
+      return false;
+
+   img->aux.enables = 0x0;
+
+   return true;
+}
index 4956bdae2ee3bb85cbf9466ade67b78c8548c95d..af15e856028d280915487dbc955f8cb88c1441a4 100644 (file)
@@ -88,10 +88,14 @@ struct ilo_image_lod {
  * Texture layout.
  */
 struct ilo_image {
+   enum pipe_texture_target target;
+
    /* size, format, etc for programming hardware states */
    unsigned width0;
    unsigned height0;
    unsigned depth0;
+   unsigned array_size;
+   unsigned level_count;
    unsigned sample_count;
    enum pipe_format format;
    bool separate_stencil;
@@ -125,8 +129,6 @@ struct ilo_image {
 
    bool scanout;
 
-   struct intel_bo *bo;
-
    struct {
       enum ilo_image_aux_type type;
 
@@ -140,8 +142,12 @@ struct ilo_image {
       unsigned bo_stride;
       unsigned bo_height;
 
+      /* managed by users */
       struct intel_bo *bo;
    } aux;
+
+   /* managed by users */
+   struct intel_bo *bo;
 };
 
 struct pipe_resource;
@@ -158,31 +164,13 @@ ilo_image_init_for_imported(struct ilo_image *img,
                             enum gen_surface_tiling tiling,
                             unsigned bo_stride);
 
-static inline void
-ilo_image_cleanup(struct ilo_image *img)
-{
-   intel_bo_unref(img->bo);
-   intel_bo_unref(img->aux.bo);
-}
-
-static inline void
-ilo_image_set_bo(struct ilo_image *img, struct intel_bo *bo)
-{
-   intel_bo_unref(img->bo);
-   img->bo = intel_bo_ref(bo);
-}
-
-static inline void
-ilo_image_set_aux_bo(struct ilo_image *img, struct intel_bo *bo)
-{
-   intel_bo_unref(img->aux.bo);
-   img->aux.bo = intel_bo_ref(bo);
-}
+bool
+ilo_image_disable_aux(struct ilo_image *img, const struct ilo_dev *dev);
 
 static inline bool
 ilo_image_can_enable_aux(const struct ilo_image *img, unsigned level)
 {
-   return (img->aux.bo && (img->aux.enables & (1 << level)));
+   return (img->aux.enables & (1 << level));
 }
 
 /**
diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d.h b/src/gallium/drivers/ilo/core/ilo_state_3d.h
deleted file mode 100644 (file)
index fdce445..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_STATE_3D_H
-#define ILO_STATE_3D_H
-
-#include "genhw/genhw.h"
-#include "pipe/p_state.h"
-
-#include "ilo_core.h"
-#include "ilo_dev.h"
-
-/**
- * \see brw_context.h
- */
-#define ILO_MAX_DRAW_BUFFERS    8
-#define ILO_MAX_CONST_BUFFERS   (1 + 12)
-#define ILO_MAX_SAMPLER_VIEWS   16
-#define ILO_MAX_SAMPLERS        16
-#define ILO_MAX_SO_BINDINGS     64
-#define ILO_MAX_SO_BUFFERS      4
-#define ILO_MAX_VIEWPORTS       1
-
-#define ILO_MAX_SURFACES        256
-
-struct intel_bo;
-struct ilo_buffer;
-struct ilo_image;
-struct ilo_shader_state;
-
-struct ilo_vb_state {
-   struct pipe_vertex_buffer states[PIPE_MAX_ATTRIBS];
-   uint32_t enabled_mask;
-};
-
-struct ilo_ib_state {
-   struct pipe_resource *buffer;
-   const void *user_buffer;
-   unsigned offset;
-   unsigned index_size;
-
-   /* these are not valid until the state is finalized */
-   struct pipe_resource *hw_resource;
-   unsigned hw_index_size;
-   /* an offset to be added to pipe_draw_info::start */
-   int64_t draw_start_offset;
-};
-
-struct ilo_ve_cso {
-   /* VERTEX_ELEMENT_STATE */
-   uint32_t payload[2];
-};
-
-struct ilo_ve_state {
-   struct ilo_ve_cso cso[PIPE_MAX_ATTRIBS];
-   unsigned count;
-
-   unsigned instance_divisors[PIPE_MAX_ATTRIBS];
-   unsigned vb_mapping[PIPE_MAX_ATTRIBS];
-   unsigned vb_count;
-
-   /* these are not valid until the state is finalized */
-   struct ilo_ve_cso edgeflag_cso;
-   bool last_cso_edgeflag;
-
-   struct ilo_ve_cso nosrc_cso;
-   bool prepend_nosrc_cso;
-};
-
-struct ilo_so_state {
-   struct pipe_stream_output_target *states[ILO_MAX_SO_BUFFERS];
-   unsigned count;
-   unsigned append_bitmask;
-
-   bool enabled;
-};
-
-struct ilo_viewport_cso {
-   /* matrix form */
-   float m00, m11, m22, m30, m31, m32;
-
-   /* guardband in NDC space */
-   float min_gbx, min_gby, max_gbx, max_gby;
-
-   /* viewport in screen space */
-   float min_x, min_y, min_z;
-   float max_x, max_y, max_z;
-};
-
-struct ilo_viewport_state {
-   struct ilo_viewport_cso cso[ILO_MAX_VIEWPORTS];
-   unsigned count;
-
-   struct pipe_viewport_state viewport0;
-};
-
-struct ilo_scissor_state {
-   /* SCISSOR_RECT */
-   uint32_t payload[ILO_MAX_VIEWPORTS * 2];
-
-   struct pipe_scissor_state scissor0;
-};
-
-struct ilo_rasterizer_clip {
-   /* 3DSTATE_CLIP */
-   uint32_t payload[3];
-
-   uint32_t can_enable_guardband;
-};
-
-struct ilo_rasterizer_sf {
-   /* 3DSTATE_SF */
-   uint32_t payload[3];
-   uint32_t dw_msaa;
-
-   /* Global Depth Offset Constant/Scale/Clamp */
-   uint32_t dw_depth_offset_const;
-   uint32_t dw_depth_offset_scale;
-   uint32_t dw_depth_offset_clamp;
-
-   /* Gen8+ 3DSTATE_RASTER */
-   uint32_t dw_raster;
-};
-
-struct ilo_rasterizer_wm {
-   /* 3DSTATE_WM */
-   uint32_t payload[2];
-   uint32_t dw_msaa_rast;
-   uint32_t dw_msaa_disp;
-};
-
-struct ilo_rasterizer_state {
-   struct pipe_rasterizer_state state;
-
-   struct ilo_rasterizer_clip clip;
-   struct ilo_rasterizer_sf sf;
-   struct ilo_rasterizer_wm wm;
-};
-
-struct ilo_dsa_state {
-   /* DEPTH_STENCIL_STATE or Gen8+ 3DSTATE_WM_DEPTH_STENCIL */
-   uint32_t payload[3];
-
-   uint32_t dw_blend_alpha;
-   uint32_t dw_ps_blend_alpha;
-   ubyte alpha_ref;
-};
-
-struct ilo_blend_cso {
-   /* BLEND_STATE */
-   uint32_t payload[2];
-
-   uint32_t dw_blend;
-   uint32_t dw_blend_dst_alpha_forced_one;
-};
-
-struct ilo_blend_state {
-   struct ilo_blend_cso cso[ILO_MAX_DRAW_BUFFERS];
-
-   bool dual_blend;
-   bool alpha_to_coverage;
-
-   uint32_t dw_shared;
-   uint32_t dw_alpha_mod;
-   uint32_t dw_logicop;
-
-   /* a part of 3DSTATE_PS_BLEND */
-   uint32_t dw_ps_blend;
-   uint32_t dw_ps_blend_dst_alpha_forced_one;
-};
-
-struct ilo_sampler_cso {
-   /* SAMPLER_STATE and SAMPLER_BORDER_COLOR_STATE */
-   uint32_t payload[15];
-
-   uint32_t dw_filter;
-   uint32_t dw_filter_aniso;
-   uint32_t dw_wrap;
-   uint32_t dw_wrap_1d;
-   uint32_t dw_wrap_cube;
-
-   bool anisotropic;
-   bool saturate_r;
-   bool saturate_s;
-   bool saturate_t;
-};
-
-struct ilo_sampler_state {
-   const struct ilo_sampler_cso *cso[ILO_MAX_SAMPLERS];
-};
-
-struct ilo_view_surface {
-   /* SURFACE_STATE */
-   uint32_t payload[13];
-   struct intel_bo *bo;
-
-   uint32_t scanout;
-};
-
-struct ilo_view_cso {
-   struct pipe_sampler_view base;
-
-   struct ilo_view_surface surface;
-};
-
-struct ilo_view_state {
-   struct pipe_sampler_view *states[ILO_MAX_SAMPLER_VIEWS];
-   unsigned count;
-};
-
-struct ilo_cbuf_cso {
-   struct pipe_resource *resource;
-   struct ilo_view_surface surface;
-
-   /*
-    * this CSO is not so constant because user buffer needs to be uploaded in
-    * finalize_constant_buffers()
-    */
-   const void *user_buffer;
-   unsigned user_buffer_size;
-};
-
-struct ilo_cbuf_state {
-   struct ilo_cbuf_cso cso[ILO_MAX_CONST_BUFFERS];
-   uint32_t enabled_mask;
-};
-
-struct ilo_resource_state {
-   struct pipe_surface *states[PIPE_MAX_SHADER_RESOURCES];
-   unsigned count;
-};
-
-struct ilo_surface_cso {
-   struct pipe_surface base;
-
-   bool is_rt;
-   union {
-      struct ilo_view_surface rt;
-      struct ilo_zs_surface {
-         uint32_t payload[12];
-         uint32_t dw_aligned_8x4;
-
-         struct intel_bo *bo;
-         struct intel_bo *hiz_bo;
-         struct intel_bo *separate_s8_bo;
-      } zs;
-   } u;
-};
-
-struct ilo_fb_state {
-   struct pipe_framebuffer_state state;
-
-   struct ilo_view_surface null_rt;
-   struct ilo_zs_surface null_zs;
-
-   struct ilo_fb_blend_caps {
-      bool can_logicop;
-      bool can_blend;
-      bool can_alpha_test;
-      bool dst_alpha_forced_one;
-   } blend_caps[PIPE_MAX_COLOR_BUFS];
-
-   unsigned num_samples;
-};
-
-struct ilo_shader_cso {
-   uint32_t payload[5];
-};
-
-/**
- * Translate a pipe texture target to the matching hardware surface type.
- */
-static inline int
-ilo_gpe_gen6_translate_texture(enum pipe_texture_target target)
-{
-   switch (target) {
-   case PIPE_BUFFER:
-      return GEN6_SURFTYPE_BUFFER;
-   case PIPE_TEXTURE_1D:
-   case PIPE_TEXTURE_1D_ARRAY:
-      return GEN6_SURFTYPE_1D;
-   case PIPE_TEXTURE_2D:
-   case PIPE_TEXTURE_RECT:
-   case PIPE_TEXTURE_2D_ARRAY:
-      return GEN6_SURFTYPE_2D;
-   case PIPE_TEXTURE_3D:
-      return GEN6_SURFTYPE_3D;
-   case PIPE_TEXTURE_CUBE:
-   case PIPE_TEXTURE_CUBE_ARRAY:
-      return GEN6_SURFTYPE_CUBE;
-   default:
-      assert(!"unknown texture target");
-      return GEN6_SURFTYPE_BUFFER;
-   }
-}
-
-void
-ilo_gpe_init_ve(const struct ilo_dev *dev,
-                unsigned num_states,
-                const struct pipe_vertex_element *states,
-                struct ilo_ve_state *ve);
-
-void
-ilo_gpe_set_ve_edgeflag(const struct ilo_dev *dev,
-                        struct ilo_ve_cso *cso);
-
-void
-ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev,
-                      int comp0, int comp1, int comp2, int comp3,
-                      struct ilo_ve_cso *cso);
-
-void
-ilo_gpe_set_viewport_cso(const struct ilo_dev *dev,
-                         const struct pipe_viewport_state *state,
-                         struct ilo_viewport_cso *vp);
-
-void
-ilo_gpe_set_scissor(const struct ilo_dev *dev,
-                    unsigned start_slot,
-                    unsigned num_states,
-                    const struct pipe_scissor_state *states,
-                    struct ilo_scissor_state *scissor);
-
-void
-ilo_gpe_set_scissor_null(const struct ilo_dev *dev,
-                         struct ilo_scissor_state *scissor);
-
-void
-ilo_gpe_init_rasterizer(const struct ilo_dev *dev,
-                        const struct pipe_rasterizer_state *state,
-                        struct ilo_rasterizer_state *rasterizer);
-void
-ilo_gpe_init_dsa(const struct ilo_dev *dev,
-                 const struct pipe_depth_stencil_alpha_state *state,
-                 struct ilo_dsa_state *dsa);
-
-void
-ilo_gpe_init_blend(const struct ilo_dev *dev,
-                   const struct pipe_blend_state *state,
-                   struct ilo_blend_state *blend);
-
-void
-ilo_gpe_init_sampler_cso(const struct ilo_dev *dev,
-                         const struct pipe_sampler_state *state,
-                         struct ilo_sampler_cso *sampler);
-
-void
-ilo_gpe_init_view_surface_null(const struct ilo_dev *dev,
-                               unsigned width, unsigned height,
-                               unsigned depth, unsigned level,
-                               struct ilo_view_surface *surf);
-
-void
-ilo_gpe_init_view_surface_for_buffer(const struct ilo_dev *dev,
-                                     const struct ilo_buffer *buf,
-                                     unsigned offset, unsigned size,
-                                     unsigned struct_size,
-                                     enum pipe_format elem_format,
-                                     bool is_rt, bool render_cache_rw,
-                                     struct ilo_view_surface *surf);
-
-void
-ilo_gpe_init_view_surface_for_image(const struct ilo_dev *dev,
-                                    const struct ilo_image *img,
-                                    enum pipe_texture_target target,
-                                    enum pipe_format format,
-                                    unsigned first_level,
-                                    unsigned num_levels,
-                                    unsigned first_layer,
-                                    unsigned num_layers,
-                                    bool is_rt,
-                                    struct ilo_view_surface *surf);
-
-void
-ilo_gpe_init_zs_surface(const struct ilo_dev *dev,
-                        const struct ilo_image *img,
-                        const struct ilo_image *s8_img,
-                        enum pipe_texture_target target,
-                        enum pipe_format format, unsigned level,
-                        unsigned first_layer, unsigned num_layers,
-                        struct ilo_zs_surface *zs);
-
-void
-ilo_gpe_init_vs_cso(const struct ilo_dev *dev,
-                    const struct ilo_shader_state *vs,
-                    struct ilo_shader_cso *cso);
-
-void
-ilo_gpe_init_gs_cso(const struct ilo_dev *dev,
-                    const struct ilo_shader_state *gs,
-                    struct ilo_shader_cso *cso);
-
-void
-ilo_gpe_init_fs_cso(const struct ilo_dev *dev,
-                    const struct ilo_shader_state *fs,
-                    struct ilo_shader_cso *cso);
-
-void
-ilo_gpe_set_fb(const struct ilo_dev *dev,
-               const struct pipe_framebuffer_state *state,
-               struct ilo_fb_state *fb);
-
-#endif /* ILO_STATE_3D_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c b/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c
deleted file mode 100644 (file)
index 5a4c5dd..0000000
+++ /dev/null
@@ -1,2222 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#include "genhw/genhw.h"
-#include "util/u_dual_blend.h"
-#include "util/u_framebuffer.h"
-#include "util/u_half.h"
-
-#include "ilo_format.h"
-#include "ilo_image.h"
-#include "ilo_state_3d.h"
-#include "../ilo_shader.h"
-
-static void
-rasterizer_init_clip(const struct ilo_dev *dev,
-                     const struct pipe_rasterizer_state *state,
-                     struct ilo_rasterizer_clip *clip)
-{
-   uint32_t dw1, dw2, dw3;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   dw1 = GEN6_CLIP_DW1_STATISTICS;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      /*
-       * From the Ivy Bridge PRM, volume 2 part 1, page 219:
-       *
-       *     "Workaround : Due to Hardware issue "EarlyCull" needs to be
-       *      enabled only for the cases where the incoming primitive topology
-       *      into the clipper guaranteed to be Trilist."
-       *
-       * What does this mean?
-       */
-      dw1 |= 0 << 19 |
-             GEN7_CLIP_DW1_EARLY_CULL_ENABLE;
-
-      if (ilo_dev_gen(dev) < ILO_GEN(8)) {
-         if (state->front_ccw)
-            dw1 |= GEN7_CLIP_DW1_FRONTWINDING_CCW;
-
-         switch (state->cull_face) {
-         case PIPE_FACE_NONE:
-            dw1 |= GEN7_CLIP_DW1_CULLMODE_NONE;
-            break;
-         case PIPE_FACE_FRONT:
-            dw1 |= GEN7_CLIP_DW1_CULLMODE_FRONT;
-            break;
-         case PIPE_FACE_BACK:
-            dw1 |= GEN7_CLIP_DW1_CULLMODE_BACK;
-            break;
-         case PIPE_FACE_FRONT_AND_BACK:
-            dw1 |= GEN7_CLIP_DW1_CULLMODE_BOTH;
-            break;
-         }
-      }
-   }
-
-   dw2 = GEN6_CLIP_DW2_CLIP_ENABLE |
-         GEN6_CLIP_DW2_XY_TEST_ENABLE |
-         state->clip_plane_enable << GEN6_CLIP_DW2_UCP_CLIP_ENABLES__SHIFT |
-         GEN6_CLIP_DW2_CLIPMODE_NORMAL;
-
-   if (state->clip_halfz)
-      dw2 |= GEN6_CLIP_DW2_APIMODE_D3D;
-   else
-      dw2 |= GEN6_CLIP_DW2_APIMODE_OGL;
-
-   if (ilo_dev_gen(dev) < ILO_GEN(8) && state->depth_clip)
-      dw2 |= GEN6_CLIP_DW2_Z_TEST_ENABLE;
-
-   if (state->flatshade_first) {
-      dw2 |= 0 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
-             0 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
-             1 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
-   }
-   else {
-      dw2 |= 2 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
-             1 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
-             2 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
-   }
-
-   dw3 = 0x1 << GEN6_CLIP_DW3_MIN_POINT_WIDTH__SHIFT |
-         0x7ff << GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT;
-
-   clip->payload[0] = dw1;
-   clip->payload[1] = dw2;
-   clip->payload[2] = dw3;
-
-   clip->can_enable_guardband = true;
-
-   /*
-    * There are several reasons that guard band test should be disabled
-    *
-    *  - GL wide points (to avoid partially visibie object)
-    *  - GL wide or AA lines (to avoid partially visibie object)
-    */
-   if (state->point_size_per_vertex || state->point_size > 1.0f)
-      clip->can_enable_guardband = false;
-   if (state->line_smooth || state->line_width > 1.0f)
-      clip->can_enable_guardband = false;
-}
-
-static void
-rasterizer_init_sf_depth_offset_gen6(const struct ilo_dev *dev,
-                                     const struct pipe_rasterizer_state *state,
-                                     struct ilo_rasterizer_sf *sf)
-{
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   /*
-    * Scale the constant term.  The minimum representable value used by the HW
-    * is not large enouch to be the minimum resolvable difference.
-    */
-   sf->dw_depth_offset_const = fui(state->offset_units * 2.0f);
-   sf->dw_depth_offset_scale = fui(state->offset_scale);
-   sf->dw_depth_offset_clamp = fui(state->offset_clamp);
-}
-
-static void
-rasterizer_init_sf_gen6(const struct ilo_dev *dev,
-                        const struct pipe_rasterizer_state *state,
-                        struct ilo_rasterizer_sf *sf)
-{
-   int line_width, point_width;
-   uint32_t dw1, dw2, dw3;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 248:
-    *
-    *     "This bit (Statistics Enable) should be set whenever clipping is
-    *      enabled and the Statistics Enable bit is set in CLIP_STATE. It
-    *      should be cleared if clipping is disabled or Statistics Enable in
-    *      CLIP_STATE is clear."
-    */
-   dw1 = GEN7_SF_DW1_STATISTICS |
-         GEN7_SF_DW1_VIEWPORT_ENABLE;
-
-   /* XXX GEN6 path seems to work fine for GEN7 */
-   if (false && ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      /*
-       * From the Ivy Bridge PRM, volume 2 part 1, page 258:
-       *
-       *     "This bit (Legacy Global Depth Bias Enable, Global Depth Offset
-       *      Enable Solid , Global Depth Offset Enable Wireframe, and Global
-       *      Depth Offset Enable Point) should be set whenever non zero depth
-       *      bias (Slope, Bias) values are used. Setting this bit may have
-       *      some degradation of performance for some workloads."
-       */
-      if (state->offset_tri || state->offset_line || state->offset_point) {
-         /* XXX need to scale offset_const according to the depth format */
-         dw1 |= GEN7_SF_DW1_LEGACY_DEPTH_OFFSET;
-
-         dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_SOLID |
-                GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME |
-                GEN7_SF_DW1_DEPTH_OFFSET_POINT;
-      }
-   } else {
-      if (state->offset_tri)
-         dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_SOLID;
-      if (state->offset_line)
-         dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME;
-      if (state->offset_point)
-         dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_POINT;
-   }
-
-   switch (state->fill_front) {
-   case PIPE_POLYGON_MODE_FILL:
-      dw1 |= GEN7_SF_DW1_FRONTFACE_SOLID;
-      break;
-   case PIPE_POLYGON_MODE_LINE:
-      dw1 |= GEN7_SF_DW1_FRONTFACE_WIREFRAME;
-      break;
-   case PIPE_POLYGON_MODE_POINT:
-      dw1 |= GEN7_SF_DW1_FRONTFACE_POINT;
-      break;
-   }
-
-   switch (state->fill_back) {
-   case PIPE_POLYGON_MODE_FILL:
-      dw1 |= GEN7_SF_DW1_BACKFACE_SOLID;
-      break;
-   case PIPE_POLYGON_MODE_LINE:
-      dw1 |= GEN7_SF_DW1_BACKFACE_WIREFRAME;
-      break;
-   case PIPE_POLYGON_MODE_POINT:
-      dw1 |= GEN7_SF_DW1_BACKFACE_POINT;
-      break;
-   }
-
-   if (state->front_ccw)
-      dw1 |= GEN7_SF_DW1_FRONTWINDING_CCW;
-
-   dw2 = 0;
-
-   if (state->line_smooth) {
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 251:
-       *
-       *     "This field (Anti-aliasing Enable) must be disabled if any of the
-       *      render targets have integer (UINT or SINT) surface format."
-       *
-       * From the Sandy Bridge PRM, volume 2 part 1, page 317:
-       *
-       *     "This field (Hierarchical Depth Buffer Enable) must be disabled
-       *      if Anti-aliasing Enable in 3DSTATE_SF is enabled.
-       *
-       * TODO We do not check those yet.
-       */
-      dw2 |= GEN7_SF_DW2_AA_LINE_ENABLE |
-             GEN7_SF_DW2_AA_LINE_CAP_1_0;
-   }
-
-   switch (state->cull_face) {
-   case PIPE_FACE_NONE:
-      dw2 |= GEN7_SF_DW2_CULLMODE_NONE;
-      break;
-   case PIPE_FACE_FRONT:
-      dw2 |= GEN7_SF_DW2_CULLMODE_FRONT;
-      break;
-   case PIPE_FACE_BACK:
-      dw2 |= GEN7_SF_DW2_CULLMODE_BACK;
-      break;
-   case PIPE_FACE_FRONT_AND_BACK:
-      dw2 |= GEN7_SF_DW2_CULLMODE_BOTH;
-      break;
-   }
-
-   /*
-    * Smooth lines should intersect ceil(line_width) or (ceil(line_width) + 1)
-    * pixels in the minor direction.  We have to make the lines slightly
-    * thicker, 0.5 pixel on both sides, so that they intersect that many
-    * pixels are considered into the lines.
-    *
-    * Line width is in U3.7.
-    */
-   line_width = (int)
-      ((state->line_width + (float) state->line_smooth) * 128.0f + 0.5f);
-   line_width = CLAMP(line_width, 0, 1023);
-
-   /* use GIQ rules */
-   if (line_width == 128 && !state->line_smooth)
-      line_width = 0;
-
-   dw2 |= line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT;
-
-   if (ilo_dev_gen(dev) == ILO_GEN(7.5) && state->line_stipple_enable)
-      dw2 |= GEN75_SF_DW2_LINE_STIPPLE_ENABLE;
-
-   if (state->scissor)
-      dw2 |= GEN7_SF_DW2_SCISSOR_ENABLE;
-
-   dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE |
-         GEN7_SF_DW3_SUBPIXEL_8BITS;
-
-   if (state->line_last_pixel)
-      dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE;
-
-   if (state->flatshade_first) {
-      dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
-             0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
-             1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
-   } else {
-      dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
-             1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
-             2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
-   }
-
-   if (!state->point_size_per_vertex)
-      dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH;
-
-   /* in U8.3 */
-   point_width = (int) (state->point_size * 8.0f + 0.5f);
-   point_width = CLAMP(point_width, 1, 2047);
-
-   dw3 |= point_width;
-
-   STATIC_ASSERT(Elements(sf->payload) >= 3);
-   sf->payload[0] = dw1;
-   sf->payload[1] = dw2;
-   sf->payload[2] = dw3;
-
-   if (state->multisample) {
-      sf->dw_msaa = GEN7_SF_DW2_MSRASTMODE_ON_PATTERN;
-
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 251:
-       *
-       *     "Software must not program a value of 0.0 when running in
-       *      MSRASTMODE_ON_xxx modes - zero-width lines are not available
-       *      when multisampling rasterization is enabled."
-       */
-      if (!line_width) {
-         line_width = 128; /* 1.0f */
-
-         sf->dw_msaa |= line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT;
-      }
-   } else {
-      sf->dw_msaa = 0;
-   }
-
-   rasterizer_init_sf_depth_offset_gen6(dev, state, sf);
-   /* 3DSTATE_RASTER is Gen8+ only */
-   sf->dw_raster = 0;
-}
-
-static uint32_t
-rasterizer_get_sf_raster_gen8(const struct ilo_dev *dev,
-                              const struct pipe_rasterizer_state *state)
-{
-   uint32_t dw = 0;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (state->front_ccw)
-      dw |= GEN8_RASTER_DW1_FRONTWINDING_CCW;
-
-   switch (state->cull_face) {
-   case PIPE_FACE_NONE:
-      dw |= GEN8_RASTER_DW1_CULLMODE_NONE;
-      break;
-   case PIPE_FACE_FRONT:
-      dw |= GEN8_RASTER_DW1_CULLMODE_FRONT;
-      break;
-   case PIPE_FACE_BACK:
-      dw |= GEN8_RASTER_DW1_CULLMODE_BACK;
-      break;
-   case PIPE_FACE_FRONT_AND_BACK:
-      dw |= GEN8_RASTER_DW1_CULLMODE_BOTH;
-      break;
-   }
-
-   if (state->point_smooth)
-      dw |= GEN8_RASTER_DW1_SMOOTH_POINT_ENABLE;
-
-   if (state->multisample)
-      dw |= GEN8_RASTER_DW1_API_MULTISAMPLE_ENABLE;
-
-   if (state->offset_tri)
-      dw|= GEN8_RASTER_DW1_DEPTH_OFFSET_SOLID;
-   if (state->offset_line)
-      dw|= GEN8_RASTER_DW1_DEPTH_OFFSET_WIREFRAME;
-   if (state->offset_point)
-      dw|= GEN8_RASTER_DW1_DEPTH_OFFSET_POINT;
-
-   switch (state->fill_front) {
-   case PIPE_POLYGON_MODE_FILL:
-      dw |= GEN8_RASTER_DW1_FRONTFACE_SOLID;
-      break;
-   case PIPE_POLYGON_MODE_LINE:
-      dw |= GEN8_RASTER_DW1_FRONTFACE_WIREFRAME;
-      break;
-   case PIPE_POLYGON_MODE_POINT:
-      dw |= GEN8_RASTER_DW1_FRONTFACE_POINT;
-      break;
-   }
-
-   switch (state->fill_back) {
-   case PIPE_POLYGON_MODE_FILL:
-      dw |= GEN8_RASTER_DW1_BACKFACE_SOLID;
-      break;
-   case PIPE_POLYGON_MODE_LINE:
-      dw |= GEN8_RASTER_DW1_BACKFACE_WIREFRAME;
-      break;
-   case PIPE_POLYGON_MODE_POINT:
-      dw |= GEN8_RASTER_DW1_BACKFACE_POINT;
-      break;
-   }
-
-   if (state->line_smooth)
-      dw |= GEN8_RASTER_DW1_AA_LINE_ENABLE;
-
-   if (state->scissor)
-      dw |= GEN8_RASTER_DW1_SCISSOR_ENABLE;
-
-   if (state->depth_clip)
-      dw |= GEN8_RASTER_DW1_Z_TEST_ENABLE;
-
-   return dw;
-}
-
-static void
-rasterizer_init_sf_gen8(const struct ilo_dev *dev,
-                        const struct pipe_rasterizer_state *state,
-                        struct ilo_rasterizer_sf *sf)
-{
-   int line_width, point_width;
-   uint32_t dw1, dw2, dw3;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   /* in U3.7 */
-   line_width = (int)
-      ((state->line_width + (float) state->line_smooth) * 128.0f + 0.5f);
-   line_width = CLAMP(line_width, 0, 1023);
-
-   /* use GIQ rules */
-   if (line_width == 128 && !state->line_smooth)
-      line_width = 0;
-
-   /* in U8.3 */
-   point_width = (int) (state->point_size * 8.0f + 0.5f);
-   point_width = CLAMP(point_width, 1, 2047);
-
-   dw1 = GEN7_SF_DW1_STATISTICS |
-         GEN7_SF_DW1_VIEWPORT_ENABLE;
-
-   dw2 = line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT;
-   if (state->line_smooth)
-      dw2 |= GEN7_SF_DW2_AA_LINE_CAP_1_0;
-
-   dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE |
-         GEN7_SF_DW3_SUBPIXEL_8BITS |
-         point_width;
-
-   if (state->line_last_pixel)
-      dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE;
-
-   if (state->flatshade_first) {
-      dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
-             0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
-             1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
-   } else {
-      dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
-             1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
-             2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
-   }
-
-   if (!state->point_size_per_vertex)
-      dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH;
-
-   dw3 |= point_width;
-
-   STATIC_ASSERT(Elements(sf->payload) >= 3);
-   sf->payload[0] = dw1;
-   sf->payload[1] = dw2;
-   sf->payload[2] = dw3;
-
-   rasterizer_init_sf_depth_offset_gen6(dev, state, sf);
-
-   sf->dw_msaa = 0;
-   sf->dw_raster = rasterizer_get_sf_raster_gen8(dev, state);
-}
-
-static void
-rasterizer_init_wm_gen6(const struct ilo_dev *dev,
-                        const struct pipe_rasterizer_state *state,
-                        struct ilo_rasterizer_wm *wm)
-{
-   uint32_t dw5, dw6;
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   /* only the FF unit states are set, as in GEN7 */
-
-   dw5 = GEN6_WM_DW5_AA_LINE_WIDTH_2_0;
-
-   /* same value as in 3DSTATE_SF */
-   if (state->line_smooth)
-      dw5 |= GEN6_WM_DW5_AA_LINE_CAP_1_0;
-
-   if (state->poly_stipple_enable)
-      dw5 |= GEN6_WM_DW5_POLY_STIPPLE_ENABLE;
-   if (state->line_stipple_enable)
-      dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE;
-
-   /*
-    * assertion that makes sure
-    *
-    *   dw6 |= wm->dw_msaa_rast | wm->dw_msaa_disp;
-    *
-    * is valid
-    */
-   STATIC_ASSERT(GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL == 0 &&
-                 GEN6_WM_DW6_MSDISPMODE_PERSAMPLE == 0);
-   dw6 = GEN6_WM_DW6_ZW_INTERP_PIXEL;
-
-   if (state->bottom_edge_rule)
-      dw6 |= GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
-
-   wm->dw_msaa_rast =
-      (state->multisample) ? GEN6_WM_DW6_MSRASTMODE_ON_PATTERN : 0;
-   wm->dw_msaa_disp = GEN6_WM_DW6_MSDISPMODE_PERPIXEL;
-
-   STATIC_ASSERT(Elements(wm->payload) >= 2);
-   wm->payload[0] = dw5;
-   wm->payload[1] = dw6;
-}
-
-static void
-rasterizer_init_wm_gen7(const struct ilo_dev *dev,
-                        const struct pipe_rasterizer_state *state,
-                        struct ilo_rasterizer_wm *wm)
-{
-   uint32_t dw1, dw2;
-
-   ILO_DEV_ASSERT(dev, 7, 7.5);
-
-   /*
-    * assertion that makes sure
-    *
-    *   dw1 |= wm->dw_msaa_rast;
-    *   dw2 |= wm->dw_msaa_disp;
-    *
-    * is valid
-    */
-   STATIC_ASSERT(GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL == 0 &&
-                 GEN7_WM_DW2_MSDISPMODE_PERSAMPLE == 0);
-   dw1 = GEN7_WM_DW1_ZW_INTERP_PIXEL |
-         GEN7_WM_DW1_AA_LINE_WIDTH_2_0;
-   dw2 = 0;
-
-   /* same value as in 3DSTATE_SF */
-   if (state->line_smooth)
-      dw1 |= GEN7_WM_DW1_AA_LINE_CAP_1_0;
-
-   if (state->poly_stipple_enable)
-      dw1 |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
-   if (state->line_stipple_enable)
-      dw1 |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
-
-   if (state->bottom_edge_rule)
-      dw1 |= GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
-
-   wm->dw_msaa_rast =
-      (state->multisample) ? GEN7_WM_DW1_MSRASTMODE_ON_PATTERN : 0;
-   wm->dw_msaa_disp = GEN7_WM_DW2_MSDISPMODE_PERPIXEL;
-
-   STATIC_ASSERT(Elements(wm->payload) >= 2);
-   wm->payload[0] = dw1;
-   wm->payload[1] = dw2;
-}
-
-static uint32_t
-rasterizer_get_wm_gen8(const struct ilo_dev *dev,
-                       const struct pipe_rasterizer_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   dw = GEN7_WM_DW1_ZW_INTERP_PIXEL |
-        GEN7_WM_DW1_AA_LINE_WIDTH_2_0;
-
-   /* same value as in 3DSTATE_SF */
-   if (state->line_smooth)
-      dw |= GEN7_WM_DW1_AA_LINE_CAP_1_0;
-
-   if (state->poly_stipple_enable)
-      dw |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
-   if (state->line_stipple_enable)
-      dw |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
-
-   if (state->bottom_edge_rule)
-      dw |= GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
-
-   return dw;
-}
-
-void
-ilo_gpe_init_rasterizer(const struct ilo_dev *dev,
-                        const struct pipe_rasterizer_state *state,
-                        struct ilo_rasterizer_state *rasterizer)
-{
-   rasterizer_init_clip(dev, state, &rasterizer->clip);
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      memset(&rasterizer->wm, 0, sizeof(rasterizer->wm));
-      rasterizer->wm.payload[0] = rasterizer_get_wm_gen8(dev, state);
-
-      rasterizer_init_sf_gen8(dev, state, &rasterizer->sf);
-   } else if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      rasterizer_init_wm_gen7(dev, state, &rasterizer->wm);
-      rasterizer_init_sf_gen6(dev, state, &rasterizer->sf);
-   } else {
-      rasterizer_init_wm_gen6(dev, state, &rasterizer->wm);
-      rasterizer_init_sf_gen6(dev, state, &rasterizer->sf);
-   }
-}
-
-static void
-fs_init_cso_gen6(const struct ilo_dev *dev,
-                 const struct ilo_shader_state *fs,
-                 struct ilo_shader_cso *cso)
-{
-   int start_grf, input_count, sampler_count, interps, max_threads;
-   uint32_t dw2, dw4, dw5, dw6;
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
-   input_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT);
-   sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
-   interps = ilo_shader_get_kernel_param(fs,
-         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
-
-   /* see brwCreateContext() */
-   max_threads = (dev->gt == 2) ? 80 : 40;
-
-   dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
-   dw2 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
-
-   dw4 = start_grf << GEN6_WM_DW4_URB_GRF_START0__SHIFT |
-         0 << GEN6_WM_DW4_URB_GRF_START1__SHIFT |
-         0 << GEN6_WM_DW4_URB_GRF_START2__SHIFT;
-
-   dw5 = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 275:
-    *
-    *     "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that the
-    *      PS kernel or color calculator has the ability to kill (discard)
-    *      pixels or samples, other than due to depth or stencil testing.
-    *      This bit is required to be ENABLED in the following situations:
-    *
-    *      The API pixel shader program contains "killpix" or "discard"
-    *      instructions, or other code in the pixel shader kernel that can
-    *      cause the final pixel mask to differ from the pixel mask received
-    *      on dispatch.
-    *
-    *      A sampler with chroma key enabled with kill pixel mode is used by
-    *      the pixel shader.
-    *
-    *      Any render target has Alpha Test Enable or AlphaToCoverage Enable
-    *      enabled.
-    *
-    *      The pixel shader kernel generates and outputs oMask.
-    *
-    *      Note: As ClipDistance clipping is fully supported in hardware and
-    *      therefore not via PS instructions, there should be no need to
-    *      ENABLE this bit due to ClipDistance clipping."
-    */
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
-      dw5 |= GEN6_WM_DW5_PS_KILL_PIXEL;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 275:
-    *
-    *     "If a NULL Depth Buffer is selected, the Pixel Shader Computed Depth
-    *      field must be set to disabled."
-    *
-    * TODO This is not checked yet.
-    */
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
-      dw5 |= GEN6_WM_DW5_PS_COMPUTE_DEPTH;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
-      dw5 |= GEN6_WM_DW5_PS_USE_DEPTH;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
-      dw5 |= GEN6_WM_DW5_PS_USE_W;
-
-   /*
-    * TODO set this bit only when
-    *
-    *  a) fs writes colors and color is not masked, or
-    *  b) fs writes depth, or
-    *  c) fs or cc kills
-    */
-   if (true)
-      dw5 |= GEN6_WM_DW5_PS_DISPATCH_ENABLE;
-
-   assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
-   dw5 |= GEN6_PS_DISPATCH_8 << GEN6_WM_DW5_PS_DISPATCH_MODE__SHIFT;
-
-   dw6 = input_count << GEN6_WM_DW6_SF_ATTR_COUNT__SHIFT |
-         GEN6_WM_DW6_PS_POSOFFSET_NONE |
-         interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT;
-
-   STATIC_ASSERT(Elements(cso->payload) >= 4);
-   cso->payload[0] = dw2;
-   cso->payload[1] = dw4;
-   cso->payload[2] = dw5;
-   cso->payload[3] = dw6;
-}
-
-static uint32_t
-fs_get_wm_gen7(const struct ilo_dev *dev,
-               const struct ilo_shader_state *fs)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 7, 7.5);
-
-   dw = ilo_shader_get_kernel_param(fs,
-         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) <<
-      GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
-
-   /*
-    * TODO set this bit only when
-    *
-    *  a) fs writes colors and color is not masked, or
-    *  b) fs writes depth, or
-    *  c) fs or cc kills
-    */
-   dw |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
-
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 278:
-    *
-    *     "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
-    *      the PS kernel or color calculator has the ability to kill
-    *      (discard) pixels or samples, other than due to depth or stencil
-    *      testing. This bit is required to be ENABLED in the following
-    *      situations:
-    *
-    *      - The API pixel shader program contains "killpix" or "discard"
-    *        instructions, or other code in the pixel shader kernel that
-    *        can cause the final pixel mask to differ from the pixel mask
-    *        received on dispatch.
-    *
-    *      - A sampler with chroma key enabled with kill pixel mode is used
-    *        by the pixel shader.
-    *
-    *      - Any render target has Alpha Test Enable or AlphaToCoverage
-    *        Enable enabled.
-    *
-    *      - The pixel shader kernel generates and outputs oMask.
-    *
-    *      Note: As ClipDistance clipping is fully supported in hardware
-    *      and therefore not via PS instructions, there should be no need
-    *      to ENABLE this bit due to ClipDistance clipping."
-    */
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
-      dw |= GEN7_WM_DW1_PS_KILL_PIXEL;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
-      dw |= GEN7_WM_DW1_PSCDEPTH_ON;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
-      dw |= GEN7_WM_DW1_PS_USE_DEPTH;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
-      dw |= GEN7_WM_DW1_PS_USE_W;
-
-   return dw;
-}
-
-static void
-fs_init_cso_gen7(const struct ilo_dev *dev,
-                 const struct ilo_shader_state *fs,
-                 struct ilo_shader_cso *cso)
-{
-   int start_grf, sampler_count, max_threads;
-   uint32_t dw2, dw4, dw5;
-
-   ILO_DEV_ASSERT(dev, 7, 7.5);
-
-   start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
-   sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
-
-   dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
-   dw2 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
-
-   dw4 = GEN7_PS_DW4_POSOFFSET_NONE;
-
-   /* see brwCreateContext() */
-   switch (ilo_dev_gen(dev)) {
-   case ILO_GEN(7.5):
-      max_threads = (dev->gt == 3) ? 408 : (dev->gt == 2) ? 204 : 102;
-      dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
-      dw4 |= 1 << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
-      break;
-   case ILO_GEN(7):
-   default:
-      max_threads = (dev->gt == 2) ? 172 : 48;
-      dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
-      break;
-   }
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
-      dw4 |= GEN7_PS_DW4_PUSH_CONSTANT_ENABLE;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
-      dw4 |= GEN7_PS_DW4_ATTR_ENABLE;
-
-   assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
-   dw4 |= GEN6_PS_DISPATCH_8 << GEN7_PS_DW4_DISPATCH_MODE__SHIFT;
-
-   dw5 = start_grf << GEN7_PS_DW5_URB_GRF_START0__SHIFT |
-         0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
-         0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
-
-   STATIC_ASSERT(Elements(cso->payload) >= 4);
-   cso->payload[0] = dw2;
-   cso->payload[1] = dw4;
-   cso->payload[2] = dw5;
-   cso->payload[3] = fs_get_wm_gen7(dev, fs);
-}
-
-static uint32_t
-fs_get_psx_gen8(const struct ilo_dev *dev,
-                const struct ilo_shader_state *fs)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   dw = GEN8_PSX_DW1_DISPATCH_ENABLE;
-
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
-      dw |= GEN8_PSX_DW1_KILL_PIXEL;
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
-      dw |= GEN8_PSX_DW1_PSCDEPTH_ON;
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
-      dw |= GEN8_PSX_DW1_USE_DEPTH;
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
-      dw |= GEN8_PSX_DW1_USE_W;
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
-      dw |= GEN8_PSX_DW1_ATTR_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-fs_get_wm_gen8(const struct ilo_dev *dev,
-               const struct ilo_shader_state *fs)
-{
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   return ilo_shader_get_kernel_param(fs,
-         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) <<
-      GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
-}
-
-static void
-fs_init_cso_gen8(const struct ilo_dev *dev,
-                 const struct ilo_shader_state *fs,
-                 struct ilo_shader_cso *cso)
-{
-   int start_grf, sampler_count;
-   uint32_t dw3, dw6, dw7;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
-   sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
-
-   dw3 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
-   dw3 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
-
-   /* always 64? */
-   dw6 = (64 - 2) << GEN8_PS_DW6_MAX_THREADS__SHIFT |
-         GEN8_PS_DW6_POSOFFSET_NONE;
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
-      dw6 |= GEN8_PS_DW6_PUSH_CONSTANT_ENABLE;
-
-   assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
-   dw6 |= GEN6_PS_DISPATCH_8 << GEN8_PS_DW6_DISPATCH_MODE__SHIFT;
-
-   dw7 = start_grf << GEN8_PS_DW7_URB_GRF_START0__SHIFT |
-         0 << GEN8_PS_DW7_URB_GRF_START1__SHIFT |
-         0 << GEN8_PS_DW7_URB_GRF_START2__SHIFT;
-
-   STATIC_ASSERT(Elements(cso->payload) >= 5);
-   cso->payload[0] = dw3;
-   cso->payload[1] = dw6;
-   cso->payload[2] = dw7;
-   cso->payload[3] = fs_get_psx_gen8(dev, fs);
-   cso->payload[4] = fs_get_wm_gen8(dev, fs);
-}
-
-void
-ilo_gpe_init_fs_cso(const struct ilo_dev *dev,
-                    const struct ilo_shader_state *fs,
-                    struct ilo_shader_cso *cso)
-{
-   if (ilo_dev_gen(dev) >= ILO_GEN(8))
-      fs_init_cso_gen8(dev, fs, cso);
-   else if (ilo_dev_gen(dev) >= ILO_GEN(7))
-      fs_init_cso_gen7(dev, fs, cso);
-   else
-      fs_init_cso_gen6(dev, fs, cso);
-}
-
-struct ilo_zs_surface_info {
-   int surface_type;
-   int format;
-
-   struct {
-      struct intel_bo *bo;
-      unsigned stride;
-      unsigned qpitch;
-      enum gen_surface_tiling tiling;
-      uint32_t offset;
-   } zs, stencil, hiz;
-
-   unsigned width, height, depth;
-   unsigned lod, first_layer, num_layers;
-};
-
-static void
-zs_init_info_null(const struct ilo_dev *dev,
-                  struct ilo_zs_surface_info *info)
-{
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   memset(info, 0, sizeof(*info));
-
-   info->surface_type = GEN6_SURFTYPE_NULL;
-   info->format = GEN6_ZFORMAT_D32_FLOAT;
-   info->width = 1;
-   info->height = 1;
-   info->depth = 1;
-   info->num_layers = 1;
-}
-
-static void
-zs_init_info(const struct ilo_dev *dev,
-             const struct ilo_image *img,
-             const struct ilo_image *s8_img,
-             enum pipe_texture_target target,
-             enum pipe_format format, unsigned level,
-             unsigned first_layer, unsigned num_layers,
-             struct ilo_zs_surface_info *info)
-{
-   bool separate_stencil;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   memset(info, 0, sizeof(*info));
-
-   info->surface_type = ilo_gpe_gen6_translate_texture(target);
-
-   if (info->surface_type == GEN6_SURFTYPE_CUBE) {
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 325-326:
-       *
-       *     "For Other Surfaces (Cube Surfaces):
-       *      This field (Minimum Array Element) is ignored."
-       *
-       *     "For Other Surfaces (Cube Surfaces):
-       *      This field (Render Target View Extent) is ignored."
-       *
-       * As such, we cannot set first_layer and num_layers on cube surfaces.
-       * To work around that, treat it as a 2D surface.
-       */
-      info->surface_type = GEN6_SURFTYPE_2D;
-   }
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      separate_stencil = true;
-   } else {
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 317:
-       *
-       *     "This field (Separate Stencil Buffer Enable) must be set to the
-       *      same value (enabled or disabled) as Hierarchical Depth Buffer
-       *      Enable."
-       */
-      separate_stencil = ilo_image_can_enable_aux(img, level);
-   }
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 317:
-    *
-    *     "If this field (Hierarchical Depth Buffer Enable) is enabled, the
-    *      Surface Format of the depth buffer cannot be
-    *      D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT. Use of stencil
-    *      requires the separate stencil buffer."
-    *
-    * From the Ironlake PRM, volume 2 part 1, page 330:
-    *
-    *     "If this field (Separate Stencil Buffer Enable) is disabled, the
-    *      Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
-    *
-    * There is no similar restriction for GEN6.  But when D24_UNORM_X8_UINT
-    * is indeed used, the depth values output by the fragment shaders will
-    * be different when read back.
-    *
-    * As for GEN7+, separate_stencil is always true.
-    */
-   switch (format) {
-   case PIPE_FORMAT_Z16_UNORM:
-      info->format = GEN6_ZFORMAT_D16_UNORM;
-      break;
-   case PIPE_FORMAT_Z32_FLOAT:
-      info->format = GEN6_ZFORMAT_D32_FLOAT;
-      break;
-   case PIPE_FORMAT_Z24X8_UNORM:
-   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-      info->format = (separate_stencil) ?
-         GEN6_ZFORMAT_D24_UNORM_X8_UINT :
-         GEN6_ZFORMAT_D24_UNORM_S8_UINT;
-      break;
-   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-      info->format = (separate_stencil) ?
-         GEN6_ZFORMAT_D32_FLOAT :
-         GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT;
-      break;
-   case PIPE_FORMAT_S8_UINT:
-      if (separate_stencil) {
-         info->format = GEN6_ZFORMAT_D32_FLOAT;
-         break;
-      }
-      /* fall through */
-   default:
-      assert(!"unsupported depth/stencil format");
-      zs_init_info_null(dev, info);
-      return;
-      break;
-   }
-
-   if (format != PIPE_FORMAT_S8_UINT) {
-      info->zs.bo = img->bo;
-      info->zs.stride = img->bo_stride;
-
-      assert(img->walk_layer_height % 4 == 0);
-      info->zs.qpitch = img->walk_layer_height / 4;
-
-      info->zs.tiling = img->tiling;
-      info->zs.offset = 0;
-   }
-
-   if (s8_img || format == PIPE_FORMAT_S8_UINT) {
-      info->stencil.bo = s8_img->bo;
-
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 329:
-       *
-       *     "The pitch must be set to 2x the value computed based on width,
-       *       as the stencil buffer is stored with two rows interleaved."
-       *
-       * For GEN7, we still dobule the stride because we did not double the
-       * slice widths when initializing the layout.
-       */
-      info->stencil.stride = s8_img->bo_stride * 2;
-
-      assert(s8_img->walk_layer_height % 4 == 0);
-      info->stencil.qpitch = s8_img->walk_layer_height / 4;
-
-      info->stencil.tiling = s8_img->tiling;
-
-      if (ilo_dev_gen(dev) == ILO_GEN(6)) {
-         unsigned x, y;
-
-         assert(s8_img->walk == ILO_IMAGE_WALK_LOD);
-
-         /* offset to the level */
-         ilo_image_get_slice_pos(s8_img, level, 0, &x, &y);
-         ilo_image_pos_to_mem(s8_img, x, y, &x, &y);
-         info->stencil.offset = ilo_image_mem_to_raw(s8_img, x, y);
-      }
-   }
-
-   if (ilo_image_can_enable_aux(img, level)) {
-      info->hiz.bo = img->aux.bo;
-      info->hiz.stride = img->aux.bo_stride;
-
-      assert(img->aux.walk_layer_height % 4 == 0);
-      info->hiz.qpitch = img->aux.walk_layer_height / 4;
-
-      info->hiz.tiling = GEN6_TILING_Y;
-
-      /* offset to the level */
-      if (ilo_dev_gen(dev) == ILO_GEN(6))
-         info->hiz.offset = img->aux.walk_lod_offsets[level];
-   }
-
-   info->width = img->width0;
-   info->height = img->height0;
-   info->depth = (target == PIPE_TEXTURE_3D) ? img->depth0 : num_layers;
-
-   info->lod = level;
-   info->first_layer = first_layer;
-   info->num_layers = num_layers;
-}
-
-void
-ilo_gpe_init_zs_surface(const struct ilo_dev *dev,
-                        const struct ilo_image *img,
-                        const struct ilo_image *s8_img,
-                        enum pipe_texture_target target,
-                        enum pipe_format format, unsigned level,
-                        unsigned first_layer, unsigned num_layers,
-                        struct ilo_zs_surface *zs)
-{
-   const int max_2d_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192;
-   const int max_array_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 2048 : 512;
-   struct ilo_zs_surface_info info;
-   uint32_t dw1, dw2, dw3, dw4, dw5, dw6;
-   int align_w = 8, align_h = 4;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   if (img) {
-      zs_init_info(dev, img, s8_img, target, format,
-            level, first_layer, num_layers, &info);
-
-      switch (img->sample_count) {
-      case 2:
-         align_w /= 2;
-         break;
-      case 4:
-         align_w /= 2;
-         align_h /= 2;
-         break;
-      case 8:
-         align_w /= 4;
-         align_h /= 2;
-         break;
-      case 16:
-         align_w /= 4;
-         align_h /= 4;
-         break;
-      default:
-         break;
-      }
-   } else {
-      zs_init_info_null(dev, &info);
-   }
-
-   switch (info.surface_type) {
-   case GEN6_SURFTYPE_NULL:
-      break;
-   case GEN6_SURFTYPE_1D:
-      assert(info.width <= max_2d_size && info.height == 1 &&
-             info.depth <= max_array_size);
-      assert(info.first_layer < max_array_size - 1 &&
-             info.num_layers <= max_array_size);
-      break;
-   case GEN6_SURFTYPE_2D:
-      assert(info.width <= max_2d_size && info.height <= max_2d_size &&
-             info.depth <= max_array_size);
-      assert(info.first_layer < max_array_size - 1 &&
-             info.num_layers <= max_array_size);
-      break;
-   case GEN6_SURFTYPE_3D:
-      assert(info.width <= 2048 && info.height <= 2048 && info.depth <= 2048);
-      assert(info.first_layer < 2048 && info.num_layers <= max_array_size);
-      break;
-   case GEN6_SURFTYPE_CUBE:
-      assert(info.width <= max_2d_size && info.height <= max_2d_size &&
-             info.depth == 1);
-      assert(info.first_layer == 0 && info.num_layers == 1);
-      assert(info.width == info.height);
-      break;
-   default:
-      assert(!"unexpected depth surface type");
-      break;
-   }
-
-   dw1 = info.surface_type << GEN6_DEPTH_DW1_TYPE__SHIFT |
-         info.format << GEN6_DEPTH_DW1_FORMAT__SHIFT;
-
-   if (info.zs.bo) {
-      /* required for GEN6+ */
-      assert(info.zs.tiling == GEN6_TILING_Y);
-      assert(info.zs.stride > 0 && info.zs.stride < 128 * 1024 &&
-            info.zs.stride % 128 == 0);
-      assert(info.width <= info.zs.stride);
-
-      dw1 |= (info.zs.stride - 1);
-      dw2 = info.zs.offset;
-   } else {
-      dw2 = 0;
-   }
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      if (info.zs.bo)
-         dw1 |= GEN7_DEPTH_DW1_DEPTH_WRITE_ENABLE;
-
-      if (info.stencil.bo)
-         dw1 |= GEN7_DEPTH_DW1_STENCIL_WRITE_ENABLE;
-
-      if (info.hiz.bo)
-         dw1 |= GEN7_DEPTH_DW1_HIZ_ENABLE;
-
-      dw3 = (info.height - 1) << GEN7_DEPTH_DW3_HEIGHT__SHIFT |
-            (info.width - 1) << GEN7_DEPTH_DW3_WIDTH__SHIFT |
-            info.lod << GEN7_DEPTH_DW3_LOD__SHIFT;
-
-      zs->dw_aligned_8x4 =
-         (align(info.height, align_h) - 1) << GEN7_DEPTH_DW3_HEIGHT__SHIFT |
-         (align(info.width, align_w) - 1) << GEN7_DEPTH_DW3_WIDTH__SHIFT |
-         info.lod << GEN7_DEPTH_DW3_LOD__SHIFT;
-
-      dw4 = (info.depth - 1) << GEN7_DEPTH_DW4_DEPTH__SHIFT |
-            info.first_layer << GEN7_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT;
-
-      dw5 = 0;
-
-      dw6 = (info.num_layers - 1) << GEN7_DEPTH_DW6_RT_VIEW_EXTENT__SHIFT;
-
-      if (ilo_dev_gen(dev) >= ILO_GEN(8))
-         dw6 |= info.zs.qpitch;
-   } else {
-      /* always Y-tiled */
-      dw1 |= GEN6_TILING_Y << GEN6_DEPTH_DW1_TILING__SHIFT;
-
-      if (info.hiz.bo) {
-         dw1 |= GEN6_DEPTH_DW1_HIZ_ENABLE |
-                GEN6_DEPTH_DW1_SEPARATE_STENCIL;
-      }
-
-      dw3 = (info.height - 1) << GEN6_DEPTH_DW3_HEIGHT__SHIFT |
-            (info.width - 1) << GEN6_DEPTH_DW3_WIDTH__SHIFT |
-            info.lod << GEN6_DEPTH_DW3_LOD__SHIFT |
-            GEN6_DEPTH_DW3_MIPLAYOUT_BELOW;
-
-      zs->dw_aligned_8x4 =
-         (align(info.height, align_h) - 1) << GEN6_DEPTH_DW3_HEIGHT__SHIFT |
-         (align(info.width, align_w) - 1) << GEN6_DEPTH_DW3_WIDTH__SHIFT |
-         info.lod << GEN6_DEPTH_DW3_LOD__SHIFT |
-         GEN6_DEPTH_DW3_MIPLAYOUT_BELOW;
-
-      dw4 = (info.depth - 1) << GEN6_DEPTH_DW4_DEPTH__SHIFT |
-            info.first_layer << GEN6_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT |
-            (info.num_layers - 1) << GEN6_DEPTH_DW4_RT_VIEW_EXTENT__SHIFT;
-
-      dw5 = 0;
-
-      dw6 = 0;
-   }
-
-   STATIC_ASSERT(Elements(zs->payload) >= 12);
-
-   zs->payload[0] = dw1;
-   zs->payload[1] = dw2;
-   zs->payload[2] = dw3;
-   zs->payload[3] = dw4;
-   zs->payload[4] = dw5;
-   zs->payload[5] = dw6;
-
-   /* do not increment reference count */
-   zs->bo = info.zs.bo;
-
-   /* separate stencil */
-   if (info.stencil.bo) {
-      assert(info.stencil.stride > 0 && info.stencil.stride < 128 * 1024 &&
-             info.stencil.stride % 128 == 0);
-
-      dw1 = (info.stencil.stride - 1) << GEN6_STENCIL_DW1_PITCH__SHIFT;
-      if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
-         dw1 |= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE;
-
-      dw2 = info.stencil.offset;
-      dw4 = info.stencil.qpitch;
-   } else {
-      dw1 = 0;
-      dw2 = 0;
-      dw4 = 0;
-   }
-
-   zs->payload[6] = dw1;
-   zs->payload[7] = dw2;
-   zs->payload[8] = dw4;
-   /* do not increment reference count */
-   zs->separate_s8_bo = info.stencil.bo;
-
-   /* hiz */
-   if (info.hiz.bo) {
-      dw1 = (info.hiz.stride - 1) << GEN6_HIZ_DW1_PITCH__SHIFT;
-      dw2 = info.hiz.offset;
-      dw4 = info.hiz.qpitch;
-   } else {
-      dw1 = 0;
-      dw2 = 0;
-      dw4 = 0;
-   }
-
-   zs->payload[9] = dw1;
-   zs->payload[10] = dw2;
-   zs->payload[11] = dw4;
-   /* do not increment reference count */
-   zs->hiz_bo = info.hiz.bo;
-}
-
-static void
-viewport_get_guardband(const struct ilo_dev *dev,
-                       int center_x, int center_y,
-                       int *min_gbx, int *max_gbx,
-                       int *min_gby, int *max_gby)
-{
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 234:
-    *
-    *     "Per-Device Guardband Extents
-    *
-    *       - Supported X,Y ScreenSpace "Guardband" Extent: [-16K,16K-1]
-    *       - Maximum Post-Clamp Delta (X or Y): 16K"
-    *
-    *     "In addition, in order to be correctly rendered, objects must have a
-    *      screenspace bounding box not exceeding 8K in the X or Y direction.
-    *      This additional restriction must also be comprehended by software,
-    *      i.e., enforced by use of clipping."
-    *
-    * From the Ivy Bridge PRM, volume 2 part 1, page 248:
-    *
-    *     "Per-Device Guardband Extents
-    *
-    *       - Supported X,Y ScreenSpace "Guardband" Extent: [-32K,32K-1]
-    *       - Maximum Post-Clamp Delta (X or Y): N/A"
-    *
-    *     "In addition, in order to be correctly rendered, objects must have a
-    *      screenspace bounding box not exceeding 8K in the X or Y direction.
-    *      This additional restriction must also be comprehended by software,
-    *      i.e., enforced by use of clipping."
-    *
-    * Combined, the bounding box of any object can not exceed 8K in both
-    * width and height.
-    *
-    * Below we set the guardband as a squre of length 8K, centered at where
-    * the viewport is.  This makes sure all objects passing the GB test are
-    * valid to the renderer, and those failing the XY clipping have a
-    * better chance of passing the GB test.
-    */
-   const int max_extent = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 32768 : 16384;
-   const int half_len = 8192 / 2;
-
-   /* make sure the guardband is within the valid range */
-   if (center_x - half_len < -max_extent)
-      center_x = -max_extent + half_len;
-   else if (center_x + half_len > max_extent - 1)
-      center_x = max_extent - half_len;
-
-   if (center_y - half_len < -max_extent)
-      center_y = -max_extent + half_len;
-   else if (center_y + half_len > max_extent - 1)
-      center_y = max_extent - half_len;
-
-   *min_gbx = (float) (center_x - half_len);
-   *max_gbx = (float) (center_x + half_len);
-   *min_gby = (float) (center_y - half_len);
-   *max_gby = (float) (center_y + half_len);
-}
-
-void
-ilo_gpe_set_viewport_cso(const struct ilo_dev *dev,
-                         const struct pipe_viewport_state *state,
-                         struct ilo_viewport_cso *vp)
-{
-   const float scale_x = fabs(state->scale[0]);
-   const float scale_y = fabs(state->scale[1]);
-   const float scale_z = fabs(state->scale[2]);
-   int min_gbx, max_gbx, min_gby, max_gby;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   viewport_get_guardband(dev,
-         (int) state->translate[0],
-         (int) state->translate[1],
-         &min_gbx, &max_gbx, &min_gby, &max_gby);
-
-   /* matrix form */
-   vp->m00 = state->scale[0];
-   vp->m11 = state->scale[1];
-   vp->m22 = state->scale[2];
-   vp->m30 = state->translate[0];
-   vp->m31 = state->translate[1];
-   vp->m32 = state->translate[2];
-
-   /* guardband in NDC space */
-   vp->min_gbx = ((float) min_gbx - state->translate[0]) / scale_x;
-   vp->max_gbx = ((float) max_gbx - state->translate[0]) / scale_x;
-   vp->min_gby = ((float) min_gby - state->translate[1]) / scale_y;
-   vp->max_gby = ((float) max_gby - state->translate[1]) / scale_y;
-
-   /* viewport in screen space */
-   vp->min_x = scale_x * -1.0f + state->translate[0];
-   vp->max_x = scale_x *  1.0f + state->translate[0];
-   vp->min_y = scale_y * -1.0f + state->translate[1];
-   vp->max_y = scale_y *  1.0f + state->translate[1];
-   vp->min_z = scale_z * -1.0f + state->translate[2];
-   vp->max_z = scale_z *  1.0f + state->translate[2];
-}
-
-/**
- * Translate a pipe logicop to the matching hardware logicop.
- */
-static int
-gen6_translate_pipe_logicop(unsigned logicop)
-{
-   switch (logicop) {
-   case PIPE_LOGICOP_CLEAR:         return GEN6_LOGICOP_CLEAR;
-   case PIPE_LOGICOP_NOR:           return GEN6_LOGICOP_NOR;
-   case PIPE_LOGICOP_AND_INVERTED:  return GEN6_LOGICOP_AND_INVERTED;
-   case PIPE_LOGICOP_COPY_INVERTED: return GEN6_LOGICOP_COPY_INVERTED;
-   case PIPE_LOGICOP_AND_REVERSE:   return GEN6_LOGICOP_AND_REVERSE;
-   case PIPE_LOGICOP_INVERT:        return GEN6_LOGICOP_INVERT;
-   case PIPE_LOGICOP_XOR:           return GEN6_LOGICOP_XOR;
-   case PIPE_LOGICOP_NAND:          return GEN6_LOGICOP_NAND;
-   case PIPE_LOGICOP_AND:           return GEN6_LOGICOP_AND;
-   case PIPE_LOGICOP_EQUIV:         return GEN6_LOGICOP_EQUIV;
-   case PIPE_LOGICOP_NOOP:          return GEN6_LOGICOP_NOOP;
-   case PIPE_LOGICOP_OR_INVERTED:   return GEN6_LOGICOP_OR_INVERTED;
-   case PIPE_LOGICOP_COPY:          return GEN6_LOGICOP_COPY;
-   case PIPE_LOGICOP_OR_REVERSE:    return GEN6_LOGICOP_OR_REVERSE;
-   case PIPE_LOGICOP_OR:            return GEN6_LOGICOP_OR;
-   case PIPE_LOGICOP_SET:           return GEN6_LOGICOP_SET;
-   default:
-      assert(!"unknown logicop function");
-      return GEN6_LOGICOP_CLEAR;
-   }
-}
-
-/**
- * Translate a pipe blend function to the matching hardware blend function.
- */
-static int
-gen6_translate_pipe_blend(unsigned blend)
-{
-   switch (blend) {
-   case PIPE_BLEND_ADD:                return GEN6_BLENDFUNCTION_ADD;
-   case PIPE_BLEND_SUBTRACT:           return GEN6_BLENDFUNCTION_SUBTRACT;
-   case PIPE_BLEND_REVERSE_SUBTRACT:   return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
-   case PIPE_BLEND_MIN:                return GEN6_BLENDFUNCTION_MIN;
-   case PIPE_BLEND_MAX:                return GEN6_BLENDFUNCTION_MAX;
-   default:
-      assert(!"unknown blend function");
-      return GEN6_BLENDFUNCTION_ADD;
-   };
-}
-
-/**
- * Translate a pipe blend factor to the matching hardware blend factor.
- */
-static int
-gen6_translate_pipe_blendfactor(unsigned blendfactor)
-{
-   switch (blendfactor) {
-   case PIPE_BLENDFACTOR_ONE:                return GEN6_BLENDFACTOR_ONE;
-   case PIPE_BLENDFACTOR_SRC_COLOR:          return GEN6_BLENDFACTOR_SRC_COLOR;
-   case PIPE_BLENDFACTOR_SRC_ALPHA:          return GEN6_BLENDFACTOR_SRC_ALPHA;
-   case PIPE_BLENDFACTOR_DST_ALPHA:          return GEN6_BLENDFACTOR_DST_ALPHA;
-   case PIPE_BLENDFACTOR_DST_COLOR:          return GEN6_BLENDFACTOR_DST_COLOR;
-   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
-   case PIPE_BLENDFACTOR_CONST_COLOR:        return GEN6_BLENDFACTOR_CONST_COLOR;
-   case PIPE_BLENDFACTOR_CONST_ALPHA:        return GEN6_BLENDFACTOR_CONST_ALPHA;
-   case PIPE_BLENDFACTOR_SRC1_COLOR:         return GEN6_BLENDFACTOR_SRC1_COLOR;
-   case PIPE_BLENDFACTOR_SRC1_ALPHA:         return GEN6_BLENDFACTOR_SRC1_ALPHA;
-   case PIPE_BLENDFACTOR_ZERO:               return GEN6_BLENDFACTOR_ZERO;
-   case PIPE_BLENDFACTOR_INV_SRC_COLOR:      return GEN6_BLENDFACTOR_INV_SRC_COLOR;
-   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:      return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
-   case PIPE_BLENDFACTOR_INV_DST_ALPHA:      return GEN6_BLENDFACTOR_INV_DST_ALPHA;
-   case PIPE_BLENDFACTOR_INV_DST_COLOR:      return GEN6_BLENDFACTOR_INV_DST_COLOR;
-   case PIPE_BLENDFACTOR_INV_CONST_COLOR:    return GEN6_BLENDFACTOR_INV_CONST_COLOR;
-   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:    return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
-   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:     return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
-   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:     return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
-   default:
-      assert(!"unknown blend factor");
-      return GEN6_BLENDFACTOR_ONE;
-   };
-}
-
-/**
- * Translate a pipe stencil op to the matching hardware stencil op.
- */
-static int
-gen6_translate_pipe_stencil_op(unsigned stencil_op)
-{
-   switch (stencil_op) {
-   case PIPE_STENCIL_OP_KEEP:       return GEN6_STENCILOP_KEEP;
-   case PIPE_STENCIL_OP_ZERO:       return GEN6_STENCILOP_ZERO;
-   case PIPE_STENCIL_OP_REPLACE:    return GEN6_STENCILOP_REPLACE;
-   case PIPE_STENCIL_OP_INCR:       return GEN6_STENCILOP_INCRSAT;
-   case PIPE_STENCIL_OP_DECR:       return GEN6_STENCILOP_DECRSAT;
-   case PIPE_STENCIL_OP_INCR_WRAP:  return GEN6_STENCILOP_INCR;
-   case PIPE_STENCIL_OP_DECR_WRAP:  return GEN6_STENCILOP_DECR;
-   case PIPE_STENCIL_OP_INVERT:     return GEN6_STENCILOP_INVERT;
-   default:
-      assert(!"unknown stencil op");
-      return GEN6_STENCILOP_KEEP;
-   }
-}
-
-static int
-gen6_blend_factor_dst_alpha_forced_one(int factor)
-{
-   switch (factor) {
-   case GEN6_BLENDFACTOR_DST_ALPHA:
-      return GEN6_BLENDFACTOR_ONE;
-   case GEN6_BLENDFACTOR_INV_DST_ALPHA:
-   case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE:
-      return GEN6_BLENDFACTOR_ZERO;
-   default:
-      return factor;
-   }
-}
-
-static uint32_t
-blend_get_rt_blend_enable_gen6(const struct ilo_dev *dev,
-                               const struct pipe_rt_blend_state *rt,
-                               bool dst_alpha_forced_one)
-{
-   int rgb_src, rgb_dst, a_src, a_dst;
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!rt->blend_enable)
-      return 0;
-
-   rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor);
-   rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor);
-   a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor);
-   a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor);
-
-   if (dst_alpha_forced_one) {
-      rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src);
-      rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst);
-      a_src = gen6_blend_factor_dst_alpha_forced_one(a_src);
-      a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
-   }
-
-   dw = GEN6_RT_DW0_BLEND_ENABLE |
-        gen6_translate_pipe_blend(rt->alpha_func) << 26 |
-        a_src << 20 |
-        a_dst << 15 |
-        gen6_translate_pipe_blend(rt->rgb_func) << 11 |
-        rgb_src << 5 |
-        rgb_dst;
-
-   if (rt->rgb_func != rt->alpha_func ||
-       rgb_src != a_src || rgb_dst != a_dst)
-      dw |= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-blend_get_rt_blend_enable_gen8(const struct ilo_dev *dev,
-                               const struct pipe_rt_blend_state *rt,
-                               bool dst_alpha_forced_one,
-                               bool *independent_alpha)
-{
-   int rgb_src, rgb_dst, a_src, a_dst;
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!rt->blend_enable) {
-      *independent_alpha = false;
-      return 0;
-   }
-
-   rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor);
-   rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor);
-   a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor);
-   a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor);
-
-   if (dst_alpha_forced_one) {
-      rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src);
-      rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst);
-      a_src = gen6_blend_factor_dst_alpha_forced_one(a_src);
-      a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
-   }
-
-   dw = GEN8_RT_DW0_BLEND_ENABLE |
-        rgb_src << 26 |
-        rgb_dst << 21 |
-        gen6_translate_pipe_blend(rt->rgb_func) << 18 |
-        a_src << 13 |
-        a_dst << 8 |
-        gen6_translate_pipe_blend(rt->alpha_func) << 5;
-
-   *independent_alpha = (rt->rgb_func != rt->alpha_func ||
-                         rgb_src != a_src ||
-                         rgb_dst != a_dst);
-
-   return dw;
-}
-
-static void
-blend_init_cso_gen6(const struct ilo_dev *dev,
-                    const struct pipe_blend_state *state,
-                    struct ilo_blend_state *blend,
-                    unsigned index)
-{
-   const struct pipe_rt_blend_state *rt = &state->rt[index];
-   struct ilo_blend_cso *cso = &blend->cso[index];
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   cso->payload[0] = 0;
-   cso->payload[1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
-                     GEN6_RT_DW1_PRE_BLEND_CLAMP |
-                     GEN6_RT_DW1_POST_BLEND_CLAMP;
-
-   if (!(rt->colormask & PIPE_MASK_A))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLE_A;
-   if (!(rt->colormask & PIPE_MASK_R))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLE_R;
-   if (!(rt->colormask & PIPE_MASK_G))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLE_G;
-   if (!(rt->colormask & PIPE_MASK_B))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLE_B;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 365:
-    *
-    *     "Color Buffer Blending and Logic Ops must not be enabled
-    *      simultaneously, or behavior is UNDEFINED."
-    *
-    * Since state->logicop_enable takes precedence over rt->blend_enable,
-    * no special care is needed.
-    */
-   if (state->logicop_enable) {
-      cso->dw_blend = 0;
-      cso->dw_blend_dst_alpha_forced_one = 0;
-   } else {
-      cso->dw_blend = blend_get_rt_blend_enable_gen6(dev, rt, false);
-      cso->dw_blend_dst_alpha_forced_one =
-         blend_get_rt_blend_enable_gen6(dev, rt, true);
-   }
-}
-
-static bool
-blend_init_cso_gen8(const struct ilo_dev *dev,
-                    const struct pipe_blend_state *state,
-                    struct ilo_blend_state *blend,
-                    unsigned index)
-{
-   const struct pipe_rt_blend_state *rt = &state->rt[index];
-   struct ilo_blend_cso *cso = &blend->cso[index];
-   bool independent_alpha = false;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   cso->payload[0] = 0;
-   cso->payload[1] = GEN8_RT_DW1_COLORCLAMP_RTFORMAT |
-                     GEN8_RT_DW1_PRE_BLEND_CLAMP |
-                     GEN8_RT_DW1_POST_BLEND_CLAMP;
-
-   if (!(rt->colormask & PIPE_MASK_A))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_A;
-   if (!(rt->colormask & PIPE_MASK_R))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_R;
-   if (!(rt->colormask & PIPE_MASK_G))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_G;
-   if (!(rt->colormask & PIPE_MASK_B))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_B;
-
-   if (state->logicop_enable) {
-      cso->dw_blend = 0;
-      cso->dw_blend_dst_alpha_forced_one = 0;
-   } else {
-      bool tmp[2];
-
-      cso->dw_blend = blend_get_rt_blend_enable_gen8(dev, rt, false, &tmp[0]);
-      cso->dw_blend_dst_alpha_forced_one =
-         blend_get_rt_blend_enable_gen8(dev, rt, true, &tmp[1]);
-
-      if (tmp[0] || tmp[1])
-         independent_alpha = true;
-   }
-
-   return independent_alpha;
-}
-
-static uint32_t
-blend_get_logicop_enable_gen6(const struct ilo_dev *dev,
-                              const struct pipe_blend_state *state)
-{
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!state->logicop_enable)
-      return 0;
-
-   return GEN6_RT_DW1_LOGICOP_ENABLE |
-          gen6_translate_pipe_logicop(state->logicop_func) << 18;
-}
-
-static uint32_t
-blend_get_logicop_enable_gen8(const struct ilo_dev *dev,
-                              const struct pipe_blend_state *state)
-{
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!state->logicop_enable)
-      return 0;
-
-   return GEN8_RT_DW1_LOGICOP_ENABLE |
-          gen6_translate_pipe_logicop(state->logicop_func) << 27;
-}
-
-static uint32_t
-blend_get_alpha_mod_gen6(const struct ilo_dev *dev,
-                         const struct pipe_blend_state *state,
-                         bool dual_blend)
-{
-   uint32_t dw = 0;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (state->alpha_to_coverage) {
-      dw |= GEN6_RT_DW1_ALPHA_TO_COVERAGE;
-      if (ilo_dev_gen(dev) >= ILO_GEN(7))
-         dw |= GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER;
-   }
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 378:
-    *
-    *     "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
-    *      must be disabled."
-    */
-   if (state->alpha_to_one && !dual_blend)
-      dw |= GEN6_RT_DW1_ALPHA_TO_ONE;
-
-   return dw;
-}
-
-static uint32_t
-blend_get_alpha_mod_gen8(const struct ilo_dev *dev,
-                         const struct pipe_blend_state *state,
-                         bool dual_blend)
-{
-   uint32_t dw = 0;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (state->alpha_to_coverage) {
-      dw |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE |
-            GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER;
-   }
-
-   if (state->alpha_to_one && !dual_blend)
-      dw |= GEN8_BLEND_DW0_ALPHA_TO_ONE;
-
-   return dw;
-}
-
-static uint32_t
-blend_get_ps_blend_gen8(const struct ilo_dev *dev, uint32_t rt_dw0)
-{
-   int rgb_src, rgb_dst, a_src, a_dst;
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!(rt_dw0 & GEN8_RT_DW0_BLEND_ENABLE))
-      return 0;
-
-   a_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_ALPHA_FACTOR);
-   a_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_ALPHA_FACTOR);
-   rgb_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_COLOR_FACTOR);
-   rgb_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_COLOR_FACTOR);
-
-   dw = GEN8_PS_BLEND_DW1_BLEND_ENABLE;
-   dw |= GEN_SHIFT32(a_src, GEN8_PS_BLEND_DW1_SRC_ALPHA_FACTOR);
-   dw |= GEN_SHIFT32(a_dst, GEN8_PS_BLEND_DW1_DST_ALPHA_FACTOR);
-   dw |= GEN_SHIFT32(rgb_src, GEN8_PS_BLEND_DW1_SRC_COLOR_FACTOR);
-   dw |= GEN_SHIFT32(rgb_dst, GEN8_PS_BLEND_DW1_DST_COLOR_FACTOR);
-
-   if (a_src != rgb_src || a_dst != rgb_dst)
-      dw |= GEN8_PS_BLEND_DW1_INDEPENDENT_ALPHA_ENABLE;
-
-   return dw;
-}
-
-void
-ilo_gpe_init_blend(const struct ilo_dev *dev,
-                   const struct pipe_blend_state *state,
-                   struct ilo_blend_state *blend)
-{
-   unsigned i;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   blend->dual_blend = (util_blend_state_is_dual(state, 0) &&
-                        state->rt[0].blend_enable &&
-                        !state->logicop_enable);
-   blend->alpha_to_coverage = state->alpha_to_coverage;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      bool independent_alpha;
-
-      blend->dw_alpha_mod =
-         blend_get_alpha_mod_gen8(dev, state, blend->dual_blend);
-      blend->dw_logicop = blend_get_logicop_enable_gen8(dev, state);
-      blend->dw_shared = (state->dither) ? GEN8_BLEND_DW0_DITHER_ENABLE : 0;
-
-      independent_alpha = blend_init_cso_gen8(dev, state, blend, 0);
-      if (independent_alpha)
-         blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
-
-      blend->dw_ps_blend = blend_get_ps_blend_gen8(dev,
-            blend->cso[0].dw_blend);
-      blend->dw_ps_blend_dst_alpha_forced_one = blend_get_ps_blend_gen8(dev,
-            blend->cso[0].dw_blend_dst_alpha_forced_one);
-
-      if (state->independent_blend_enable) {
-         for (i = 1; i < Elements(blend->cso); i++) {
-            independent_alpha = blend_init_cso_gen8(dev, state, blend, i);
-            if (independent_alpha)
-               blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
-         }
-      } else {
-         for (i = 1; i < Elements(blend->cso); i++)
-            blend->cso[i] = blend->cso[0];
-      }
-   } else {
-      blend->dw_alpha_mod =
-         blend_get_alpha_mod_gen6(dev, state, blend->dual_blend);
-      blend->dw_logicop = blend_get_logicop_enable_gen6(dev, state);
-      blend->dw_shared = (state->dither) ? GEN6_RT_DW1_DITHER_ENABLE : 0;
-
-      blend->dw_ps_blend = 0;
-      blend->dw_ps_blend_dst_alpha_forced_one = 0;
-
-      blend_init_cso_gen6(dev, state, blend, 0);
-      if (state->independent_blend_enable) {
-         for (i = 1; i < Elements(blend->cso); i++)
-            blend_init_cso_gen6(dev, state, blend, i);
-      } else {
-         for (i = 1; i < Elements(blend->cso); i++)
-            blend->cso[i] = blend->cso[0];
-      }
-   }
-}
-
-/**
- * Translate a pipe DSA test function to the matching hardware compare
- * function.
- */
-static int
-gen6_translate_dsa_func(unsigned func)
-{
-   switch (func) {
-   case PIPE_FUNC_NEVER:      return GEN6_COMPAREFUNCTION_NEVER;
-   case PIPE_FUNC_LESS:       return GEN6_COMPAREFUNCTION_LESS;
-   case PIPE_FUNC_EQUAL:      return GEN6_COMPAREFUNCTION_EQUAL;
-   case PIPE_FUNC_LEQUAL:     return GEN6_COMPAREFUNCTION_LEQUAL;
-   case PIPE_FUNC_GREATER:    return GEN6_COMPAREFUNCTION_GREATER;
-   case PIPE_FUNC_NOTEQUAL:   return GEN6_COMPAREFUNCTION_NOTEQUAL;
-   case PIPE_FUNC_GEQUAL:     return GEN6_COMPAREFUNCTION_GEQUAL;
-   case PIPE_FUNC_ALWAYS:     return GEN6_COMPAREFUNCTION_ALWAYS;
-   default:
-      assert(!"unknown depth/stencil/alpha test function");
-      return GEN6_COMPAREFUNCTION_NEVER;
-   }
-}
-
-static uint32_t
-dsa_get_stencil_enable_gen6(const struct ilo_dev *dev,
-                            const struct pipe_stencil_state *stencil0,
-                            const struct pipe_stencil_state *stencil1)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!stencil0->enabled)
-      return 0;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 359:
-    *
-    *     "If the Depth Buffer is either undefined or does not have a surface
-    *      format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
-    *      stencil buffer is disabled, Stencil Test Enable must be DISABLED"
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 370:
-    *
-    *     "This field (Stencil Test Enable) cannot be enabled if
-    *      Surface Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
-    *
-    * TODO We do not check these yet.
-    */
-   dw = GEN6_ZS_DW0_STENCIL_TEST_ENABLE |
-        gen6_translate_dsa_func(stencil0->func) << 28 |
-        gen6_translate_pipe_stencil_op(stencil0->fail_op) << 25 |
-        gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 22 |
-        gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 19;
-   if (stencil0->writemask)
-      dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
-
-   if (stencil1->enabled) {
-      dw |= GEN6_ZS_DW0_STENCIL1_ENABLE |
-            gen6_translate_dsa_func(stencil1->func) << 12 |
-            gen6_translate_pipe_stencil_op(stencil1->fail_op) << 9 |
-            gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 6 |
-            gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 3;
-      if (stencil1->writemask)
-         dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
-   }
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_stencil_enable_gen8(const struct ilo_dev *dev,
-                            const struct pipe_stencil_state *stencil0,
-                            const struct pipe_stencil_state *stencil1)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!stencil0->enabled)
-      return 0;
-
-   dw = gen6_translate_pipe_stencil_op(stencil0->fail_op) << 29 |
-        gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 26 |
-        gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 23 |
-        gen6_translate_dsa_func(stencil0->func) << 8 |
-        GEN8_ZS_DW1_STENCIL_TEST_ENABLE;
-   if (stencil0->writemask)
-      dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
-
-   if (stencil1->enabled) {
-      dw |= gen6_translate_dsa_func(stencil1->func) << 20 |
-            gen6_translate_pipe_stencil_op(stencil1->fail_op) << 17 |
-            gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 14 |
-            gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 11 |
-            GEN8_ZS_DW1_STENCIL1_ENABLE;
-      if (stencil1->writemask)
-         dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
-   }
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_depth_enable_gen6(const struct ilo_dev *dev,
-                          const struct pipe_depth_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 360:
-    *
-    *     "Enabling the Depth Test function without defining a Depth Buffer is
-    *      UNDEFINED."
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 375:
-    *
-    *     "A Depth Buffer must be defined before enabling writes to it, or
-    *      operation is UNDEFINED."
-    *
-    * TODO We do not check these yet.
-    */
-   if (state->enabled) {
-      dw = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
-           gen6_translate_dsa_func(state->func) << 27;
-   } else {
-      dw = GEN6_COMPAREFUNCTION_ALWAYS << 27;
-   }
-
-   if (state->writemask)
-      dw |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_depth_enable_gen8(const struct ilo_dev *dev,
-                          const struct pipe_depth_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (state->enabled) {
-      dw = GEN8_ZS_DW1_DEPTH_TEST_ENABLE |
-           gen6_translate_dsa_func(state->func) << 5;
-   } else {
-      dw = GEN6_COMPAREFUNCTION_ALWAYS << 5;
-   }
-
-   if (state->writemask)
-      dw |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_alpha_enable_gen6(const struct ilo_dev *dev,
-                          const struct pipe_alpha_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!state->enabled)
-      return 0;
-
-   /* this will be ORed to BLEND_STATE */
-   dw = GEN6_RT_DW1_ALPHA_TEST_ENABLE |
-        gen6_translate_dsa_func(state->func) << 13;
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_alpha_enable_gen8(const struct ilo_dev *dev,
-                          const struct pipe_alpha_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!state->enabled)
-      return 0;
-
-   /* this will be ORed to BLEND_STATE */
-   dw = GEN8_BLEND_DW0_ALPHA_TEST_ENABLE |
-        gen6_translate_dsa_func(state->func) << 24;
-
-   return dw;
-}
-
-void
-ilo_gpe_init_dsa(const struct ilo_dev *dev,
-                 const struct pipe_depth_stencil_alpha_state *state,
-                 struct ilo_dsa_state *dsa)
-{
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   STATIC_ASSERT(Elements(dsa->payload) >= 3);
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      const uint32_t dw_stencil = dsa_get_stencil_enable_gen8(dev,
-            &state->stencil[0], &state->stencil[1]);
-      const uint32_t dw_depth = dsa_get_depth_enable_gen8(dev, &state->depth);
-
-      assert(!(dw_stencil & dw_depth));
-      dsa->payload[0] = dw_stencil | dw_depth;
-
-      dsa->dw_blend_alpha = dsa_get_alpha_enable_gen8(dev, &state->alpha);
-      dsa->dw_ps_blend_alpha = (state->alpha.enabled) ?
-         GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE : 0;
-   } else {
-      dsa->payload[0] = dsa_get_stencil_enable_gen6(dev,
-            &state->stencil[0], &state->stencil[1]);
-      dsa->payload[2] = dsa_get_depth_enable_gen6(dev, &state->depth);
-
-      dsa->dw_blend_alpha = dsa_get_alpha_enable_gen6(dev, &state->alpha);
-      dsa->dw_ps_blend_alpha = 0;
-   }
-
-   dsa->payload[1] = state->stencil[0].valuemask << 24 |
-                     state->stencil[0].writemask << 16 |
-                     state->stencil[1].valuemask << 8 |
-                     state->stencil[1].writemask;
-
-   dsa->alpha_ref = float_to_ubyte(state->alpha.ref_value);
-}
-
-void
-ilo_gpe_set_scissor(const struct ilo_dev *dev,
-                    unsigned start_slot,
-                    unsigned num_states,
-                    const struct pipe_scissor_state *states,
-                    struct ilo_scissor_state *scissor)
-{
-   unsigned i;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   for (i = 0; i < num_states; i++) {
-      uint16_t min_x, min_y, max_x, max_y;
-
-      /* both max and min are inclusive in SCISSOR_RECT */
-      if (states[i].minx < states[i].maxx &&
-          states[i].miny < states[i].maxy) {
-         min_x = states[i].minx;
-         min_y = states[i].miny;
-         max_x = states[i].maxx - 1;
-         max_y = states[i].maxy - 1;
-      }
-      else {
-         /* we have to make min greater than max */
-         min_x = 1;
-         min_y = 1;
-         max_x = 0;
-         max_y = 0;
-      }
-
-      scissor->payload[(start_slot + i) * 2 + 0] = min_y << 16 | min_x;
-      scissor->payload[(start_slot + i) * 2 + 1] = max_y << 16 | max_x;
-   }
-
-   if (!start_slot && num_states)
-      scissor->scissor0 = states[0];
-}
-
-void
-ilo_gpe_set_scissor_null(const struct ilo_dev *dev,
-                         struct ilo_scissor_state *scissor)
-{
-   unsigned i;
-
-   for (i = 0; i < Elements(scissor->payload); i += 2) {
-      scissor->payload[i + 0] = 1 << 16 | 1;
-      scissor->payload[i + 1] = 0;
-   }
-}
-
-static void
-fb_set_blend_caps(const struct ilo_dev *dev,
-                  enum pipe_format format,
-                  struct ilo_fb_blend_caps *caps)
-{
-   const struct util_format_description *desc =
-      util_format_description(format);
-   const int ch = util_format_get_first_non_void_channel(format);
-
-   memset(caps, 0, sizeof(*caps));
-
-   if (format == PIPE_FORMAT_NONE || desc->is_mixed)
-      return;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 365:
-    *
-    *     "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
-    *      variants), otherwise Logic Ops must be DISABLED."
-    *
-    * According to the classic driver, this is lifted on Gen8+.
-    */
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      caps->can_logicop = true;
-   } else {
-      caps->can_logicop = (ch >= 0 && desc->channel[ch].normalized &&
-            desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED &&
-            desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB);
-   }
-
-   /* no blending for pure integer formats */
-   caps->can_blend = !util_format_is_pure_integer(format);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 382:
-    *
-    *     "Alpha Test can only be enabled if Pixel Shader outputs a float
-    *      alpha value."
-    */
-   caps->can_alpha_test = !util_format_is_pure_integer(format);
-
-   caps->dst_alpha_forced_one =
-      (ilo_format_translate_render(dev, format) !=
-       ilo_format_translate_color(dev, format));
-
-   /* sanity check */
-   if (caps->dst_alpha_forced_one) {
-      enum pipe_format render_format;
-
-      switch (format) {
-      case PIPE_FORMAT_B8G8R8X8_UNORM:
-         render_format = PIPE_FORMAT_B8G8R8A8_UNORM;
-         break;
-      default:
-         render_format = PIPE_FORMAT_NONE;
-         break;
-      }
-
-      assert(ilo_format_translate_render(dev, format) ==
-             ilo_format_translate_color(dev, render_format));
-   }
-}
-
-void
-ilo_gpe_set_fb(const struct ilo_dev *dev,
-               const struct pipe_framebuffer_state *state,
-               struct ilo_fb_state *fb)
-{
-   const struct pipe_surface *first_surf = NULL;
-   int i;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   util_copy_framebuffer_state(&fb->state, state);
-
-   ilo_gpe_init_view_surface_null(dev,
-         (state->width) ? state->width : 1,
-         (state->height) ? state->height : 1,
-         1, 0, &fb->null_rt);
-
-   for (i = 0; i < state->nr_cbufs; i++) {
-      if (state->cbufs[i]) {
-         fb_set_blend_caps(dev, state->cbufs[i]->format, &fb->blend_caps[i]);
-
-         if (!first_surf)
-            first_surf = state->cbufs[i];
-      } else {
-         fb_set_blend_caps(dev, PIPE_FORMAT_NONE, &fb->blend_caps[i]);
-      }
-   }
-
-   if (!first_surf && state->zsbuf)
-      first_surf = state->zsbuf;
-
-   fb->num_samples = (first_surf) ? first_surf->texture->nr_samples : 1;
-   if (!fb->num_samples)
-      fb->num_samples = 1;
-
-   /*
-    * The PRMs list several restrictions when the framebuffer has more than
-    * one surface.  It seems they are actually lifted on GEN6+.
-    */
-}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d_top.c b/src/gallium/drivers/ilo/core/ilo_state_3d_top.c
deleted file mode 100644 (file)
index c17957f..0000000
+++ /dev/null
@@ -1,1716 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#include "genhw/genhw.h"
-#include "util/u_dual_blend.h"
-#include "util/u_framebuffer.h"
-#include "util/u_half.h"
-#include "util/u_resource.h"
-
-#include "ilo_buffer.h"
-#include "ilo_format.h"
-#include "ilo_image.h"
-#include "ilo_state_3d.h"
-#include "../ilo_shader.h"
-
-static void
-ve_init_cso(const struct ilo_dev *dev,
-            const struct pipe_vertex_element *state,
-            unsigned vb_index,
-            struct ilo_ve_cso *cso)
-{
-   int comp[4] = {
-      GEN6_VFCOMP_STORE_SRC,
-      GEN6_VFCOMP_STORE_SRC,
-      GEN6_VFCOMP_STORE_SRC,
-      GEN6_VFCOMP_STORE_SRC,
-   };
-   int format;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   switch (util_format_get_nr_components(state->src_format)) {
-   case 1: comp[1] = GEN6_VFCOMP_STORE_0;
-   case 2: comp[2] = GEN6_VFCOMP_STORE_0;
-   case 3: comp[3] = (util_format_is_pure_integer(state->src_format)) ?
-                     GEN6_VFCOMP_STORE_1_INT :
-                     GEN6_VFCOMP_STORE_1_FP;
-   }
-
-   format = ilo_format_translate_vertex(dev, state->src_format);
-
-   STATIC_ASSERT(Elements(cso->payload) >= 2);
-   cso->payload[0] =
-      vb_index << GEN6_VE_DW0_VB_INDEX__SHIFT |
-      GEN6_VE_DW0_VALID |
-      format << GEN6_VE_DW0_FORMAT__SHIFT |
-      state->src_offset << GEN6_VE_DW0_VB_OFFSET__SHIFT;
-
-   cso->payload[1] =
-         comp[0] << GEN6_VE_DW1_COMP0__SHIFT |
-         comp[1] << GEN6_VE_DW1_COMP1__SHIFT |
-         comp[2] << GEN6_VE_DW1_COMP2__SHIFT |
-         comp[3] << GEN6_VE_DW1_COMP3__SHIFT;
-}
-
-void
-ilo_gpe_init_ve(const struct ilo_dev *dev,
-                unsigned num_states,
-                const struct pipe_vertex_element *states,
-                struct ilo_ve_state *ve)
-{
-   unsigned i;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   ve->count = num_states;
-   ve->vb_count = 0;
-
-   for (i = 0; i < num_states; i++) {
-      const unsigned pipe_idx = states[i].vertex_buffer_index;
-      const unsigned instance_divisor = states[i].instance_divisor;
-      unsigned hw_idx;
-
-      /*
-       * map the pipe vb to the hardware vb, which has a fixed instance
-       * divisor
-       */
-      for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
-         if (ve->vb_mapping[hw_idx] == pipe_idx &&
-             ve->instance_divisors[hw_idx] == instance_divisor)
-            break;
-      }
-
-      /* create one if there is no matching hardware vb */
-      if (hw_idx >= ve->vb_count) {
-         hw_idx = ve->vb_count++;
-
-         ve->vb_mapping[hw_idx] = pipe_idx;
-         ve->instance_divisors[hw_idx] = instance_divisor;
-      }
-
-      ve_init_cso(dev, &states[i], hw_idx, &ve->cso[i]);
-   }
-}
-
-void
-ilo_gpe_set_ve_edgeflag(const struct ilo_dev *dev,
-                        struct ilo_ve_cso *cso)
-{
-   int format;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 94:
-    *
-    *     "- This bit (Edge Flag Enable) must only be ENABLED on the last
-    *        valid VERTEX_ELEMENT structure.
-    *
-    *      - When set, Component 0 Control must be set to VFCOMP_STORE_SRC,
-    *        and Component 1-3 Control must be set to VFCOMP_NOSTORE.
-    *
-    *      - The Source Element Format must be set to the UINT format.
-    *
-    *      - [DevSNB]: Edge Flags are not supported for QUADLIST
-    *        primitives.  Software may elect to convert QUADLIST primitives
-    *        to some set of corresponding edge-flag-supported primitive
-    *        types (e.g., POLYGONs) prior to submission to the 3D pipeline."
-    */
-   cso->payload[0] |= GEN6_VE_DW0_EDGE_FLAG_ENABLE;
-
-   /*
-    * Edge flags have format GEN6_FORMAT_R8_USCALED when defined via
-    * glEdgeFlagPointer(), and format GEN6_FORMAT_R32_FLOAT when defined
-    * via glEdgeFlag(), as can be seen in vbo_attrib_tmp.h.
-    *
-    * Since all the hardware cares about is whether the flags are zero or not,
-    * we can treat them as the corresponding _UINT formats.
-    */
-   format = GEN_EXTRACT(cso->payload[0], GEN6_VE_DW0_FORMAT);
-   cso->payload[0] &= ~GEN6_VE_DW0_FORMAT__MASK;
-
-   switch (format) {
-   case GEN6_FORMAT_R32_FLOAT:
-      format = GEN6_FORMAT_R32_UINT;
-      break;
-   case GEN6_FORMAT_R8_USCALED:
-      format = GEN6_FORMAT_R8_UINT;
-      break;
-   default:
-      break;
-   }
-
-   cso->payload[0] |= GEN_SHIFT32(format, GEN6_VE_DW0_FORMAT);
-
-   cso->payload[1] =
-         GEN6_VFCOMP_STORE_SRC << GEN6_VE_DW1_COMP0__SHIFT |
-         GEN6_VFCOMP_NOSTORE << GEN6_VE_DW1_COMP1__SHIFT |
-         GEN6_VFCOMP_NOSTORE << GEN6_VE_DW1_COMP2__SHIFT |
-         GEN6_VFCOMP_NOSTORE << GEN6_VE_DW1_COMP3__SHIFT;
-}
-
-void
-ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev,
-                          int comp0, int comp1, int comp2, int comp3,
-                          struct ilo_ve_cso *cso)
-{
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   STATIC_ASSERT(Elements(cso->payload) >= 2);
-
-   assert(comp0 != GEN6_VFCOMP_STORE_SRC &&
-          comp1 != GEN6_VFCOMP_STORE_SRC &&
-          comp2 != GEN6_VFCOMP_STORE_SRC &&
-          comp3 != GEN6_VFCOMP_STORE_SRC);
-
-   cso->payload[0] = GEN6_VE_DW0_VALID;
-   cso->payload[1] =
-         comp0 << GEN6_VE_DW1_COMP0__SHIFT |
-         comp1 << GEN6_VE_DW1_COMP1__SHIFT |
-         comp2 << GEN6_VE_DW1_COMP2__SHIFT |
-         comp3 << GEN6_VE_DW1_COMP3__SHIFT;
-}
-
-void
-ilo_gpe_init_vs_cso(const struct ilo_dev *dev,
-                    const struct ilo_shader_state *vs,
-                    struct ilo_shader_cso *cso)
-{
-   int start_grf, vue_read_len, sampler_count, max_threads;
-   uint32_t dw2, dw4, dw5;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   start_grf = ilo_shader_get_kernel_param(vs, ILO_KERNEL_URB_DATA_START_REG);
-   vue_read_len = ilo_shader_get_kernel_param(vs, ILO_KERNEL_INPUT_COUNT);
-   sampler_count = ilo_shader_get_kernel_param(vs, ILO_KERNEL_SAMPLER_COUNT);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 135:
-    *
-    *     "(Vertex URB Entry Read Length) Specifies the number of pairs of
-    *      128-bit vertex elements to be passed into the payload for each
-    *      vertex."
-    *
-    *     "It is UNDEFINED to set this field to 0 indicating no Vertex URB
-    *      data to be read and passed to the thread."
-    */
-   vue_read_len = (vue_read_len + 1) / 2;
-   if (!vue_read_len)
-      vue_read_len = 1;
-
-   max_threads = dev->thread_count;
-   if (ilo_dev_gen(dev) == ILO_GEN(7.5) && dev->gt == 2)
-      max_threads *= 2;
-
-   dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
-   dw2 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
-
-   dw4 = start_grf << GEN6_VS_DW4_URB_GRF_START__SHIFT |
-         vue_read_len << GEN6_VS_DW4_URB_READ_LEN__SHIFT |
-         0 << GEN6_VS_DW4_URB_READ_OFFSET__SHIFT;
-
-   dw5 = GEN6_VS_DW5_STATISTICS |
-         GEN6_VS_DW5_VS_ENABLE;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
-      dw5 |= (max_threads - 1) << GEN75_VS_DW5_MAX_THREADS__SHIFT;
-   else
-      dw5 |= (max_threads - 1) << GEN6_VS_DW5_MAX_THREADS__SHIFT;
-
-   STATIC_ASSERT(Elements(cso->payload) >= 3);
-   cso->payload[0] = dw2;
-   cso->payload[1] = dw4;
-   cso->payload[2] = dw5;
-}
-
-static void
-gs_init_cso_gen6(const struct ilo_dev *dev,
-                 const struct ilo_shader_state *gs,
-                 struct ilo_shader_cso *cso)
-{
-   int start_grf, vue_read_len, max_threads;
-   uint32_t dw2, dw4, dw5, dw6;
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   if (ilo_shader_get_type(gs) == PIPE_SHADER_GEOMETRY) {
-      start_grf = ilo_shader_get_kernel_param(gs,
-            ILO_KERNEL_URB_DATA_START_REG);
-
-      vue_read_len = ilo_shader_get_kernel_param(gs, ILO_KERNEL_INPUT_COUNT);
-   }
-   else {
-      start_grf = ilo_shader_get_kernel_param(gs,
-            ILO_KERNEL_VS_GEN6_SO_START_REG);
-
-      vue_read_len = ilo_shader_get_kernel_param(gs, ILO_KERNEL_OUTPUT_COUNT);
-   }
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 153:
-    *
-    *     "Specifies the amount of URB data read and passed in the thread
-    *      payload for each Vertex URB entry, in 256-bit register increments.
-    *
-    *      It is UNDEFINED to set this field (Vertex URB Entry Read Length) to
-    *      0 indicating no Vertex URB data to be read and passed to the
-    *      thread."
-    */
-   vue_read_len = (vue_read_len + 1) / 2;
-   if (!vue_read_len)
-      vue_read_len = 1;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 154:
-    *
-    *     "Maximum Number of Threads valid range is [0,27] when Rendering
-    *      Enabled bit is set."
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 173:
-    *
-    *     "Programming Note: If the GS stage is enabled, software must always
-    *      allocate at least one GS URB Entry. This is true even if the GS
-    *      thread never needs to output vertices to the pipeline, e.g., when
-    *      only performing stream output. This is an artifact of the need to
-    *      pass the GS thread an initial destination URB handle."
-    *
-    * As such, we always enable rendering, and limit the number of threads.
-    */
-   if (dev->gt == 2) {
-      /* maximum is 60, but limited to 28 */
-      max_threads = 28;
-   }
-   else {
-      /* maximum is 24, but limited to 21 (see brwCreateContext()) */
-      max_threads = 21;
-   }
-
-   dw2 = GEN6_THREADDISP_SPF;
-
-   dw4 = vue_read_len << GEN6_GS_DW4_URB_READ_LEN__SHIFT |
-         0 << GEN6_GS_DW4_URB_READ_OFFSET__SHIFT |
-         start_grf << GEN6_GS_DW4_URB_GRF_START__SHIFT;
-
-   dw5 = (max_threads - 1) << GEN6_GS_DW5_MAX_THREADS__SHIFT |
-         GEN6_GS_DW5_STATISTICS |
-         GEN6_GS_DW5_SO_STATISTICS |
-         GEN6_GS_DW5_RENDER_ENABLE;
-
-   /*
-    * we cannot make use of GEN6_GS_REORDER because it will reorder
-    * triangle strips according to D3D rules (triangle 2N+1 uses vertices
-    * (2N+1, 2N+3, 2N+2)), instead of GL rules (triangle 2N+1 uses vertices
-    * (2N+2, 2N+1, 2N+3)).
-    */
-   dw6 = GEN6_GS_DW6_GS_ENABLE;
-
-   if (ilo_shader_get_kernel_param(gs, ILO_KERNEL_GS_DISCARD_ADJACENCY))
-      dw6 |= GEN6_GS_DW6_DISCARD_ADJACENCY;
-
-   if (ilo_shader_get_kernel_param(gs, ILO_KERNEL_VS_GEN6_SO)) {
-      const uint32_t svbi_post_inc =
-         ilo_shader_get_kernel_param(gs, ILO_KERNEL_GS_GEN6_SVBI_POST_INC);
-
-      dw6 |= GEN6_GS_DW6_SVBI_PAYLOAD_ENABLE;
-      if (svbi_post_inc) {
-         dw6 |= GEN6_GS_DW6_SVBI_POST_INC_ENABLE |
-                svbi_post_inc << GEN6_GS_DW6_SVBI_POST_INC_VAL__SHIFT;
-      }
-   }
-
-   STATIC_ASSERT(Elements(cso->payload) >= 4);
-   cso->payload[0] = dw2;
-   cso->payload[1] = dw4;
-   cso->payload[2] = dw5;
-   cso->payload[3] = dw6;
-}
-
-static void
-gs_init_cso_gen7(const struct ilo_dev *dev,
-                 const struct ilo_shader_state *gs,
-                 struct ilo_shader_cso *cso)
-{
-   int start_grf, vue_read_len, sampler_count, max_threads;
-   uint32_t dw2, dw4, dw5;
-
-   ILO_DEV_ASSERT(dev, 7, 7.5);
-
-   start_grf = ilo_shader_get_kernel_param(gs, ILO_KERNEL_URB_DATA_START_REG);
-   vue_read_len = ilo_shader_get_kernel_param(gs, ILO_KERNEL_INPUT_COUNT);
-   sampler_count = ilo_shader_get_kernel_param(gs, ILO_KERNEL_SAMPLER_COUNT);
-
-   /* in pairs */
-   vue_read_len = (vue_read_len + 1) / 2;
-
-   switch (ilo_dev_gen(dev)) {
-   case ILO_GEN(7.5):
-      max_threads = (dev->gt >= 2) ? 256 : 70;
-      break;
-   case ILO_GEN(7):
-      max_threads = (dev->gt == 2) ? 128 : 36;
-      break;
-   default:
-      max_threads = 1;
-      break;
-   }
-
-   dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
-   dw2 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
-
-   dw4 = vue_read_len << GEN7_GS_DW4_URB_READ_LEN__SHIFT |
-         GEN7_GS_DW4_INCLUDE_VERTEX_HANDLES |
-         0 << GEN7_GS_DW4_URB_READ_OFFSET__SHIFT |
-         start_grf << GEN7_GS_DW4_URB_GRF_START__SHIFT;
-
-   dw5 = (max_threads - 1) << GEN7_GS_DW5_MAX_THREADS__SHIFT |
-         GEN7_GS_DW5_STATISTICS |
-         GEN7_GS_DW5_GS_ENABLE;
-
-   STATIC_ASSERT(Elements(cso->payload) >= 3);
-   cso->payload[0] = dw2;
-   cso->payload[1] = dw4;
-   cso->payload[2] = dw5;
-}
-
-void
-ilo_gpe_init_gs_cso(const struct ilo_dev *dev,
-                    const struct ilo_shader_state *gs,
-                    struct ilo_shader_cso *cso)
-{
-   if (ilo_dev_gen(dev) >= ILO_GEN(7))
-      gs_init_cso_gen7(dev, gs, cso);
-   else
-      gs_init_cso_gen6(dev, gs, cso);
-}
-
-static void
-view_init_null_gen6(const struct ilo_dev *dev,
-                    unsigned width, unsigned height,
-                    unsigned depth, unsigned level,
-                    struct ilo_view_surface *surf)
-{
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   assert(width >= 1 && height >= 1 && depth >= 1);
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 1, page 71:
-    *
-    *     "A null surface will be used in instances where an actual surface is
-    *      not bound. When a write message is generated to a null surface, no
-    *      actual surface is written to. When a read message (including any
-    *      sampling engine message) is generated to a null surface, the result
-    *      is all zeros. Note that a null surface type is allowed to be used
-    *      with all messages, even if it is not specificially indicated as
-    *      supported. All of the remaining fields in surface state are ignored
-    *      for null surfaces, with the following exceptions:
-    *
-    *        * [DevSNB+]: Width, Height, Depth, and LOD fields must match the
-    *          depth buffer's corresponding state for all render target
-    *          surfaces, including null.
-    *        * Surface Format must be R8G8B8A8_UNORM."
-    *
-    * From the Sandy Bridge PRM, volume 4 part 1, page 82:
-    *
-    *     "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
-    *      true"
-    */
-
-   STATIC_ASSERT(Elements(surf->payload) >= 6);
-   dw = surf->payload;
-
-   dw[0] = GEN6_SURFTYPE_NULL << GEN6_SURFACE_DW0_TYPE__SHIFT |
-           GEN6_FORMAT_B8G8R8A8_UNORM << GEN6_SURFACE_DW0_FORMAT__SHIFT;
-
-   dw[1] = 0;
-
-   dw[2] = (height - 1) << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
-           (width  - 1) << GEN6_SURFACE_DW2_WIDTH__SHIFT |
-           level << GEN6_SURFACE_DW2_MIP_COUNT_LOD__SHIFT;
-
-   dw[3] = (depth - 1) << GEN6_SURFACE_DW3_DEPTH__SHIFT |
-           GEN6_TILING_X;
-
-   dw[4] = 0;
-   dw[5] = 0;
-}
-
-static void
-view_init_for_buffer_gen6(const struct ilo_dev *dev,
-                          const struct ilo_buffer *buf,
-                          unsigned offset, unsigned size,
-                          unsigned struct_size,
-                          enum pipe_format elem_format,
-                          bool is_rt, bool render_cache_rw,
-                          struct ilo_view_surface *surf)
-{
-   const int elem_size = util_format_get_blocksize(elem_format);
-   int width, height, depth, pitch;
-   int surface_format, num_entries;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   /*
-    * For SURFTYPE_BUFFER, a SURFACE_STATE specifies an element of a
-    * structure in a buffer.
-    */
-
-   surface_format = ilo_format_translate_color(dev, elem_format);
-
-   num_entries = size / struct_size;
-   /* see if there is enough space to fit another element */
-   if (size % struct_size >= elem_size)
-      num_entries++;
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 1, page 76:
-    *
-    *     "For SURFTYPE_BUFFER render targets, this field (Surface Base
-    *      Address) specifies the base address of first element of the
-    *      surface. The surface is interpreted as a simple array of that
-    *      single element type. The address must be naturally-aligned to the
-    *      element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
-    *      must be 16-byte aligned).
-    *
-    *      For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
-    *      the base address of the first element of the surface, computed in
-    *      software by adding the surface base address to the byte offset of
-    *      the element in the buffer."
-    */
-   if (is_rt)
-      assert(offset % elem_size == 0);
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 1, page 77:
-    *
-    *     "For buffer surfaces, the number of entries in the buffer ranges
-    *      from 1 to 2^27."
-    */
-   assert(num_entries >= 1 && num_entries <= 1 << 27);
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 1, page 81:
-    *
-    *     "For surfaces of type SURFTYPE_BUFFER, this field (Surface Pitch)
-    *      indicates the size of the structure."
-    */
-   pitch = struct_size;
-
-   pitch--;
-   num_entries--;
-   /* bits [6:0] */
-   width  = (num_entries & 0x0000007f);
-   /* bits [19:7] */
-   height = (num_entries & 0x000fff80) >> 7;
-   /* bits [26:20] */
-   depth  = (num_entries & 0x07f00000) >> 20;
-
-   STATIC_ASSERT(Elements(surf->payload) >= 6);
-   dw = surf->payload;
-
-   dw[0] = GEN6_SURFTYPE_BUFFER << GEN6_SURFACE_DW0_TYPE__SHIFT |
-           surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT;
-   if (render_cache_rw)
-      dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;
-
-   dw[1] = offset;
-
-   dw[2] = height << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
-           width << GEN6_SURFACE_DW2_WIDTH__SHIFT;
-
-   dw[3] = depth << GEN6_SURFACE_DW3_DEPTH__SHIFT |
-           pitch << GEN6_SURFACE_DW3_PITCH__SHIFT;
-
-   dw[4] = 0;
-   dw[5] = 0;
-}
-
-static void
-view_init_for_image_gen6(const struct ilo_dev *dev,
-                         const struct ilo_image *img,
-                         enum pipe_texture_target target,
-                         enum pipe_format format,
-                         unsigned first_level,
-                         unsigned num_levels,
-                         unsigned first_layer,
-                         unsigned num_layers,
-                         bool is_rt,
-                         struct ilo_view_surface *surf)
-{
-   int surface_type, surface_format;
-   int width, height, depth, pitch, lod;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   surface_type = ilo_gpe_gen6_translate_texture(target);
-   assert(surface_type != GEN6_SURFTYPE_BUFFER);
-
-   if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && img->separate_stencil)
-      format = PIPE_FORMAT_Z32_FLOAT;
-
-   if (is_rt)
-      surface_format = ilo_format_translate_render(dev, format);
-   else
-      surface_format = ilo_format_translate_texture(dev, format);
-   assert(surface_format >= 0);
-
-   width = img->width0;
-   height = img->height0;
-   depth = (target == PIPE_TEXTURE_3D) ? img->depth0 : num_layers;
-   pitch = img->bo_stride;
-
-   if (surface_type == GEN6_SURFTYPE_CUBE) {
-      /*
-       * From the Sandy Bridge PRM, volume 4 part 1, page 81:
-       *
-       *     "For SURFTYPE_CUBE: [DevSNB+]: for Sampling Engine Surfaces, the
-       *      range of this field (Depth) is [0,84], indicating the number of
-       *      cube array elements (equal to the number of underlying 2D array
-       *      elements divided by 6). For other surfaces, this field must be
-       *      zero."
-       *
-       * When is_rt is true, we treat the texture as a 2D one to avoid the
-       * restriction.
-       */
-      if (is_rt) {
-         surface_type = GEN6_SURFTYPE_2D;
-      }
-      else {
-         assert(num_layers % 6 == 0);
-         depth = num_layers / 6;
-      }
-   }
-
-   /* sanity check the size */
-   assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
-   switch (surface_type) {
-   case GEN6_SURFTYPE_1D:
-      assert(width <= 8192 && height == 1 && depth <= 512);
-      assert(first_layer < 512 && num_layers <= 512);
-      break;
-   case GEN6_SURFTYPE_2D:
-      assert(width <= 8192 && height <= 8192 && depth <= 512);
-      assert(first_layer < 512 && num_layers <= 512);
-      break;
-   case GEN6_SURFTYPE_3D:
-      assert(width <= 2048 && height <= 2048 && depth <= 2048);
-      assert(first_layer < 2048 && num_layers <= 512);
-      if (!is_rt)
-         assert(first_layer == 0);
-      break;
-   case GEN6_SURFTYPE_CUBE:
-      assert(width <= 8192 && height <= 8192 && depth <= 85);
-      assert(width == height);
-      assert(first_layer < 512 && num_layers <= 512);
-      if (is_rt)
-         assert(first_layer == 0);
-      break;
-   default:
-      assert(!"unexpected surface type");
-      break;
-   }
-
-   /* non-full array spacing is supported only on GEN7+ */
-   assert(img->walk != ILO_IMAGE_WALK_LOD);
-   /* non-interleaved samples are supported only on GEN7+ */
-   if (img->sample_count > 1)
-      assert(img->interleaved_samples);
-
-   if (is_rt) {
-      assert(num_levels == 1);
-      lod = first_level;
-   }
-   else {
-      lod = num_levels - 1;
-   }
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 1, page 76:
-    *
-    *     "Linear render target surface base addresses must be element-size
-    *      aligned, for non-YUV surface formats, or a multiple of 2
-    *      element-sizes for YUV surface formats. Other linear surfaces have
-    *      no alignment requirements (byte alignment is sufficient.)"
-    *
-    * From the Sandy Bridge PRM, volume 4 part 1, page 81:
-    *
-    *     "For linear render target surfaces, the pitch must be a multiple
-    *      of the element size for non-YUV surface formats. Pitch must be a
-    *      multiple of 2 * element size for YUV surface formats."
-    *
-    * From the Sandy Bridge PRM, volume 4 part 1, page 86:
-    *
-    *     "For linear surfaces, this field (X Offset) must be zero"
-    */
-   if (img->tiling == GEN6_TILING_NONE) {
-      if (is_rt) {
-         const int elem_size = util_format_get_blocksize(format);
-         assert(pitch % elem_size == 0);
-      }
-   }
-
-   STATIC_ASSERT(Elements(surf->payload) >= 6);
-   dw = surf->payload;
-
-   dw[0] = surface_type << GEN6_SURFACE_DW0_TYPE__SHIFT |
-           surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT |
-           GEN6_SURFACE_DW0_MIPLAYOUT_BELOW;
-
-   if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt) {
-      dw[0] |= 1 << 9 |
-               GEN6_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
-   }
-
-   if (is_rt)
-      dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;
-
-   dw[1] = 0;
-
-   dw[2] = (height - 1) << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
-           (width - 1) << GEN6_SURFACE_DW2_WIDTH__SHIFT |
-           lod << GEN6_SURFACE_DW2_MIP_COUNT_LOD__SHIFT;
-
-   assert(img->tiling != GEN8_TILING_W);
-   dw[3] = (depth - 1) << GEN6_SURFACE_DW3_DEPTH__SHIFT |
-           (pitch - 1) << GEN6_SURFACE_DW3_PITCH__SHIFT |
-           img->tiling;
-
-   dw[4] = first_level << GEN6_SURFACE_DW4_MIN_LOD__SHIFT |
-           first_layer << 17 |
-           (num_layers - 1) << 8 |
-           ((img->sample_count > 1) ? GEN6_SURFACE_DW4_MULTISAMPLECOUNT_4 :
-                                      GEN6_SURFACE_DW4_MULTISAMPLECOUNT_1);
-
-   dw[5] = 0;
-
-   assert(img->align_j == 2 || img->align_j == 4);
-   if (img->align_j == 4)
-      dw[5] |= GEN6_SURFACE_DW5_VALIGN_4;
-}
-
-static void
-view_init_null_gen7(const struct ilo_dev *dev,
-                    unsigned width, unsigned height,
-                    unsigned depth, unsigned level,
-                    struct ilo_view_surface *surf)
-{
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(dev, 7, 8);
-
-   assert(width >= 1 && height >= 1 && depth >= 1);
-
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 62:
-    *
-    *     "A null surface is used in instances where an actual surface is not
-    *      bound. When a write message is generated to a null surface, no
-    *      actual surface is written to. When a read message (including any
-    *      sampling engine message) is generated to a null surface, the result
-    *      is all zeros.  Note that a null surface type is allowed to be used
-    *      with all messages, even if it is not specificially indicated as
-    *      supported. All of the remaining fields in surface state are ignored
-    *      for null surfaces, with the following exceptions:
-    *
-    *      * Width, Height, Depth, LOD, and Render Target View Extent fields
-    *        must match the depth buffer's corresponding state for all render
-    *        target surfaces, including null.
-    *      * All sampling engine and data port messages support null surfaces
-    *        with the above behavior, even if not mentioned as specifically
-    *        supported, except for the following:
-    *        * Data Port Media Block Read/Write messages.
-    *      * The Surface Type of a surface used as a render target (accessed
-    *        via the Data Port's Render Target Write message) must be the same
-    *        as the Surface Type of all other render targets and of the depth
-    *        buffer (defined in 3DSTATE_DEPTH_BUFFER), unless either the depth
-    *        buffer or render targets are SURFTYPE_NULL."
-    *
-    * From the Ivy Bridge PRM, volume 4 part 1, page 65:
-    *
-    *     "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
-    *      true"
-    */
-
-   STATIC_ASSERT(Elements(surf->payload) >= 13);
-   dw = surf->payload;
-
-   dw[0] = GEN6_SURFTYPE_NULL << GEN7_SURFACE_DW0_TYPE__SHIFT |
-           GEN6_FORMAT_B8G8R8A8_UNORM << GEN7_SURFACE_DW0_FORMAT__SHIFT;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8))
-      dw[0] |= GEN6_TILING_X << GEN8_SURFACE_DW0_TILING__SHIFT;
-   else
-      dw[0] |= GEN6_TILING_X << GEN7_SURFACE_DW0_TILING__SHIFT;
-
-   dw[1] = 0;
-
-   dw[2] = GEN_SHIFT32(height - 1, GEN7_SURFACE_DW2_HEIGHT) |
-           GEN_SHIFT32(width  - 1, GEN7_SURFACE_DW2_WIDTH);
-
-   dw[3] = GEN_SHIFT32(depth - 1, GEN7_SURFACE_DW3_DEPTH);
-
-   dw[4] = 0;
-   dw[5] = level;
-
-   dw[6] = 0;
-   dw[7] = 0;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8))
-      memset(&dw[8], 0, sizeof(*dw) * (13 - 8));
-}
-
-static void
-view_init_for_buffer_gen7(const struct ilo_dev *dev,
-                          const struct ilo_buffer *buf,
-                          unsigned offset, unsigned size,
-                          unsigned struct_size,
-                          enum pipe_format elem_format,
-                          bool is_rt, bool render_cache_rw,
-                          struct ilo_view_surface *surf)
-{
-   const bool typed = (elem_format != PIPE_FORMAT_NONE);
-   const bool structured = (!typed && struct_size > 1);
-   const int elem_size = (typed) ?
-      util_format_get_blocksize(elem_format) : 1;
-   int width, height, depth, pitch;
-   int surface_type, surface_format, num_entries;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(dev, 7, 8);
-
-   surface_type = (structured) ? GEN7_SURFTYPE_STRBUF : GEN6_SURFTYPE_BUFFER;
-
-   surface_format = (typed) ?
-      ilo_format_translate_color(dev, elem_format) : GEN6_FORMAT_RAW;
-
-   num_entries = size / struct_size;
-   /* see if there is enough space to fit another element */
-   if (size % struct_size >= elem_size && !structured)
-      num_entries++;
-
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 67:
-    *
-    *     "For SURFTYPE_BUFFER render targets, this field (Surface Base
-    *      Address) specifies the base address of first element of the
-    *      surface. The surface is interpreted as a simple array of that
-    *      single element type. The address must be naturally-aligned to the
-    *      element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
-    *      must be 16-byte aligned)
-    *
-    *      For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
-    *      the base address of the first element of the surface, computed in
-    *      software by adding the surface base address to the byte offset of
-    *      the element in the buffer."
-    */
-   if (is_rt)
-      assert(offset % elem_size == 0);
-
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 68:
-    *
-    *     "For typed buffer and structured buffer surfaces, the number of
-    *      entries in the buffer ranges from 1 to 2^27.  For raw buffer
-    *      surfaces, the number of entries in the buffer is the number of
-    *      bytes which can range from 1 to 2^30."
-    */
-   assert(num_entries >= 1 &&
-          num_entries <= 1 << ((typed || structured) ? 27 : 30));
-
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 69:
-    *
-    *     "For SURFTYPE_BUFFER: The low two bits of this field (Width) must be
-    *      11 if the Surface Format is RAW (the size of the buffer must be a
-    *      multiple of 4 bytes)."
-    *
-    * From the Ivy Bridge PRM, volume 4 part 1, page 70:
-    *
-    *     "For surfaces of type SURFTYPE_BUFFER and SURFTYPE_STRBUF, this
-    *      field (Surface Pitch) indicates the size of the structure."
-    *
-    *     "For linear surfaces with Surface Type of SURFTYPE_STRBUF, the pitch
-    *      must be a multiple of 4 bytes."
-    */
-   if (structured)
-      assert(struct_size % 4 == 0);
-   else if (!typed)
-      assert(num_entries % 4 == 0);
-
-   pitch = struct_size;
-
-   pitch--;
-   num_entries--;
-   /* bits [6:0] */
-   width  = (num_entries & 0x0000007f);
-   /* bits [20:7] */
-   height = (num_entries & 0x001fff80) >> 7;
-   /* bits [30:21] */
-   depth  = (num_entries & 0x7fe00000) >> 21;
-   /* limit to [26:21] */
-   if (typed || structured)
-      depth &= 0x3f;
-
-   STATIC_ASSERT(Elements(surf->payload) >= 13);
-   dw = surf->payload;
-
-   dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
-           surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT;
-   if (render_cache_rw)
-      dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      dw[8] = offset;
-      memset(&dw[9], 0, sizeof(*dw) * (13 - 9));
-   } else {
-      dw[1] = offset;
-   }
-
-   dw[2] = GEN_SHIFT32(height, GEN7_SURFACE_DW2_HEIGHT) |
-           GEN_SHIFT32(width, GEN7_SURFACE_DW2_WIDTH);
-
-   dw[3] = GEN_SHIFT32(depth, GEN7_SURFACE_DW3_DEPTH) |
-           pitch;
-
-   dw[4] = 0;
-   dw[5] = 0;
-
-   dw[6] = 0;
-   dw[7] = 0;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
-      dw[7] |= GEN_SHIFT32(GEN75_SCS_RED,   GEN75_SURFACE_DW7_SCS_R) |
-               GEN_SHIFT32(GEN75_SCS_GREEN, GEN75_SURFACE_DW7_SCS_G) |
-               GEN_SHIFT32(GEN75_SCS_BLUE,  GEN75_SURFACE_DW7_SCS_B) |
-               GEN_SHIFT32(GEN75_SCS_ALPHA, GEN75_SURFACE_DW7_SCS_A);
-   }
-}
-
-static void
-view_init_for_image_gen7(const struct ilo_dev *dev,
-                         const struct ilo_image *img,
-                         enum pipe_texture_target target,
-                         enum pipe_format format,
-                         unsigned first_level,
-                         unsigned num_levels,
-                         unsigned first_layer,
-                         unsigned num_layers,
-                         bool is_rt,
-                         struct ilo_view_surface *surf)
-{
-   int surface_type, surface_format;
-   int width, height, depth, pitch, lod;
-   uint32_t *dw;
-
-   ILO_DEV_ASSERT(dev, 7, 8);
-
-   surface_type = ilo_gpe_gen6_translate_texture(target);
-   assert(surface_type != GEN6_SURFTYPE_BUFFER);
-
-   if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && img->separate_stencil)
-      format = PIPE_FORMAT_Z32_FLOAT;
-
-   if (is_rt)
-      surface_format = ilo_format_translate_render(dev, format);
-   else
-      surface_format = ilo_format_translate_texture(dev, format);
-   assert(surface_format >= 0);
-
-   width = img->width0;
-   height = img->height0;
-   depth = (target == PIPE_TEXTURE_3D) ? img->depth0 : num_layers;
-   pitch = img->bo_stride;
-
-   if (surface_type == GEN6_SURFTYPE_CUBE) {
-      /*
-       * From the Ivy Bridge PRM, volume 4 part 1, page 70:
-       *
-       *     "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of
-       *      this field is [0,340], indicating the number of cube array
-       *      elements (equal to the number of underlying 2D array elements
-       *      divided by 6). For other surfaces, this field must be zero."
-       *
-       * When is_rt is true, we treat the texture as a 2D one to avoid the
-       * restriction.
-       */
-      if (is_rt) {
-         surface_type = GEN6_SURFTYPE_2D;
-      }
-      else {
-         assert(num_layers % 6 == 0);
-         depth = num_layers / 6;
-      }
-   }
-
-   /* sanity check the size */
-   assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
-   assert(first_layer < 2048 && num_layers <= 2048);
-   switch (surface_type) {
-   case GEN6_SURFTYPE_1D:
-      assert(width <= 16384 && height == 1 && depth <= 2048);
-      break;
-   case GEN6_SURFTYPE_2D:
-      assert(width <= 16384 && height <= 16384 && depth <= 2048);
-      break;
-   case GEN6_SURFTYPE_3D:
-      assert(width <= 2048 && height <= 2048 && depth <= 2048);
-      if (!is_rt)
-         assert(first_layer == 0);
-      break;
-   case GEN6_SURFTYPE_CUBE:
-      assert(width <= 16384 && height <= 16384 && depth <= 86);
-      assert(width == height);
-      if (is_rt)
-         assert(first_layer == 0);
-      break;
-   default:
-      assert(!"unexpected surface type");
-      break;
-   }
-
-   if (is_rt) {
-      assert(num_levels == 1);
-      lod = first_level;
-   }
-   else {
-      lod = num_levels - 1;
-   }
-
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 68:
-    *
-    *     "The Base Address for linear render target surfaces and surfaces
-    *      accessed with the typed surface read/write data port messages must
-    *      be element-size aligned, for non-YUV surface formats, or a multiple
-    *      of 2 element-sizes for YUV surface formats.  Other linear surfaces
-    *      have no alignment requirements (byte alignment is sufficient)."
-    *
-    * From the Ivy Bridge PRM, volume 4 part 1, page 70:
-    *
-    *     "For linear render target surfaces and surfaces accessed with the
-    *      typed data port messages, the pitch must be a multiple of the
-    *      element size for non-YUV surface formats. Pitch must be a multiple
-    *      of 2 * element size for YUV surface formats. For linear surfaces
-    *      with Surface Type of SURFTYPE_STRBUF, the pitch must be a multiple
-    *      of 4 bytes.For other linear surfaces, the pitch can be any multiple
-    *      of bytes."
-    *
-    * From the Ivy Bridge PRM, volume 4 part 1, page 74:
-    *
-    *     "For linear surfaces, this field (X Offset) must be zero."
-    */
-   if (img->tiling == GEN6_TILING_NONE) {
-      if (is_rt) {
-         const int elem_size = util_format_get_blocksize(format);
-         assert(pitch % elem_size == 0);
-      }
-   }
-
-   STATIC_ASSERT(Elements(surf->payload) >= 13);
-   dw = surf->payload;
-
-   dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
-           surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT;
-
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
-    *
-    *     "If this field (Surface Array) is enabled, the Surface Type must be
-    *      SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is
-    *      disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or
-    *      SURFTYPE_CUBE, the Depth field must be set to zero."
-    *
-    * For non-3D sampler surfaces, resinfo (the sampler message) always
-    * returns zero for the number of layers when this field is not set.
-    */
-   if (surface_type != GEN6_SURFTYPE_3D) {
-      switch (target) {
-      case PIPE_TEXTURE_1D_ARRAY:
-      case PIPE_TEXTURE_2D_ARRAY:
-      case PIPE_TEXTURE_CUBE_ARRAY:
-         dw[0] |= GEN7_SURFACE_DW0_IS_ARRAY;
-         break;
-      default:
-         assert(depth == 1);
-         break;
-      }
-   }
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      switch (img->align_j) {
-      case 4:
-         dw[0] |= GEN7_SURFACE_DW0_VALIGN_4;
-         break;
-      case 8:
-         dw[0] |= GEN8_SURFACE_DW0_VALIGN_8;
-         break;
-      case 16:
-         dw[0] |= GEN8_SURFACE_DW0_VALIGN_16;
-         break;
-      default:
-         assert(!"unsupported valign");
-         break;
-      }
-
-      switch (img->align_i) {
-      case 4:
-         dw[0] |= GEN8_SURFACE_DW0_HALIGN_4;
-         break;
-      case 8:
-         dw[0] |= GEN8_SURFACE_DW0_HALIGN_8;
-         break;
-      case 16:
-         dw[0] |= GEN8_SURFACE_DW0_HALIGN_16;
-         break;
-      default:
-         assert(!"unsupported halign");
-         break;
-      }
-
-      dw[0] |= img->tiling << GEN8_SURFACE_DW0_TILING__SHIFT;
-   } else {
-      assert(img->align_i == 4 || img->align_i == 8);
-      assert(img->align_j == 2 || img->align_j == 4);
-
-      if (img->align_j == 4)
-         dw[0] |= GEN7_SURFACE_DW0_VALIGN_4;
-
-      if (img->align_i == 8)
-         dw[0] |= GEN7_SURFACE_DW0_HALIGN_8;
-
-      assert(img->tiling != GEN8_TILING_W);
-      dw[0] |= img->tiling << GEN7_SURFACE_DW0_TILING__SHIFT;
-
-      if (img->walk == ILO_IMAGE_WALK_LOD)
-         dw[0] |= GEN7_SURFACE_DW0_ARYSPC_LOD0;
-      else
-         dw[0] |= GEN7_SURFACE_DW0_ARYSPC_FULL;
-   }
-
-   if (is_rt)
-      dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;
-
-   if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt)
-      dw[0] |= GEN7_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      assert(img->walk_layer_height % 4 == 0);
-      dw[1] = img->walk_layer_height / 4;
-   } else {
-      dw[1] = 0;
-   }
-
-   dw[2] = GEN_SHIFT32(height - 1, GEN7_SURFACE_DW2_HEIGHT) |
-           GEN_SHIFT32(width - 1, GEN7_SURFACE_DW2_WIDTH);
-
-   dw[3] = GEN_SHIFT32(depth - 1, GEN7_SURFACE_DW3_DEPTH) |
-           (pitch - 1);
-
-   dw[4] = first_layer << 18 |
-           (num_layers - 1) << 7;
-
-   /*
-    * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
-    * means the samples are interleaved.  The layouts are the same when the
-    * number of samples is 1.
-    */
-   if (img->interleaved_samples && img->sample_count > 1) {
-      assert(!is_rt);
-      dw[4] |= GEN7_SURFACE_DW4_MSFMT_DEPTH_STENCIL;
-   }
-   else {
-      dw[4] |= GEN7_SURFACE_DW4_MSFMT_MSS;
-   }
-
-   switch (img->sample_count) {
-   case 0:
-   case 1:
-   default:
-      dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_1;
-      break;
-   case 2:
-      dw[4] |= GEN8_SURFACE_DW4_MULTISAMPLECOUNT_2;
-      break;
-   case 4:
-      dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_4;
-      break;
-   case 8:
-      dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_8;
-      break;
-   case 16:
-      dw[4] |= GEN8_SURFACE_DW4_MULTISAMPLECOUNT_16;
-      break;
-   }
-
-   dw[5] = GEN_SHIFT32(first_level, GEN7_SURFACE_DW5_MIN_LOD) |
-           lod;
-
-   dw[6] = 0;
-   dw[7] = 0;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
-      dw[7] |= GEN_SHIFT32(GEN75_SCS_RED,   GEN75_SURFACE_DW7_SCS_R) |
-               GEN_SHIFT32(GEN75_SCS_GREEN, GEN75_SURFACE_DW7_SCS_G) |
-               GEN_SHIFT32(GEN75_SCS_BLUE,  GEN75_SURFACE_DW7_SCS_B) |
-               GEN_SHIFT32(GEN75_SCS_ALPHA, GEN75_SURFACE_DW7_SCS_A);
-   }
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8))
-      memset(&dw[8], 0, sizeof(*dw) * (13 - 8));
-}
-
-void
-ilo_gpe_init_view_surface_null(const struct ilo_dev *dev,
-                               unsigned width, unsigned height,
-                               unsigned depth, unsigned level,
-                               struct ilo_view_surface *surf)
-{
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      view_init_null_gen7(dev,
-            width, height, depth, level, surf);
-   } else {
-      view_init_null_gen6(dev,
-            width, height, depth, level, surf);
-   }
-
-   surf->bo = NULL;
-   surf->scanout = false;
-}
-
-void
-ilo_gpe_init_view_surface_for_buffer(const struct ilo_dev *dev,
-                                     const struct ilo_buffer *buf,
-                                     unsigned offset, unsigned size,
-                                     unsigned struct_size,
-                                     enum pipe_format elem_format,
-                                     bool is_rt, bool render_cache_rw,
-                                     struct ilo_view_surface *surf)
-{
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      view_init_for_buffer_gen7(dev, buf, offset, size,
-            struct_size, elem_format, is_rt, render_cache_rw, surf);
-   } else {
-      view_init_for_buffer_gen6(dev, buf, offset, size,
-            struct_size, elem_format, is_rt, render_cache_rw, surf);
-   }
-
-   /* do not increment reference count */
-   surf->bo = buf->bo;
-   surf->scanout = false;
-}
-
-void
-ilo_gpe_init_view_surface_for_image(const struct ilo_dev *dev,
-                                    const struct ilo_image *img,
-                                    enum pipe_texture_target target,
-                                    enum pipe_format format,
-                                    unsigned first_level,
-                                    unsigned num_levels,
-                                    unsigned first_layer,
-                                    unsigned num_layers,
-                                    bool is_rt,
-                                    struct ilo_view_surface *surf)
-{
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      view_init_for_image_gen7(dev, img, target, format,
-            first_level, num_levels, first_layer, num_layers,
-            is_rt, surf);
-   } else {
-      view_init_for_image_gen6(dev, img, target, format,
-            first_level, num_levels, first_layer, num_layers,
-            is_rt, surf);
-   }
-
-   surf->scanout = img->scanout;
-   /* do not increment reference count */
-   surf->bo = img->bo;
-}
-
-static void
-sampler_init_border_color_gen6(const struct ilo_dev *dev,
-                               const union pipe_color_union *color,
-                               uint32_t *dw, int num_dwords)
-{
-   float rgba[4] = {
-      color->f[0], color->f[1], color->f[2], color->f[3],
-   };
-
-   ILO_DEV_ASSERT(dev, 6, 6);
-
-   assert(num_dwords >= 12);
-
-   /*
-    * This state is not documented in the Sandy Bridge PRM, but in the
-    * Ironlake PRM.  SNORM8 seems to be in DW11 instead of DW1.
-    */
-
-   /* IEEE_FP */
-   dw[1] = fui(rgba[0]);
-   dw[2] = fui(rgba[1]);
-   dw[3] = fui(rgba[2]);
-   dw[4] = fui(rgba[3]);
-
-   /* FLOAT_16 */
-   dw[5] = util_float_to_half(rgba[0]) |
-           util_float_to_half(rgba[1]) << 16;
-   dw[6] = util_float_to_half(rgba[2]) |
-           util_float_to_half(rgba[3]) << 16;
-
-   /* clamp to [-1.0f, 1.0f] */
-   rgba[0] = CLAMP(rgba[0], -1.0f, 1.0f);
-   rgba[1] = CLAMP(rgba[1], -1.0f, 1.0f);
-   rgba[2] = CLAMP(rgba[2], -1.0f, 1.0f);
-   rgba[3] = CLAMP(rgba[3], -1.0f, 1.0f);
-
-   /* SNORM16 */
-   dw[9] =  (int16_t) util_iround(rgba[0] * 32767.0f) |
-            (int16_t) util_iround(rgba[1] * 32767.0f) << 16;
-   dw[10] = (int16_t) util_iround(rgba[2] * 32767.0f) |
-            (int16_t) util_iround(rgba[3] * 32767.0f) << 16;
-
-   /* SNORM8 */
-   dw[11] = (int8_t) util_iround(rgba[0] * 127.0f) |
-            (int8_t) util_iround(rgba[1] * 127.0f) << 8 |
-            (int8_t) util_iround(rgba[2] * 127.0f) << 16 |
-            (int8_t) util_iround(rgba[3] * 127.0f) << 24;
-
-   /* clamp to [0.0f, 1.0f] */
-   rgba[0] = CLAMP(rgba[0], 0.0f, 1.0f);
-   rgba[1] = CLAMP(rgba[1], 0.0f, 1.0f);
-   rgba[2] = CLAMP(rgba[2], 0.0f, 1.0f);
-   rgba[3] = CLAMP(rgba[3], 0.0f, 1.0f);
-
-   /* UNORM8 */
-   dw[0] = (uint8_t) util_iround(rgba[0] * 255.0f) |
-           (uint8_t) util_iround(rgba[1] * 255.0f) << 8 |
-           (uint8_t) util_iround(rgba[2] * 255.0f) << 16 |
-           (uint8_t) util_iround(rgba[3] * 255.0f) << 24;
-
-   /* UNORM16 */
-   dw[7] = (uint16_t) util_iround(rgba[0] * 65535.0f) |
-           (uint16_t) util_iround(rgba[1] * 65535.0f) << 16;
-   dw[8] = (uint16_t) util_iround(rgba[2] * 65535.0f) |
-           (uint16_t) util_iround(rgba[3] * 65535.0f) << 16;
-}
-
-/**
- * Translate a pipe texture mipfilter to the matching hardware mipfilter.
- */
-static int
-gen6_translate_tex_mipfilter(unsigned filter)
-{
-   switch (filter) {
-   case PIPE_TEX_MIPFILTER_NEAREST: return GEN6_MIPFILTER_NEAREST;
-   case PIPE_TEX_MIPFILTER_LINEAR:  return GEN6_MIPFILTER_LINEAR;
-   case PIPE_TEX_MIPFILTER_NONE:    return GEN6_MIPFILTER_NONE;
-   default:
-      assert(!"unknown mipfilter");
-      return GEN6_MIPFILTER_NONE;
-   }
-}
-
-/**
- * Translate a pipe texture filter to the matching hardware mapfilter.
- */
-static int
-gen6_translate_tex_filter(unsigned filter)
-{
-   switch (filter) {
-   case PIPE_TEX_FILTER_NEAREST: return GEN6_MAPFILTER_NEAREST;
-   case PIPE_TEX_FILTER_LINEAR:  return GEN6_MAPFILTER_LINEAR;
-   default:
-      assert(!"unknown sampler filter");
-      return GEN6_MAPFILTER_NEAREST;
-   }
-}
-
-/**
- * Translate a pipe texture coordinate wrapping mode to the matching hardware
- * wrapping mode.
- */
-static int
-gen6_translate_tex_wrap(unsigned wrap)
-{
-   switch (wrap) {
-   case PIPE_TEX_WRAP_CLAMP:              return GEN8_TEXCOORDMODE_HALF_BORDER;
-   case PIPE_TEX_WRAP_REPEAT:             return GEN6_TEXCOORDMODE_WRAP;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:      return GEN6_TEXCOORDMODE_CLAMP;
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:    return GEN6_TEXCOORDMODE_CLAMP_BORDER;
-   case PIPE_TEX_WRAP_MIRROR_REPEAT:      return GEN6_TEXCOORDMODE_MIRROR;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP:
-   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
-   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
-   default:
-      assert(!"unknown sampler wrap mode");
-      return GEN6_TEXCOORDMODE_WRAP;
-   }
-}
-
-/**
- * Translate a pipe shadow compare function to the matching hardware shadow
- * function.
- */
-static int
-gen6_translate_shadow_func(unsigned func)
-{
-   /*
-    * For PIPE_FUNC_x, the reference value is on the left-hand side of the
-    * comparison, and 1.0 is returned when the comparison is true.
-    *
-    * For GEN6_COMPAREFUNCTION_x, the reference value is on the right-hand side of
-    * the comparison, and 0.0 is returned when the comparison is true.
-    */
-   switch (func) {
-   case PIPE_FUNC_NEVER:      return GEN6_COMPAREFUNCTION_ALWAYS;
-   case PIPE_FUNC_LESS:       return GEN6_COMPAREFUNCTION_LEQUAL;
-   case PIPE_FUNC_EQUAL:      return GEN6_COMPAREFUNCTION_NOTEQUAL;
-   case PIPE_FUNC_LEQUAL:     return GEN6_COMPAREFUNCTION_LESS;
-   case PIPE_FUNC_GREATER:    return GEN6_COMPAREFUNCTION_GEQUAL;
-   case PIPE_FUNC_NOTEQUAL:   return GEN6_COMPAREFUNCTION_EQUAL;
-   case PIPE_FUNC_GEQUAL:     return GEN6_COMPAREFUNCTION_GREATER;
-   case PIPE_FUNC_ALWAYS:     return GEN6_COMPAREFUNCTION_NEVER;
-   default:
-      assert(!"unknown shadow compare function");
-      return GEN6_COMPAREFUNCTION_NEVER;
-   }
-}
-
-void
-ilo_gpe_init_sampler_cso(const struct ilo_dev *dev,
-                         const struct pipe_sampler_state *state,
-                         struct ilo_sampler_cso *sampler)
-{
-   int mip_filter, min_filter, mag_filter, max_aniso;
-   int lod_bias, max_lod, min_lod;
-   int wrap_s, wrap_t, wrap_r, wrap_cube;
-   uint32_t dw0, dw1, dw3;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   memset(sampler, 0, sizeof(*sampler));
-
-   mip_filter = gen6_translate_tex_mipfilter(state->min_mip_filter);
-   min_filter = gen6_translate_tex_filter(state->min_img_filter);
-   mag_filter = gen6_translate_tex_filter(state->mag_img_filter);
-
-   sampler->anisotropic = state->max_anisotropy;
-
-   if (state->max_anisotropy >= 2 && state->max_anisotropy <= 16)
-      max_aniso = state->max_anisotropy / 2 - 1;
-   else if (state->max_anisotropy > 16)
-      max_aniso = GEN6_ANISORATIO_16;
-   else
-      max_aniso = GEN6_ANISORATIO_2;
-
-   /*
-    *
-    * Here is how the hardware calculate per-pixel LOD, from my reading of the
-    * PRMs:
-    *
-    *  1) LOD is set to log2(ratio of texels to pixels) if not specified in
-    *     other ways.  The number of texels is measured using level
-    *     SurfMinLod.
-    *  2) Bias is added to LOD.
-    *  3) LOD is clamped to [MinLod, MaxLod], and the clamped value is
-    *     compared with Base to determine whether magnification or
-    *     minification is needed.  (if preclamp is disabled, LOD is compared
-    *     with Base before clamping)
-    *  4) If magnification is needed, or no mipmapping is requested, LOD is
-    *     set to floor(MinLod).
-    *  5) LOD is clamped to [0, MIPCnt], and SurfMinLod is added to LOD.
-    *
-    * With Gallium interface, Base is always zero and
-    * pipe_sampler_view::u.tex.first_level specifies SurfMinLod.
-    */
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      const float scale = 256.0f;
-
-      /* [-16.0, 16.0) in S4.8 */
-      lod_bias = (int)
-         (CLAMP(state->lod_bias, -16.0f, 15.9f) * scale);
-      lod_bias &= 0x1fff;
-
-      /* [0.0, 14.0] in U4.8 */
-      max_lod = (int) (CLAMP(state->max_lod, 0.0f, 14.0f) * scale);
-      min_lod = (int) (CLAMP(state->min_lod, 0.0f, 14.0f) * scale);
-   }
-   else {
-      const float scale = 64.0f;
-
-      /* [-16.0, 16.0) in S4.6 */
-      lod_bias = (int)
-         (CLAMP(state->lod_bias, -16.0f, 15.9f) * scale);
-      lod_bias &= 0x7ff;
-
-      /* [0.0, 13.0] in U4.6 */
-      max_lod = (int) (CLAMP(state->max_lod, 0.0f, 13.0f) * scale);
-      min_lod = (int) (CLAMP(state->min_lod, 0.0f, 13.0f) * scale);
-   }
-
-   /*
-    * We want LOD to be clamped to determine magnification/minification, and
-    * get set to zero when it is magnification or when mipmapping is disabled.
-    * The hardware would set LOD to floor(MinLod) and that is a problem when
-    * MinLod is greater than or equal to 1.0f.
-    *
-    * With Base being zero, it is always minification when MinLod is non-zero.
-    * To achieve our goal, we just need to set MinLod to zero and set
-    * MagFilter to MinFilter when mipmapping is disabled.
-    */
-   if (state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE && min_lod) {
-      min_lod = 0;
-      mag_filter = min_filter;
-   }
-
-   /* determine wrap s/t/r */
-   wrap_s = gen6_translate_tex_wrap(state->wrap_s);
-   wrap_t = gen6_translate_tex_wrap(state->wrap_t);
-   wrap_r = gen6_translate_tex_wrap(state->wrap_r);
-   if (ilo_dev_gen(dev) < ILO_GEN(8)) {
-      /*
-       * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
-       * PIPE_TEX_WRAP_CLAMP_TO_EDGE;  for linear filtering,
-       * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
-       * additionally clamping the texture coordinates to [0.0, 1.0].
-       *
-       * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8.  The
-       * clamping has to be taken care of in the shaders.  There are two
-       * filters here, but let the minification one has a say.
-       */
-      const bool clamp_is_to_edge =
-         (state->min_img_filter == PIPE_TEX_FILTER_NEAREST);
-
-      if (clamp_is_to_edge) {
-         if (wrap_s == GEN8_TEXCOORDMODE_HALF_BORDER)
-            wrap_s = GEN6_TEXCOORDMODE_CLAMP;
-         if (wrap_t == GEN8_TEXCOORDMODE_HALF_BORDER)
-            wrap_t = GEN6_TEXCOORDMODE_CLAMP;
-         if (wrap_r == GEN8_TEXCOORDMODE_HALF_BORDER)
-            wrap_r = GEN6_TEXCOORDMODE_CLAMP;
-      } else {
-         if (wrap_s == GEN8_TEXCOORDMODE_HALF_BORDER) {
-            wrap_s = GEN6_TEXCOORDMODE_CLAMP_BORDER;
-            sampler->saturate_s = true;
-         }
-         if (wrap_t == GEN8_TEXCOORDMODE_HALF_BORDER) {
-            wrap_t = GEN6_TEXCOORDMODE_CLAMP_BORDER;
-            sampler->saturate_t = true;
-         }
-         if (wrap_r == GEN8_TEXCOORDMODE_HALF_BORDER) {
-            wrap_r = GEN6_TEXCOORDMODE_CLAMP_BORDER;
-            sampler->saturate_r = true;
-         }
-      }
-   }
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 1, page 107:
-    *
-    *     "When using cube map texture coordinates, only TEXCOORDMODE_CLAMP
-    *      and TEXCOORDMODE_CUBE settings are valid, and each TC component
-    *      must have the same Address Control mode."
-    *
-    * From the Ivy Bridge PRM, volume 4 part 1, page 96:
-    *
-    *     "This field (Cube Surface Control Mode) must be set to
-    *      CUBECTRLMODE_PROGRAMMED"
-    *
-    * Therefore, we cannot use "Cube Surface Control Mode" for semless cube
-    * map filtering.
-    */
-   if (state->seamless_cube_map &&
-       (state->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
-        state->mag_img_filter != PIPE_TEX_FILTER_NEAREST)) {
-      wrap_cube = GEN6_TEXCOORDMODE_CUBE;
-   }
-   else {
-      wrap_cube = GEN6_TEXCOORDMODE_CLAMP;
-   }
-
-   if (!state->normalized_coords) {
-      /*
-       * From the Ivy Bridge PRM, volume 4 part 1, page 98:
-       *
-       *     "The following state must be set as indicated if this field
-       *      (Non-normalized Coordinate Enable) is enabled:
-       *
-       *      - TCX/Y/Z Address Control Mode must be TEXCOORDMODE_CLAMP,
-       *        TEXCOORDMODE_HALF_BORDER, or TEXCOORDMODE_CLAMP_BORDER.
-       *      - Surface Type must be SURFTYPE_2D or SURFTYPE_3D.
-       *      - Mag Mode Filter must be MAPFILTER_NEAREST or
-       *        MAPFILTER_LINEAR.
-       *      - Min Mode Filter must be MAPFILTER_NEAREST or
-       *        MAPFILTER_LINEAR.
-       *      - Mip Mode Filter must be MIPFILTER_NONE.
-       *      - Min LOD must be 0.
-       *      - Max LOD must be 0.
-       *      - MIP Count must be 0.
-       *      - Surface Min LOD must be 0.
-       *      - Texture LOD Bias must be 0."
-       */
-      assert(wrap_s == GEN6_TEXCOORDMODE_CLAMP ||
-             wrap_s == GEN6_TEXCOORDMODE_CLAMP_BORDER);
-      assert(wrap_t == GEN6_TEXCOORDMODE_CLAMP ||
-             wrap_t == GEN6_TEXCOORDMODE_CLAMP_BORDER);
-      assert(wrap_r == GEN6_TEXCOORDMODE_CLAMP ||
-             wrap_r == GEN6_TEXCOORDMODE_CLAMP_BORDER);
-
-      assert(mag_filter == GEN6_MAPFILTER_NEAREST ||
-             mag_filter == GEN6_MAPFILTER_LINEAR);
-      assert(min_filter == GEN6_MAPFILTER_NEAREST ||
-             min_filter == GEN6_MAPFILTER_LINEAR);
-
-      /* work around a bug in util_blitter */
-      mip_filter = GEN6_MIPFILTER_NONE;
-
-      assert(mip_filter == GEN6_MIPFILTER_NONE);
-   }
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
-      dw0 = 1 << 28 |
-            mip_filter << 20 |
-            lod_bias << 1;
-
-      sampler->dw_filter = mag_filter << 17 |
-                           min_filter << 14;
-
-      sampler->dw_filter_aniso = GEN6_MAPFILTER_ANISOTROPIC << 17 |
-                                 GEN6_MAPFILTER_ANISOTROPIC << 14 |
-                                 1;
-
-      dw1 = min_lod << 20 |
-            max_lod << 8;
-
-      if (state->compare_mode != PIPE_TEX_COMPARE_NONE)
-         dw1 |= gen6_translate_shadow_func(state->compare_func) << 1;
-
-      dw3 = max_aniso << 19;
-
-      /* round the coordinates for linear filtering */
-      if (min_filter != GEN6_MAPFILTER_NEAREST) {
-         dw3 |= (GEN6_SAMPLER_DW3_U_MIN_ROUND |
-                 GEN6_SAMPLER_DW3_V_MIN_ROUND |
-                 GEN6_SAMPLER_DW3_R_MIN_ROUND);
-      }
-      if (mag_filter != GEN6_MAPFILTER_NEAREST) {
-         dw3 |= (GEN6_SAMPLER_DW3_U_MAG_ROUND |
-                 GEN6_SAMPLER_DW3_V_MAG_ROUND |
-                 GEN6_SAMPLER_DW3_R_MAG_ROUND);
-      }
-
-      if (!state->normalized_coords)
-         dw3 |= 1 << 10;
-
-      sampler->dw_wrap = wrap_s << 6 |
-                         wrap_t << 3 |
-                         wrap_r;
-
-      /*
-       * As noted in the classic i965 driver, the HW may still reference
-       * wrap_t and wrap_r for 1D textures.  We need to set them to a safe
-       * mode
-       */
-      sampler->dw_wrap_1d = wrap_s << 6 |
-                            GEN6_TEXCOORDMODE_WRAP << 3 |
-                            GEN6_TEXCOORDMODE_WRAP;
-
-      sampler->dw_wrap_cube = wrap_cube << 6 |
-                              wrap_cube << 3 |
-                              wrap_cube;
-
-      STATIC_ASSERT(Elements(sampler->payload) >= 7);
-
-      sampler->payload[0] = dw0;
-      sampler->payload[1] = dw1;
-      sampler->payload[2] = dw3;
-
-      memcpy(&sampler->payload[3],
-            state->border_color.ui, sizeof(state->border_color.ui));
-   }
-   else {
-      dw0 = 1 << 28 |
-            mip_filter << 20 |
-            lod_bias << 3;
-
-      if (state->compare_mode != PIPE_TEX_COMPARE_NONE)
-         dw0 |= gen6_translate_shadow_func(state->compare_func);
-
-      sampler->dw_filter = (min_filter != mag_filter) << 27 |
-                           mag_filter << 17 |
-                           min_filter << 14;
-
-      sampler->dw_filter_aniso = GEN6_MAPFILTER_ANISOTROPIC << 17 |
-                                 GEN6_MAPFILTER_ANISOTROPIC << 14;
-
-      dw1 = min_lod << 22 |
-            max_lod << 12;
-
-      sampler->dw_wrap = wrap_s << 6 |
-                         wrap_t << 3 |
-                         wrap_r;
-
-      sampler->dw_wrap_1d = wrap_s << 6 |
-                            GEN6_TEXCOORDMODE_WRAP << 3 |
-                            GEN6_TEXCOORDMODE_WRAP;
-
-      sampler->dw_wrap_cube = wrap_cube << 6 |
-                              wrap_cube << 3 |
-                              wrap_cube;
-
-      dw3 = max_aniso << 19;
-
-      /* round the coordinates for linear filtering */
-      if (min_filter != GEN6_MAPFILTER_NEAREST) {
-         dw3 |= (GEN6_SAMPLER_DW3_U_MIN_ROUND |
-                 GEN6_SAMPLER_DW3_V_MIN_ROUND |
-                 GEN6_SAMPLER_DW3_R_MIN_ROUND);
-      }
-      if (mag_filter != GEN6_MAPFILTER_NEAREST) {
-         dw3 |= (GEN6_SAMPLER_DW3_U_MAG_ROUND |
-                 GEN6_SAMPLER_DW3_V_MAG_ROUND |
-                 GEN6_SAMPLER_DW3_R_MAG_ROUND);
-      }
-
-      if (!state->normalized_coords)
-         dw3 |= 1;
-
-      STATIC_ASSERT(Elements(sampler->payload) >= 15);
-
-      sampler->payload[0] = dw0;
-      sampler->payload[1] = dw1;
-      sampler->payload[2] = dw3;
-
-      sampler_init_border_color_gen6(dev,
-            &state->border_color, &sampler->payload[3], 12);
-   }
-}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_cc.c b/src/gallium/drivers/ilo/core/ilo_state_cc.c
new file mode 100644 (file)
index 0000000..83ee8de
--- /dev/null
@@ -0,0 +1,890 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_cc.h"
+
+static bool
+cc_validate_gen6_stencil(const struct ilo_dev *dev,
+                         const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_stencil_info *stencil = &info->stencil;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 359:
+    *
+    *     "If the Depth Buffer is either undefined or does not have a surface
+    *      format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
+    *      stencil buffer is disabled, Stencil Test Enable must be DISABLED"
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 370:
+    *
+    *     "This field (Stencil Test Enable) cannot be enabled if Surface
+    *      Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
+    */
+   if (stencil->test_enable)
+      assert(stencil->cv_has_buffer);
+
+   return true;
+}
+
+static bool
+cc_validate_gen6_depth(const struct ilo_dev *dev,
+                       const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_depth_info *depth = &info->depth;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 360:
+    *
+    *     "Enabling the Depth Test function without defining a Depth Buffer is
+    *      UNDEFINED."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 375:
+    *
+    *     "A Depth Buffer must be defined before enabling writes to it, or
+    *      operation is UNDEFINED."
+    */
+   if (depth->test_enable || depth->write_enable)
+      assert(depth->cv_has_buffer);
+
+   return true;
+}
+
+static bool
+cc_set_gen6_DEPTH_STENCIL_STATE(struct ilo_state_cc *cc,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_stencil_info *stencil = &info->stencil;
+   const struct ilo_state_cc_depth_info *depth = &info->depth;
+   const struct ilo_state_cc_params_info *params = &info->params;
+   uint32_t dw0, dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 6, 7.5);
+
+   if (!cc_validate_gen6_stencil(dev, info) ||
+       !cc_validate_gen6_depth(dev, info))
+      return false;
+
+   dw0 = 0;
+   dw1 = 0;
+   if (stencil->test_enable) {
+      const struct ilo_state_cc_stencil_op_info *front = &stencil->front;
+      const struct ilo_state_cc_stencil_params_info *front_p =
+         &params->stencil_front;
+      const struct ilo_state_cc_stencil_op_info *back;
+      const struct ilo_state_cc_stencil_params_info *back_p;
+
+      dw0 |= GEN6_ZS_DW0_STENCIL_TEST_ENABLE;
+
+      if (stencil->twosided_enable) {
+         dw0 |= GEN6_ZS_DW0_STENCIL1_ENABLE;
+
+         back = &stencil->back;
+         back_p = &params->stencil_back;
+      } else {
+         back = &stencil->front;
+         back_p = &params->stencil_front;
+      }
+
+      dw0 |= front->test_func << GEN6_ZS_DW0_STENCIL_FUNC__SHIFT |
+             front->fail_op << GEN6_ZS_DW0_STENCIL_FAIL_OP__SHIFT |
+             front->zfail_op << GEN6_ZS_DW0_STENCIL_ZFAIL_OP__SHIFT |
+             front->zpass_op << GEN6_ZS_DW0_STENCIL_ZPASS_OP__SHIFT |
+             back->test_func << GEN6_ZS_DW0_STENCIL1_FUNC__SHIFT |
+             back->fail_op << GEN6_ZS_DW0_STENCIL1_FAIL_OP__SHIFT |
+             back->zfail_op << GEN6_ZS_DW0_STENCIL1_ZFAIL_OP__SHIFT |
+             back->zpass_op << GEN6_ZS_DW0_STENCIL1_ZPASS_OP__SHIFT;
+
+      /*
+       * From the Ivy Bridge PRM, volume 2 part 1, page 363:
+       *
+       *     "If this field (Stencil Buffer Write Enable) is enabled, Stencil
+       *      Test Enable must also be enabled."
+       *
+       * This is different from depth write enable, which is independent from
+       * depth test enable.
+       */
+      if (front_p->write_mask || back_p->write_mask)
+         dw0 |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
+
+      dw1 |= front_p->test_mask << GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT |
+             front_p->write_mask << GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT |
+             back_p->test_mask << GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT |
+             back_p->write_mask << GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT;
+   }
+
+   dw2 = 0;
+   if (depth->test_enable) {
+      dw2 |= GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
+             depth->test_func << GEN6_ZS_DW2_DEPTH_FUNC__SHIFT;
+   } else {
+      dw2 |= GEN6_COMPAREFUNCTION_ALWAYS << GEN6_ZS_DW2_DEPTH_FUNC__SHIFT;
+   }
+
+   /* independent from depth->test_enable */
+   if (depth->write_enable)
+      dw2 |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(cc->ds) >= 3);
+   cc->ds[0] = dw0;
+   cc->ds[1] = dw1;
+   cc->ds[2] = dw2;
+
+   return true;
+}
+
+static bool
+cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_state_cc *cc,
+                                     const struct ilo_dev *dev,
+                                     const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_stencil_info *stencil = &info->stencil;
+   const struct ilo_state_cc_depth_info *depth = &info->depth;
+   const struct ilo_state_cc_params_info *params = &info->params;
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   if (!cc_validate_gen6_stencil(dev, info) ||
+       !cc_validate_gen6_depth(dev, info))
+      return false;
+
+   dw1 = 0;
+   dw2 = 0;
+   if (stencil->test_enable) {
+      const struct ilo_state_cc_stencil_op_info *front = &stencil->front;
+      const struct ilo_state_cc_stencil_params_info *front_p =
+         &params->stencil_front;
+      const struct ilo_state_cc_stencil_op_info *back;
+      const struct ilo_state_cc_stencil_params_info *back_p;
+
+      dw1 |= GEN8_ZS_DW1_STENCIL_TEST_ENABLE;
+
+      if (stencil->twosided_enable) {
+         dw1 |= GEN8_ZS_DW1_STENCIL1_ENABLE;
+
+         back = &stencil->back;
+         back_p = &params->stencil_back;
+      } else {
+         back = &stencil->front;
+         back_p = &params->stencil_front;
+      }
+
+      dw1 |= front->fail_op << GEN8_ZS_DW1_STENCIL_FAIL_OP__SHIFT |
+             front->zfail_op << GEN8_ZS_DW1_STENCIL_ZFAIL_OP__SHIFT |
+             front->zpass_op << GEN8_ZS_DW1_STENCIL_ZPASS_OP__SHIFT |
+             back->test_func << GEN8_ZS_DW1_STENCIL1_FUNC__SHIFT |
+             back->fail_op << GEN8_ZS_DW1_STENCIL1_FAIL_OP__SHIFT |
+             back->zfail_op << GEN8_ZS_DW1_STENCIL1_ZFAIL_OP__SHIFT |
+             back->zpass_op << GEN8_ZS_DW1_STENCIL1_ZPASS_OP__SHIFT |
+             front->test_func << GEN8_ZS_DW1_STENCIL_FUNC__SHIFT;
+
+      if (front_p->write_mask || back_p->write_mask)
+         dw1 |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
+
+      dw2 |= front_p->test_mask << GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT |
+             front_p->write_mask << GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT |
+             back_p->test_mask << GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT |
+             back_p->write_mask << GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT;
+   }
+
+   if (depth->test_enable) {
+      dw1 |= GEN8_ZS_DW1_DEPTH_TEST_ENABLE |
+             depth->test_func << GEN8_ZS_DW1_DEPTH_FUNC__SHIFT;
+   } else {
+      dw1 |= GEN6_COMPAREFUNCTION_ALWAYS << GEN8_ZS_DW1_DEPTH_FUNC__SHIFT;
+   }
+
+   if (depth->write_enable)
+      dw1 |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(cc->ds) >= 2);
+   cc->ds[0] = dw1;
+   cc->ds[1] = dw2;
+
+   return true;
+}
+
+static bool
+is_dual_source_blend_factor(enum gen_blend_factor factor)
+{
+   switch (factor) {
+   case GEN6_BLENDFACTOR_SRC1_COLOR:
+   case GEN6_BLENDFACTOR_SRC1_ALPHA:
+   case GEN6_BLENDFACTOR_INV_SRC1_COLOR:
+   case GEN6_BLENDFACTOR_INV_SRC1_ALPHA:
+      return true;
+   default:
+      return false;
+   }
+}
+
+static bool
+cc_get_gen6_dual_source_blending(const struct ilo_dev *dev,
+                                 const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_blend_info *blend = &info->blend;
+   bool dual_source_blending;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   dual_source_blending = (blend->rt_count &&
+         (is_dual_source_blend_factor(blend->rt[0].rgb_src) ||
+          is_dual_source_blend_factor(blend->rt[0].rgb_dst) ||
+          is_dual_source_blend_factor(blend->rt[0].a_src) ||
+          is_dual_source_blend_factor(blend->rt[0].a_dst)));
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 356:
+    *
+    *     "Dual Source Blending: When using "Dual Source" Render Target
+    *      Write messages, the Source1 pixel color+alpha passed in the
+    *      message can be selected as a src/dst blend factor. See Color
+    *      Buffer Blending.  In single-source mode, those blend factor
+    *      selections are invalid. If SRC1 is included in a src/dst blend
+    *      factor and a DualSource RT Write message is not utilized,
+    *      results are UNDEFINED. (This reflects the same restriction in DX
+    *      APIs, where undefined results are produced if "o1" is not
+    *      written by a PS - there are no default values defined). If SRC1
+    *      is not included in a src/dst blend factor, dual source blending
+    *      must be disabled."
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 356:
+    *
+    *     "The single source message will not cause a write to the render
+    *      target if Dual Source Blend Enable in 3DSTATE_WM is enabled."
+    *
+    *     "The dual source message will revert to a single source message
+    *      using source 0 if Dual Source Blend Enable in 3DSTATE_WM is
+    *      disabled."
+    *
+    * Dual source blending must be enabled or disabled universally.
+    */
+   for (i = 1; i < blend->rt_count; i++) {
+      assert(dual_source_blending ==
+         (is_dual_source_blend_factor(blend->rt[i].rgb_src) ||
+          is_dual_source_blend_factor(blend->rt[i].rgb_dst) ||
+          is_dual_source_blend_factor(blend->rt[i].a_src) ||
+          is_dual_source_blend_factor(blend->rt[i].a_dst)));
+   }
+
+   return dual_source_blending;
+}
+
+static bool
+cc_validate_gen6_alpha(const struct ilo_dev *dev,
+                       const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_alpha_info *alpha = &info->alpha;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 356:
+    *
+    *     "Alpha values from the pixel shader are treated as FLOAT32 format
+    *      for computing the AlphaToCoverage Mask."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 378:
+    *
+    *     "If set (AlphaToCoverage Enable), Source0 Alpha is converted to a
+    *      temporary 1/2/4-bit coverage mask and the mask bit corresponding to
+    *      the sample# ANDed with the sample mask bit. If set, sample coverage
+    *      is computed based on src0 alpha value. Value of 0 disables all
+    *      samples and value of 1 enables all samples for that pixel. The same
+    *      coverage needs to apply to all the RTs in MRT case. Further, any
+    *      value of src0 alpha between 0 and 1 monotonically increases the
+    *      number of enabled pixels.
+    *
+    *      The same coverage needs to be applied to all the RTs in MRT case."
+    *
+    *     "If set (AlphaToOne Enable), Source0 Alpha is set to 1.0f after
+    *      (possibly) being used to generate the AlphaToCoverage coverage
+    *      mask.
+    *
+    *      The same coverage needs to be applied to all the RTs in MRT case.
+    *
+    *      If Dual Source Blending is enabled, this bit must be disabled."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 382:
+    *
+    *     "Alpha Test can only be enabled if Pixel Shader outputs a float
+    *      alpha value.
+    *
+    *      Alpha Test is applied independently on each render target by
+    *      comparing that render target's alpha value against the alpha
+    *      reference value. If the alpha test fails, the corresponding pixel
+    *      write will be supressed only for that render target. The
+    *      depth/stencil update will occur if alpha test passes for any render
+    *      target."
+    *
+    * From the Sandy Bridge PRM, volume 4 part 1, page 194:
+    *
+    *     "Multiple render targets are supported with the single source and
+    *      replicate data messages. Each render target is accessed with a
+    *      separate Render Target Write message, each with a different surface
+    *      indicated (different binding table index). The depth buffer is
+    *      written only by the message(s) to the last render target, indicated
+    *      by the Last Render Target Select bit set to clear the pixel
+    *      scoreboard bits."
+    *
+    * When AlphaToCoverage/AlphaToOne/AlphaTest is enabled, it is
+    * required/desirable for the RT write messages to set "Source0 Alpha
+    * Present to RenderTarget" in the MRT case.  It is also required/desirable
+    * for the alpha values to be FLOAT32.
+    */
+   if (alpha->alpha_to_coverage || alpha->alpha_to_one || alpha->test_enable)
+      assert(alpha->cv_float_source0_alpha);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 356:
+    *
+    *     "[DevSNB]: When NumSamples = 1, AlphaToCoverage and AlphaTo
+    *      Coverage Dither both must be disabled."
+    */
+   if (ilo_dev_gen(dev) == ILO_GEN(6) && alpha->alpha_to_coverage)
+      assert(alpha->cv_sample_count_one);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 378:
+    *
+    *     "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
+    *      must be disabled."
+    */
+   if (alpha->alpha_to_one)
+      assert(!cc_get_gen6_dual_source_blending(dev, info));
+
+   return true;
+}
+
+static bool
+cc_validate_gen6_blend(const struct ilo_dev *dev,
+                       const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_blend_info *blend = &info->blend;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(blend->rt_count <= ILO_STATE_CC_BLEND_MAX_RT_COUNT);
+
+   return true;
+}
+
+static enum gen_blend_factor
+get_dst_alpha_one_blend_factor(enum gen_blend_factor factor, bool is_rgb)
+{
+   switch (factor) {
+   case GEN6_BLENDFACTOR_DST_ALPHA:
+      return GEN6_BLENDFACTOR_ONE;
+   case GEN6_BLENDFACTOR_INV_DST_ALPHA:
+      return GEN6_BLENDFACTOR_ZERO;
+   case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE:
+      return (is_rgb) ? GEN6_BLENDFACTOR_ZERO : GEN6_BLENDFACTOR_ONE;
+   default:
+      return factor;
+   }
+}
+
+static void
+cc_get_gen6_effective_rt(const struct ilo_dev *dev,
+                         const struct ilo_state_cc_info *info,
+                         uint8_t rt_index,
+                         struct ilo_state_cc_blend_rt_info *dst)
+{
+   const struct ilo_state_cc_blend_rt_info *rt = &info->blend.rt[rt_index];
+
+   if (rt->logicop_enable || rt->blend_enable ||
+       rt->argb_write_disables != 0xf)
+      assert(rt->cv_has_buffer);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 365:
+    *
+    *     "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
+    *      variants), otherwise Logic Ops must be DISABLED."
+    *
+    * From the Broadwell PRM, volume 7, page 671:
+    *
+    *     "Logic Ops are supported on all blendable render targets and render
+    *      targets with *INT formats."
+    */
+   if (ilo_dev_gen(dev) < ILO_GEN(8) && rt->logicop_enable)
+      assert(rt->cv_is_unorm);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 361:
+    *
+    *     "Only certain surface formats support Color Buffer Blending.  Refer
+    *      to the Surface Format tables in Sampling Engine. Blending must be
+    *      disabled on a RenderTarget if blending is not supported."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 365:
+    *
+    *     "Color Buffer Blending and Logic Ops must not be enabled
+    *      simultaneously, or behavior is UNDEFINED."
+    */
+   if (rt->blend_enable)
+      assert(!rt->cv_is_integer && !rt->logicop_enable);
+
+   *dst = *rt;
+   if (rt->blend_enable) {
+      /* 0x0 is reserved in enum gen_blend_factor */
+      assert(rt->rgb_src && rt->rgb_dst && rt->a_src && rt->a_dst);
+
+      if (rt->force_dst_alpha_one) {
+         dst->rgb_src = get_dst_alpha_one_blend_factor(rt->rgb_src, true);
+         dst->rgb_dst = get_dst_alpha_one_blend_factor(rt->rgb_dst, true);
+         dst->a_src = get_dst_alpha_one_blend_factor(rt->a_src, false);
+         dst->a_dst = get_dst_alpha_one_blend_factor(rt->a_dst, false);
+         dst->force_dst_alpha_one = false;
+      }
+   } else {
+      dst->rgb_src = GEN6_BLENDFACTOR_ONE;
+      dst->rgb_dst = GEN6_BLENDFACTOR_ZERO;
+      dst->rgb_func = GEN6_BLENDFUNCTION_ADD;
+      dst->a_src = dst->rgb_src;
+      dst->a_dst = dst->rgb_dst;
+      dst->a_func = dst->rgb_func;
+   }
+}
+
+static bool
+cc_set_gen6_BLEND_STATE(struct ilo_state_cc *cc,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_alpha_info *alpha = &info->alpha;
+   const struct ilo_state_cc_blend_info *blend = &info->blend;
+   uint32_t dw_rt[2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT], dw1_invariant;
+   uint32_t dw0, dw1;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 7.5);
+
+   if (!cc_validate_gen6_alpha(dev, info) ||
+       !cc_validate_gen6_blend(dev, info))
+      return false;
+
+   /*
+    * According to the Sandy Bridge PRM, volume 2 part 1, page 360, pre-blend
+    * and post-blend color clamps must be enabled in most cases.  For the
+    * other cases, they are either desirable or ignored.  We can enable them
+    * unconditionally.
+    */
+   dw1 = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
+         GEN6_RT_DW1_PRE_BLEND_CLAMP |
+         GEN6_RT_DW1_POST_BLEND_CLAMP;
+
+   if (alpha->alpha_to_coverage) {
+      dw1 |= GEN6_RT_DW1_ALPHA_TO_COVERAGE;
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 379:
+       *
+       *     "[DevSNB]: This bit (AlphaToCoverage Dither Enable) must be
+       *      disabled."
+       */
+      if (ilo_dev_gen(dev) >= ILO_GEN(7))
+         dw1 |= GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER;
+   }
+
+   if (alpha->alpha_to_one)
+      dw1 |= GEN6_RT_DW1_ALPHA_TO_ONE;
+
+   if (alpha->test_enable) {
+      dw1 |= GEN6_RT_DW1_ALPHA_TEST_ENABLE |
+             alpha->test_func << GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT;
+   } else {
+      /*
+       * From the Ivy Bridge PRM, volume 2 part 1, page 371:
+       *
+       *     "When Alpha Test is disabled, Alpha Test Function must be
+       *      COMPAREFUNCTION_ALWAYS."
+       */
+      dw1 |= GEN6_COMPAREFUNCTION_ALWAYS <<
+         GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT;
+   }
+
+   if (blend->dither_enable)
+      dw1 |= GEN6_RT_DW1_DITHER_ENABLE;
+
+   dw1_invariant = dw1;
+
+   for (i = 0; i < blend->rt_count; i++) {
+      struct ilo_state_cc_blend_rt_info rt;
+
+      cc_get_gen6_effective_rt(dev, info, i, &rt);
+
+      /* 0x0 is reserved for blend factors and we have to set them all */
+      dw0 = rt.a_func << GEN6_RT_DW0_ALPHA_FUNC__SHIFT |
+            rt.a_src << GEN6_RT_DW0_SRC_ALPHA_FACTOR__SHIFT |
+            rt.a_dst << GEN6_RT_DW0_DST_ALPHA_FACTOR__SHIFT |
+            rt.rgb_func << GEN6_RT_DW0_COLOR_FUNC__SHIFT |
+            rt.rgb_src << GEN6_RT_DW0_SRC_COLOR_FACTOR__SHIFT |
+            rt.rgb_dst << GEN6_RT_DW0_DST_COLOR_FACTOR__SHIFT;
+
+      if (rt.blend_enable) {
+         dw0 |= GEN6_RT_DW0_BLEND_ENABLE;
+
+         if (rt.a_src != rt.rgb_src ||
+             rt.a_dst != rt.rgb_dst ||
+             rt.a_func != rt.rgb_func)
+            dw0 |= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE;
+      }
+
+      dw1 = dw1_invariant |
+            rt.argb_write_disables << GEN6_RT_DW1_WRITE_DISABLES__SHIFT;
+
+      if (rt.logicop_enable) {
+         dw1 |= GEN6_RT_DW1_LOGICOP_ENABLE |
+                rt.logicop_func << GEN6_RT_DW1_LOGICOP_FUNC__SHIFT;
+      }
+
+      dw_rt[2 * i + 0] = dw0;
+      dw_rt[2 * i + 1] = dw1;
+   }
+
+
+   STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= ARRAY_SIZE(dw_rt));
+   memcpy(&cc->blend[0], dw_rt, sizeof(uint32_t) * 2 * blend->rt_count);
+   cc->blend_state_count = info->blend.rt_count;
+
+   return true;
+}
+
+static bool
+cc_set_gen8_BLEND_STATE(struct ilo_state_cc *cc,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_alpha_info *alpha = &info->alpha;
+   const struct ilo_state_cc_blend_info *blend = &info->blend;
+   uint32_t dw_rt[2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT], dw0, dw1;
+   bool indep_alpha_enable;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   if (!cc_validate_gen6_alpha(dev, info) ||
+       !cc_validate_gen6_blend(dev, info))
+      return false;
+
+   indep_alpha_enable = false;
+   for (i = 0; i < blend->rt_count; i++) {
+      struct ilo_state_cc_blend_rt_info rt;
+
+      cc_get_gen6_effective_rt(dev, info, i, &rt);
+
+      dw0 = rt.rgb_src << GEN8_RT_DW0_SRC_COLOR_FACTOR__SHIFT |
+            rt.rgb_dst << GEN8_RT_DW0_DST_COLOR_FACTOR__SHIFT |
+            rt.rgb_func << GEN8_RT_DW0_COLOR_FUNC__SHIFT |
+            rt.a_src << GEN8_RT_DW0_SRC_ALPHA_FACTOR__SHIFT |
+            rt.a_dst << GEN8_RT_DW0_DST_ALPHA_FACTOR__SHIFT |
+            rt.a_func << GEN8_RT_DW0_ALPHA_FUNC__SHIFT |
+            rt.argb_write_disables << GEN8_RT_DW0_WRITE_DISABLES__SHIFT;
+
+      if (rt.blend_enable) {
+         dw0 |= GEN8_RT_DW0_BLEND_ENABLE;
+
+         if (rt.a_src != rt.rgb_src ||
+             rt.a_dst != rt.rgb_dst ||
+             rt.a_func != rt.rgb_func)
+            indep_alpha_enable = true;
+      }
+
+      dw1 = GEN8_RT_DW1_COLORCLAMP_RTFORMAT |
+            GEN8_RT_DW1_PRE_BLEND_CLAMP |
+            GEN8_RT_DW1_POST_BLEND_CLAMP;
+
+      if (rt.logicop_enable) {
+         dw1 |= GEN8_RT_DW1_LOGICOP_ENABLE |
+                rt.logicop_func << GEN8_RT_DW1_LOGICOP_FUNC__SHIFT;
+      }
+
+      dw_rt[2 * i + 0] = dw0;
+      dw_rt[2 * i + 1] = dw1;
+   }
+
+   dw0 = 0;
+
+   if (alpha->alpha_to_coverage) {
+      dw0 |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE |
+             GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER;
+   }
+
+   if (indep_alpha_enable)
+      dw0 |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
+
+   if (alpha->alpha_to_one)
+      dw0 |= GEN8_BLEND_DW0_ALPHA_TO_ONE;
+
+   if (alpha->test_enable) {
+      dw0 |= GEN8_BLEND_DW0_ALPHA_TEST_ENABLE |
+             alpha->test_func << GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT;
+   } else {
+      dw0 |= GEN6_COMPAREFUNCTION_ALWAYS <<
+         GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT;
+   }
+
+   if (blend->dither_enable)
+      dw0 |= GEN8_BLEND_DW0_DITHER_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= 2 + ARRAY_SIZE(dw_rt));
+   cc->blend[1] = dw0;
+   memcpy(&cc->blend[2], dw_rt, sizeof(uint32_t) * 2 * blend->rt_count);
+   cc->blend_state_count = info->blend.rt_count;
+
+   return true;
+}
+
+static bool
+cc_set_gen8_3DSTATE_PS_BLEND(struct ilo_state_cc *cc,
+                             const struct ilo_dev *dev,
+                             const struct ilo_state_cc_info *info)
+{
+   const struct ilo_state_cc_alpha_info *alpha = &info->alpha;
+   const struct ilo_state_cc_blend_info *blend = &info->blend;
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw1 = 0;
+
+   if (alpha->alpha_to_coverage)
+      dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE;
+
+   if (alpha->test_enable)
+      dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE;
+
+   if (blend->rt_count) {
+      struct ilo_state_cc_blend_rt_info rt0;
+      uint8_t i;
+
+      cc_get_gen6_effective_rt(dev, info, 0, &rt0);
+
+      /* 0x0 is reserved for blend factors and we have to set them all */
+      dw1 |= rt0.a_src << GEN8_PS_BLEND_DW1_SRC_ALPHA_FACTOR__SHIFT |
+             rt0.a_dst << GEN8_PS_BLEND_DW1_DST_ALPHA_FACTOR__SHIFT |
+             rt0.rgb_src << GEN8_PS_BLEND_DW1_SRC_COLOR_FACTOR__SHIFT |
+             rt0.rgb_dst << GEN8_PS_BLEND_DW1_DST_COLOR_FACTOR__SHIFT;
+
+      for (i = 0; i < blend->rt_count; i++) {
+         if (blend->rt[i].argb_write_disables != 0xf) {
+            dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT;
+            break;
+         }
+      }
+
+      if (rt0.blend_enable) {
+         dw1 |= GEN8_PS_BLEND_DW1_BLEND_ENABLE;
+
+         if (rt0.a_src != rt0.rgb_src || rt0.a_dst != rt0.rgb_dst)
+            dw1 |= GEN8_PS_BLEND_DW1_INDEPENDENT_ALPHA_ENABLE;
+      }
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= 1);
+   cc->blend[0] = dw1;
+
+   return true;
+}
+
+static bool
+cc_params_set_gen6_COLOR_CALC_STATE(struct ilo_state_cc *cc,
+                                    const struct ilo_dev *dev,
+                                    const struct ilo_state_cc_params_info *params)
+{
+   uint32_t dw0;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   dw0 = params->stencil_front.test_ref << GEN6_CC_DW0_STENCIL_REF__SHIFT |
+         params->stencil_back.test_ref << GEN6_CC_DW0_STENCIL1_REF__SHIFT |
+         GEN6_CC_DW0_ALPHATEST_FLOAT32;
+
+   STATIC_ASSERT(ARRAY_SIZE(cc->cc) >= 6);
+   cc->cc[0] = dw0;
+   cc->cc[1] = fui(params->alpha_ref);
+   cc->cc[2] = fui(params->blend_rgba[0]);
+   cc->cc[3] = fui(params->blend_rgba[1]);
+   cc->cc[4] = fui(params->blend_rgba[2]);
+   cc->cc[5] = fui(params->blend_rgba[3]);
+
+   return true;
+}
+
+bool
+ilo_state_cc_init(struct ilo_state_cc *cc,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_cc_info *info)
+{
+   assert(ilo_is_zeroed(cc, sizeof(*cc)));
+   return ilo_state_cc_set_info(cc, dev, info);
+}
+
+bool
+ilo_state_cc_set_info(struct ilo_state_cc *cc,
+                      const struct ilo_dev *dev,
+                      const struct ilo_state_cc_info *info)
+{
+   bool ret = true;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      ret &= cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(cc, dev, info);
+      ret &= cc_set_gen8_BLEND_STATE(cc, dev, info);
+      ret &= cc_set_gen8_3DSTATE_PS_BLEND(cc, dev, info);
+   } else {
+      ret &= cc_set_gen6_DEPTH_STENCIL_STATE(cc, dev, info);
+      ret &= cc_set_gen6_BLEND_STATE(cc, dev, info);
+   }
+
+   ret &= cc_params_set_gen6_COLOR_CALC_STATE(cc, dev, &info->params);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_cc_set_params(struct ilo_state_cc *cc,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_cc_params_info *params)
+{
+   /* modify stencil masks */
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      uint32_t dw1 = cc->ds[0];
+      uint32_t dw2 = cc->ds[1];
+
+      if (dw1 & GEN8_ZS_DW1_STENCIL_TEST_ENABLE) {
+         const bool twosided_enable = (dw1 & GEN8_ZS_DW1_STENCIL1_ENABLE);
+         const struct ilo_state_cc_stencil_params_info *front_p =
+            &params->stencil_front;
+         const struct ilo_state_cc_stencil_params_info *back_p =
+            (twosided_enable) ? &params->stencil_back :
+                                &params->stencil_front;
+
+         if (front_p->write_mask || back_p->write_mask)
+            dw1 |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
+         else
+            dw1 &= ~GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
+
+         dw2 =
+            front_p->test_mask << GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT |
+            front_p->write_mask << GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT |
+            back_p->test_mask << GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT |
+            back_p->write_mask << GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT;
+      }
+
+      cc->ds[0] = dw1;
+      cc->ds[1] = dw2;
+   } else {
+      uint32_t dw0 = cc->ds[0];
+      uint32_t dw1 = cc->ds[1];
+
+      if (dw0 & GEN6_ZS_DW0_STENCIL_TEST_ENABLE) {
+         const bool twosided_enable = (dw0 & GEN6_ZS_DW0_STENCIL1_ENABLE);
+         const struct ilo_state_cc_stencil_params_info *front_p =
+            &params->stencil_front;
+         const struct ilo_state_cc_stencil_params_info *back_p =
+            (twosided_enable) ? &params->stencil_back :
+                                &params->stencil_front;
+
+         if (front_p->write_mask || back_p->write_mask)
+            dw0 |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
+         else
+            dw0 &= ~GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
+
+         dw1 =
+            front_p->test_mask << GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT |
+            front_p->write_mask << GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT |
+            back_p->test_mask << GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT |
+            back_p->write_mask << GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT;
+      }
+
+      cc->ds[0] = dw0;
+      cc->ds[1] = dw1;
+   }
+
+   /* modify COLOR_CALC_STATE */
+   cc_params_set_gen6_COLOR_CALC_STATE(cc, dev, params);
+
+   return true;
+}
+
+void
+ilo_state_cc_full_delta(const struct ilo_state_cc *cc,
+                        const struct ilo_dev *dev,
+                        struct ilo_state_cc_delta *delta)
+{
+   delta->dirty = ILO_STATE_CC_BLEND_STATE |
+                  ILO_STATE_CC_COLOR_CALC_STATE;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      delta->dirty |= ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL |
+                      ILO_STATE_CC_3DSTATE_PS_BLEND;
+   } else {
+      delta->dirty |= ILO_STATE_CC_DEPTH_STENCIL_STATE;
+   }
+}
+
+void
+ilo_state_cc_get_delta(const struct ilo_state_cc *cc,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_cc *old,
+                       struct ilo_state_cc_delta *delta)
+{
+   delta->dirty = 0;
+
+   if (memcmp(cc->ds, old->ds, sizeof(cc->ds))) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(8))
+         delta->dirty |= ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL;
+      else
+         delta->dirty |= ILO_STATE_CC_DEPTH_STENCIL_STATE;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      if (cc->blend[0] != old->blend[0])
+         delta->dirty |= ILO_STATE_CC_3DSTATE_PS_BLEND;
+
+      if (memcmp(&cc->blend[1], &old->blend[1],
+               sizeof(uint32_t) * (1 + 2 * cc->blend_state_count)))
+         delta->dirty |= ILO_STATE_CC_BLEND_STATE;
+   } else if (memcmp(cc->blend, old->blend,
+            sizeof(uint32_t) * 2 * cc->blend_state_count)) {
+      delta->dirty |= ILO_STATE_CC_BLEND_STATE;
+   }
+
+   if (memcmp(cc->cc, old->cc, sizeof(cc->cc)))
+      delta->dirty |= ILO_STATE_CC_COLOR_CALC_STATE;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_cc.h b/src/gallium/drivers/ilo/core/ilo_state_cc.h
new file mode 100644 (file)
index 0000000..5b96a60
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_CC_H
+#define ILO_STATE_CC_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 38:
+ *
+ *     "Render Target Index. Specifies the render target index that will be
+ *      used to select blend state from BLEND_STATE.
+ *      Format = U3"
+ */
+#define ILO_STATE_CC_BLEND_MAX_RT_COUNT 8
+
+enum ilo_state_cc_dirty_bits {
+   ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL           = (1 << 0),
+   ILO_STATE_CC_3DSTATE_PS_BLEND                   = (1 << 1),
+   ILO_STATE_CC_DEPTH_STENCIL_STATE                = (1 << 2),
+   ILO_STATE_CC_BLEND_STATE                        = (1 << 3),
+   ILO_STATE_CC_COLOR_CALC_STATE                   = (1 << 4),
+};
+
+/**
+ * AlphaCoverage and AlphaTest.
+ */
+struct ilo_state_cc_alpha_info {
+   bool cv_sample_count_one;
+   bool cv_float_source0_alpha;
+
+   bool alpha_to_coverage;
+   bool alpha_to_one;
+
+   bool test_enable;
+   enum gen_compare_function test_func;
+};
+
+struct ilo_state_cc_stencil_op_info {
+   enum gen_compare_function test_func;
+   enum gen_stencil_op fail_op;
+   enum gen_stencil_op zfail_op;
+   enum gen_stencil_op zpass_op;
+};
+
+/**
+ * StencilTest.
+ */
+struct ilo_state_cc_stencil_info {
+   bool cv_has_buffer;
+
+   bool test_enable;
+   bool twosided_enable;
+
+   struct ilo_state_cc_stencil_op_info front;
+   struct ilo_state_cc_stencil_op_info back;
+};
+
+/**
+ * DepthTest.
+ */
+struct ilo_state_cc_depth_info {
+   bool cv_has_buffer;
+
+   bool test_enable;
+   /* independent from test_enable */
+   bool write_enable;
+
+   enum gen_compare_function test_func;
+};
+
+struct ilo_state_cc_blend_rt_info {
+   bool cv_has_buffer;
+   bool cv_is_unorm;
+   bool cv_is_integer;
+
+   uint8_t argb_write_disables;
+
+   bool logicop_enable;
+   enum gen_logic_op logicop_func;
+
+   bool blend_enable;
+   bool force_dst_alpha_one;
+   enum gen_blend_factor rgb_src;
+   enum gen_blend_factor rgb_dst;
+   enum gen_blend_function rgb_func;
+   enum gen_blend_factor a_src;
+   enum gen_blend_factor a_dst;
+   enum gen_blend_function a_func;
+};
+
+/**
+ * ColorBufferBlending, Dithering, and LogicOps.
+ */
+struct ilo_state_cc_blend_info {
+   const struct ilo_state_cc_blend_rt_info *rt;
+   uint8_t rt_count;
+
+   bool dither_enable;
+};
+
+struct ilo_state_cc_stencil_params_info {
+   uint8_t test_ref;
+   uint8_t test_mask;
+   uint8_t write_mask;
+};
+
+/**
+ * CC parameters.
+ */
+struct ilo_state_cc_params_info {
+   float alpha_ref;
+
+   struct ilo_state_cc_stencil_params_info stencil_front;
+   struct ilo_state_cc_stencil_params_info stencil_back;
+
+   float blend_rgba[4];
+};
+
+/**
+ * Pixel processing.
+ */
+struct ilo_state_cc_info {
+   struct ilo_state_cc_alpha_info alpha;
+   struct ilo_state_cc_stencil_info stencil;
+   struct ilo_state_cc_depth_info depth;
+   struct ilo_state_cc_blend_info blend;
+
+   struct ilo_state_cc_params_info params;
+};
+
+struct ilo_state_cc {
+   uint32_t ds[3];
+
+   uint8_t blend_state_count;
+   uint32_t blend[1 + 1 + 2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT];
+
+   uint32_t cc[6];
+};
+
+struct ilo_state_cc_delta {
+   uint32_t dirty;
+};
+
+bool
+ilo_state_cc_init(struct ilo_state_cc *cc,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_cc_info *info);
+
+bool
+ilo_state_cc_set_info(struct ilo_state_cc *cc,
+                      const struct ilo_dev *dev,
+                      const struct ilo_state_cc_info *info);
+
+bool
+ilo_state_cc_set_params(struct ilo_state_cc *cc,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_cc_params_info *params);
+
+void
+ilo_state_cc_full_delta(const struct ilo_state_cc *cc,
+                        const struct ilo_dev *dev,
+                        struct ilo_state_cc_delta *delta);
+
+void
+ilo_state_cc_get_delta(const struct ilo_state_cc *cc,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_cc *old,
+                       struct ilo_state_cc_delta *delta);
+
+#endif /* ILO_STATE_CC_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_compute.c b/src/gallium/drivers/ilo/core/ilo_state_compute.c
new file mode 100644 (file)
index 0000000..a5fe5e1
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_compute.h"
+
+struct compute_urb_configuration {
+   int idrt_entry_count;
+   int curbe_entry_count;
+
+   int urb_entry_count;
+   /* in 256-bit register increments */
+   int urb_entry_size;
+};
+
+static int
+get_gen6_rob_entry_count(const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 60:
+    *
+    *     "ROB has 64KB of storage; 2048 entries."
+    *
+    * From the valid ranges of "CURBE Allocation Size", we can also conclude
+    * that interface entries and CURBE data must be in ROB.  And that ROB
+    * should be 16KB, or 512 entries, on Gen7 GT1.
+    */
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      return 2048;
+   else if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      return (dev->gt == 2) ? 2048 : 512;
+   else
+      return (dev->gt == 2) ? 2048 : 1024;
+}
+
+static int
+get_gen6_idrt_entry_count(const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 21:
+    *
+    *     "The first 32 URB entries are reserved for the interface
+    *      descriptor..."
+    *
+    * From the Haswell PRM, volume 7, page 836:
+    *
+    *     "The first 64 URB entries are reserved for the interface
+    *      description..."
+    */
+   return (ilo_dev_gen(dev) >= ILO_GEN(7.5)) ? 64 : 32;
+}
+
+static int
+get_gen6_curbe_entry_count(const struct ilo_dev *dev, uint32_t curbe_size)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 21:
+    *
+    *     "(CURBE Allocation Size) Specifies the total length allocated for
+    *      CURBE, in 256-bit register increments.
+    */
+   const int entry_count = (curbe_size + 31) / 32;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(get_gen6_idrt_entry_count(dev) + entry_count <=
+         get_gen6_rob_entry_count(dev));
+
+   return entry_count;
+}
+
+static bool
+compute_get_gen6_urb_configuration(const struct ilo_dev *dev,
+                                   const struct ilo_state_compute_info *info,
+                                   struct compute_urb_configuration *urb)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   urb->idrt_entry_count = get_gen6_idrt_entry_count(dev);
+   urb->curbe_entry_count =
+      get_gen6_curbe_entry_count(dev, info->curbe_alloc_size);
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 451:
+    *
+    *     "Please note that 0 is not allowed for this field (Number of URB
+    *      Entries)."
+    */
+   urb->urb_entry_count = (ilo_dev_gen(dev) >= ILO_GEN(8)) ? 1 : 0;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 52:
+    *
+    *     "(URB Entry Allocation Size) Specifies the length of each URB entry
+    *      used by the unit, in 256-bit register increments - 1."
+    */
+   urb->urb_entry_size = 1;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 22:
+    *
+    *      MEDIA_VFE_STATE specifies the amount of CURBE space, the URB handle
+    *      size and the number of URB handles. The driver must ensure that
+    *      ((URB_handle_size * URB_num_handle) - CURBE - 32) <=
+    *      URB_allocation_in_L3."
+    */
+   assert(urb->idrt_entry_count + urb->curbe_entry_count +
+         urb->urb_entry_count * urb->urb_entry_size <=
+         info->cv_urb_alloc_size / 32);
+
+   return true;
+}
+
+static int
+compute_interface_get_gen6_read_end(const struct ilo_dev *dev,
+                                    const struct ilo_state_compute_interface_info *interface)
+{
+   const int per_thread_read = (interface->curbe_read_length + 31) / 32;
+   const int cross_thread_read =
+      (interface->cross_thread_curbe_read_length + 31) / 32;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(interface->curbe_read_offset % 32 == 0);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 60:
+    *
+    *     "(Constant URB Entry Read Length) [0,63]"
+    */
+   assert(per_thread_read <= 63);
+
+   /* From the Haswell PRM, volume 2d, page 199:
+    *
+    *     "(Cross-Thread Constant Data Read Length) [0,127]"
+    */
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      assert(cross_thread_read <= 127);
+   else
+      assert(!cross_thread_read);
+
+   if (per_thread_read || cross_thread_read) {
+      return interface->curbe_read_offset / 32 + cross_thread_read +
+         per_thread_read * interface->thread_group_size;
+   } else {
+      return 0;
+   }
+}
+
+static bool
+compute_validate_gen6(const struct ilo_dev *dev,
+                      const struct ilo_state_compute_info *info,
+                      const struct compute_urb_configuration *urb)
+{
+   int min_curbe_entry_count;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(info->interface_count <= urb->idrt_entry_count);
+
+   min_curbe_entry_count = 0;
+   for (i = 0; i < info->interface_count; i++) {
+      const int read_end =
+         compute_interface_get_gen6_read_end(dev, &info->interfaces[i]);
+
+      if (min_curbe_entry_count < read_end)
+         min_curbe_entry_count = read_end;
+   }
+
+   assert(min_curbe_entry_count <= urb->curbe_entry_count);
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 452:
+    *
+    *     "CURBE Allocation Size should be 0 for GPGPU workloads that uses
+    *      indirect instead of CURBE."
+    */
+   if (!min_curbe_entry_count)
+      assert(!urb->curbe_entry_count);
+
+   return true;
+}
+
+static uint8_t
+compute_get_gen6_scratch_space(const struct ilo_dev *dev,
+                               const struct ilo_state_compute_info *info)
+{
+   uint32_t scratch_size = 0;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   for (i = 0; i < info->interface_count; i++) {
+      if (scratch_size < info->interfaces[i].scratch_size)
+         scratch_size = info->interfaces[i].scratch_size;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      assert(scratch_size <= 2 * 1024 * 1024);
+
+      /* next power of two, starting from 1KB */
+      return (scratch_size > 1024) ?
+         (util_last_bit(scratch_size - 1) - 10): 0;
+   } else if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
+      assert(scratch_size <= 2 * 1024 * 1024);
+
+      /* next power of two, starting from 2KB */
+      return (scratch_size > 2048) ?
+         (util_last_bit(scratch_size - 1) - 11): 0;
+   } else {
+      assert(scratch_size <= 12 * 1024);
+
+      return (scratch_size > 1024) ?
+         (scratch_size - 1) / 1024 : 0;
+   }
+}
+
+static bool
+compute_set_gen6_MEDIA_VFE_STATE(struct ilo_state_compute *compute,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_compute_info *info)
+{
+   struct compute_urb_configuration urb;
+   uint8_t scratch_space;
+
+   uint32_t dw1, dw2, dw4;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!compute_get_gen6_urb_configuration(dev, info, &urb) ||
+       !compute_validate_gen6(dev, info, &urb))
+      return false;
+
+   scratch_space = compute_get_gen6_scratch_space(dev, info);
+
+   dw1 = scratch_space << GEN6_VFE_DW1_SCRATCH_SPACE_PER_THREAD__SHIFT;
+   dw2 = (dev->thread_count - 1) << GEN6_VFE_DW2_MAX_THREADS__SHIFT |
+         urb.urb_entry_count << GEN6_VFE_DW2_URB_ENTRY_COUNT__SHIFT |
+         GEN6_VFE_DW2_RESET_GATEWAY_TIMER |
+         GEN6_VFE_DW2_BYPASS_GATEWAY_CONTROL;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7) && ilo_dev_gen(dev) <= ILO_GEN(7.5))
+      dw2 |= GEN7_VFE_DW2_GPGPU_MODE;
+
+   assert(urb.urb_entry_size);
+
+   dw4 = (urb.urb_entry_size - 1) << GEN6_VFE_DW4_URB_ENTRY_SIZE__SHIFT |
+         urb.curbe_entry_count << GEN6_VFE_DW4_CURBE_SIZE__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(compute->vfe) >= 3);
+   compute->vfe[0] = dw1;
+   compute->vfe[1] = dw2;
+   compute->vfe[2] = dw4;
+
+   return true;
+}
+
+static uint8_t
+compute_interface_get_gen6_sampler_count(const struct ilo_dev *dev,
+                                         const struct ilo_state_compute_interface_info *interface)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+   return (interface->sampler_count <= 12) ?
+      (interface->sampler_count + 3) / 4 : 4;
+}
+
+static uint8_t
+compute_interface_get_gen6_surface_count(const struct ilo_dev *dev,
+                                         const struct ilo_state_compute_interface_info *interface)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+   return (interface->surface_count <= 31) ? interface->surface_count : 31;
+}
+
+static uint8_t
+compute_interface_get_gen7_slm_size(const struct ilo_dev *dev,
+                                    const struct ilo_state_compute_interface_info *interface)
+{
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 2, page 61:
+    *
+    *     "The amount is specified in 4k blocks, but only powers of 2 are
+    *      allowed: 0, 4k, 8k, 16k, 32k and 64k per half-slice."
+    */
+   assert(interface->slm_size <= 64 * 1024);
+
+   return util_next_power_of_two((interface->slm_size + 4095) / 4096);
+}
+
+static bool
+compute_set_gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_state_compute *compute,
+                                           const struct ilo_dev *dev,
+                                           const struct ilo_state_compute_info *info)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   for (i = 0; i < info->interface_count; i++) {
+      const struct ilo_state_compute_interface_info *interface =
+         &info->interfaces[i];
+      uint16_t read_offset, per_thread_read_len, cross_thread_read_len;
+      uint8_t sampler_count, surface_count;
+      uint32_t dw0, dw2, dw3, dw4, dw5, dw6;
+
+      assert(interface->kernel_offset % 64 == 0);
+      assert(interface->thread_group_size);
+
+      read_offset = interface->curbe_read_offset / 32;
+      per_thread_read_len = (interface->curbe_read_length + 31) / 32;
+      cross_thread_read_len =
+         (interface->cross_thread_curbe_read_length + 31) / 32;
+
+      sampler_count =
+         compute_interface_get_gen6_sampler_count(dev, interface);
+      surface_count =
+         compute_interface_get_gen6_surface_count(dev, interface);
+
+      dw0 = interface->kernel_offset;
+      dw2 = sampler_count << GEN6_IDRT_DW2_SAMPLER_COUNT__SHIFT;
+      dw3 = surface_count << GEN6_IDRT_DW3_BINDING_TABLE_SIZE__SHIFT;
+      dw4 = per_thread_read_len << GEN6_IDRT_DW4_CURBE_READ_LEN__SHIFT |
+            read_offset << GEN6_IDRT_DW4_CURBE_READ_OFFSET__SHIFT;
+
+      dw5 = 0;
+      dw6 = 0;
+      if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+         const uint8_t slm_size =
+            compute_interface_get_gen7_slm_size(dev, interface);
+
+         dw5 |= GEN7_IDRT_DW5_ROUNDING_MODE_RTNE;
+
+         if (slm_size) {
+            dw5 |= GEN7_IDRT_DW5_BARRIER_ENABLE |
+                   slm_size << GEN7_IDRT_DW5_SLM_SIZE__SHIFT;
+         }
+
+         /*
+          * From the Haswell PRM, volume 2d, page 199:
+          *
+          *     "(Number of Threads in GPGPU Thread Group) Specifies the
+          *      number of threads that are in this thread group.  Used to
+          *      program the barrier for the number of messages to expect. The
+          *      minimum value is 0 (which will disable the barrier), while
+          *      the maximum value is the number of threads in a subslice for
+          *      local barriers."
+          *
+          * From the Broadwell PRM, volume 2d, page 183:
+          *
+          *     "(Number of Threads in GPGPU Thread Group) Specifies the
+          *      number of threads that are in this thread group.  The minimum
+          *      value is 1, while the maximum value is the number of threads
+          *      in a subslice for local barriers. See vol1b Configurations
+          *      for the number of threads per subslice for different
+          *      products.  The maximum value for global barriers is limited
+          *      by the number of threads in the system, or by 511, whichever
+          *      is lower. This field should not be set to 0 even if the
+          *      barrier is disabled, since an accurate value is needed for
+          *      proper pre-emption."
+          */
+         if (slm_size || ilo_dev_gen(dev) >= ILO_GEN(8)) {
+            dw5 |= interface->thread_group_size <<
+               GEN7_IDRT_DW5_THREAD_GROUP_SIZE__SHIFT;
+         }
+
+         if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
+            dw6 |= cross_thread_read_len <<
+               GEN75_IDRT_DW6_CROSS_THREAD_CURBE_READ_LEN__SHIFT;
+         }
+      }
+
+      STATIC_ASSERT(ARRAY_SIZE(compute->idrt[i]) >= 6);
+      compute->idrt[i][0] = dw0;
+      compute->idrt[i][1] = dw2;
+      compute->idrt[i][2] = dw3;
+      compute->idrt[i][3] = dw4;
+      compute->idrt[i][4] = dw5;
+      compute->idrt[i][5] = dw6;
+   }
+
+   return true;
+}
+
+bool
+ilo_state_compute_init(struct ilo_state_compute *compute,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_compute_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(compute, sizeof(*compute)));
+   assert(ilo_is_zeroed(info->data, info->data_size));
+
+   assert(ilo_state_compute_data_size(dev, info->interface_count) <=
+         info->data_size);
+   compute->idrt = (uint32_t (*)[6]) info->data;
+
+   ret &= compute_set_gen6_MEDIA_VFE_STATE(compute, dev, info);
+   ret &= compute_set_gen6_INTERFACE_DESCRIPTOR_DATA(compute, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_compute.h b/src/gallium/drivers/ilo/core/ilo_state_compute.h
new file mode 100644 (file)
index 0000000..346f7b6
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_COMPUTE_H
+#define ILO_STATE_COMPUTE_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/*
+ * From the Haswell PRM, volume 7, page 836:
+ *
+ *     "The first 64 URB entries are reserved for the interface
+ *      description..."
+ */
+#define ILO_STATE_COMPUTE_MAX_INTERFACE_COUNT 64
+
+struct ilo_state_compute_interface_info {
+   /* usually 0 unless there are multiple interfaces */
+   uint32_t kernel_offset;
+
+   uint32_t scratch_size;
+
+   uint8_t sampler_count;
+   uint8_t surface_count;
+
+   uint16_t thread_group_size;
+   uint32_t slm_size;
+
+   uint16_t curbe_read_offset;
+   uint16_t curbe_read_length;
+   uint16_t cross_thread_curbe_read_length;
+};
+
+struct ilo_state_compute_info {
+   void *data;
+   size_t data_size;
+
+   const struct ilo_state_compute_interface_info *interfaces;
+   uint8_t interface_count;
+
+   uint32_t cv_urb_alloc_size;
+   uint32_t curbe_alloc_size;
+};
+
+struct ilo_state_compute {
+   uint32_t vfe[3];
+
+   uint32_t (*idrt)[6];
+   uint8_t idrt_count;
+};
+
+static inline size_t
+ilo_state_compute_data_size(const struct ilo_dev *dev,
+                            uint8_t interface_count)
+{
+   const struct ilo_state_compute *compute = NULL;
+   return sizeof(compute->idrt[0]) * interface_count;
+}
+
+bool
+ilo_state_compute_init(struct ilo_state_compute *compute,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_compute_info *info);
+
+#endif /* ILO_STATE_COMPUTE_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_raster.c b/src/gallium/drivers/ilo/core/ilo_state_raster.c
new file mode 100644 (file)
index 0000000..ed64a1f
--- /dev/null
@@ -0,0 +1,1252 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_raster.h"
+
+static bool
+raster_validate_gen6_clip(const struct ilo_dev *dev,
+                          const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_clip_info *clip = &info->clip;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(clip->viewport_count);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 188:
+    *
+    *     ""Clip Distance Cull Test Enable Bitmask" and "Clip Distance Clip
+    *      Test Enable Bitmask" should not have overlapping bits in the mask,
+    *      else the results are undefined."
+    */
+   assert(!(clip->user_cull_enables & clip->user_clip_enables));
+
+   if (ilo_dev_gen(dev) < ILO_GEN(9))
+      assert(clip->z_near_enable == clip->z_far_enable);
+
+   return true;
+}
+
+static bool
+raster_set_gen6_3DSTATE_CLIP(struct ilo_state_raster *rs,
+                             const struct ilo_dev *dev,
+                             const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_clip_info *clip = &info->clip;
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_tri_info *tri = &info->tri;
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+   uint32_t dw1, dw2, dw3;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!raster_validate_gen6_clip(dev, info))
+      return false;
+
+   dw1 = clip->user_cull_enables << GEN6_CLIP_DW1_UCP_CULL_ENABLES__SHIFT;
+
+   if (clip->stats_enable)
+      dw1 |= GEN6_CLIP_DW1_STATISTICS;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      /*
+       * From the Ivy Bridge PRM, volume 2 part 1, page 219:
+       *
+       *     "Workaround : Due to Hardware issue "EarlyCull" needs to be
+       *      enabled only for the cases where the incoming primitive topology
+       *      into the clipper guaranteed to be Trilist."
+       *
+       * What does this mean?
+       */
+      dw1 |= GEN7_CLIP_DW1_SUBPIXEL_8BITS |
+             GEN7_CLIP_DW1_EARLY_CULL_ENABLE;
+
+      if (ilo_dev_gen(dev) <= ILO_GEN(7.5)) {
+         dw1 |= tri->front_winding << GEN7_CLIP_DW1_FRONT_WINDING__SHIFT |
+                tri->cull_mode << GEN7_CLIP_DW1_CULL_MODE__SHIFT;
+      }
+   }
+
+   dw2 = clip->user_clip_enables << GEN6_CLIP_DW2_UCP_CLIP_ENABLES__SHIFT |
+         GEN6_CLIPMODE_NORMAL << GEN6_CLIP_DW2_CLIP_MODE__SHIFT;
+
+   if (clip->clip_enable)
+      dw2 |= GEN6_CLIP_DW2_CLIP_ENABLE;
+
+   if (clip->z_near_zero)
+      dw2 |= GEN6_CLIP_DW2_APIMODE_D3D;
+   else
+      dw2 |= GEN6_CLIP_DW2_APIMODE_OGL;
+
+   if (clip->xy_test_enable)
+      dw2 |= GEN6_CLIP_DW2_XY_TEST_ENABLE;
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8) && clip->z_near_enable)
+      dw2 |= GEN6_CLIP_DW2_Z_TEST_ENABLE;
+
+   if (clip->gb_test_enable)
+      dw2 |= GEN6_CLIP_DW2_GB_TEST_ENABLE;
+
+   if (scan->barycentric_interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
+                                    GEN6_INTERP_NONPERSPECTIVE_CENTROID |
+                                    GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
+      dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
+
+   if (setup->first_vertex_provoking) {
+      dw2 |= 0 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
+             0 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
+             1 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
+   } else {
+      dw2 |= 2 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
+             1 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
+             2 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
+   }
+
+   dw3 = 0x1 << GEN6_CLIP_DW3_MIN_POINT_WIDTH__SHIFT |
+         0x7ff << GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT |
+         (clip->viewport_count - 1) << GEN6_CLIP_DW3_MAX_VPINDEX__SHIFT;
+
+   if (clip->force_rtaindex_zero)
+      dw3 |= GEN6_CLIP_DW3_FORCE_RTAINDEX_ZERO;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->clip) >= 3);
+   rs->clip[0] = dw1;
+   rs->clip[1] = dw2;
+   rs->clip[2] = dw3;
+
+   return true;
+}
+
+static bool
+raster_params_is_gen6_line_aa_allowed(const struct ilo_dev *dev,
+                                      const struct ilo_state_raster_params_info *params)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 251:
+    *
+    *     "This field (Anti-aliasing Enable) must be disabled if any of the
+    *      render targets have integer (UINT or SINT) surface format."
+    */
+   if (params->any_integer_rt)
+      return false;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 321:
+    *
+    *     "[DevSNB+]: This field (Hierarchical Depth Buffer Enable) must be
+    *      disabled if Anti-aliasing Enable in 3DSTATE_SF is enabled.
+    */
+   if (ilo_dev_gen(dev) == ILO_GEN(6) && params->hiz_enable)
+      return false;
+
+   return true;
+}
+
+static void
+raster_get_gen6_effective_line(const struct ilo_dev *dev,
+                               const struct ilo_state_raster_info *info,
+                               struct ilo_state_raster_line_info *line)
+{
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_params_info *params = &info->params;
+
+   *line = info->line;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 251:
+    *
+    *     "This field (Anti-aliasing Enable) is ignored when Multisample
+    *      Rasterization Mode is MSRASTMODE_ON_xx."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 251:
+    *
+    *     "Setting a Line Width of 0.0 specifies the rasterization of the
+    *      "thinnest" (one-pixel-wide), non-antialiased lines. Note that
+    *      this effectively overrides the effect of AAEnable (though the
+    *      AAEnable state variable is not modified). Lines rendered with
+    *      zero Line Width are rasterized using GIQ (Grid Intersection
+    *      Quantization) rules as specified by the GDI and Direct3D APIs."
+    *
+    *     "Software must not program a value of 0.0 when running in
+    *      MSRASTMODE_ON_xxx modes - zero-width lines are not available
+    *      when multisampling rasterization is enabled."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 294:
+    *
+    *     "Line stipple, controlled via the Line Stipple Enable state variable
+    *      in WM_STATE, discards certain pixels that are produced by non-AA
+    *      line rasterization."
+    */
+   if (setup->line_msaa_enable ||
+       !raster_params_is_gen6_line_aa_allowed(dev, params))
+      line->aa_enable = false;
+   if (setup->line_msaa_enable || line->aa_enable) {
+      line->stipple_enable = false;
+      line->giq_enable = false;
+      line->giq_last_pixel = false;
+   }
+}
+
+static bool
+raster_validate_gen8_raster(const struct ilo_dev *dev,
+                            const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_tri_info *tri = &info->tri;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 249:
+    *
+    *     "This setting (SOLID) is required when rendering rectangle
+    *      (RECTLIST) objects.
+    */
+   if (tri->fill_mode_front != GEN6_FILLMODE_SOLID ||
+       tri->fill_mode_back != GEN6_FILLMODE_SOLID)
+      assert(!setup->cv_is_rectangle);
+
+   return true;
+}
+
+static enum gen_msrast_mode
+raster_setup_get_gen6_msrast_mode(const struct ilo_dev *dev,
+                                  const struct ilo_state_raster_setup_info *setup)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (setup->line_msaa_enable) {
+      return (setup->msaa_enable) ? GEN6_MSRASTMODE_ON_PATTERN :
+                                    GEN6_MSRASTMODE_ON_PIXEL;
+   } else {
+      return (setup->msaa_enable) ? GEN6_MSRASTMODE_OFF_PATTERN :
+                                    GEN6_MSRASTMODE_OFF_PIXEL;
+   }
+}
+
+static int
+get_gen6_line_width(const struct ilo_dev *dev, float fwidth,
+                    bool line_aa_enable, bool line_giq_enable)
+{
+   int line_width;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* in U3.7 */
+   line_width = (int) (fwidth * 128.0f + 0.5f);
+
+   /*
+    * Smooth lines should intersect ceil(line_width) or (ceil(line_width) + 1)
+    * pixels in the minor direction.  We have to make the lines slightly
+    * thicker, 0.5 pixel on both sides, so that they intersect that many
+    * pixels.
+    */
+   if (line_aa_enable)
+      line_width += 128;
+
+   line_width = CLAMP(line_width, 1, 1023);
+
+   if (line_giq_enable && line_width == 128)
+      line_width = 0;
+
+   return line_width;
+}
+
+static int
+get_gen6_point_width(const struct ilo_dev *dev, float fwidth)
+{
+   int point_width;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* in U8.3 */
+   point_width = (int) (fwidth * 8.0f + 0.5f);
+   point_width = CLAMP(point_width, 1, 2047);
+
+   return point_width;
+}
+
+static bool
+raster_set_gen7_3DSTATE_SF(struct ilo_state_raster *rs,
+                           const struct ilo_dev *dev,
+                           const struct ilo_state_raster_info *info,
+                           const struct ilo_state_raster_line_info *line)
+{
+   const struct ilo_state_raster_clip_info *clip = &info->clip;
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_point_info *point = &info->point;
+   const struct ilo_state_raster_tri_info *tri = &info->tri;
+   const struct ilo_state_raster_params_info *params = &info->params;
+   const enum gen_msrast_mode msrast =
+      raster_setup_get_gen6_msrast_mode(dev, setup);
+   const int line_width = get_gen6_line_width(dev, params->line_width,
+         line->aa_enable, line->giq_enable);
+   const int point_width = get_gen6_point_width(dev, params->point_width);
+   uint32_t dw1, dw2, dw3;
+
+   ILO_DEV_ASSERT(dev, 6, 7.5);
+
+   if (!raster_validate_gen8_raster(dev, info))
+      return false;
+
+   dw1 = tri->fill_mode_front << GEN7_SF_DW1_FILL_MODE_FRONT__SHIFT |
+         tri->fill_mode_back << GEN7_SF_DW1_FILL_MODE_BACK__SHIFT |
+         tri->front_winding << GEN7_SF_DW1_FRONT_WINDING__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7) && ilo_dev_gen(dev) <= ILO_GEN(7.5)) {
+      enum gen_depth_format format;
+
+      /* do it here as we want 0x0 to be valid */
+      switch (tri->depth_offset_format) {
+      case GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT:
+         format = GEN6_ZFORMAT_D32_FLOAT;
+         break;
+      case GEN6_ZFORMAT_D24_UNORM_S8_UINT:
+         format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
+         break;
+      default:
+         format = tri->depth_offset_format;
+         break;
+      }
+
+      dw1 |= format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT;
+   }
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 248:
+    *
+    *     "This bit (Statistics Enable) should be set whenever clipping is
+    *      enabled and the Statistics Enable bit is set in CLIP_STATE. It
+    *      should be cleared if clipping is disabled or Statistics Enable in
+    *      CLIP_STATE is clear."
+    */
+   if (clip->stats_enable && clip->clip_enable)
+      dw1 |= GEN7_SF_DW1_STATISTICS;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 258:
+    *
+    *     "This bit (Legacy Global Depth Bias Enable, Global Depth Offset
+    *      Enable Solid , Global Depth Offset Enable Wireframe, and Global
+    *      Depth Offset Enable Point) should be set whenever non zero depth
+    *      bias (Slope, Bias) values are used. Setting this bit may have some
+    *      degradation of performance for some workloads."
+    *
+    * But it seems fine to ignore that.
+    */
+   if (tri->depth_offset_solid)
+      dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_SOLID;
+   if (tri->depth_offset_wireframe)
+      dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME;
+   if (tri->depth_offset_point)
+      dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_POINT;
+
+   if (setup->viewport_transform)
+      dw1 |= GEN7_SF_DW1_VIEWPORT_TRANSFORM;
+
+   dw2 = tri->cull_mode << GEN7_SF_DW2_CULL_MODE__SHIFT |
+         line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT |
+         GEN7_SF_DW2_AA_LINE_CAP_1_0 |
+         msrast << GEN7_SF_DW2_MSRASTMODE__SHIFT;
+
+   if (line->aa_enable)
+      dw2 |= GEN7_SF_DW2_AA_LINE_ENABLE;
+
+   if (ilo_dev_gen(dev) == ILO_GEN(7.5) && line->stipple_enable)
+      dw2 |= GEN75_SF_DW2_LINE_STIPPLE_ENABLE;
+
+   if (setup->scissor_enable)
+      dw2 |= GEN7_SF_DW2_SCISSOR_ENABLE;
+
+   dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE |
+         GEN7_SF_DW3_SUBPIXEL_8BITS;
+
+   /* this has no effect when line_width != 0 */
+   if (line->giq_last_pixel)
+      dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE;
+
+   if (setup->first_vertex_provoking) {
+      dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
+             0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
+             1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
+   } else {
+      dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
+             1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
+             2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
+   }
+
+   /* setup->point_aa_enable is ignored */
+   if (!point->programmable_width) {
+      dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH |
+             point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->sf) >= 3);
+   rs->sf[0] = dw1;
+   rs->sf[1] = dw2;
+   rs->sf[2] = dw3;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->raster) >= 4);
+   rs->raster[0] = 0;
+   rs->raster[1] = fui(params->depth_offset_const);
+   rs->raster[2] = fui(params->depth_offset_scale);
+   rs->raster[3] = fui(params->depth_offset_clamp);
+
+   rs->line_aa_enable = line->aa_enable;
+   rs->line_giq_enable = line->giq_enable;
+
+   return true;
+}
+
+static bool
+raster_set_gen8_3DSTATE_SF(struct ilo_state_raster *rs,
+                           const struct ilo_dev *dev,
+                           const struct ilo_state_raster_info *info,
+                           const struct ilo_state_raster_line_info *line)
+{
+   const struct ilo_state_raster_clip_info *clip = &info->clip;
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_point_info *point = &info->point;
+   const struct ilo_state_raster_params_info *params = &info->params;
+   const int line_width = get_gen6_line_width(dev, params->line_width,
+         line->aa_enable, line->giq_enable);
+   const int point_width = get_gen6_point_width(dev, params->point_width);
+   uint32_t dw1, dw2, dw3;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw1 = 0;
+
+   if (clip->stats_enable && clip->clip_enable)
+      dw1 |= GEN7_SF_DW1_STATISTICS;
+
+   if (setup->viewport_transform)
+      dw1 |= GEN7_SF_DW1_VIEWPORT_TRANSFORM;
+
+   dw2 = line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT |
+         GEN7_SF_DW2_AA_LINE_CAP_1_0;
+
+   dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE |
+         GEN7_SF_DW3_SUBPIXEL_8BITS;
+
+   /* this has no effect when line_width != 0 */
+   if (line->giq_last_pixel)
+      dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE;
+
+   if (setup->first_vertex_provoking) {
+      dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
+             0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
+             1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
+   } else {
+      dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
+             1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
+             2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
+   }
+
+   if (!point->programmable_width) {
+      dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH |
+             point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->sf) >= 3);
+   rs->sf[0] = dw1;
+   rs->sf[1] = dw2;
+   rs->sf[2] = dw3;
+
+   return true;
+}
+
+static bool
+raster_set_gen8_3DSTATE_RASTER(struct ilo_state_raster *rs,
+                               const struct ilo_dev *dev,
+                               const struct ilo_state_raster_info *info,
+                               const struct ilo_state_raster_line_info *line)
+{
+   const struct ilo_state_raster_clip_info *clip = &info->clip;
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_point_info *point = &info->point;
+   const struct ilo_state_raster_tri_info *tri = &info->tri;
+   const struct ilo_state_raster_params_info *params = &info->params;
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   if (!raster_validate_gen8_raster(dev, info))
+      return false;
+
+   dw1 = tri->front_winding << GEN8_RASTER_DW1_FRONT_WINDING__SHIFT |
+         tri->cull_mode << GEN8_RASTER_DW1_CULL_MODE__SHIFT |
+         tri->fill_mode_front << GEN8_RASTER_DW1_FILL_MODE_FRONT__SHIFT |
+         tri->fill_mode_back << GEN8_RASTER_DW1_FILL_MODE_BACK__SHIFT;
+
+   if (point->aa_enable)
+      dw1 |= GEN8_RASTER_DW1_SMOOTH_POINT_ENABLE;
+
+   /* where should line_msaa_enable be set? */
+   if (setup->msaa_enable)
+      dw1 |= GEN8_RASTER_DW1_API_MULTISAMPLE_ENABLE;
+
+   if (tri->depth_offset_solid)
+      dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_SOLID;
+   if (tri->depth_offset_wireframe)
+      dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_WIREFRAME;
+   if (tri->depth_offset_point)
+      dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_POINT;
+
+   if (line->aa_enable)
+      dw1 |= GEN8_RASTER_DW1_AA_LINE_ENABLE;
+
+   if (setup->scissor_enable)
+      dw1 |= GEN8_RASTER_DW1_SCISSOR_ENABLE;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(9)) {
+      if (clip->z_far_enable)
+         dw1 |= GEN9_RASTER_DW1_Z_TEST_FAR_ENABLE;
+      if (clip->z_near_enable)
+         dw1 |= GEN9_RASTER_DW1_Z_TEST_NEAR_ENABLE;
+   } else {
+      if (clip->z_near_enable)
+         dw1 |= GEN8_RASTER_DW1_Z_TEST_ENABLE;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->raster) >= 4);
+   rs->raster[0] = dw1;
+   rs->raster[1] = fui(params->depth_offset_const);
+   rs->raster[2] = fui(params->depth_offset_scale);
+   rs->raster[3] = fui(params->depth_offset_clamp);
+
+   rs->line_aa_enable = line->aa_enable;
+   rs->line_giq_enable = line->giq_enable;
+
+   return true;
+}
+
+static enum gen_sample_count
+get_gen6_sample_count(const struct ilo_dev *dev, uint8_t sample_count)
+{
+   enum gen_sample_count c;
+   int min_gen;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (sample_count) {
+   case 1:
+      c = GEN6_NUMSAMPLES_1;
+      min_gen = ILO_GEN(6);
+      break;
+   case 2:
+      c = GEN8_NUMSAMPLES_2;
+      min_gen = ILO_GEN(8);
+      break;
+   case 4:
+      c = GEN6_NUMSAMPLES_4;
+      min_gen = ILO_GEN(6);
+      break;
+   case 8:
+      c = GEN7_NUMSAMPLES_8;
+      min_gen = ILO_GEN(7);
+      break;
+   case 16:
+      c = GEN8_NUMSAMPLES_16;
+      min_gen = ILO_GEN(8);
+      break;
+   default:
+      assert(!"unexpected sample count");
+      c = GEN6_NUMSAMPLES_1;
+      break;
+   }
+
+   assert(ilo_dev_gen(dev) >= min_gen);
+
+   return c;
+}
+
+static bool
+raster_set_gen8_3DSTATE_MULTISAMPLE(struct ilo_state_raster *rs,
+                                    const struct ilo_dev *dev,
+                                    const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+   const enum gen_sample_count count =
+      get_gen6_sample_count(dev, scan->sample_count);
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 307:
+    *
+    *     "Setting Multisample Rasterization Mode to MSRASTMODE_xxx_PATTERN
+    *      when Number of Multisamples == NUMSAMPLES_1 is UNDEFINED."
+    */
+   if (setup->msaa_enable)
+      assert(scan->sample_count > 1);
+
+   dw1 = scan->pixloc << GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__SHIFT |
+         count << GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 1);
+   rs->sample[0] = dw1;
+
+   return true;
+}
+
+static bool
+raster_set_gen6_3DSTATE_SAMPLE_MASK(struct ilo_state_raster *rs,
+                                    const struct ilo_dev *dev,
+                                    const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 294:
+    *
+    *     "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field
+    *      (Sample Mask) must be zero.
+    *
+    *      If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field
+    *      must be zero."
+    */
+   const uint32_t mask = (1 << scan->sample_count) - 1;
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   dw1 = (scan->sample_mask & mask) << GEN6_SAMPLE_MASK_DW1_VAL__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 2);
+   rs->sample[1] = dw1;
+
+   return true;
+}
+
+static bool
+raster_validate_gen6_wm(const struct ilo_dev *dev,
+                        const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (ilo_dev_gen(dev) == ILO_GEN(6))
+      assert(scan->earlyz_control == GEN7_EDSC_NORMAL);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 272:
+    *
+    *     "This bit (Statistics Enable) must be disabled if either of these
+    *      bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve
+    *      Enable or Depth Buffer Resolve Enable."
+    */
+   if (scan->earlyz_op != ILO_STATE_RASTER_EARLYZ_NORMAL)
+      assert(!scan->stats_enable);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 273:
+    *
+    *     "If this field (Depth Buffer Resolve Enable) is enabled, the Depth
+    *      Buffer Clear and Hierarchical Depth Buffer Resolve Enable fields
+    *      must both be disabled."
+    *
+    *     "If this field (Hierarchical Depth Buffer Resolve Enable) is
+    *      enabled, the Depth Buffer Clear and Depth Buffer Resolve Enable
+    *      fields must both be disabled."
+    *
+    * This is guaranteed.
+    */
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 314-315:
+    *
+    *     "Stencil buffer clear can be performed at the same time by enabling
+    *      Stencil Buffer Write Enable."
+    *
+    *     "Note also that stencil buffer clear can be performed without depth
+    *      buffer clear."
+    */
+   if (scan->earlyz_stencil_clear) {
+      assert(scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_NORMAL ||
+             scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR);
+   }
+
+   return true;
+}
+
+static bool
+raster_set_gen6_3dstate_wm(struct ilo_state_raster *rs,
+                           const struct ilo_dev *dev,
+                           const struct ilo_state_raster_info *info,
+                           const struct ilo_state_raster_line_info *line)
+{
+   const struct ilo_state_raster_tri_info *tri = &info->tri;
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+   const enum gen_msrast_mode msrast =
+      raster_setup_get_gen6_msrast_mode(dev, setup);
+   /* only scan conversion states are set, as in Gen8+ */
+   uint32_t dw4, dw5, dw6;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   if (!raster_validate_gen6_wm(dev, info))
+      return false;
+
+   dw4 = 0;
+
+   if (scan->stats_enable)
+      dw4 |= GEN6_WM_DW4_STATISTICS;
+
+   switch (scan->earlyz_op) {
+   case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
+      dw4 |= GEN6_WM_DW4_DEPTH_CLEAR;
+      break;
+   case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
+      dw4 |= GEN6_WM_DW4_DEPTH_RESOLVE;
+      break;
+   case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
+      dw4 |= GEN6_WM_DW4_HIZ_RESOLVE;
+      break;
+   default:
+      if (scan->earlyz_stencil_clear)
+         dw4 |= GEN6_WM_DW4_DEPTH_CLEAR;
+      break;
+   }
+
+   dw5 = GEN6_WM_DW5_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */
+         GEN6_WM_DW5_AA_LINE_WIDTH_2_0;
+
+   if (tri->poly_stipple_enable)
+      dw5 |= GEN6_WM_DW5_POLY_STIPPLE_ENABLE;
+   if (line->stipple_enable)
+      dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE;
+
+   dw6 = scan->zw_interp << GEN6_WM_DW6_ZW_INTERP__SHIFT |
+         scan->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT |
+         GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT |
+         msrast << GEN6_WM_DW6_MSRASTMODE__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3);
+   rs->wm[0] = dw4;
+   rs->wm[1] = dw5;
+   rs->wm[2] = dw6;
+
+   return true;
+}
+
+static bool
+raster_set_gen8_3DSTATE_WM(struct ilo_state_raster *rs,
+                           const struct ilo_dev *dev,
+                           const struct ilo_state_raster_info *info,
+                           const struct ilo_state_raster_line_info *line)
+{
+   const struct ilo_state_raster_tri_info *tri = &info->tri;
+   const struct ilo_state_raster_setup_info *setup = &info->setup;
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+   const enum gen_msrast_mode msrast =
+      raster_setup_get_gen6_msrast_mode(dev, setup);
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!raster_validate_gen6_wm(dev, info))
+      return false;
+
+   dw1 = scan->earlyz_control << GEN7_WM_DW1_EDSC__SHIFT |
+         scan->zw_interp << GEN7_WM_DW1_ZW_INTERP__SHIFT |
+         scan->barycentric_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT |
+         GEN7_WM_DW1_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */
+         GEN7_WM_DW1_AA_LINE_WIDTH_2_0 |
+         GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
+
+   if (scan->stats_enable)
+      dw1 |= GEN7_WM_DW1_STATISTICS;
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8)) {
+      switch (scan->earlyz_op) {
+      case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
+         dw1 |= GEN7_WM_DW1_DEPTH_CLEAR;
+         break;
+      case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
+         dw1 |= GEN7_WM_DW1_DEPTH_RESOLVE;
+         break;
+      case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
+         dw1 |= GEN7_WM_DW1_HIZ_RESOLVE;
+         break;
+      default:
+         if (scan->earlyz_stencil_clear)
+            dw1 |= GEN7_WM_DW1_DEPTH_CLEAR;
+         break;
+      }
+   }
+
+   if (tri->poly_stipple_enable)
+      dw1 |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
+   if (line->stipple_enable)
+      dw1 |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8))
+      dw1 |= msrast << GEN7_WM_DW1_MSRASTMODE__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 1);
+   rs->wm[0] = dw1;
+
+   return true;
+}
+
+static bool
+raster_set_gen8_3dstate_wm_hz_op(struct ilo_state_raster *rs,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_raster_info *info)
+{
+   const struct ilo_state_raster_scan_info *scan = &info->scan;
+   const enum gen_sample_count count =
+      get_gen6_sample_count(dev, scan->sample_count);
+   const uint32_t mask = (1 << scan->sample_count) - 1;
+   uint32_t dw1, dw4;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw1 = count << GEN8_WM_HZ_DW1_NUM_SAMPLES__SHIFT;
+
+   if (scan->earlyz_stencil_clear)
+      dw1 |= GEN8_WM_HZ_DW1_STENCIL_CLEAR;
+
+   switch (scan->earlyz_op) {
+   case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
+      dw1 |= GEN8_WM_HZ_DW1_DEPTH_CLEAR;
+      break;
+   case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
+      dw1 |= GEN8_WM_HZ_DW1_DEPTH_RESOLVE;
+      break;
+   case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
+      dw1 |= GEN8_WM_HZ_DW1_HIZ_RESOLVE;
+      break;
+   default:
+      break;
+   }
+
+   dw4 = (scan->sample_mask & mask) << GEN8_WM_HZ_DW4_SAMPLE_MASK__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3);
+   rs->wm[1] = dw1;
+   rs->wm[2] = dw4;
+
+   return true;
+}
+
+static bool
+sample_pattern_get_gen6_packed_offsets(const struct ilo_dev *dev,
+                                       uint8_t sample_count,
+                                       const struct ilo_state_sample_pattern_offset_info *in,
+                                       uint8_t *out)
+{
+   uint8_t max_dist, i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   max_dist = 0;
+   for (i = 0; i < sample_count; i++) {
+      const int8_t dist_x = (int8_t) in[i].x - 8;
+      const int8_t dist_y = (int8_t) in[i].y - 8;
+      const uint8_t dist = dist_x * dist_x + dist_y * dist_y;
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 305:
+       *
+       *     "Programming Note: When programming the sample offsets (for
+       *      NUMSAMPLES_4 or _8 and MSRASTMODE_xxx_PATTERN), the order of the
+       *      samples 0 to 3 (or 7 for 8X) must have monotonically increasing
+       *      distance from the pixel center. This is required to get the
+       *      correct centroid computation in the device."
+       */
+      assert(dist >= max_dist);
+      max_dist = dist;
+
+      assert(in[i].x < 16);
+      assert(in[i].y < 16);
+
+      out[i] = in[i].x << 4 | in[i].y;
+   }
+
+   return true;
+}
+
+static bool
+line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(struct ilo_state_line_stipple *stipple,
+                                           const struct ilo_dev *dev,
+                                           const struct ilo_state_line_stipple_info *info)
+{
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(info->repeat_count >= 1 && info->repeat_count <= 256);
+
+   dw1 = info->pattern;
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      /* in U1.16 */
+      const uint32_t inverse = 65536 / info->repeat_count;
+      dw2 = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
+            info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT;
+   } else {
+      /* in U1.13 */
+      const uint16_t inverse = 8192 / info->repeat_count;
+      dw2 = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
+            info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 2);
+   stipple->stipple[0] = dw1;
+   stipple->stipple[1] = dw2;
+
+   return true;
+}
+
+static bool
+sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern *pattern,
+                                               const struct ilo_dev *dev,
+                                               const struct ilo_state_sample_pattern_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_1x) >= 1);
+   STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_2x) >= 2);
+   STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_4x) >= 4);
+   STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_8x) >= 8);
+   STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_16x) >= 16);
+
+   return (sample_pattern_get_gen6_packed_offsets(dev, 1,
+              info->pattern_1x, pattern->pattern_1x) &&
+           sample_pattern_get_gen6_packed_offsets(dev, 2,
+              info->pattern_2x, pattern->pattern_2x) &&
+           sample_pattern_get_gen6_packed_offsets(dev, 4,
+              info->pattern_4x, pattern->pattern_4x) &&
+           sample_pattern_get_gen6_packed_offsets(dev, 8,
+              info->pattern_8x, pattern->pattern_8x) &&
+           sample_pattern_get_gen6_packed_offsets(dev, 16,
+              info->pattern_16x, pattern->pattern_16x));
+
+}
+
+static bool
+poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_state_poly_stipple *stipple,
+                                                   const struct ilo_dev *dev,
+                                                   const struct ilo_state_poly_stipple_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 32);
+   memcpy(stipple->stipple, info->pattern, sizeof(info->pattern));
+
+   return true;
+}
+
+bool
+ilo_state_raster_init(struct ilo_state_raster *rs,
+                      const struct ilo_dev *dev,
+                      const struct ilo_state_raster_info *info)
+{
+   assert(ilo_is_zeroed(rs, sizeof(*rs)));
+   return ilo_state_raster_set_info(rs, dev, info);
+}
+
+bool
+ilo_state_raster_init_for_rectlist(struct ilo_state_raster *rs,
+                                   const struct ilo_dev *dev,
+                                   uint8_t sample_count,
+                                   enum ilo_state_raster_earlyz_op earlyz_op,
+                                   bool earlyz_stencil_clear)
+{
+   struct ilo_state_raster_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   info.clip.viewport_count = 1;
+   info.setup.cv_is_rectangle = true;
+   info.setup.msaa_enable = (sample_count > 1);
+   info.scan.sample_count = sample_count;
+   info.scan.sample_mask = ~0u;
+   info.scan.earlyz_op = earlyz_op;
+   info.scan.earlyz_stencil_clear = earlyz_stencil_clear;
+
+   return ilo_state_raster_init(rs, dev, &info);
+}
+
+bool
+ilo_state_raster_set_info(struct ilo_state_raster *rs,
+                          const struct ilo_dev *dev,
+                          const struct ilo_state_raster_info *info)
+{
+   struct ilo_state_raster_line_info line;
+   bool ret = true;
+
+   ret &= raster_set_gen6_3DSTATE_CLIP(rs, dev, info);
+
+   raster_get_gen6_effective_line(dev, info, &line);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      ret &= raster_set_gen8_3DSTATE_SF(rs, dev, info, &line);
+      ret &= raster_set_gen8_3DSTATE_RASTER(rs, dev, info, &line);
+   } else {
+      ret &= raster_set_gen7_3DSTATE_SF(rs, dev, info, &line);
+   }
+
+   ret &= raster_set_gen8_3DSTATE_MULTISAMPLE(rs, dev, info);
+   ret &= raster_set_gen6_3DSTATE_SAMPLE_MASK(rs, dev, info);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      ret &= raster_set_gen8_3DSTATE_WM(rs, dev, info, &line);
+
+      if (ilo_dev_gen(dev) >= ILO_GEN(8))
+         ret &= raster_set_gen8_3dstate_wm_hz_op(rs, dev, info);
+   } else {
+      ret &= raster_set_gen6_3dstate_wm(rs, dev, info, &line);
+   }
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_raster_set_params(struct ilo_state_raster *rs,
+                            const struct ilo_dev *dev,
+                            const struct ilo_state_raster_params_info *params)
+{
+   const bool line_aa_enable = (rs->line_aa_enable &&
+         raster_params_is_gen6_line_aa_allowed(dev, params));
+   const int line_width = get_gen6_line_width(dev, params->line_width,
+         line_aa_enable, rs->line_giq_enable);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* modify line AA enable */
+   if (rs->line_aa_enable) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+         if (line_aa_enable)
+            rs->raster[0] |= GEN8_RASTER_DW1_AA_LINE_ENABLE;
+         else
+            rs->raster[0] &= ~GEN8_RASTER_DW1_AA_LINE_ENABLE;
+      } else {
+         if (line_aa_enable)
+            rs->sf[1] |= GEN7_SF_DW2_AA_LINE_ENABLE;
+         else
+            rs->sf[1] &= ~GEN7_SF_DW2_AA_LINE_ENABLE;
+      }
+   }
+
+   /* modify line width */
+   rs->sf[1] = (rs->sf[1] & ~GEN7_SF_DW2_LINE_WIDTH__MASK) |
+               line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT;
+
+   /* modify point width */
+   if (rs->sf[2] & GEN7_SF_DW3_USE_POINT_WIDTH) {
+      const int point_width = get_gen6_point_width(dev, params->point_width);
+
+      rs->sf[2] = (rs->sf[2] & ~GEN7_SF_DW3_POINT_WIDTH__MASK) |
+                  point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
+   }
+
+   /* modify depth offset */
+   rs->raster[1] = fui(params->depth_offset_const);
+   rs->raster[2] = fui(params->depth_offset_scale);
+   rs->raster[3] = fui(params->depth_offset_clamp);
+
+   return true;
+}
+
+void
+ilo_state_raster_full_delta(const struct ilo_state_raster *rs,
+                            const struct ilo_dev *dev,
+                            struct ilo_state_raster_delta *delta)
+{
+   delta->dirty = ILO_STATE_RASTER_3DSTATE_CLIP |
+                  ILO_STATE_RASTER_3DSTATE_SF |
+                  ILO_STATE_RASTER_3DSTATE_MULTISAMPLE |
+                  ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK |
+                  ILO_STATE_RASTER_3DSTATE_WM |
+                  ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER |
+                      ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
+   }
+}
+
+void
+ilo_state_raster_get_delta(const struct ilo_state_raster *rs,
+                           const struct ilo_dev *dev,
+                           const struct ilo_state_raster *old,
+                           struct ilo_state_raster_delta *delta)
+{
+   delta->dirty = 0;
+
+   if (memcmp(rs->clip, old->clip, sizeof(rs->clip)))
+      delta->dirty |= ILO_STATE_RASTER_3DSTATE_CLIP;
+
+   if (memcmp(rs->sf, old->sf, sizeof(rs->sf)))
+      delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF;
+
+   if (memcmp(rs->raster, old->raster, sizeof(rs->raster))) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(8))
+         delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER;
+      else
+         delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF;
+   }
+
+   if (memcmp(rs->sample, old->sample, sizeof(rs->sample))) {
+      delta->dirty |= ILO_STATE_RASTER_3DSTATE_MULTISAMPLE |
+                      ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK;
+   }
+
+   if (memcmp(rs->wm, old->wm, sizeof(rs->wm))) {
+      delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM;
+
+      if (ilo_dev_gen(dev) >= ILO_GEN(8))
+         delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
+   }
+}
+
+bool
+ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_sample_pattern_info *info)
+{
+   bool ret = true;
+
+   ret &= sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(pattern, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern,
+                                      const struct ilo_dev *dev)
+{
+   static const struct ilo_state_sample_pattern_info default_info = {
+      .pattern_1x = {
+         {  8,  8 },
+      },
+
+      .pattern_2x = {
+         {  4,  4 }, { 12, 12 },
+      },
+
+      .pattern_4x = {
+         {  6,  2 }, { 14,  6 }, {  2, 10 }, { 10, 14 },
+      },
+
+      /* \see brw_multisample_positions_8x */
+      .pattern_8x = {
+         {  7,  9 }, {  9, 13 }, { 11,  3 }, { 13, 11 },
+         {  1,  7 }, {  5,  1 }, { 15,  5 }, {  3, 15 },
+      },
+
+      .pattern_16x = {
+         {  8, 10 }, { 11,  8 }, {  5,  6 }, {  6,  4 },
+         { 12, 11 }, { 13,  9 }, { 14,  7 }, { 10,  2 },
+         {  4, 13 }, {  3,  3 }, {  7,  1 }, { 15,  5 },
+         {  1, 12 }, {  9,  0 }, {  2, 14 }, {  0, 15 },
+      },
+   };
+
+   return ilo_state_sample_pattern_init(pattern, dev, &default_info);
+}
+
+const uint8_t *
+ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern,
+                                            const struct ilo_dev *dev,
+                                            uint8_t sample_count)
+{
+   switch (sample_count) {
+   case 1:  return pattern->pattern_1x;
+   case 2:  return pattern->pattern_2x;
+   case 4:  return pattern->pattern_4x;
+   case 8:  return pattern->pattern_8x;
+   case 16: return pattern->pattern_16x;
+   default:
+      assert(!"unknown sample count");
+      return NULL;
+   }
+}
+
+void
+ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern,
+                                    const struct ilo_dev *dev,
+                                    uint8_t sample_count, uint8_t sample_index,
+                                    uint8_t *x, uint8_t *y)
+{
+   const const uint8_t *packed =
+      ilo_state_sample_pattern_get_packed_offsets(pattern, dev, sample_count);
+
+   assert(sample_index < sample_count);
+
+   *x = (packed[sample_index] >> 4) & 0xf;
+   *y = packed[sample_index] & 0xf;
+}
+
+/**
+ * No need to initialize first.
+ */
+bool
+ilo_state_line_stipple_set_info(struct ilo_state_line_stipple *stipple,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_line_stipple_info *info)
+{
+   bool ret = true;
+
+   ret &= line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(stipple,
+         dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+/**
+ * No need to initialize first.
+ */
+bool
+ilo_state_poly_stipple_set_info(struct ilo_state_poly_stipple *stipple,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_poly_stipple_info *info)
+{
+   bool ret = true;
+
+   ret &= poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(stipple,
+         dev, info);
+
+   assert(ret);
+
+   return ret;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_raster.h b/src/gallium/drivers/ilo/core/ilo_state_raster.h
new file mode 100644 (file)
index 0000000..fc90b49
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_RASTER_H
+#define ILO_STATE_RASTER_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+enum ilo_state_raster_dirty_bits {
+   ILO_STATE_RASTER_3DSTATE_CLIP                   = (1 << 0),
+   ILO_STATE_RASTER_3DSTATE_SF                     = (1 << 1),
+   ILO_STATE_RASTER_3DSTATE_RASTER                 = (1 << 2),
+   ILO_STATE_RASTER_3DSTATE_MULTISAMPLE            = (1 << 3),
+   ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK            = (1 << 4),
+   ILO_STATE_RASTER_3DSTATE_WM                     = (1 << 5),
+   ILO_STATE_RASTER_3DSTATE_WM_HZ_OP               = (1 << 6),
+   ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS     = (1 << 7),
+};
+
+enum ilo_state_raster_earlyz_op {
+   ILO_STATE_RASTER_EARLYZ_NORMAL,
+   ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR,
+   ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE,
+   ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE,
+};
+
+/**
+ * VUE readback, VertexClipTest, ClipDetermination, and primitive output.
+ */
+struct ilo_state_raster_clip_info {
+   bool clip_enable;
+   /* CL_INVOCATION_COUNT and CL_PRIMITIVES_COUNT */
+   bool stats_enable;
+
+   uint8_t viewport_count;
+   bool force_rtaindex_zero;
+
+   /* these should be mutually exclusive */
+   uint8_t user_cull_enables;
+   uint8_t user_clip_enables;
+
+   bool gb_test_enable;
+   bool xy_test_enable;
+
+   /* far/near must be enabled together prior to Gen9 */
+   bool z_far_enable;
+   bool z_near_enable;
+   bool z_near_zero;
+};
+
+/**
+ * Primitive assembly, viewport transformation, scissoring, MSAA, etc.
+ */
+struct ilo_state_raster_setup_info {
+   bool cv_is_rectangle;
+
+   bool first_vertex_provoking;
+   bool viewport_transform;
+
+   bool scissor_enable;
+
+   /* MSAA enables for lines and non-lines */
+   bool msaa_enable;
+   bool line_msaa_enable;
+};
+
+/**
+ * 3DOBJ_POINT rasterization rules.
+ */
+struct ilo_state_raster_point_info {
+   /* ignored when msaa_enable is set */
+   bool aa_enable;
+
+   bool programmable_width;
+};
+
+/**
+ * 3DOBJ_LINE rasterization rules.
+ */
+struct ilo_state_raster_line_info {
+   /* ignored when line_msaa_enable is set */
+   bool aa_enable;
+
+   /* ignored when line_msaa_enable or aa_enable is set */
+   bool stipple_enable;
+   bool giq_enable;
+   bool giq_last_pixel;
+};
+
+/**
+ * 3DOBJ_TRIANGLE rasterization rules.
+ */
+struct ilo_state_raster_tri_info {
+   enum gen_front_winding front_winding;
+   enum gen_cull_mode cull_mode;
+   enum gen_fill_mode fill_mode_front;
+   enum gen_fill_mode fill_mode_back;
+
+   enum gen_depth_format depth_offset_format;
+   bool depth_offset_solid;
+   bool depth_offset_wireframe;
+   bool depth_offset_point;
+
+   bool poly_stipple_enable;
+};
+
+/**
+ * Scan conversion.
+ */
+struct ilo_state_raster_scan_info {
+   /* PS_DEPTH_COUNT and PS_INVOCATION_COUNT */
+   bool stats_enable;
+
+   uint8_t sample_count;
+
+   /* pixel location for non-MSAA or 1x-MSAA */
+   enum gen_pixel_location pixloc;
+
+   uint32_t sample_mask;
+
+   /* interpolations */
+   enum gen_zw_interp zw_interp;
+   uint8_t barycentric_interps;
+
+   /* Gen7+ only */
+   enum gen_edsc_mode earlyz_control;
+   enum ilo_state_raster_earlyz_op earlyz_op;
+   bool earlyz_stencil_clear;
+};
+
+/**
+ * Raster parameters.
+ */
+struct ilo_state_raster_params_info {
+   bool any_integer_rt;
+   bool hiz_enable;
+
+   float point_width;
+   float line_width;
+
+   /* const term will be scaled by 'r' */
+   float depth_offset_const;
+   float depth_offset_scale;
+   float depth_offset_clamp;
+};
+
+struct ilo_state_raster_info {
+   struct ilo_state_raster_clip_info clip;
+   struct ilo_state_raster_setup_info setup;
+   struct ilo_state_raster_point_info point;
+   struct ilo_state_raster_line_info line;
+   struct ilo_state_raster_tri_info tri;
+   struct ilo_state_raster_scan_info scan;
+
+   struct ilo_state_raster_params_info params;
+};
+
+struct ilo_state_raster {
+   uint32_t clip[3];
+   uint32_t sf[3];
+   uint32_t raster[4];
+   uint32_t sample[2];
+   uint32_t wm[3];
+
+   bool line_aa_enable;
+   bool line_giq_enable;
+};
+
+struct ilo_state_raster_delta {
+   uint32_t dirty;
+};
+
+struct ilo_state_sample_pattern_offset_info {
+   /* in U0.4 */
+   uint8_t x;
+   uint8_t y;
+};
+
+struct ilo_state_sample_pattern_info {
+   struct ilo_state_sample_pattern_offset_info pattern_1x[1];
+   struct ilo_state_sample_pattern_offset_info pattern_2x[2];
+   struct ilo_state_sample_pattern_offset_info pattern_4x[4];
+   struct ilo_state_sample_pattern_offset_info pattern_8x[8];
+   struct ilo_state_sample_pattern_offset_info pattern_16x[16];
+};
+
+struct ilo_state_sample_pattern {
+   uint8_t pattern_1x[1];
+   uint8_t pattern_2x[2];
+   uint8_t pattern_4x[4];
+   uint8_t pattern_8x[8];
+   uint8_t pattern_16x[16];
+};
+
+struct ilo_state_line_stipple_info {
+   uint16_t pattern;
+   uint16_t repeat_count;
+};
+
+struct ilo_state_line_stipple {
+   uint32_t stipple[2];
+};
+
+struct ilo_state_poly_stipple_info {
+   uint32_t pattern[32];
+};
+
+struct ilo_state_poly_stipple {
+   uint32_t stipple[32];
+};
+
+bool
+ilo_state_raster_init(struct ilo_state_raster *rs,
+                      const struct ilo_dev *dev,
+                      const struct ilo_state_raster_info *info);
+
+bool
+ilo_state_raster_init_for_rectlist(struct ilo_state_raster *rs,
+                                   const struct ilo_dev *dev,
+                                   uint8_t sample_count,
+                                   enum ilo_state_raster_earlyz_op earlyz_op,
+                                   bool earlyz_stencil_clear);
+
+bool
+ilo_state_raster_set_info(struct ilo_state_raster *rs,
+                          const struct ilo_dev *dev,
+                          const struct ilo_state_raster_info *info);
+
+bool
+ilo_state_raster_set_params(struct ilo_state_raster *rs,
+                            const struct ilo_dev *dev,
+                            const struct ilo_state_raster_params_info *params);
+
+void
+ilo_state_raster_full_delta(const struct ilo_state_raster *rs,
+                            const struct ilo_dev *dev,
+                            struct ilo_state_raster_delta *delta);
+
+void
+ilo_state_raster_get_delta(const struct ilo_state_raster *rs,
+                           const struct ilo_dev *dev,
+                           const struct ilo_state_raster *old,
+                           struct ilo_state_raster_delta *delta);
+
+bool
+ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_sample_pattern_info *info);
+
+bool
+ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern,
+                                      const struct ilo_dev *dev);
+
+const uint8_t *
+ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern,
+                                            const struct ilo_dev *dev,
+                                            uint8_t sample_count);
+
+void
+ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern,
+                                    const struct ilo_dev *dev,
+                                    uint8_t sample_count, uint8_t sample_index,
+                                    uint8_t *x, uint8_t *y);
+bool
+ilo_state_line_stipple_set_info(struct ilo_state_line_stipple *stipple,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_line_stipple_info *info);
+
+bool
+ilo_state_poly_stipple_set_info(struct ilo_state_poly_stipple *stipple,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_poly_stipple_info *info);
+
+#endif /* ILO_STATE_RASTER_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sampler.c b/src/gallium/drivers/ilo/core/ilo_state_sampler.c
new file mode 100644 (file)
index 0000000..3787f68
--- /dev/null
@@ -0,0 +1,742 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_half.h"
+
+#include "ilo_debug.h"
+#include "ilo_state_surface.h"
+#include "ilo_state_sampler.h"
+
+static bool
+sampler_validate_gen6_non_normalized(const struct ilo_dev *dev,
+                                     const struct ilo_state_sampler_info *info)
+{
+   const enum gen_texcoord_mode addr_ctrls[3] = {
+      info->tcx_ctrl, info->tcy_ctrl, info->tcz_ctrl,
+   };
+   int i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 98:
+    *
+    *     "The following state must be set as indicated if this field
+    *      (Non-normalized Coordinate Enable) is enabled:
+    *
+    *      - TCX/Y/Z Address Control Mode must be TEXCOORDMODE_CLAMP,
+    *        TEXCOORDMODE_HALF_BORDER, or TEXCOORDMODE_CLAMP_BORDER.
+    *      - Surface Type must be SURFTYPE_2D or SURFTYPE_3D.
+    *      - Mag Mode Filter must be MAPFILTER_NEAREST or
+    *        MAPFILTER_LINEAR.
+    *      - Min Mode Filter must be MAPFILTER_NEAREST or
+    *        MAPFILTER_LINEAR.
+    *      - Mip Mode Filter must be MIPFILTER_NONE.
+    *      - Min LOD must be 0.
+    *      - Max LOD must be 0.
+    *      - MIP Count must be 0.
+    *      - Surface Min LOD must be 0.
+    *      - Texture LOD Bias must be 0."
+    */
+   for (i = 0; i < 3; i++) {
+      switch (addr_ctrls[i]) {
+      case GEN6_TEXCOORDMODE_CLAMP:
+      case GEN6_TEXCOORDMODE_CLAMP_BORDER:
+      case GEN8_TEXCOORDMODE_HALF_BORDER:
+         break;
+      default:
+         assert(!"bad non-normalized coordinate wrap mode");
+         break;
+      }
+   }
+
+   assert(info->mip_filter == GEN6_MIPFILTER_NONE);
+
+   assert((info->min_filter == GEN6_MAPFILTER_NEAREST ||
+           info->min_filter == GEN6_MAPFILTER_LINEAR) &&
+          (info->mag_filter == GEN6_MAPFILTER_NEAREST ||
+           info->mag_filter == GEN6_MAPFILTER_LINEAR));
+
+   assert(info->min_lod == 0.0f &&
+          info->max_lod == 0.0f &&
+          info->lod_bias == 0.0f);
+
+   return true;
+}
+
+static bool
+sampler_validate_gen6_sampler(const struct ilo_dev *dev,
+                              const struct ilo_state_sampler_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (info->non_normalized &&
+       !sampler_validate_gen6_non_normalized(dev, info))
+      return false;
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8)) {
+       assert(info->tcx_ctrl != GEN8_TEXCOORDMODE_HALF_BORDER &&
+              info->tcy_ctrl != GEN8_TEXCOORDMODE_HALF_BORDER &&
+              info->tcz_ctrl != GEN8_TEXCOORDMODE_HALF_BORDER);
+   }
+
+   return true;
+}
+
+static uint32_t
+sampler_get_gen6_integer_filters(const struct ilo_dev *dev,
+                                 const struct ilo_state_sampler_info *info)
+{
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 103:
+    *
+    *     "MIPFILTER_LINEAR is not supported for surface formats that do not
+    *      support "Sampling Engine Filtering" as indicated in the Surface
+    *      Formats table unless using the sample_c message type."
+    *
+    *     "Only MAPFILTER_NEAREST is supported for surface formats that do not
+    *      support "Sampling Engine Filtering" as indicated in the Surface
+    *      Formats table unless using the sample_c message type.
+    */
+   const enum gen_mip_filter mip_filter =
+      (info->mip_filter == GEN6_MIPFILTER_LINEAR) ?
+      GEN6_MIPFILTER_NEAREST : info->mip_filter;
+   const enum gen_map_filter min_filter = GEN6_MAPFILTER_NEAREST;
+   const enum gen_map_filter mag_filter = GEN6_MAPFILTER_NEAREST;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return mip_filter << GEN6_SAMPLER_DW0_MIP_FILTER__SHIFT |
+          mag_filter << GEN6_SAMPLER_DW0_MAG_FILTER__SHIFT |
+          min_filter << GEN6_SAMPLER_DW0_MIN_FILTER__SHIFT;
+}
+
+static uint32_t
+sampler_get_gen6_3d_filters(const struct ilo_dev *dev,
+                            const struct ilo_state_sampler_info *info)
+{
+   const enum gen_mip_filter mip_filter = info->mip_filter;
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 103:
+    *
+    *     "Only MAPFILTER_NEAREST and MAPFILTER_LINEAR are supported for
+    *      surfaces of type SURFTYPE_3D."
+    */
+   const enum gen_map_filter min_filter =
+      (info->min_filter == GEN6_MAPFILTER_NEAREST ||
+       info->min_filter == GEN6_MAPFILTER_LINEAR) ?
+      info->min_filter : GEN6_MAPFILTER_LINEAR;
+   const enum gen_map_filter mag_filter =
+      (info->mag_filter == GEN6_MAPFILTER_NEAREST ||
+       info->mag_filter == GEN6_MAPFILTER_LINEAR) ?
+       info->mag_filter : GEN6_MAPFILTER_LINEAR;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return mip_filter << GEN6_SAMPLER_DW0_MIP_FILTER__SHIFT |
+          mag_filter << GEN6_SAMPLER_DW0_MAG_FILTER__SHIFT |
+          min_filter << GEN6_SAMPLER_DW0_MIN_FILTER__SHIFT;
+}
+
+static uint32_t
+get_gen6_addr_controls(const struct ilo_dev *dev,
+                       enum gen_texcoord_mode tcx_ctrl,
+                       enum gen_texcoord_mode tcy_ctrl,
+                       enum gen_texcoord_mode tcz_ctrl)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      return tcx_ctrl << GEN7_SAMPLER_DW3_U_WRAP__SHIFT |
+             tcy_ctrl << GEN7_SAMPLER_DW3_V_WRAP__SHIFT |
+             tcz_ctrl << GEN7_SAMPLER_DW3_R_WRAP__SHIFT;
+   } else {
+      return tcx_ctrl << GEN6_SAMPLER_DW1_U_WRAP__SHIFT |
+             tcy_ctrl << GEN6_SAMPLER_DW1_V_WRAP__SHIFT |
+             tcz_ctrl << GEN6_SAMPLER_DW1_R_WRAP__SHIFT;
+   }
+}
+
+static uint32_t
+sampler_get_gen6_1d_addr_controls(const struct ilo_dev *dev,
+                                  const struct ilo_state_sampler_info *info)
+{
+   const enum gen_texcoord_mode tcx_ctrl =
+      (info->tcx_ctrl == GEN6_TEXCOORDMODE_CUBE) ?
+      GEN6_TEXCOORDMODE_CLAMP : info->tcx_ctrl;
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 100:
+    *
+    *     "If this field (TCY Address Control Mode) is set to
+    *      TEXCOORDMODE_CLAMP_BORDER or TEXCOORDMODE_HALF_BORDER and a 1D
+    *      surface is sampled, incorrect blending with the border color in the
+    *      vertical direction may occur."
+    */
+   const enum gen_texcoord_mode tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+   const enum gen_texcoord_mode tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return get_gen6_addr_controls(dev, tcx_ctrl, tcy_ctrl, tcz_ctrl);
+}
+
+static uint32_t
+sampler_get_gen6_2d_3d_addr_controls(const struct ilo_dev *dev,
+                                     const struct ilo_state_sampler_info *info)
+{
+   const enum gen_texcoord_mode tcx_ctrl =
+      (info->tcx_ctrl == GEN6_TEXCOORDMODE_CUBE) ?
+      GEN6_TEXCOORDMODE_CLAMP : info->tcx_ctrl;
+   const enum gen_texcoord_mode tcy_ctrl =
+      (info->tcy_ctrl == GEN6_TEXCOORDMODE_CUBE) ?
+      GEN6_TEXCOORDMODE_CLAMP : info->tcy_ctrl;
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 108:
+    *
+    *     "[DevSNB]: if this field (TCZ Address Control Mode) is set to
+    *      TEXCOORDMODE_CLAMP_BORDER samples outside the map will clamp to 0
+    *      instead of boarder color"
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 100:
+    *
+    *     "If this field is set to TEXCOORDMODE_CLAMP_BORDER for 3D maps on
+    *      formats without an alpha channel, samples straddling the map in the
+    *      Z direction may have their alpha channels off by 1."
+    *
+    * Do we want to do something here?
+    */
+   const enum gen_texcoord_mode tcz_ctrl =
+      (info->tcz_ctrl == GEN6_TEXCOORDMODE_CUBE) ?
+      GEN6_TEXCOORDMODE_CLAMP : info->tcz_ctrl;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return get_gen6_addr_controls(dev, tcx_ctrl, tcy_ctrl, tcz_ctrl);
+}
+
+static uint32_t
+sampler_get_gen6_cube_addr_controls(const struct ilo_dev *dev,
+                                    const struct ilo_state_sampler_info *info)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 99:
+    *
+    *     "When using cube map texture coordinates, only TEXCOORDMODE_CLAMP
+    *      and TEXCOORDMODE_CUBE settings are valid, and each TC component
+    *      must have the same Address Control mode.
+    *
+    *      When TEXCOORDMODE_CUBE is not used accessing a cube map, the map's
+    *      Cube Face Enable field must be programmed to 111111b (all faces
+    *      enabled)."
+    *
+    * From the Haswell PRM, volume 2d, page 278:
+    *
+    *     "When using cube map texture coordinates, each TC component must
+    *      have the same Address Control Mode.
+    *
+    *      When TEXCOORDMODE_CUBE is not used accessing a cube map, the map's
+    *      Cube Face Enable field must be programmed to 111111b (all faces
+    *      enabled)."
+    *
+    * We always enable all cube faces and only need to make sure all address
+    * control modes are the same.
+    */
+   const enum gen_texcoord_mode tcx_ctrl =
+      (ilo_dev_gen(dev) >= ILO_GEN(7.5) ||
+       info->tcx_ctrl == GEN6_TEXCOORDMODE_CUBE ||
+       info->tcx_ctrl == GEN6_TEXCOORDMODE_CLAMP) ?
+      info->tcx_ctrl : GEN6_TEXCOORDMODE_CLAMP;
+   const enum gen_texcoord_mode tcy_ctrl = tcx_ctrl;
+   const enum gen_texcoord_mode tcz_ctrl = tcx_ctrl;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return get_gen6_addr_controls(dev, tcx_ctrl, tcy_ctrl, tcz_ctrl);
+}
+
+static uint16_t
+get_gen6_lod_bias(const struct ilo_dev *dev, float bias)
+{
+   /* [-16.0, 16.0) in S4.6 or S4.8 */
+   const int fbits = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 8 : 6;
+   const float max = 16.0f;
+   const float scale = (float) (1 << fbits);
+   const int mask = (1 << (1 + 4 + fbits)) - 1;
+   const int scaled_max = (16 << fbits) - 1;
+   int scaled;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (bias > max)
+      bias = max;
+   else if (bias < -max)
+      bias = -max;
+
+   scaled = (int) (bias * scale);
+   if (scaled > scaled_max)
+      scaled = scaled_max;
+
+   return (scaled & mask);
+}
+
+static uint16_t
+get_gen6_lod_clamp(const struct ilo_dev *dev, float clamp)
+{
+   /* [0.0, 13.0] in U4.6 or [0.0, 14.0] in U4.8 */
+   const int fbits = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 8 : 6;
+   const float max = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 14.0f : 13.0f;
+   const float scale = (float) (1 << fbits);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (clamp > max)
+      clamp = max;
+   else if (clamp < 0.0f)
+      clamp = 0.0f;
+
+   return (int) (clamp * scale);
+}
+
+static bool
+sampler_set_gen6_SAMPLER_STATE(struct ilo_state_sampler *sampler,
+                               const struct ilo_dev *dev,
+                               const struct ilo_state_sampler_info *info)
+{
+   uint16_t lod_bias, max_lod, min_lod;
+   uint32_t dw0, dw1, dw3;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!sampler_validate_gen6_sampler(dev, info))
+      return false;
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 15:
+    *
+    *     "The per-pixel LOD is computed in an implementation-dependent manner
+    *      and approximates the log2 of the texel/pixel ratio at the given
+    *      pixel. The computation is typically based on the differential
+    *      texel-space distances associated with a one-pixel differential
+    *      distance along the screen x- and y-axes. These texel-space
+    *      distances are computed by evaluating neighboring pixel texture
+    *      coordinates, these coordinates being in units of texels on the base
+    *      MIP level (multiplied by the corresponding surface size in
+    *      texels)."
+    *
+    * Judging from the LOD computation pseudocode on page 16-18, the "base MIP
+    * level" should be given by SurfMinLod.  To summarize, for the "sample"
+    * message,
+    *
+    *   1) LOD is set to log2(texel/pixel ratio).  The number of texels is
+    *      measured against level SurfMinLod.
+    *   2) Bias is added to LOD.
+    *   3) if pre-clamp is enabled, LOD is clamped to [MinLod, MaxLod] first
+    *   4) LOD is compared with Base to determine whether magnification or
+    *      minification is needed.
+    *   5) If magnification is needed, or no mipmapping is requested, LOD is
+    *      set to floor(MinLod).
+    *   6) LOD is clamped to [0, MIPCnt], and SurfMinLod is added to LOD.
+    *
+    * As an example, we could set SurfMinLod to GL_TEXTURE_BASE_LEVEL and Base
+    * to 0 to match GL.  But GL expects LOD to be set to 0, instead of
+    * floor(MinLod), in 5).  Since this is only an issue when MinLod is
+    * greater than or equal to one, and, with Base being 0, a non-zero MinLod
+    * implies minification, we only need to deal with the case when mipmapping
+    * is disabled.  We can thus do:
+    *
+    *   if (MipFilter == MIPFILTER_NONE && MinLod) {
+    *     MinLod = 0;
+    *     MagFilter = MinFilter;
+    *   }
+    */
+
+   lod_bias = get_gen6_lod_bias(dev, info->lod_bias);
+   min_lod = get_gen6_lod_clamp(dev, info->min_lod);
+   max_lod = get_gen6_lod_clamp(dev, info->max_lod);
+
+   dw0 = GEN6_SAMPLER_DW0_LOD_PRECLAMP_ENABLE |
+         0 << GEN6_SAMPLER_DW0_BASE_LOD__SHIFT |
+         info->mip_filter << GEN6_SAMPLER_DW0_MIP_FILTER__SHIFT |
+         info->mag_filter << GEN6_SAMPLER_DW0_MAG_FILTER__SHIFT |
+         info->min_filter << GEN6_SAMPLER_DW0_MIN_FILTER__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      dw0 |= GEN7_SAMPLER_DW0_BORDER_COLOR_MODE_DX10_OGL |
+             lod_bias << GEN7_SAMPLER_DW0_LOD_BIAS__SHIFT;
+
+      if (info->min_filter == GEN6_MAPFILTER_ANISOTROPIC ||
+          info->mag_filter == GEN6_MAPFILTER_ANISOTROPIC)
+         dw0 |= GEN7_SAMPLER_DW0_ANISO_ALGO_EWA;
+   } else {
+      dw0 |= lod_bias << GEN6_SAMPLER_DW0_LOD_BIAS__SHIFT |
+             info->shadow_func << GEN6_SAMPLER_DW0_SHADOW_FUNC__SHIFT;
+
+      /*
+       * From the Sandy Bridge PRM, volume 4 part 1, page 102:
+       *
+       *     "(Min and Mag State Not Equal) Must be set to 1 if any of the
+       *      following are true:
+       *
+       *      - Mag Mode Filter and Min Mode Filter are not the same
+       *      - Address Rounding Enable: U address mag filter and U address
+       *        min filter are not the same
+       *      - Address Rounding Enable: V address mag filter and V address
+       *        min filter are not the same
+       *      - Address Rounding Enable: R address mag filter and R address
+       *        min filter are not the same"
+       *
+       * We set address rounding for U, V, and R uniformly.  Only need to
+       * check the filters.
+       */
+      if (info->min_filter != info->mag_filter)
+         dw0 |= GEN6_SAMPLER_DW0_MIN_MAG_NOT_EQUAL;
+   }
+
+   dw1 = 0;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      /*
+       * From the Ivy Bridge PRM, volume 4 part 1, page 96:
+       *
+       *     "This field (Cube Surface Control Mode) must be set to
+       *      CUBECTRLMODE_PROGRAMMED"
+       */
+      dw1 |= min_lod << GEN7_SAMPLER_DW1_MIN_LOD__SHIFT |
+             max_lod << GEN7_SAMPLER_DW1_MAX_LOD__SHIFT |
+             info->shadow_func << GEN7_SAMPLER_DW1_SHADOW_FUNC__SHIFT |
+             GEN7_SAMPLER_DW1_CUBECTRLMODE_PROGRAMMED;
+   } else {
+      dw1 |= min_lod << GEN6_SAMPLER_DW1_MIN_LOD__SHIFT |
+             max_lod << GEN6_SAMPLER_DW1_MAX_LOD__SHIFT |
+             GEN6_SAMPLER_DW1_CUBECTRLMODE_PROGRAMMED |
+             info->tcx_ctrl << GEN6_SAMPLER_DW1_U_WRAP__SHIFT |
+             info->tcy_ctrl << GEN6_SAMPLER_DW1_V_WRAP__SHIFT |
+             info->tcz_ctrl << GEN6_SAMPLER_DW1_R_WRAP__SHIFT;
+   }
+
+   dw3 = info->max_anisotropy << GEN6_SAMPLER_DW3_MAX_ANISO__SHIFT;
+
+   /* round the coordinates for linear filtering */
+   if (info->min_filter != GEN6_MAPFILTER_NEAREST) {
+      dw3 |= GEN6_SAMPLER_DW3_U_MIN_ROUND |
+             GEN6_SAMPLER_DW3_V_MIN_ROUND |
+             GEN6_SAMPLER_DW3_R_MIN_ROUND;
+   }
+   if (info->mag_filter != GEN6_MAPFILTER_NEAREST) {
+      dw3 |= GEN6_SAMPLER_DW3_U_MAG_ROUND |
+             GEN6_SAMPLER_DW3_V_MAG_ROUND |
+             GEN6_SAMPLER_DW3_R_MAG_ROUND;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      dw3 |= GEN7_SAMPLER_DW3_TRIQUAL_FULL |
+             info->tcx_ctrl << GEN7_SAMPLER_DW3_U_WRAP__SHIFT |
+             info->tcy_ctrl << GEN7_SAMPLER_DW3_V_WRAP__SHIFT |
+             info->tcz_ctrl << GEN7_SAMPLER_DW3_R_WRAP__SHIFT;
+
+      if (info->non_normalized)
+         dw3 |= GEN7_SAMPLER_DW3_NON_NORMALIZED_COORD;
+   } else {
+      if (info->non_normalized)
+         dw3 |= GEN6_SAMPLER_DW3_NON_NORMALIZED_COORD;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(sampler->sampler) >= 3);
+   sampler->sampler[0] = dw0;
+   sampler->sampler[1] = dw1;
+   sampler->sampler[2] = dw3;
+
+   sampler->filter_integer = sampler_get_gen6_integer_filters(dev, info);
+   sampler->filter_3d = sampler_get_gen6_3d_filters(dev, info);
+   sampler->addr_ctrl_1d = sampler_get_gen6_1d_addr_controls(dev, info);
+   sampler->addr_ctrl_2d_3d = sampler_get_gen6_2d_3d_addr_controls(dev, info);
+   sampler->addr_ctrl_cube = sampler_get_gen6_cube_addr_controls(dev, info);
+
+   sampler->non_normalized = info->non_normalized;
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 21:
+    *
+    *     "[DevSNB] Errata: Incorrect behavior is observed in cases where the
+    *      min and mag mode filters are different and SurfMinLOD is nonzero.
+    *      The determination of MagMode uses the following equation instead of
+    *      the one in the above pseudocode:
+    *
+    *      MagMode = (LOD + SurfMinLOD - Base <= 0)"
+    *
+    * As a way to work around that, request Base to be set to SurfMinLod.
+    */
+   if (ilo_dev_gen(dev) == ILO_GEN(6) &&
+       info->min_filter != info->mag_filter)
+      sampler->base_to_surf_min_lod = true;
+
+   return true;
+}
+
+static bool
+sampler_border_set_gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_state_sampler_border *border,
+                                                   const struct ilo_dev *dev,
+                                                   const struct ilo_state_sampler_border_info *info)
+{
+   uint32_t dw[12];
+   float rgba[4];
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 117:
+    *
+    *     "For ([DevSNB]), if border color is used, all formats must be
+    *      provided.  Hardware will choose the appropriate format based on
+    *      Surface Format and Texture Border Color Mode. The values
+    *      represented by each format should be the same (other than being
+    *      subject to range-based clamping and precision) to avoid unexpected
+    *      behavior."
+    *
+    * XXX We do not honor info->is_integer yet.
+    */
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   /* make a copy so that we can clamp for SNORM and UNORM */
+   memcpy(rgba, info->rgba.f, sizeof(rgba));
+
+   /* IEEE_FP */
+   dw[1] = fui(rgba[0]);
+   dw[2] = fui(rgba[1]);
+   dw[3] = fui(rgba[2]);
+   dw[4] = fui(rgba[3]);
+
+   /* FLOAT_16 */
+   dw[5] = util_float_to_half(rgba[0]) |
+           util_float_to_half(rgba[1]) << 16;
+   dw[6] = util_float_to_half(rgba[2]) |
+           util_float_to_half(rgba[3]) << 16;
+
+   /* clamp to [-1.0f, 1.0f] */
+   rgba[0] = CLAMP(rgba[0], -1.0f, 1.0f);
+   rgba[1] = CLAMP(rgba[1], -1.0f, 1.0f);
+   rgba[2] = CLAMP(rgba[2], -1.0f, 1.0f);
+   rgba[3] = CLAMP(rgba[3], -1.0f, 1.0f);
+
+   /* SNORM16 */
+   dw[9] =  (int16_t) util_iround(rgba[0] * 32767.0f) |
+            (int16_t) util_iround(rgba[1] * 32767.0f) << 16;
+   dw[10] = (int16_t) util_iround(rgba[2] * 32767.0f) |
+            (int16_t) util_iround(rgba[3] * 32767.0f) << 16;
+
+   /* SNORM8 */
+   dw[11] = (int8_t) util_iround(rgba[0] * 127.0f) |
+            (int8_t) util_iround(rgba[1] * 127.0f) << 8 |
+            (int8_t) util_iround(rgba[2] * 127.0f) << 16 |
+            (int8_t) util_iround(rgba[3] * 127.0f) << 24;
+
+   /* clamp to [0.0f, 1.0f] */
+   rgba[0] = CLAMP(rgba[0], 0.0f, 1.0f);
+   rgba[1] = CLAMP(rgba[1], 0.0f, 1.0f);
+   rgba[2] = CLAMP(rgba[2], 0.0f, 1.0f);
+   rgba[3] = CLAMP(rgba[3], 0.0f, 1.0f);
+
+   /* UNORM8 */
+   dw[0] = (uint8_t) util_iround(rgba[0] * 255.0f) |
+           (uint8_t) util_iround(rgba[1] * 255.0f) << 8 |
+           (uint8_t) util_iround(rgba[2] * 255.0f) << 16 |
+           (uint8_t) util_iround(rgba[3] * 255.0f) << 24;
+
+   /* UNORM16 */
+   dw[7] = (uint16_t) util_iround(rgba[0] * 65535.0f) |
+           (uint16_t) util_iround(rgba[1] * 65535.0f) << 16;
+   dw[8] = (uint16_t) util_iround(rgba[2] * 65535.0f) |
+           (uint16_t) util_iround(rgba[3] * 65535.0f) << 16;
+
+   STATIC_ASSERT(ARRAY_SIZE(border->color) >= 12);
+   memcpy(border->color, dw, sizeof(dw));
+
+   return true;
+}
+
+static bool
+sampler_border_set_gen7_SAMPLER_BORDER_COLOR_STATE(struct ilo_state_sampler_border *border,
+                                                   const struct ilo_dev *dev,
+                                                   const struct ilo_state_sampler_border_info *info)
+{
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 116:
+    *
+    *     "In DX10/OGL mode, the format of the border color is
+    *      R32G32B32A32_FLOAT, regardless of the surface format chosen."
+    *
+    * From the Haswell PRM, volume 2d, page 240:
+    *
+    *     "So, SW will have to program the table in SAMPLER_BORDER_COLOR_STATE
+    *      at offsets DWORD16 to 19, as per the integer surface format type."
+    *
+    * From the Broadwell PRM, volume 2d, page 297:
+    *
+    *     "DX10/OGL mode: the format of the border color depends on the format
+    *      of the surface being sampled. If the map format is UINT, then the
+    *      border color format is R32G32B32A32_UINT. If the map format is
+    *      SINT, then the border color format is R32G32B32A32_SINT. Otherwise,
+    *      the border color format is R32G32B32A32_FLOAT."
+    *
+    * XXX every Gen is different
+    */
+
+   STATIC_ASSERT(ARRAY_SIZE(border->color) >= 4);
+   memcpy(border->color, info->rgba.f, sizeof(info->rgba.f));
+
+   return true;
+}
+
+bool
+ilo_state_sampler_init(struct ilo_state_sampler *sampler,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_sampler_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(sampler, sizeof(*sampler)));
+
+   ret &= sampler_set_gen6_SAMPLER_STATE(sampler, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_sampler_init_disabled(struct ilo_state_sampler *sampler,
+                                const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(ilo_is_zeroed(sampler, sizeof(*sampler)));
+
+   sampler->sampler[0] = GEN6_SAMPLER_DW0_DISABLE;
+   sampler->sampler[1] = 0;
+   sampler->sampler[2] = 0;
+
+   return true;
+}
+
+/**
+ * Modify \p sampler to work with \p surf.  There will be loss of information.
+ * Callers should make a copy of the orignal sampler first.
+ */
+bool
+ilo_state_sampler_set_surface(struct ilo_state_sampler *sampler,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_surface *surf)
+{
+   uint32_t addr_ctrl;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (sampler->non_normalized) {
+      /* see sampler_validate_gen6_non_normalized() */
+      assert(surf->type == GEN6_SURFTYPE_2D ||
+             surf->type == GEN6_SURFTYPE_3D);
+      assert(!surf->min_lod && !surf->mip_count);
+   }
+
+   if (sampler->base_to_surf_min_lod) {
+      const uint8_t base = surf->min_lod << GEN6_SAMPLER_DW0_BASE_LOD__RADIX;
+
+      sampler->sampler[0] =
+         (sampler->sampler[0] & ~GEN6_SAMPLER_DW0_BASE_LOD__MASK) |
+         base << GEN6_SAMPLER_DW0_BASE_LOD__SHIFT;
+   }
+
+   if (surf->is_integer || surf->type == GEN6_SURFTYPE_3D) {
+      const uint32_t mask = (GEN6_SAMPLER_DW0_MIP_FILTER__MASK |
+                             GEN6_SAMPLER_DW0_MIN_FILTER__MASK |
+                             GEN6_SAMPLER_DW0_MAG_FILTER__MASK);
+      const uint32_t filter = (surf->is_integer) ?
+         sampler->filter_integer : sampler->filter_3d;
+
+      assert((filter & mask) == filter);
+      sampler->sampler[0] = (sampler->sampler[0] & ~mask) |
+                            filter;
+   }
+
+   switch (surf->type) {
+   case GEN6_SURFTYPE_1D:
+      addr_ctrl = sampler->addr_ctrl_1d;
+      break;
+   case GEN6_SURFTYPE_2D:
+   case GEN6_SURFTYPE_3D:
+      addr_ctrl = sampler->addr_ctrl_2d_3d;
+      break;
+   case GEN6_SURFTYPE_CUBE:
+      addr_ctrl = sampler->addr_ctrl_cube;
+      break;
+   default:
+      assert(!"unexpected surface type");
+      addr_ctrl = 0;
+      break;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      const uint32_t mask = (GEN7_SAMPLER_DW3_U_WRAP__MASK |
+                             GEN7_SAMPLER_DW3_V_WRAP__MASK |
+                             GEN7_SAMPLER_DW3_R_WRAP__MASK);
+
+      assert((addr_ctrl & mask) == addr_ctrl);
+      sampler->sampler[2] = (sampler->sampler[2] & ~mask) |
+                            addr_ctrl;
+   } else {
+      const uint32_t mask = (GEN6_SAMPLER_DW1_U_WRAP__MASK |
+                             GEN6_SAMPLER_DW1_V_WRAP__MASK |
+                             GEN6_SAMPLER_DW1_R_WRAP__MASK);
+
+      assert((addr_ctrl & mask) == addr_ctrl);
+      sampler->sampler[1] = (sampler->sampler[1] & ~mask) |
+                            addr_ctrl;
+   }
+
+   return true;
+}
+
+bool
+ilo_state_sampler_border_init(struct ilo_state_sampler_border *border,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_sampler_border_info *info)
+{
+   bool ret = true;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      ret &= sampler_border_set_gen7_SAMPLER_BORDER_COLOR_STATE(border,
+            dev, info);
+   } else {
+      ret &= sampler_border_set_gen6_SAMPLER_BORDER_COLOR_STATE(border,
+            dev, info);
+   }
+
+   assert(ret);
+
+   return ret;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sampler.h b/src/gallium/drivers/ilo/core/ilo_state_sampler.h
new file mode 100644 (file)
index 0000000..75c7620
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_SAMPLER_H
+#define ILO_STATE_SAMPLER_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+struct ilo_state_surface;
+
+struct ilo_state_sampler_info {
+   bool non_normalized;
+
+   float lod_bias;
+   float min_lod;
+   float max_lod;
+
+   enum gen_mip_filter mip_filter;
+   enum gen_map_filter min_filter;
+   enum gen_map_filter mag_filter;
+   enum gen_aniso_ratio max_anisotropy;
+
+   enum gen_texcoord_mode tcx_ctrl;
+   enum gen_texcoord_mode tcy_ctrl;
+   enum gen_texcoord_mode tcz_ctrl;
+
+   enum gen_prefilter_op shadow_func;
+};
+
+struct ilo_state_sampler_border_info {
+   union {
+      float f[4];
+      uint32_t ui[4];
+   } rgba;
+
+   bool is_integer;
+};
+
+struct ilo_state_sampler {
+   uint32_t sampler[3];
+
+   uint32_t filter_integer;
+   uint32_t filter_3d;
+
+   uint32_t addr_ctrl_1d;
+   uint32_t addr_ctrl_2d_3d;
+   uint32_t addr_ctrl_cube;
+
+   bool non_normalized;
+   bool base_to_surf_min_lod;
+};
+
+struct ilo_state_sampler_border {
+   uint32_t color[12];
+};
+
+bool
+ilo_state_sampler_init(struct ilo_state_sampler *sampler,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_sampler_info *info);
+
+bool
+ilo_state_sampler_init_disabled(struct ilo_state_sampler *sampler,
+                                const struct ilo_dev *dev);
+
+bool
+ilo_state_sampler_set_surface(struct ilo_state_sampler *sampler,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_surface *surf);
+
+bool
+ilo_state_sampler_border_init(struct ilo_state_sampler_border *border,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_sampler_border_info *info);
+
+#endif /* ILO_STATE_SAMPLER_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sbe.c b/src/gallium/drivers/ilo/core/ilo_state_sbe.c
new file mode 100644 (file)
index 0000000..5d1d400
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_sbe.h"
+
+static bool
+sbe_validate_gen8(const struct ilo_dev *dev,
+                  const struct ilo_state_sbe_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(info->attr_count <= ILO_STATE_SBE_MAX_ATTR_COUNT);
+
+   assert(info->vue_read_base + info->vue_read_count <=
+         info->cv_vue_attr_count);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 248:
+    *
+    *     "(Vertex URB Entry Read Length)
+    *      Format: U5
+    *      Range [1,16]
+    *
+    *      Specifies the amount of URB data read for each Vertex URB entry, in
+    *      256-bit register increments.
+    *
+    *      Programming Notes
+    *      It is UNDEFINED to set this field to 0 indicating no Vertex URB
+    *      data to be read."
+    *
+    *     "(Vertex URB Entry Read Offset)
+    *      Format: U6
+    *      Range [0,63]
+    *
+    *      Specifies the offset (in 256-bit units) at which Vertex URB data is
+    *      to be read from the URB."
+    */
+   assert(info->vue_read_base % 2 == 0 && info->vue_read_base <= 126);
+   assert(info->vue_read_count <= 32);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 268:
+    *
+    *     "This field (Point Sprite Texture Coordinate Enable) must be
+    *      programmed to 0 when non-point primitives are rendered."
+    */
+   if (ilo_dev_gen(dev) < ILO_GEN(7.5) && info->point_sprite_enables)
+      assert(info->cv_is_point);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 246:
+    *
+    *     "(Number of SF Output Attributes) 33-48: Specifies 17-32 attributes
+    *      (# attributes = field value - 16). Swizzling performed on
+    *      Attributes 16-31 (as required) only. Attributes 0-15 passed through
+    *      unmodified.
+    *
+    *      Note :
+    *
+    *      Attribute n Component Override and Constant Source states apply to
+    *      Attributes 16-31 (as required) instead of Attributes 0-15. E.g.,
+    *      this allows an Attribute 16-31 component to be overridden with the
+    *      PrimitiveID value.
+    *
+    *      Attribute n WrapShortest Enables still apply to Attributes 0-15.
+    *
+    *      Attribute n Swizzle Select and Attribute n Source Attribute states
+    *      are ignored and none of the swizzling functions available through
+    *      these controls are performed."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 247:
+    *
+    *     "This bit (Attribute Swizzle Enable) controls the use of the
+    *      Attribute n Swizzle Select and Attribute n Source Attribute fields
+    *      only. If ENABLED, those fields are used as described below. If
+    *      DISABLED, attributes are copied from their corresponding source
+    *      attributes, for the purposes of Swizzle Select only.
+    *
+    *      Note that the following fields are unaffected by this bit, and are
+    *      therefore always used to control their respective fields:
+    *      Attribute n Component Override X/Y/Z/W
+    *      Attribute n Constant Source
+    *      Attribute n WrapShortest Enables"
+    *
+    * From the Ivy Bridge PRM, volume 2 part 1, page 264:
+    *
+    *     "When Attribute Swizzle Enable is ENABLED, this bit (Attribute
+    *      Swizzle Control Mode) controls whether attributes 0-15 or 16-31 are
+    *      subject to the following swizzle controls:
+    *
+    *      - Attribute n Component Override X/Y/Z/W
+    *      - Attribute n Constant Source
+    *      - Attribute n Swizzle Select
+    *      - Attribute n Source Attribute
+    *      - Attribute n Wrap Shortest Enables"
+    *
+    *     "SWIZ_16_31... Only valid when 16 or more attributes are output."
+    */
+   assert(info->swizzle_count <= ILO_STATE_SBE_MAX_SWIZZLE_COUNT);
+   if (info->swizzle_16_31) {
+      assert(ilo_dev_gen(dev) >= ILO_GEN(7) &&
+             info->swizzle_enable &&
+             info->attr_count > 16);
+   }
+
+   return true;
+}
+
+static uint8_t
+sbe_get_gen8_min_read_count(const struct ilo_dev *dev,
+                            const struct ilo_state_sbe_info *info)
+{
+   uint8_t min_count = 0;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* minimum read count for non-swizzled attributes */
+   if (!info->swizzle_enable || info->swizzle_count < info->attr_count) {
+      if (info->swizzle_16_31 && info->swizzle_count + 16 == info->attr_count)
+         min_count = 16;
+      else
+         min_count = info->attr_count;
+   }
+
+   if (info->swizzle_enable) {
+      uint8_t i;
+
+      for (i = 0; i < info->swizzle_count; i++) {
+         const struct ilo_state_sbe_swizzle_info *swizzle =
+            &info->swizzles[i];
+         bool inputattr_facing;
+
+         switch (swizzle->attr_select) {
+         case GEN6_INPUTATTR_FACING:
+         case GEN6_INPUTATTR_FACING_W:
+            inputattr_facing = true;
+            break;
+         default:
+            inputattr_facing = false;
+            break;
+         }
+
+         if (min_count < swizzle->attr + inputattr_facing + 1)
+            min_count = swizzle->attr + inputattr_facing + 1;
+      }
+   }
+
+   return min_count;
+}
+
+static uint8_t
+sbe_get_gen8_read_length(const struct ilo_dev *dev,
+                         const struct ilo_state_sbe_info *info)
+{
+   uint8_t read_len;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 248:
+    *
+    *     "(Vertex URB Entry Read Length)
+    *      This field should be set to the minimum length required to read the
+    *      maximum source attribute. The maximum source attribute is indicated
+    *      by the maximum value of the enabled Attribute # Source Attribute if
+    *      Attribute Swizzle Enable is set, Number of Output Attributes -1 if
+    *      enable is not set.
+    *      read_length = ceiling((max_source_attr+1)/2)
+    *
+    *      [errata] Corruption/Hang possible if length programmed larger than
+    *      recommended"
+    */
+   if (info->has_min_read_count) {
+      read_len = info->vue_read_count;
+      assert(read_len == sbe_get_gen8_min_read_count(dev, info));
+   } else {
+      read_len = sbe_get_gen8_min_read_count(dev, info);
+      assert(read_len <= info->vue_read_count);
+   }
+
+   /*
+    * In pairs.  URB entries are aligned to 1024-bits or 512-bits.  There is
+    * no need to worry about reading past entries.
+    */
+   read_len = (read_len + 1) / 2;
+   if (!read_len)
+      read_len = 1;
+
+   return read_len;
+}
+
+static bool
+sbe_set_gen8_3DSTATE_SBE(struct ilo_state_sbe *sbe,
+                         const struct ilo_dev *dev,
+                         const struct ilo_state_sbe_info *info)
+{
+   uint8_t vue_read_offset, vue_read_len;
+   uint8_t attr_count;
+   uint32_t dw1, dw2, dw3;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!sbe_validate_gen8(dev, info))
+      return false;
+
+   vue_read_offset = info->vue_read_base / 2;
+   vue_read_len = sbe_get_gen8_read_length(dev, info);
+
+   attr_count = info->attr_count;
+   if (ilo_dev_gen(dev) == ILO_GEN(6) && info->swizzle_16_31)
+      attr_count += 16;
+
+   dw1 = attr_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
+         vue_read_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      dw1 |= GEN8_SBE_DW1_USE_URB_READ_LEN |
+             GEN8_SBE_DW1_USE_URB_READ_OFFSET |
+             vue_read_offset << GEN8_SBE_DW1_URB_READ_OFFSET__SHIFT;
+   } else {
+      dw1 |= vue_read_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7) && info->swizzle_16_31)
+      dw1 |= GEN7_SBE_DW1_ATTR_SWIZZLE_16_31;
+
+   if (info->swizzle_enable)
+      dw1 |= GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE;
+
+   dw1 |= (info->point_sprite_origin_lower_left) ?
+      GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_LOWERLEFT :
+      GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_UPPERLEFT;
+
+   dw2 = info->point_sprite_enables;
+   dw3 = info->const_interp_enables;
+
+   STATIC_ASSERT(ARRAY_SIZE(sbe->sbe) >= 3);
+   sbe->sbe[0] = dw1;
+   sbe->sbe[1] = dw2;
+   sbe->sbe[2] = dw3;
+
+   return true;
+}
+
+static bool
+sbe_set_gen8_3DSTATE_SBE_SWIZ(struct ilo_state_sbe *sbe,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_sbe_info *info)
+{
+   uint16_t swiz[ILO_STATE_SBE_MAX_SWIZZLE_COUNT];
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   for (i = 0; i < info->swizzle_count; i++) {
+      const struct ilo_state_sbe_swizzle_info *swizzle = &info->swizzles[i];
+
+      /* U5 */
+      assert(swizzle->attr < 32);
+      swiz[i] = swizzle->attr_select << GEN8_SBE_SWIZ_SWIZZLE_SELECT__SHIFT |
+                swizzle->attr << GEN8_SBE_SWIZ_SRC_ATTR__SHIFT;
+
+      if (swizzle->force_zeros) {
+         swiz[i] |= GEN8_SBE_SWIZ_OVERRIDE_W |
+                    GEN8_SBE_SWIZ_OVERRIDE_Z |
+                    GEN8_SBE_SWIZ_OVERRIDE_Y |
+                    GEN8_SBE_SWIZ_OVERRIDE_X |
+                    GEN8_SBE_SWIZ_CONST_0000;
+      }
+   }
+
+   for (; i < ARRAY_SIZE(swiz); i++) {
+      swiz[i] = GEN6_INPUTATTR_NORMAL << GEN8_SBE_SWIZ_SWIZZLE_SELECT__SHIFT |
+                i << GEN8_SBE_SWIZ_SRC_ATTR__SHIFT;
+   }
+
+   STATIC_ASSERT(sizeof(sbe->swiz) == sizeof(swiz));
+   memcpy(sbe->swiz, swiz, sizeof(swiz));
+
+   return true;
+}
+
+bool
+ilo_state_sbe_init(struct ilo_state_sbe *sbe,
+                   const struct ilo_dev *dev,
+                   const struct ilo_state_sbe_info *info)
+{
+   assert(ilo_is_zeroed(sbe, sizeof(*sbe)));
+   return ilo_state_sbe_set_info(sbe, dev, info);
+}
+
+bool
+ilo_state_sbe_init_for_rectlist(struct ilo_state_sbe *sbe,
+                                const struct ilo_dev *dev,
+                                uint8_t read_base,
+                                uint8_t read_count)
+{
+   struct ilo_state_sbe_info info;
+
+   memset(&info, 0, sizeof(info));
+   info.attr_count = read_count;
+   info.cv_vue_attr_count = read_base + read_count;
+   info.vue_read_base = read_base;
+   info.vue_read_count = read_count;
+   info.has_min_read_count = true;
+
+   return ilo_state_sbe_set_info(sbe, dev, &info);
+}
+
+bool
+ilo_state_sbe_set_info(struct ilo_state_sbe *sbe,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_sbe_info *info)
+{
+   bool ret = true;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   ret &= sbe_set_gen8_3DSTATE_SBE(sbe, dev, info);
+   ret &= sbe_set_gen8_3DSTATE_SBE_SWIZ(sbe, dev, info);
+
+   assert(ret);
+
+   return true;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sbe.h b/src/gallium/drivers/ilo/core/ilo_state_sbe.h
new file mode 100644 (file)
index 0000000..122999a
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_SBE_H
+#define ILO_STATE_SBE_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 264:
+ *
+ *     "Number of SF Output Attributes sets the number of attributes that will
+ *      be output from the SF stage, not including position. This can be used
+ *      to specify up to 32, and may differ from the number of input
+ *      attributes."
+ *
+ *     "The first or last set of 16 attributes can be swizzled according to
+ *      certain state fields."
+ */
+#define ILO_STATE_SBE_MAX_ATTR_COUNT 32
+#define ILO_STATE_SBE_MAX_SWIZZLE_COUNT 16
+
+struct ilo_state_sbe_swizzle_info {
+   /* select an attribute from read ones */
+   enum gen_inputattr_select attr_select;
+   uint8_t attr;
+
+   bool force_zeros;
+};
+
+struct ilo_state_sbe_info {
+   uint8_t attr_count;
+
+   /* which VUE attributes to read */
+   uint8_t cv_vue_attr_count;
+   uint8_t vue_read_base;
+   uint8_t vue_read_count;
+   bool has_min_read_count;
+
+   bool cv_is_point;
+   bool point_sprite_origin_lower_left;
+   /* force sprite coordinates to the four corner vertices of the point */
+   uint32_t point_sprite_enables;
+
+   /* force attr at the provoking vertex to a0 and zero to a1/a2 */
+   uint32_t const_interp_enables;
+
+   bool swizzle_enable;
+   /* swizzle attribute 16 to 31 instead; Gen7+ only */
+   bool swizzle_16_31;
+   uint8_t swizzle_count;
+   const struct ilo_state_sbe_swizzle_info *swizzles;
+};
+
+struct ilo_state_sbe {
+   uint32_t sbe[3];
+   uint32_t swiz[8];
+};
+
+bool
+ilo_state_sbe_init(struct ilo_state_sbe *sbe,
+                   const struct ilo_dev *dev,
+                   const struct ilo_state_sbe_info *info);
+
+bool
+ilo_state_sbe_init_for_rectlist(struct ilo_state_sbe *sbe,
+                                const struct ilo_dev *dev,
+                                uint8_t read_base,
+                                uint8_t read_count);
+
+bool
+ilo_state_sbe_set_info(struct ilo_state_sbe *sbe,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_sbe_info *info);
+
+#endif /* ILO_STATE_SBE_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_shader.c b/src/gallium/drivers/ilo/core/ilo_state_shader.c
new file mode 100644 (file)
index 0000000..f67326c
--- /dev/null
@@ -0,0 +1,737 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_shader.h"
+
+enum vertex_stage {
+   STAGE_VS,
+   STAGE_HS,
+   STAGE_DS,
+   STAGE_GS,
+};
+
+struct vertex_ff {
+   uint8_t grf_start;
+   uint8_t scratch_space;
+
+   uint8_t sampler_count;
+   uint8_t surface_count;
+   bool has_uav;
+
+   uint8_t vue_read_offset;
+   uint8_t vue_read_len;
+
+   uint8_t user_clip_enables;
+};
+
+static bool
+vertex_validate_gen6_kernel(const struct ilo_dev *dev,
+                            enum vertex_stage stage,
+                            const struct ilo_state_shader_kernel_info *kernel)
+{
+   /*
+    * "Dispatch GRF Start Register for URB Data" is U4 for GS and U5 for
+    * others.
+    */
+   const uint8_t max_grf_start = (stage == STAGE_GS) ? 16 : 32;
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 134:
+    *
+    *     "(Per-Thread Scratch Space)
+    *      Range    [0,11] indicating [1K Bytes, 2M Bytes]"
+    */
+   const uint32_t max_scratch_size = 2 * 1024 * 1024;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* we do not want to save it */
+   assert(!kernel->offset);
+
+   assert(kernel->grf_start < max_grf_start);
+   assert(kernel->scratch_size <= max_scratch_size);
+
+   return true;
+}
+
+static bool
+vertex_validate_gen6_urb(const struct ilo_dev *dev,
+                         enum vertex_stage stage,
+                         const struct ilo_state_shader_urb_info *urb)
+{
+   /* "Vertex/Patch URB Entry Read Offset" is U6, in pairs */
+   const uint8_t max_read_base = 63 * 2;
+   /*
+    * "Vertex/Patch URB Entry Read Length" is limited to 64 for DS and U6 for
+    * others, in pairs
+    */
+   const uint8_t max_read_count = ((stage == STAGE_DS) ? 64 : 63) * 2;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(urb->read_base + urb->read_count <= urb->cv_input_attr_count);
+
+   assert(urb->read_base % 2 == 0 && urb->read_base <= max_read_base);
+
+   /*
+    * There is no need to worry about reading past entries, as URB entries are
+    * aligned to 1024-bits (Gen6) or 512-bits (Gen7+).
+    */
+   assert(urb->read_count <= max_read_count);
+
+   return true;
+}
+
+static bool
+vertex_get_gen6_ff(const struct ilo_dev *dev,
+                   enum vertex_stage stage,
+                   const struct ilo_state_shader_kernel_info *kernel,
+                   const struct ilo_state_shader_resource_info *resource,
+                   const struct ilo_state_shader_urb_info *urb,
+                   struct vertex_ff *ff)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!vertex_validate_gen6_kernel(dev, stage, kernel) ||
+       !vertex_validate_gen6_urb(dev, stage, urb))
+      return false;
+
+   ff->grf_start = kernel->grf_start;
+   /* next power of two, starting from 1KB */
+   ff->scratch_space = (kernel->scratch_size > 1024) ?
+      (util_last_bit(kernel->scratch_size - 1) - 10): 0;
+
+   ff->sampler_count = (resource->sampler_count <= 12) ?
+      (resource->sampler_count + 3) / 4 : 4;
+   ff->surface_count = resource->surface_count;
+   ff->has_uav = resource->has_uav;
+
+   ff->vue_read_offset = urb->read_base / 2;
+   ff->vue_read_len = (urb->read_count + 1) / 2;
+
+   /* need to read something unless VUE handles are included */
+   switch (stage) {
+   case STAGE_VS:
+      if (!ff->vue_read_len)
+         ff->vue_read_len = 1;
+
+      /* one GRF per attribute */
+      assert(kernel->grf_start + urb->read_count * 2 <= 128);
+      break;
+   case STAGE_GS:
+      if (ilo_dev_gen(dev) == ILO_GEN(6) && !ff->vue_read_len)
+         ff->vue_read_len = 1;
+      break;
+   default:
+      break;
+   }
+
+   ff->user_clip_enables = urb->user_clip_enables;
+
+   return true;
+}
+
+static uint16_t
+vs_get_gen6_thread_count(const struct ilo_dev *dev,
+                         const struct ilo_state_vs_info *info)
+{
+   uint16_t thread_count;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* Maximum Number of Threads of 3DSTATE_VS */
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+      thread_count = 504;
+      break;
+   case ILO_GEN(7.5):
+      thread_count = (dev->gt >= 2) ? 280 : 70;
+      break;
+   case ILO_GEN(7):
+   case ILO_GEN(6):
+   default:
+      thread_count = dev->thread_count;
+      break;
+   }
+
+   return thread_count - 1;
+}
+
+static bool
+vs_set_gen6_3DSTATE_VS(struct ilo_state_vs *vs,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_vs_info *info)
+{
+   struct vertex_ff ff;
+   uint16_t thread_count;
+   uint32_t dw2, dw3, dw4, dw5;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!vertex_get_gen6_ff(dev, STAGE_VS, &info->kernel,
+            &info->resource, &info->urb, &ff))
+      return false;
+
+   thread_count = vs_get_gen6_thread_count(dev, info);
+
+   dw2 = ff.sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff.surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (false)
+      dw2 |= GEN6_THREADDISP_FP_MODE_ALT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5) && ff.has_uav)
+      dw2 |= GEN75_THREADDISP_ACCESS_UAV;
+
+   dw3 = ff.scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw4 = ff.grf_start << GEN6_VS_DW4_URB_GRF_START__SHIFT |
+         ff.vue_read_len << GEN6_VS_DW4_URB_READ_LEN__SHIFT |
+         ff.vue_read_offset << GEN6_VS_DW4_URB_READ_OFFSET__SHIFT;
+
+   dw5 = 0;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      dw5 |= thread_count << GEN75_VS_DW5_MAX_THREADS__SHIFT;
+   else
+      dw5 |= thread_count << GEN6_VS_DW5_MAX_THREADS__SHIFT;
+
+   if (info->stats_enable)
+      dw5 |= GEN6_VS_DW5_STATISTICS;
+   if (info->dispatch_enable)
+      dw5 |= GEN6_VS_DW5_VS_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(vs->vs) >= 5);
+   vs->vs[0] = dw2;
+   vs->vs[1] = dw3;
+   vs->vs[2] = dw4;
+   vs->vs[3] = dw5;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      vs->vs[4] = ff.user_clip_enables << GEN8_VS_DW8_UCP_CLIP_ENABLES__SHIFT;
+
+   return true;
+}
+
+static uint16_t
+hs_get_gen7_thread_count(const struct ilo_dev *dev,
+                         const struct ilo_state_hs_info *info)
+{
+   uint16_t thread_count;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /* Maximum Number of Threads of 3DSTATE_HS */
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+      thread_count = 504;
+      break;
+   case ILO_GEN(7.5):
+      thread_count = (dev->gt >= 2) ? 256 : 70;
+      break;
+   case ILO_GEN(7):
+   default:
+      thread_count = dev->thread_count;
+      break;
+   }
+
+   return thread_count - 1;
+}
+
+static bool
+hs_set_gen7_3DSTATE_HS(struct ilo_state_hs *hs,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_hs_info *info)
+{
+   struct vertex_ff ff;
+   uint16_t thread_count;
+   uint32_t dw1, dw2, dw4, dw5;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!vertex_get_gen6_ff(dev, STAGE_HS, &info->kernel,
+            &info->resource, &info->urb, &ff))
+      return false;
+
+   thread_count = hs_get_gen7_thread_count(dev, info);
+
+   dw1 = ff.sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff.surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      dw1 |= thread_count << GEN75_HS_DW1_DISPATCH_MAX_THREADS__SHIFT;
+   else
+      dw1 |= thread_count << GEN7_HS_DW1_DISPATCH_MAX_THREADS__SHIFT;
+
+   dw2 = 0 << GEN7_HS_DW2_INSTANCE_COUNT__SHIFT;
+
+   if (info->dispatch_enable)
+      dw2 |= GEN7_HS_DW2_HS_ENABLE;
+   if (info->stats_enable)
+      dw2 |= GEN7_HS_DW2_STATISTICS;
+
+   dw4 = ff.scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw5 = GEN7_HS_DW5_INCLUDE_VERTEX_HANDLES |
+         ff.grf_start << GEN7_HS_DW5_URB_GRF_START__SHIFT |
+         ff.vue_read_len << GEN7_HS_DW5_URB_READ_LEN__SHIFT |
+         ff.vue_read_offset << GEN7_HS_DW5_URB_READ_OFFSET__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5) && ff.has_uav)
+      dw5 |= GEN75_HS_DW5_ACCESS_UAV;
+
+   STATIC_ASSERT(ARRAY_SIZE(hs->hs) >= 4);
+   hs->hs[0] = dw1;
+   hs->hs[1] = dw2;
+   hs->hs[2] = dw4;
+   hs->hs[3] = dw5;
+
+   return true;
+}
+
+static bool
+ds_set_gen7_3DSTATE_TE(struct ilo_state_ds *ds,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_ds_info *info)
+{
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   dw1 = 0;
+
+   if (info->dispatch_enable) {
+      dw1 |= GEN7_TE_DW1_MODE_HW |
+             GEN7_TE_DW1_TE_ENABLE;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(ds->te) >= 3);
+   ds->te[0] = dw1;
+   ds->te[1] = fui(63.0f);
+   ds->te[2] = fui(64.0f);
+
+   return true;
+}
+
+static uint16_t
+ds_get_gen7_thread_count(const struct ilo_dev *dev,
+                         const struct ilo_state_ds_info *info)
+{
+   uint16_t thread_count;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /* Maximum Number of Threads of 3DSTATE_DS */
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+      thread_count = 504;
+      break;
+   case ILO_GEN(7.5):
+      thread_count = (dev->gt >= 2) ? 280 : 70;
+      break;
+   case ILO_GEN(7):
+   default:
+      thread_count = dev->thread_count;
+      break;
+   }
+
+   return thread_count - 1;
+}
+
+static bool
+ds_set_gen7_3DSTATE_DS(struct ilo_state_ds *ds,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_ds_info *info)
+{
+   struct vertex_ff ff;
+   uint16_t thread_count;
+   uint32_t dw2, dw3, dw4, dw5;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!vertex_get_gen6_ff(dev, STAGE_DS, &info->kernel,
+            &info->resource, &info->urb, &ff))
+      return false;
+
+   thread_count = ds_get_gen7_thread_count(dev, info);
+
+   dw2 = ff.sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff.surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5) && ff.has_uav)
+      dw2 |= GEN75_THREADDISP_ACCESS_UAV;
+
+   dw3 = ff.scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw4 = ff.grf_start << GEN7_DS_DW4_URB_GRF_START__SHIFT |
+         ff.vue_read_len << GEN7_DS_DW4_URB_READ_LEN__SHIFT |
+         ff.vue_read_offset << GEN7_DS_DW4_URB_READ_OFFSET__SHIFT;
+
+   dw5 = 0;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      dw5 |= thread_count << GEN75_DS_DW5_MAX_THREADS__SHIFT;
+   else
+      dw5 |= thread_count << GEN7_DS_DW5_MAX_THREADS__SHIFT;
+
+   if (info->stats_enable)
+      dw5 |= GEN7_DS_DW5_STATISTICS;
+   if (info->dispatch_enable)
+      dw5 |= GEN7_DS_DW5_DS_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(ds->ds) >= 5);
+   ds->ds[0] = dw2;
+   ds->ds[1] = dw3;
+   ds->ds[2] = dw4;
+   ds->ds[3] = dw5;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      ds->ds[4] = ff.user_clip_enables << GEN8_DS_DW8_UCP_CLIP_ENABLES__SHIFT;
+
+   return true;
+}
+
+static bool
+gs_get_gen6_ff(const struct ilo_dev *dev,
+               const struct ilo_state_gs_info *info,
+               struct vertex_ff *ff)
+{
+   const struct ilo_state_shader_urb_info *urb = &info->urb;
+   const struct ilo_state_gs_sol_info *sol = &info->sol;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!vertex_get_gen6_ff(dev, STAGE_GS, &info->kernel,
+            &info->resource, &info->urb, ff))
+      return false;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 168-169:
+    *
+    *     "[0,62] indicating [1,63] 16B units"
+    *
+    *     "Programming Restrictions: The vertex size must be programmed as a
+    *      multiple of 32B units with the following exception: Rendering is
+    *      disabled (as per SOL stage state) and the vertex size output by the
+    *      GS thread is 16B.
+    *
+    *      If rendering is enabled (as per SOL state) the vertex size must be
+    *      programmed as a multiple of 32B units. In other words, the only
+    *      time software can program a vertex size with an odd number of 16B
+    *      units is when rendering is disabled."
+    */
+   assert(urb->output_attr_count <= 63);
+   if (!sol->render_disable)
+      assert(urb->output_attr_count % 2 == 0);
+
+   return true;
+}
+
+static uint16_t
+gs_get_gen6_thread_count(const struct ilo_dev *dev,
+                         const struct ilo_state_gs_info *info)
+{
+   const struct ilo_state_gs_sol_info *sol = &info->sol;
+   uint16_t thread_count;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* Maximum Number of Threads of 3DSTATE_GS */
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+      thread_count = 504;
+      break;
+   case ILO_GEN(7.5):
+      thread_count = (dev->gt >= 2) ? 256 : 70;
+      break;
+   case ILO_GEN(7):
+   case ILO_GEN(6):
+   default:
+      thread_count = dev->thread_count;
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 154:
+       *
+       *     "Maximum Number of Threads valid range is [0,27] when Rendering
+       *      Enabled bit is set."
+       *
+       * According to the classic driver, [0, 20] for GT1.
+       */
+      if (!sol->render_disable)
+         thread_count = (dev->gt == 2) ? 27 : 20;
+      break;
+   }
+
+   return thread_count - 1;
+}
+
+static bool
+gs_set_gen6_3DSTATE_GS(struct ilo_state_gs *gs,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_gs_info *info)
+{
+   const struct ilo_state_gs_sol_info *sol = &info->sol;
+   struct vertex_ff ff;
+   uint16_t thread_count;
+   uint32_t dw2, dw3, dw4, dw5, dw6;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   if (!gs_get_gen6_ff(dev, info, &ff))
+      return false;
+
+   thread_count = gs_get_gen6_thread_count(dev, info);
+
+   dw2 = GEN6_THREADDISP_SPF |
+         ff.sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff.surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   dw3 = ff.scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw4 = ff.vue_read_len << GEN6_GS_DW4_URB_READ_LEN__SHIFT |
+         ff.vue_read_offset << GEN6_GS_DW4_URB_READ_OFFSET__SHIFT |
+         ff.grf_start << GEN6_GS_DW4_URB_GRF_START__SHIFT;
+
+   dw5 = thread_count << GEN6_GS_DW5_MAX_THREADS__SHIFT;
+
+   if (info->stats_enable)
+      dw5 |= GEN6_GS_DW5_STATISTICS;
+   if (sol->stats_enable)
+      dw5 |= GEN6_GS_DW5_SO_STATISTICS;
+   if (!sol->render_disable)
+      dw5 |= GEN6_GS_DW5_RENDER_ENABLE;
+
+   dw6 = 0;
+
+   /* GEN7_REORDER_TRAILING is handled by the kernel */
+   if (sol->tristrip_reorder == GEN7_REORDER_LEADING)
+      dw6 |= GEN6_GS_DW6_REORDER_LEADING_ENABLE;
+
+   if (sol->sol_enable) {
+      dw6 |= GEN6_GS_DW6_SVBI_PAYLOAD_ENABLE;
+
+      if (sol->svbi_post_inc) {
+         dw6 |= GEN6_GS_DW6_SVBI_POST_INC_ENABLE |
+                sol->svbi_post_inc << GEN6_GS_DW6_SVBI_POST_INC_VAL__SHIFT;
+      }
+   }
+
+   if (info->dispatch_enable)
+      dw6 |= GEN6_GS_DW6_GS_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(gs->gs) >= 5);
+   gs->gs[0] = dw2;
+   gs->gs[1] = dw3;
+   gs->gs[2] = dw4;
+   gs->gs[3] = dw5;
+   gs->gs[4] = dw6;
+
+   return true;
+}
+
+static uint8_t
+gs_get_gen7_vertex_size(const struct ilo_dev *dev,
+                        const struct ilo_state_gs_info *info)
+{
+   const struct ilo_state_shader_urb_info *urb = &info->urb;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   return (urb->output_attr_count) ? urb->output_attr_count - 1 : 0;
+}
+
+static bool
+gs_set_gen7_3DSTATE_GS(struct ilo_state_gs *gs,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_gs_info *info)
+{
+   struct vertex_ff ff;
+   uint16_t thread_count;
+   uint8_t vertex_size;
+   uint32_t dw2, dw3, dw4, dw5;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!gs_get_gen6_ff(dev, info, &ff))
+      return false;
+
+   thread_count = gs_get_gen6_thread_count(dev, info);
+   vertex_size = gs_get_gen7_vertex_size(dev, info);
+
+   dw2 = ff.sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff.surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5) && ff.has_uav)
+      dw2 |= GEN75_THREADDISP_ACCESS_UAV;
+
+   dw3 = ff.scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw4 = vertex_size << GEN7_GS_DW4_OUTPUT_SIZE__SHIFT |
+         0 << GEN7_GS_DW4_OUTPUT_TOPO__SHIFT |
+         ff.vue_read_len << GEN7_GS_DW4_URB_READ_LEN__SHIFT |
+         GEN7_GS_DW4_INCLUDE_VERTEX_HANDLES |
+         ff.vue_read_offset << GEN7_GS_DW4_URB_READ_OFFSET__SHIFT |
+         ff.grf_start << GEN7_GS_DW4_URB_GRF_START__SHIFT;
+
+   dw5 = 0;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      dw5 = thread_count << GEN75_GS_DW5_MAX_THREADS__SHIFT;
+   else
+      dw5 = thread_count << GEN7_GS_DW5_MAX_THREADS__SHIFT;
+
+   if (info->stats_enable)
+      dw5 |= GEN7_GS_DW5_STATISTICS;
+   if (info->dispatch_enable)
+      dw5 |= GEN7_GS_DW5_GS_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(gs->gs) >= 5);
+   gs->gs[0] = dw2;
+   gs->gs[1] = dw3;
+   gs->gs[2] = dw4;
+   gs->gs[3] = dw5;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      gs->gs[4] = ff.user_clip_enables << GEN8_GS_DW9_UCP_CLIP_ENABLES__SHIFT;
+
+   return true;
+}
+
+bool
+ilo_state_vs_init(struct ilo_state_vs *vs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_vs_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(vs, sizeof(*vs)));
+
+   ret &= vs_set_gen6_3DSTATE_VS(vs, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_vs_init_disabled(struct ilo_state_vs *vs,
+                           const struct ilo_dev *dev)
+{
+   struct ilo_state_vs_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_vs_init(vs, dev, &info);
+}
+
+bool
+ilo_state_hs_init(struct ilo_state_hs *hs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_hs_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(hs, sizeof(*hs)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      ret &= hs_set_gen7_3DSTATE_HS(hs, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_hs_init_disabled(struct ilo_state_hs *hs,
+                           const struct ilo_dev *dev)
+{
+   struct ilo_state_hs_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_hs_init(hs, dev, &info);
+}
+
+bool
+ilo_state_ds_init(struct ilo_state_ds *ds,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_ds_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(ds, sizeof(*ds)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      ret &= ds_set_gen7_3DSTATE_TE(ds, dev, info);
+      ret &= ds_set_gen7_3DSTATE_DS(ds, dev, info);
+   }
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_ds_init_disabled(struct ilo_state_ds *ds,
+                           const struct ilo_dev *dev)
+{
+   struct ilo_state_ds_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_ds_init(ds, dev, &info);
+}
+
+bool
+ilo_state_gs_init(struct ilo_state_gs *gs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_gs_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(gs, sizeof(*gs)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      ret &= gs_set_gen7_3DSTATE_GS(gs, dev, info);
+   else
+      ret &= gs_set_gen6_3DSTATE_GS(gs, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_gs_init_disabled(struct ilo_state_gs *gs,
+                           const struct ilo_dev *dev)
+{
+   struct ilo_state_gs_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_gs_init(gs, dev, &info);
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_shader.h b/src/gallium/drivers/ilo/core/ilo_state_shader.h
new file mode 100644 (file)
index 0000000..44690c5
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_SHADER_H
+#define ILO_STATE_SHADER_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/**
+ * Kernel information.
+ */
+struct ilo_state_shader_kernel_info {
+   /* usually 0 unless the shader has multiple kernels */
+   uint32_t offset;
+
+   uint8_t grf_start;
+   uint8_t pcb_attr_count;
+
+   uint32_t scratch_size;
+};
+
+/**
+ * Shader resources.
+ */
+struct ilo_state_shader_resource_info {
+   /* for prefetches */
+   uint8_t sampler_count;
+   uint8_t surface_count;
+
+   bool has_uav;
+};
+
+/**
+ * URB inputs/outputs.
+ */
+struct ilo_state_shader_urb_info {
+   uint8_t cv_input_attr_count;
+
+   uint8_t read_base;
+   uint8_t read_count;
+
+   uint8_t output_attr_count;
+
+   uint8_t user_cull_enables;
+   uint8_t user_clip_enables;
+};
+
+struct ilo_state_vs_info {
+   struct ilo_state_shader_kernel_info kernel;
+   struct ilo_state_shader_resource_info resource;
+   struct ilo_state_shader_urb_info urb;
+
+   bool dispatch_enable;
+   bool stats_enable;
+};
+
+struct ilo_state_hs_info {
+   struct ilo_state_shader_kernel_info kernel;
+   struct ilo_state_shader_resource_info resource;
+   struct ilo_state_shader_urb_info urb;
+
+   bool dispatch_enable;
+   bool stats_enable;
+};
+
+struct ilo_state_ds_info {
+   struct ilo_state_shader_kernel_info kernel;
+   struct ilo_state_shader_resource_info resource;
+   struct ilo_state_shader_urb_info urb;
+
+   bool dispatch_enable;
+   bool stats_enable;
+};
+
+/**
+ * Stream output.  Must be consistent with ilo_state_sol_info.
+ */
+struct ilo_state_gs_sol_info {
+   bool sol_enable;
+   bool stats_enable;
+   bool render_disable;
+
+   uint16_t svbi_post_inc;
+
+   enum gen_reorder_mode tristrip_reorder;
+};
+
+struct ilo_state_gs_info {
+   struct ilo_state_shader_kernel_info kernel;
+   struct ilo_state_shader_resource_info resource;
+   struct ilo_state_shader_urb_info urb;
+
+   struct ilo_state_gs_sol_info sol;
+
+   bool dispatch_enable;
+   bool stats_enable;
+};
+
+struct ilo_state_ps_io_info {
+   /* inputs */
+   enum gen_position_offset posoffset;
+   uint8_t attr_count;
+   bool use_z;
+   bool use_w;
+   bool use_coverage_mask;
+
+   /* outputs */
+   enum gen_pscdepth_mode pscdepth;
+   bool has_rt_write;
+   bool write_pixel_mask;
+   bool write_omask;
+};
+
+struct ilo_state_ps_params_info {
+   /* compatibility with raster states */
+   uint32_t sample_mask;
+   bool earlyz_control_psexec;
+
+   /* compatibility with cc states */
+   bool alpha_may_kill;
+   bool dual_source_blending;
+   bool has_writeable_rt;
+};
+
+struct ilo_state_ps_info {
+   struct ilo_state_shader_kernel_info kernel_8;
+   struct ilo_state_shader_kernel_info kernel_16;
+   struct ilo_state_shader_kernel_info kernel_32;
+   struct ilo_state_shader_resource_info resource;
+
+   struct ilo_state_ps_io_info io;
+   struct ilo_state_ps_params_info params;
+
+   /* bitmask of GEN6_PS_DISPATCH_x */
+   uint8_t valid_kernels;
+   bool per_sample_dispatch;
+   bool sample_count_one;
+   bool cv_per_sample_interp;
+   bool cv_has_earlyz_op;
+
+   bool rt_clear_enable;
+   bool rt_resolve_enable;
+
+   bool cv_has_depth_buffer;
+};
+
+struct ilo_state_vs {
+   uint32_t vs[5];
+};
+
+struct ilo_state_hs {
+   uint32_t hs[4];
+};
+
+struct ilo_state_ds {
+   uint32_t te[3];
+   uint32_t ds[5];
+};
+
+struct ilo_state_gs {
+   uint32_t gs[5];
+};
+
+struct ilo_state_ps {
+   uint32_t ps[8];
+
+   struct ilo_state_ps_dispatch_conds {
+      bool ps_valid;
+
+      bool has_rt_write;
+      bool write_odepth;
+      bool write_ostencil;
+      bool has_uav_write;
+      bool ps_may_kill;
+   } conds;
+};
+
+bool
+ilo_state_vs_init(struct ilo_state_vs *vs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_vs_info *info);
+
+bool
+ilo_state_vs_init_disabled(struct ilo_state_vs *vs,
+                           const struct ilo_dev *dev);
+
+bool
+ilo_state_hs_init(struct ilo_state_hs *hs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_hs_info *info);
+
+bool
+ilo_state_hs_init_disabled(struct ilo_state_hs *hs,
+                           const struct ilo_dev *dev);
+
+
+bool
+ilo_state_ds_init(struct ilo_state_ds *ds,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_ds_info *info);
+
+bool
+ilo_state_ds_init_disabled(struct ilo_state_ds *ds,
+                           const struct ilo_dev *dev);
+
+bool
+ilo_state_gs_init(struct ilo_state_gs *gs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_gs_info *info);
+
+bool
+ilo_state_gs_init_disabled(struct ilo_state_gs *gs,
+                           const struct ilo_dev *dev);
+
+bool
+ilo_state_ps_init(struct ilo_state_ps *ps,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_ps_info *info);
+
+bool
+ilo_state_ps_init_disabled(struct ilo_state_ps *ps,
+                           const struct ilo_dev *dev);
+
+bool
+ilo_state_ps_set_params(struct ilo_state_ps *ps,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_ps_params_info *params);
+
+#endif /* ILO_STATE_SHADER_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_shader_ps.c b/src/gallium/drivers/ilo/core/ilo_state_shader_ps.c
new file mode 100644 (file)
index 0000000..f4d801e
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_shader.h"
+
+struct pixel_ff {
+   uint8_t dispatch_modes;
+
+   uint32_t kernel_offsets[3];
+   uint8_t grf_starts[3];
+   bool pcb_enable;
+   uint8_t scratch_space;
+
+   uint8_t sampler_count;
+   uint8_t surface_count;
+   bool has_uav;
+
+   uint16_t thread_count;
+
+   struct ilo_state_ps_dispatch_conds conds;
+
+   bool kill_pixel;
+   bool dispatch_enable;
+   bool dual_source_blending;
+   uint32_t sample_mask;
+};
+
+static bool
+ps_kernel_validate_gen6(const struct ilo_dev *dev,
+                        const struct ilo_state_shader_kernel_info *kernel)
+{
+   /* "Dispatch GRF Start Register for Constant/Setup Data" is U7 */
+   const uint8_t max_grf_start = 128;
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 271:
+    *
+    *     "(Per-Thread Scratch Space)
+    *      Range  [0,11] indicating [1k bytes, 2M bytes] in powers of two"
+    */
+   const uint32_t max_scratch_size = 2 * 1024 * 1024;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* "Kernel Start Pointer" is 64-byte aligned */
+   assert(kernel->offset % 64 == 0);
+
+   assert(kernel->grf_start < max_grf_start);
+   assert(kernel->scratch_size <= max_scratch_size);
+
+   return true;
+}
+
+static bool
+ps_validate_gen6(const struct ilo_dev *dev,
+                 const struct ilo_state_ps_info *info)
+{
+   const struct ilo_state_shader_kernel_info *kernel_8 = &info->kernel_8;
+   const struct ilo_state_shader_kernel_info *kernel_16 = &info->kernel_16;
+   const struct ilo_state_shader_kernel_info *kernel_32 = &info->kernel_32;
+   const struct ilo_state_ps_io_info *io = &info->io;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!ps_kernel_validate_gen6(dev, kernel_8) ||
+       !ps_kernel_validate_gen6(dev, kernel_16) ||
+       !ps_kernel_validate_gen6(dev, kernel_32))
+      return false;
+
+   /* unsupported on Gen6 */
+   if (ilo_dev_gen(dev) == ILO_GEN(6))
+      assert(!io->use_coverage_mask);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 275:
+    *
+    *     "If a NULL Depth Buffer is selected, the Pixel Shader Computed Depth
+    *      field must be set to disabled."
+    */
+   if (ilo_dev_gen(dev) == ILO_GEN(6) && io->pscdepth != GEN7_PSCDEPTH_OFF)
+      assert(info->cv_has_depth_buffer);
+
+   if (!info->per_sample_dispatch) {
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 281:
+       *
+       *     "MSDISPMODE_PERSAMPLE is required in order to select
+       *      POSOFFSET_SAMPLE."
+       */
+      assert(io->posoffset != GEN6_POSOFFSET_SAMPLE);
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 282:
+       *
+       *     "MSDISPMODE_PERSAMPLE is required in order to select
+       *      INTERP_SAMPLE."
+       *
+       * From the Sandy Bridge PRM, volume 2 part 1, page 283:
+       *
+       *     "MSDISPMODE_PERSAMPLE is required in order to select Perspective
+       *      Sample or Non-perspective Sample barycentric coordinates."
+       */
+      assert(!info->cv_per_sample_interp);
+   }
+
+   /*
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 314:
+    *
+    *     "Pixel Shader Dispatch, Alpha... must all be disabled."
+    *
+    * Simply disallow any valid kernel when there is early-z op.  Also, when
+    * there is no valid kernel, io should be zeroed.
+    */
+   if (info->valid_kernels)
+      assert(!info->cv_has_earlyz_op);
+   else
+      assert(ilo_is_zeroed(io, sizeof(*io)));
+
+   return true;
+}
+
+static uint8_t
+ps_get_gen6_dispatch_modes(const struct ilo_dev *dev,
+                           const struct ilo_state_ps_info *info)
+{
+   const struct ilo_state_ps_io_info *io = &info->io;
+   uint8_t dispatch_modes = info->valid_kernels;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!dispatch_modes)
+      return 0;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 334:
+    *
+    *     "Not valid on [DevSNB] if 4x PERPIXEL mode with pixel shader
+    *      computed depth."
+    *
+    *     "Valid on all products, except when in non-1x PERSAMPLE mode
+    *      (applies to [DevSNB+] only)"
+    *
+    * From the Sandy Bridge PRM, volume 4 part 1, page 239:
+    *
+    *     "[DevSNB]: When Pixel Shader outputs oDepth and PS invocation mode
+    *      is PERPIXEL, Message Type for Render Target Write must be SIMD8.
+    *
+    *      Errata: [DevSNB+]: When Pixel Shader outputs oMask, this message
+    *      type is not supported: SIMD8 (including SIMD8_DUALSRC_xx)."
+    *
+    * It is really hard to follow what combinations are valid on what
+    * platforms.  Judging from the restrictions on RT write messages on Gen6,
+    * oDepth and oMask related issues should be Gen6-specific.  PERSAMPLE
+    * issue should be universal, and disallows multiple dispatch modes.
+    */
+   if (ilo_dev_gen(dev) == ILO_GEN(6)) {
+      if (io->pscdepth != GEN7_PSCDEPTH_OFF && !info->per_sample_dispatch)
+         dispatch_modes &= GEN6_PS_DISPATCH_8;
+      if (io->write_omask)
+         dispatch_modes &= ~GEN6_PS_DISPATCH_8;
+   }
+   if (info->per_sample_dispatch && !info->sample_count_one) {
+      /* prefer 32 over 16 over 8 */
+      if (dispatch_modes & GEN6_PS_DISPATCH_32)
+         dispatch_modes &= GEN6_PS_DISPATCH_32;
+      else if (dispatch_modes & GEN6_PS_DISPATCH_16)
+         dispatch_modes &= GEN6_PS_DISPATCH_16;
+      else
+         dispatch_modes &= GEN6_PS_DISPATCH_8;
+   }
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 149:
+    *
+    *     "When Render Target Fast Clear Enable is ENABLED or Render Target
+    *      Resolve Type = RESOLVE_PARTIAL or RESOLVE_FULL, this bit (8 Pixel
+    *      Dispatch or Dual-8 Pixel Dispatch Enable) must be DISABLED."
+    */
+   if (info->rt_clear_enable || info->rt_resolve_enable)
+      dispatch_modes &= ~GEN6_PS_DISPATCH_8;
+
+   assert(dispatch_modes);
+
+   return dispatch_modes;
+}
+
+static uint16_t
+ps_get_gen6_thread_count(const struct ilo_dev *dev,
+                         const struct ilo_state_ps_info *info)
+{
+   uint16_t thread_count;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* Maximum Number of Threads of 3DSTATE_PS */
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+      /* scaled automatically */
+      thread_count = 64 - 1;
+      break;
+   case ILO_GEN(7.5):
+      thread_count = (dev->gt == 3) ? 408 :
+                     (dev->gt == 2) ? 204 : 102;
+      break;
+   case ILO_GEN(7):
+      thread_count = (dev->gt == 2) ? 172 : 48;
+      break;
+   case ILO_GEN(6):
+   default:
+      /* from the classic driver instead of the PRM */
+      thread_count = (dev->gt == 2) ? 80 : 40;
+      break;
+   }
+
+   return thread_count - 1;
+}
+
+static bool
+ps_params_get_gen6_kill_pixel(const struct ilo_dev *dev,
+                              const struct ilo_state_ps_params_info *params,
+                              const struct ilo_state_ps_dispatch_conds *conds)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 275:
+    *
+    *     "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that the
+    *      PS kernel or color calculator has the ability to kill (discard)
+    *      pixels or samples, other than due to depth or stencil testing.
+    *      This bit is required to be ENABLED in the following situations:
+    *
+    *      The API pixel shader program contains "killpix" or "discard"
+    *      instructions, or other code in the pixel shader kernel that can
+    *      cause the final pixel mask to differ from the pixel mask received
+    *      on dispatch.
+    *
+    *      A sampler with chroma key enabled with kill pixel mode is used by
+    *      the pixel shader.
+    *
+    *      Any render target has Alpha Test Enable or AlphaToCoverage Enable
+    *      enabled.
+    *
+    *      The pixel shader kernel generates and outputs oMask.
+    *
+    *      Note: As ClipDistance clipping is fully supported in hardware and
+    *      therefore not via PS instructions, there should be no need to
+    *      ENABLE this bit due to ClipDistance clipping."
+    */
+   return (conds->ps_may_kill || params->alpha_may_kill);
+}
+
+static bool
+ps_params_get_gen6_dispatch_enable(const struct ilo_dev *dev,
+                                   const struct ilo_state_ps_params_info *params,
+                                   const struct ilo_state_ps_dispatch_conds *conds)
+{
+   /*
+    * We want to skip dispatching when EarlyZ suffices.  The conditions that
+    * require dispatching are
+    *
+    *  - PS writes RTs and RTs are writeable
+    *  - PS changes depth value and depth test/write is enabled
+    *  - PS changes stencil value and stencil test is enabled
+    *  - PS writes UAVs
+    *  - PS or CC kills pixels
+    *  - EDSC is PSEXEC, and depth test/write or stencil test is enabled
+    */
+   bool dispatch_required =
+      ((conds->has_rt_write && params->has_writeable_rt) ||
+       conds->write_odepth ||
+       conds->write_ostencil ||
+       conds->has_uav_write ||
+       ps_params_get_gen6_kill_pixel(dev, params, conds) ||
+       params->earlyz_control_psexec);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 280:
+    *
+    *     "If EDSC_PSEXEC mode is selected, Thread Dispatch Enable must be
+    *      set."
+    */
+   if (ilo_dev_gen(dev) < ILO_GEN(8) && params->earlyz_control_psexec)
+      dispatch_required = true;
+
+   /* assert it is valid to dispatch */
+   if (dispatch_required)
+      assert(conds->ps_valid);
+
+   return dispatch_required;
+}
+
+static bool
+ps_get_gen6_ff_kernels(const struct ilo_dev *dev,
+                       const struct ilo_state_ps_info *info,
+                       struct pixel_ff *ff)
+{
+   const struct ilo_state_shader_kernel_info *kernel_8 = &info->kernel_8;
+   const struct ilo_state_shader_kernel_info *kernel_16 = &info->kernel_16;
+   const struct ilo_state_shader_kernel_info *kernel_32 = &info->kernel_32;
+   uint32_t scratch_size;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   ff->dispatch_modes = ps_get_gen6_dispatch_modes(dev, info);
+
+   /* initialize kernel offsets and GRF starts */
+   if (util_is_power_of_two(ff->dispatch_modes)) {
+      if (ff->dispatch_modes & GEN6_PS_DISPATCH_8) {
+         ff->kernel_offsets[0] = kernel_8->offset;
+         ff->grf_starts[0] = kernel_8->grf_start;
+      } else if (ff->dispatch_modes & GEN6_PS_DISPATCH_16) {
+         ff->kernel_offsets[0] = kernel_16->offset;
+         ff->grf_starts[0] = kernel_16->grf_start;
+      } else if (ff->dispatch_modes & GEN6_PS_DISPATCH_32) {
+         ff->kernel_offsets[0] = kernel_32->offset;
+         ff->grf_starts[0] = kernel_32->grf_start;
+      }
+   } else {
+      ff->kernel_offsets[0] = kernel_8->offset;
+      ff->kernel_offsets[1] = kernel_32->offset;
+      ff->kernel_offsets[2] = kernel_16->offset;
+
+      ff->grf_starts[0] = kernel_8->grf_start;
+      ff->grf_starts[1] = kernel_32->grf_start;
+      ff->grf_starts[2] = kernel_16->grf_start;
+   }
+
+   /* we do not want to save it */
+   assert(ff->kernel_offsets[0] == 0);
+
+   ff->pcb_enable = (((ff->dispatch_modes & GEN6_PS_DISPATCH_8) &&
+                      kernel_8->pcb_attr_count) ||
+                     ((ff->dispatch_modes & GEN6_PS_DISPATCH_16) &&
+                      kernel_16->pcb_attr_count) ||
+                     ((ff->dispatch_modes & GEN6_PS_DISPATCH_32) &&
+                      kernel_32->pcb_attr_count));
+
+   scratch_size = 0;
+   if ((ff->dispatch_modes & GEN6_PS_DISPATCH_8) &&
+       scratch_size < kernel_8->scratch_size)
+      scratch_size = kernel_8->scratch_size;
+   if ((ff->dispatch_modes & GEN6_PS_DISPATCH_16) &&
+       scratch_size < kernel_16->scratch_size)
+      scratch_size = kernel_16->scratch_size;
+   if ((ff->dispatch_modes & GEN6_PS_DISPATCH_32) &&
+       scratch_size < kernel_32->scratch_size)
+      scratch_size = kernel_32->scratch_size;
+
+   /* next power of two, starting from 1KB */
+   ff->scratch_space = (scratch_size > 1024) ?
+      (util_last_bit(scratch_size - 1) - 10): 0;
+
+   /* GPU hangs on Haswell if none of the dispatch mode bits is set */
+   if (ilo_dev_gen(dev) == ILO_GEN(7.5) && !ff->dispatch_modes)
+      ff->dispatch_modes |= GEN6_PS_DISPATCH_8;
+
+   return true;
+}
+
+static bool
+ps_get_gen6_ff(const struct ilo_dev *dev,
+               const struct ilo_state_ps_info *info,
+               struct pixel_ff *ff)
+{
+   const struct ilo_state_shader_resource_info *resource = &info->resource;
+   const struct ilo_state_ps_io_info *io = &info->io;
+   const struct ilo_state_ps_params_info *params = &info->params;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   memset(ff, 0, sizeof(*ff));
+
+   if (!ps_validate_gen6(dev, info) || !ps_get_gen6_ff_kernels(dev, info, ff))
+      return false;
+
+   ff->sampler_count = (resource->sampler_count <= 12) ?
+      (resource->sampler_count + 3) / 4 : 4;
+   ff->surface_count = resource->surface_count;
+   ff->has_uav = resource->has_uav;
+
+   ff->thread_count = ps_get_gen6_thread_count(dev, info);
+
+   ff->conds.ps_valid = (info->valid_kernels != 0x0);
+   ff->conds.has_rt_write = io->has_rt_write;
+   ff->conds.write_odepth = (io->pscdepth != GEN7_PSCDEPTH_OFF);
+   ff->conds.write_ostencil = false;
+   ff->conds.has_uav_write = resource->has_uav;
+   ff->conds.ps_may_kill = (io->write_pixel_mask || io->write_omask);
+
+   ff->kill_pixel = ps_params_get_gen6_kill_pixel(dev, params, &ff->conds);
+   ff->dispatch_enable =
+      ps_params_get_gen6_dispatch_enable(dev, params, &ff->conds);
+   ff->dual_source_blending = params->dual_source_blending;
+   ff->sample_mask = params->sample_mask;
+
+   return true;
+}
+
+static bool
+ps_set_gen6_3dstate_wm(struct ilo_state_ps *ps,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_ps_info *info,
+                       const struct pixel_ff *ff)
+{
+   const struct ilo_state_ps_io_info *io = &info->io;
+   uint32_t dw2, dw3, dw4, dw5, dw6;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   dw2 = ff->sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (false)
+      dw2 |= GEN6_THREADDISP_FP_MODE_ALT;
+
+   dw3 = ff->scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw4 = ff->grf_starts[0] << GEN6_WM_DW4_URB_GRF_START0__SHIFT |
+         ff->grf_starts[1] << GEN6_WM_DW4_URB_GRF_START1__SHIFT |
+         ff->grf_starts[2] << GEN6_WM_DW4_URB_GRF_START2__SHIFT;
+
+   dw5 = ff->thread_count << GEN6_WM_DW5_MAX_THREADS__SHIFT |
+         ff->dispatch_modes << GEN6_WM_DW5_PS_DISPATCH_MODE__SHIFT;
+
+   if (ff->kill_pixel)
+      dw5 |= GEN6_WM_DW5_PS_KILL_PIXEL;
+
+   if (io->pscdepth != GEN7_PSCDEPTH_OFF)
+      dw5 |= GEN6_WM_DW5_PS_COMPUTE_DEPTH;
+   if (io->use_z)
+      dw5 |= GEN6_WM_DW5_PS_USE_DEPTH;
+
+   if (ff->dispatch_enable)
+      dw5 |= GEN6_WM_DW5_PS_DISPATCH_ENABLE;
+
+   if (io->write_omask)
+      dw5 |= GEN6_WM_DW5_PS_COMPUTE_OMASK;
+   if (io->use_w)
+      dw5 |= GEN6_WM_DW5_PS_USE_W;
+
+   if (ff->dual_source_blending)
+      dw5 |= GEN6_WM_DW5_PS_DUAL_SOURCE_BLEND;
+
+   dw6 = io->attr_count << GEN6_WM_DW6_SF_ATTR_COUNT__SHIFT |
+         io->posoffset << GEN6_WM_DW6_PS_POSOFFSET__SHIFT;
+
+   dw6 |= (info->per_sample_dispatch) ?
+      GEN6_WM_DW6_MSDISPMODE_PERSAMPLE : GEN6_WM_DW6_MSDISPMODE_PERPIXEL;
+
+   STATIC_ASSERT(ARRAY_SIZE(ps->ps) >= 7);
+   ps->ps[0] = dw2;
+   ps->ps[1] = dw3;
+   ps->ps[2] = dw4;
+   ps->ps[3] = dw5;
+   ps->ps[4] = dw6;
+   ps->ps[5] = ff->kernel_offsets[1];
+   ps->ps[6] = ff->kernel_offsets[2];
+
+   return true;
+}
+
+static bool
+ps_set_gen7_3dstate_wm(struct ilo_state_ps *ps,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_ps_info *info,
+                       const struct pixel_ff *ff)
+{
+   const struct ilo_state_ps_io_info *io = &info->io;
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 7, 7.5);
+
+   dw1 = io->pscdepth << GEN7_WM_DW1_PSCDEPTH__SHIFT;
+
+   if (ff->dispatch_enable)
+      dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
+   if (ff->kill_pixel)
+      dw1 |= GEN7_WM_DW1_PS_KILL_PIXEL;
+
+   if (io->use_z)
+      dw1 |= GEN7_WM_DW1_PS_USE_DEPTH;
+   if (io->use_w)
+      dw1 |= GEN7_WM_DW1_PS_USE_W;
+   if (io->use_coverage_mask)
+      dw1 |= GEN7_WM_DW1_PS_USE_COVERAGE_MASK;
+
+   dw2 = (info->per_sample_dispatch) ?
+      GEN7_WM_DW2_MSDISPMODE_PERSAMPLE : GEN7_WM_DW2_MSDISPMODE_PERPIXEL;
+
+   STATIC_ASSERT(ARRAY_SIZE(ps->ps) >= 2);
+   ps->ps[0] = dw1;
+   ps->ps[1] = dw2;
+
+   return true;
+}
+
+static bool
+ps_set_gen7_3DSTATE_PS(struct ilo_state_ps *ps,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_ps_info *info,
+                       const struct pixel_ff *ff)
+{
+   const struct ilo_state_ps_io_info *io = &info->io;
+   uint32_t dw2, dw3, dw4, dw5;
+
+   ILO_DEV_ASSERT(dev, 7, 7.5);
+
+   dw2 = ff->sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (false)
+      dw2 |= GEN6_THREADDISP_FP_MODE_ALT;
+
+   dw3 = ff->scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw4 = io->posoffset << GEN7_PS_DW4_POSOFFSET__SHIFT |
+         ff->dispatch_modes << GEN7_PS_DW4_DISPATCH_MODE__SHIFT;
+
+   if (ilo_dev_gen(dev) == ILO_GEN(7.5)) {
+      dw4 |= ff->thread_count << GEN75_PS_DW4_MAX_THREADS__SHIFT |
+             (ff->sample_mask & 0xff) << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
+   } else {
+      dw4 |= ff->thread_count << GEN7_PS_DW4_MAX_THREADS__SHIFT;
+   }
+
+   if (ff->pcb_enable)
+      dw4 |= GEN7_PS_DW4_PUSH_CONSTANT_ENABLE;
+   if (io->attr_count)
+      dw4 |= GEN7_PS_DW4_ATTR_ENABLE;
+   if (io->write_omask)
+      dw4 |= GEN7_PS_DW4_COMPUTE_OMASK;
+   if (info->rt_clear_enable)
+      dw4 |= GEN7_PS_DW4_RT_FAST_CLEAR;
+   if (ff->dual_source_blending)
+      dw4 |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
+   if (info->rt_resolve_enable)
+      dw4 |= GEN7_PS_DW4_RT_RESOLVE;
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5) && ff->has_uav)
+      dw4 |= GEN75_PS_DW4_ACCESS_UAV;
+
+   dw5 = ff->grf_starts[0] << GEN7_PS_DW5_URB_GRF_START0__SHIFT |
+         ff->grf_starts[1] << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
+         ff->grf_starts[2] << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(ps->ps) >= 8);
+   ps->ps[2] = dw2;
+   ps->ps[3] = dw3;
+   ps->ps[4] = dw4;
+   ps->ps[5] = dw5;
+   ps->ps[6] = ff->kernel_offsets[1];
+   ps->ps[7] = ff->kernel_offsets[2];
+
+   return true;
+}
+
+static bool
+ps_set_gen8_3DSTATE_PS(struct ilo_state_ps *ps,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_ps_info *info,
+                       const struct pixel_ff *ff)
+{
+   const struct ilo_state_ps_io_info *io = &info->io;
+   uint32_t dw3, dw4, dw6, dw7;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw3 = ff->sampler_count << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
+         ff->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
+
+   if (false)
+      dw3 |= GEN6_THREADDISP_FP_MODE_ALT;
+
+   dw4 = ff->scratch_space << GEN6_THREADSCRATCH_SPACE_PER_THREAD__SHIFT;
+
+   dw6 = ff->thread_count << GEN8_PS_DW6_MAX_THREADS__SHIFT |
+         io->posoffset << GEN8_PS_DW6_POSOFFSET__SHIFT |
+         ff->dispatch_modes << GEN8_PS_DW6_DISPATCH_MODE__SHIFT;
+
+   if (ff->pcb_enable)
+      dw6 |= GEN8_PS_DW6_PUSH_CONSTANT_ENABLE;
+
+   if (info->rt_clear_enable)
+      dw6 |= GEN8_PS_DW6_RT_FAST_CLEAR;
+   if (info->rt_resolve_enable)
+      dw6 |= GEN8_PS_DW6_RT_RESOLVE;
+
+   dw7 = ff->grf_starts[0] << GEN8_PS_DW7_URB_GRF_START0__SHIFT |
+         ff->grf_starts[1] << GEN8_PS_DW7_URB_GRF_START1__SHIFT |
+         ff->grf_starts[2] << GEN8_PS_DW7_URB_GRF_START2__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(ps->ps) >= 6);
+   ps->ps[0] = dw3;
+   ps->ps[1] = dw4;
+   ps->ps[2] = dw6;
+   ps->ps[3] = dw7;
+   ps->ps[4] = ff->kernel_offsets[1];
+   ps->ps[5] = ff->kernel_offsets[2];
+
+   return true;
+}
+
+static bool
+ps_set_gen8_3DSTATE_PS_EXTRA(struct ilo_state_ps *ps,
+                             const struct ilo_dev *dev,
+                             const struct ilo_state_ps_info *info,
+                             const struct pixel_ff *ff)
+{
+   const struct ilo_state_ps_io_info *io = &info->io;
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw1 = io->pscdepth << GEN8_PSX_DW1_PSCDEPTH__SHIFT;
+
+   if (info->valid_kernels)
+      dw1 |= GEN8_PSX_DW1_VALID;
+   if (!io->has_rt_write)
+      dw1 |= GEN8_PSX_DW1_UAV_ONLY;
+   if (io->write_omask)
+      dw1 |= GEN8_PSX_DW1_COMPUTE_OMASK;
+   if (io->write_pixel_mask)
+      dw1 |= GEN8_PSX_DW1_KILL_PIXEL;
+
+   if (io->use_z)
+      dw1 |= GEN8_PSX_DW1_USE_DEPTH;
+   if (io->use_w)
+      dw1 |= GEN8_PSX_DW1_USE_W;
+   if (io->attr_count)
+      dw1 |= GEN8_PSX_DW1_ATTR_ENABLE;
+
+   if (info->per_sample_dispatch)
+      dw1 |= GEN8_PSX_DW1_PER_SAMPLE;
+   if (ff->has_uav)
+      dw1 |= GEN8_PSX_DW1_ACCESS_UAV;
+   if (io->use_coverage_mask)
+      dw1 |= GEN8_PSX_DW1_USE_COVERAGE_MASK;
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 151:
+    *
+    *     "When this bit (Pixel Shader Valid) clear the rest of this command
+    *      should also be clear.
+    */
+   if (!info->valid_kernels)
+      dw1 = 0;
+
+   STATIC_ASSERT(ARRAY_SIZE(ps->ps) >= 5);
+   ps->ps[4] = dw1;
+
+   return true;
+}
+
+bool
+ilo_state_ps_init(struct ilo_state_ps *ps,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_ps_info *info)
+{
+   struct pixel_ff ff;
+   bool ret = true;
+
+   assert(ilo_is_zeroed(ps, sizeof(*ps)));
+
+   ret &= ps_get_gen6_ff(dev, info, &ff);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      ret &= ps_set_gen8_3DSTATE_PS(ps, dev, info, &ff);
+      ret &= ps_set_gen8_3DSTATE_PS_EXTRA(ps, dev, info, &ff);
+   } else if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      ret &= ps_set_gen7_3dstate_wm(ps, dev, info, &ff);
+      ret &= ps_set_gen7_3DSTATE_PS(ps, dev, info, &ff);
+   } else {
+      ret &= ps_set_gen6_3dstate_wm(ps, dev, info, &ff);
+   }
+
+   /* save conditions */
+   ps->conds = ff.conds;
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_ps_init_disabled(struct ilo_state_ps *ps,
+                           const struct ilo_dev *dev)
+{
+   struct ilo_state_ps_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_ps_init(ps, dev, &info);
+}
+
+bool
+ilo_state_ps_set_params(struct ilo_state_ps *ps,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_ps_params_info *params)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* modify sample mask */
+   if (ilo_dev_gen(dev) == ILO_GEN(7.5)) {
+      ps->ps[4] = (ps->ps[4] & ~GEN75_PS_DW4_SAMPLE_MASK__MASK) |
+         (params->sample_mask & 0xff) << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
+   }
+
+   /* modify dispatch enable, pixel kill, and dual source blending */
+   if (ilo_dev_gen(dev) < ILO_GEN(8)) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+         if (ps_params_get_gen6_dispatch_enable(dev, params, &ps->conds))
+            ps->ps[0] |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
+         else
+            ps->ps[0] &= ~GEN7_WM_DW1_PS_DISPATCH_ENABLE;
+
+         if (ps_params_get_gen6_kill_pixel(dev, params, &ps->conds))
+            ps->ps[0] |= GEN7_WM_DW1_PS_KILL_PIXEL;
+         else
+            ps->ps[0] &= ~GEN7_WM_DW1_PS_KILL_PIXEL;
+
+         if (params->dual_source_blending)
+            ps->ps[4] |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
+         else
+            ps->ps[4] &= ~GEN7_PS_DW4_DUAL_SOURCE_BLEND;
+      } else {
+         if (ps_params_get_gen6_dispatch_enable(dev, params, &ps->conds))
+            ps->ps[3] |= GEN6_WM_DW5_PS_DISPATCH_ENABLE;
+         else
+            ps->ps[3] &= ~GEN6_WM_DW5_PS_DISPATCH_ENABLE;
+
+         if (ps_params_get_gen6_kill_pixel(dev, params, &ps->conds))
+            ps->ps[3] |= GEN6_WM_DW5_PS_KILL_PIXEL;
+         else
+            ps->ps[3] &= ~GEN6_WM_DW5_PS_KILL_PIXEL;
+
+         if (params->dual_source_blending)
+            ps->ps[3] |= GEN6_WM_DW5_PS_DUAL_SOURCE_BLEND;
+         else
+            ps->ps[3] &= ~GEN6_WM_DW5_PS_DUAL_SOURCE_BLEND;
+      }
+   }
+
+   return true;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sol.c b/src/gallium/drivers/ilo/core/ilo_state_sol.c
new file mode 100644 (file)
index 0000000..38c0b71
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_buffer.h"
+#include "ilo_state_sol.h"
+
+static bool
+sol_stream_validate_gen7(const struct ilo_dev *dev,
+                         const struct ilo_state_sol_stream_info *stream)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   assert(stream->vue_read_base + stream->vue_read_count <=
+         stream->cv_vue_attr_count);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 200:
+    *
+    *     "(Stream 0 Vertex Read Offset)
+    *      Format: U1 count of 256-bit units
+    *
+    *      Specifies amount of data to skip over before reading back Stream 0
+    *      vertex data. Must be zero if the GS is enabled and the Output
+    *      Vertex Size field in 3DSTATE_GS is programmed to 0 (i.e., one 16B
+    *      unit)."
+    *
+    *     "(Stream 0 Vertex Read Length)
+    *      Format: U5-1 count of 256-bit units
+    *
+    *      Specifies amount of vertex data to read back for Stream 0 vertices,
+    *      starting at the Stream 0 Vertex Read Offset location. Maximum
+    *      readback is 17 256-bit units (34 128-bit vertex attributes). Read
+    *      data past the end of the valid vertex data has undefined contents,
+    *      and therefore shouldn't be used to source stream out data.  Must be
+    *      zero (i.e., read length = 256b) if the GS is enabled and the Output
+    *      Vertex Size field in 3DSTATE_GS is programmed to 0 (i.e., one 16B
+    *      unit)."
+    */
+   assert(stream->vue_read_base == 0 || stream->vue_read_base == 2);
+   assert(stream->vue_read_count <= 34);
+
+   assert(stream->decl_count <= ILO_STATE_SOL_MAX_DECL_COUNT);
+
+   for (i = 0; i < stream->decl_count; i++) {
+      const struct ilo_state_sol_decl_info *decl = &stream->decls[i];
+
+      assert(decl->is_hole || decl->attr < stream->vue_read_count);
+
+      /*
+       * From the Ivy Bridge PRM, volume 2 part 1, page 205:
+       *
+       *     "There is only enough internal storage for the 128-bit vertex
+       *      header and 32 128-bit vertex attributes."
+       */
+      assert(decl->attr < 33);
+
+      assert(decl->component_base < 4 &&
+             decl->component_base + decl->component_count <= 4);
+      assert(decl->buffer < ILO_STATE_SOL_MAX_BUFFER_COUNT);
+   }
+
+   return true;
+}
+
+static bool
+sol_validate_gen7(const struct ilo_dev *dev,
+                  const struct ilo_state_sol_info *info)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 198:
+    *
+    *     "This bit (Render Stream Select) is used even if SO Function Enable
+    *      is DISABLED."
+    *
+    * From the Haswell PRM, volume 2b, page 796:
+    *
+    *     "SO Function Enable must also be ENABLED in order for thiis field
+    *      (Render Stream Select) to select a stream for rendering. When SO
+    *      Function Enable is DISABLED and Rendering Disable is cleared (i.e.,
+    *      rendering is enabled), StreamID is ignored downstream of the SO
+    *      stage, allowing any stream to be rendered."
+    *
+    * We want Gen7 behavior, but we have to require users to follow Gen7.5
+    * behavior: info->sol_enable must be set for info->render_stream to work.
+    */
+
+   for (i = 0; i < ARRAY_SIZE(info->streams); i++) {
+      if (!sol_stream_validate_gen7(dev, &info->streams[i]))
+         return false;
+   }
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 208:
+    *
+    *     "(Surface Pitch)
+    *      [0,2048]  Must be 0 or a multiple of 4 Bytes."
+    */
+   for (i = 0; i < ARRAY_SIZE(info->buffer_strides); i++) {
+      assert(info->buffer_strides[i] <= 2048 &&
+             info->buffer_strides[i] % 4 == 0);
+   }
+
+   return true;
+}
+
+static bool
+sol_set_gen7_3DSTATE_STREAMOUT(struct ilo_state_sol *sol,
+                               const struct ilo_dev *dev,
+                               const struct ilo_state_sol_info *info)
+{
+   struct {
+      uint8_t offset;
+      uint8_t len;
+   } vue_read[ILO_STATE_SOL_MAX_STREAM_COUNT];
+   uint8_t i;
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!sol_validate_gen7(dev, info))
+      return false;
+
+   for (i = 0; i < ARRAY_SIZE(info->streams); i++) {
+      const struct ilo_state_sol_stream_info *stream = &info->streams[i];
+
+      vue_read[i].offset = stream->vue_read_base / 2;
+      /*
+       * In pairs minus 1.  URB entries are aligned to 512-bits.  There is no
+       * need to worry about reading past entries.
+       */
+      vue_read[i].len = (stream->vue_read_count + 1) / 2;
+      if (vue_read[i].len)
+         vue_read[i].len--;
+   }
+
+   dw1 = info->render_stream << GEN7_SO_DW1_RENDER_STREAM_SELECT__SHIFT |
+         info->tristrip_reorder << GEN7_SO_DW1_REORDER_MODE__SHIFT;
+
+   if (info->sol_enable)
+      dw1 |= GEN7_SO_DW1_SO_ENABLE;
+
+   if (info->render_disable)
+      dw1 |= GEN7_SO_DW1_RENDER_DISABLE;
+
+   if (info->stats_enable)
+      dw1 |= GEN7_SO_DW1_STATISTICS;
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8)) {
+      const uint8_t buffer_enables = ((bool) info->buffer_strides[3]) << 3 |
+                                     ((bool) info->buffer_strides[2]) << 2 |
+                                     ((bool) info->buffer_strides[1]) << 1 |
+                                     ((bool) info->buffer_strides[0]);
+      dw1 |= buffer_enables << GEN7_SO_DW1_BUFFER_ENABLES__SHIFT;
+   }
+
+   dw2 = vue_read[3].offset << GEN7_SO_DW2_STREAM3_READ_OFFSET__SHIFT |
+         vue_read[3].len << GEN7_SO_DW2_STREAM3_READ_LEN__SHIFT |
+         vue_read[2].offset << GEN7_SO_DW2_STREAM2_READ_OFFSET__SHIFT |
+         vue_read[2].len << GEN7_SO_DW2_STREAM2_READ_LEN__SHIFT |
+         vue_read[1].offset << GEN7_SO_DW2_STREAM1_READ_OFFSET__SHIFT |
+         vue_read[1].len << GEN7_SO_DW2_STREAM1_READ_LEN__SHIFT |
+         vue_read[0].offset << GEN7_SO_DW2_STREAM0_READ_OFFSET__SHIFT |
+         vue_read[0].len << GEN7_SO_DW2_STREAM0_READ_LEN__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(sol->streamout) >= 2);
+   sol->streamout[0] = dw1;
+   sol->streamout[1] = dw2;
+
+   memcpy(sol->strides, info->buffer_strides, sizeof(sol->strides));
+
+   return true;
+}
+
+static bool
+sol_set_gen7_3DSTATE_SO_DECL_LIST(struct ilo_state_sol *sol,
+                                  const struct ilo_dev *dev,
+                                  const struct ilo_state_sol_info *info,
+                                  uint8_t max_decl_count)
+{
+   uint64_t decl_list[ILO_STATE_SOL_MAX_DECL_COUNT];
+   uint8_t decl_counts[ILO_STATE_SOL_MAX_STREAM_COUNT];
+   uint8_t buffer_selects[ILO_STATE_SOL_MAX_STREAM_COUNT];
+   uint32_t dw1, dw2;
+   uint8_t i, j;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   memset(decl_list, 0, sizeof(decl_list[0]) * max_decl_count);
+
+   for (i = 0; i < ARRAY_SIZE(info->streams); i++) {
+      const struct ilo_state_sol_stream_info *stream = &info->streams[i];
+
+      assert(stream->decl_count <= max_decl_count);
+      decl_counts[i] = stream->decl_count;
+      buffer_selects[i] = 0;
+
+      for (j = 0; j < stream->decl_count; j++) {
+         const struct ilo_state_sol_decl_info *decl = &stream->decls[j];
+         const uint8_t mask = ((1 << decl->component_count) - 1) <<
+            decl->component_base;
+         uint16_t val;
+
+         val = decl->buffer << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
+               mask << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
+
+         if (decl->is_hole)
+            val |= GEN7_SO_DECL_HOLE_FLAG;
+         else
+            val |= decl->attr << GEN7_SO_DECL_REG_INDEX__SHIFT;
+
+         decl_list[j] |= (uint64_t) val << (16 * i);
+         buffer_selects[i] |= 1 << decl->buffer;
+      }
+   }
+
+   dw1 = buffer_selects[3] << GEN7_SO_DECL_DW1_STREAM3_BUFFER_SELECTS__SHIFT |
+         buffer_selects[2] << GEN7_SO_DECL_DW1_STREAM2_BUFFER_SELECTS__SHIFT |
+         buffer_selects[1] << GEN7_SO_DECL_DW1_STREAM1_BUFFER_SELECTS__SHIFT |
+         buffer_selects[0] << GEN7_SO_DECL_DW1_STREAM0_BUFFER_SELECTS__SHIFT;
+   dw2 = decl_counts[3] << GEN7_SO_DECL_DW2_STREAM3_ENTRY_COUNT__SHIFT |
+         decl_counts[2] << GEN7_SO_DECL_DW2_STREAM2_ENTRY_COUNT__SHIFT |
+         decl_counts[1] << GEN7_SO_DECL_DW2_STREAM1_ENTRY_COUNT__SHIFT |
+         decl_counts[0] << GEN7_SO_DECL_DW2_STREAM0_ENTRY_COUNT__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(sol->so_decl) >= 2);
+   sol->so_decl[0] = dw1;
+   sol->so_decl[1] = dw2;
+
+   STATIC_ASSERT(ARRAY_SIZE(sol->decl[0]) == 2);
+   memcpy(sol->decl, decl_list, sizeof(sol->decl[0]) * max_decl_count);
+   sol->decl_count = max_decl_count;
+
+   return true;
+}
+
+static bool
+sol_buffer_validate_gen7(const struct ilo_dev *dev,
+                         const struct ilo_state_sol_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (info->buf)
+      assert(info->offset < info->buf->bo_size && info->size);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 208:
+    *
+    *     "(Surface Base Address) This field specifies the starting DWord
+    *      address..."
+    */
+   assert(info->offset % 4 == 0);
+
+   /* Gen8+ only */
+   if (info->write_offset_load || info->write_offset_save)
+      assert(ilo_dev_gen(dev) >= ILO_GEN(8));
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 206:
+    *
+    *     "This field (Stream Offset) specifies the Offset in stream output
+    *      buffer to start at, or whether to append to the end of an existing
+    *      buffer. The Offset must be DWORD aligned."
+    */
+   if (info->write_offset_imm_enable) {
+      assert(info->write_offset_load);
+      assert(info->write_offset_imm % 4 == 0);
+   }
+
+   return true;
+}
+
+static uint32_t
+sol_buffer_get_gen6_size(const struct ilo_dev *dev,
+                         const struct ilo_state_sol_buffer_info *info)
+{
+   uint32_t size;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!info->buf)
+      return 0;
+
+   size = (info->offset + info->size <= info->buf->bo_size) ? info->size :
+      info->buf->bo_size - info->offset;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 208:
+    *
+    *     "(Surface End Address) This field specifies the ending DWord
+    *      address..."
+    */
+   size &= ~3;
+
+   return size;
+}
+
+static bool
+sol_buffer_set_gen7_3dstate_so_buffer(struct ilo_state_sol_buffer *sb,
+                                      const struct ilo_dev *dev,
+                                      const struct ilo_state_sol_buffer_info *info)
+{
+   const uint32_t size = sol_buffer_get_gen6_size(dev, info);
+
+   ILO_DEV_ASSERT(dev, 7, 7.5);
+
+   if (!sol_buffer_validate_gen7(dev, info))
+      return false;
+
+   STATIC_ASSERT(ARRAY_SIZE(sb->so_buf) >= 2);
+   sb->so_buf[0] = info->offset;
+   sb->so_buf[1] = (size) ? info->offset + size : 0;
+
+   return true;
+}
+
+static bool
+sol_buffer_set_gen8_3dstate_so_buffer(struct ilo_state_sol_buffer *sb,
+                                      const struct ilo_dev *dev,
+                                      const struct ilo_state_sol_buffer_info *info)
+{
+   const uint32_t size = sol_buffer_get_gen6_size(dev, info);
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   if (!sol_buffer_validate_gen7(dev, info))
+      return false;
+
+   dw1 = 0;
+
+   if (info->buf)
+      dw1 |= GEN8_SO_BUF_DW1_ENABLE;
+   if (info->write_offset_load)
+      dw1 |= GEN8_SO_BUF_DW1_OFFSET_WRITE_ENABLE;
+   if (info->write_offset_save)
+      dw1 |= GEN8_SO_BUF_DW1_OFFSET_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(sb->so_buf) >= 4);
+   sb->so_buf[0] = dw1;
+   sb->so_buf[1] = info->offset;
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 205:
+    *
+    *     "This field (Surface Size) specifies the size of buffer in number
+    *      DWords minus 1 of the buffer in Graphics Memory."
+    */
+   sb->so_buf[2] = (size) ? size / 4 - 1 : 0;
+
+   /* load from imm or sb->write_offset_bo */
+   sb->so_buf[3] = (info->write_offset_imm_enable) ?
+      info->write_offset_imm : ~0u;
+
+   return true;
+}
+
+bool
+ilo_state_sol_init(struct ilo_state_sol *sol,
+                   const struct ilo_dev *dev,
+                   const struct ilo_state_sol_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(sol, sizeof(*sol)));
+   assert(ilo_is_zeroed(info->data, info->data_size));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      uint8_t max_decl_count, i;
+
+      max_decl_count = info->streams[0].decl_count;
+      for (i = 1; i < ARRAY_SIZE(info->streams); i++) {
+         if (max_decl_count < info->streams[i].decl_count)
+            max_decl_count = info->streams[i].decl_count;
+      }
+
+      assert(ilo_state_sol_data_size(dev, max_decl_count) <= info->data_size);
+      sol->decl = (uint32_t (*)[2]) info->data;
+
+      ret &= sol_set_gen7_3DSTATE_STREAMOUT(sol, dev, info);
+      ret &= sol_set_gen7_3DSTATE_SO_DECL_LIST(sol, dev, info, max_decl_count);
+   }
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_sol_init_disabled(struct ilo_state_sol *sol,
+                            const struct ilo_dev *dev,
+                            bool render_disable)
+{
+   struct ilo_state_sol_info info;
+
+   memset(&info, 0, sizeof(info));
+   info.render_disable = render_disable;
+
+   return ilo_state_sol_init(sol, dev, &info);
+}
+
+bool
+ilo_state_sol_buffer_init(struct ilo_state_sol_buffer *sb,
+                          const struct ilo_dev *dev,
+                          const struct ilo_state_sol_buffer_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(sb, sizeof(*sb)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      ret &= sol_buffer_set_gen8_3dstate_so_buffer(sb, dev, info);
+   else
+      ret &= sol_buffer_set_gen7_3dstate_so_buffer(sb, dev, info);
+
+   sb->need_bo = (info->size > 0);
+   sb->need_write_offset_bo = (info->write_offset_save ||
+         (info->write_offset_load && !info->write_offset_imm_enable));
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_sol_buffer_init_disabled(struct ilo_state_sol_buffer *sb,
+                                   const struct ilo_dev *dev)
+{
+   struct ilo_state_sol_buffer_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_sol_buffer_init(sb, dev, &info);
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sol.h b/src/gallium/drivers/ilo/core/ilo_state_sol.h
new file mode 100644 (file)
index 0000000..2513fcb
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_SOL_H
+#define ILO_STATE_SOL_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 193:
+ *
+ *     "Incoming topologies are tagged with a 2-bit StreamID."
+ */
+#define ILO_STATE_SOL_MAX_STREAM_COUNT 4
+
+/*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 195:
+ *
+ *     "Up to four SO buffers are supported."
+ */
+#define ILO_STATE_SOL_MAX_BUFFER_COUNT 4
+
+/*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 201:
+ *
+ *     "All 128 decls..."
+ */
+#define ILO_STATE_SOL_MAX_DECL_COUNT 128
+
+/**
+ * Output a vertex attribute.
+ */
+struct ilo_state_sol_decl_info {
+   /* select an attribute from read ones */
+   uint8_t attr;
+   bool is_hole;
+
+   /* which components to write */
+   uint8_t component_base;
+   uint8_t component_count;
+
+   /* destination buffer */
+   uint8_t buffer;
+};
+
+struct ilo_state_sol_stream_info {
+   /* which VUE attributes to read */
+   uint8_t cv_vue_attr_count;
+   uint8_t vue_read_base;
+   uint8_t vue_read_count;
+
+   uint8_t decl_count;
+   const struct ilo_state_sol_decl_info *decls;
+};
+
+struct ilo_state_sol_info {
+   void *data;
+   size_t data_size;
+
+   bool sol_enable;
+   bool stats_enable;
+   enum gen_reorder_mode tristrip_reorder;
+
+   bool render_disable;
+   /* ignored when SOL is disabled */
+   uint8_t render_stream;
+
+   /* a buffer is disabled when its stride is zero */
+   uint16_t buffer_strides[ILO_STATE_SOL_MAX_BUFFER_COUNT];
+
+   struct ilo_state_sol_stream_info streams[ILO_STATE_SOL_MAX_STREAM_COUNT];
+};
+
+struct ilo_state_sol {
+   uint32_t streamout[2];
+   uint16_t strides[4];
+
+   uint32_t so_decl[2];
+   uint32_t (*decl)[2];
+   uint8_t decl_count;
+};
+
+struct ilo_buffer;
+
+struct ilo_state_sol_buffer_info {
+   const struct ilo_buffer *buf;
+   uint32_t offset;
+   uint32_t size;
+
+   /*
+    * Gen8+ only.  When enabled, require a write offset bo of at least
+    * (sizeof(uint32_t) * ILO_STATE_SOL_MAX_BUFFER_COUNT) bytes
+    */
+   bool write_offset_load;
+   bool write_offset_save;
+
+   bool write_offset_imm_enable;
+   uint32_t write_offset_imm;
+};
+
+struct ilo_state_sol_buffer {
+   uint32_t so_buf[4];
+
+   bool need_bo;
+   bool need_write_offset_bo;
+
+   /* managed by users */
+   struct intel_bo *bo;
+   struct intel_bo *write_offset_bo;
+};
+
+static inline size_t
+ilo_state_sol_data_size(const struct ilo_dev *dev, uint8_t max_decl_count)
+{
+   const struct ilo_state_sol *so = NULL;
+   return (ilo_dev_gen(dev) >= ILO_GEN(7)) ?
+      sizeof(so->decl[0]) * max_decl_count : 0;
+}
+
+bool
+ilo_state_sol_init(struct ilo_state_sol *sol,
+                   const struct ilo_dev *dev,
+                   const struct ilo_state_sol_info *info);
+
+bool
+ilo_state_sol_init_disabled(struct ilo_state_sol *sol,
+                            const struct ilo_dev *dev,
+                            bool render_disable);
+
+bool
+ilo_state_sol_buffer_init(struct ilo_state_sol_buffer *sb,
+                          const struct ilo_dev *dev,
+                          const struct ilo_state_sol_buffer_info *info);
+
+bool
+ilo_state_sol_buffer_init_disabled(struct ilo_state_sol_buffer *sb,
+                                   const struct ilo_dev *dev);
+
+#endif /* ILO_STATE_SOL_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_surface.c b/src/gallium/drivers/ilo/core/ilo_state_surface.c
new file mode 100644 (file)
index 0000000..5be9f8f
--- /dev/null
@@ -0,0 +1,1179 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_buffer.h"
+#include "ilo_image.h"
+#include "ilo_state_surface.h"
+
+static bool
+surface_set_gen6_null_SURFACE_STATE(struct ilo_state_surface *surf,
+                                    const struct ilo_dev *dev)
+{
+   uint32_t dw0, dw3;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 71:
+    *
+    *     "All of the remaining fields in surface state are ignored for null
+    *      surfaces, with the following exceptions:
+    *
+    *        - [DevSNB+]: Width, Height, Depth, and LOD fields must match the
+    *          depth buffer's corresponding state for all render target
+    *          surfaces, including null.
+    *        - Surface Format must be R8G8B8A8_UNORM."
+    *
+    * From the Sandy Bridge PRM, volume 4 part 1, page 82:
+    *
+    *     "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must
+    *      be true"
+    *
+    * Note that we ignore the first exception for all surface types.
+    */
+   dw0 = GEN6_SURFTYPE_NULL << GEN6_SURFACE_DW0_TYPE__SHIFT |
+         GEN6_FORMAT_R8G8B8A8_UNORM << GEN6_SURFACE_DW0_FORMAT__SHIFT;
+   dw3 = GEN6_TILING_X << GEN6_SURFACE_DW3_TILING__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(surf->surface) >= 6);
+   surf->surface[0] = dw0;
+   surf->surface[1] = 0;
+   surf->surface[2] = 0;
+   surf->surface[3] = dw3;
+   surf->surface[4] = 0;
+   surf->surface[5] = 0;
+
+   return true;
+}
+
+static bool
+surface_set_gen7_null_SURFACE_STATE(struct ilo_state_surface *surf,
+                                    const struct ilo_dev *dev)
+{
+   uint32_t dw0;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   dw0 = GEN6_SURFTYPE_NULL << GEN7_SURFACE_DW0_TYPE__SHIFT |
+         GEN6_FORMAT_R8G8B8A8_UNORM << GEN7_SURFACE_DW0_FORMAT__SHIFT;
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      dw0 |= GEN6_TILING_X << GEN8_SURFACE_DW0_TILING__SHIFT;
+   else
+      dw0 |= GEN6_TILING_X << GEN7_SURFACE_DW0_TILING__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(surf->surface) >= 13);
+   surf->surface[0] = dw0;
+   memset(&surf->surface[1], 0, sizeof(uint32_t) *
+         (((ilo_dev_gen(dev) >= ILO_GEN(8)) ? 13 : 8) - 1));
+
+   return true;
+}
+
+static bool
+surface_validate_gen6_buffer(const struct ilo_dev *dev,
+                             const struct ilo_state_surface_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* SVB writes are Gen6-only */
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      assert(info->access != ILO_STATE_SURFACE_ACCESS_DP_SVB);
+
+   if (info->offset + info->size > info->buf->bo_size) {
+      ilo_warn("invalid buffer range\n");
+      return false;
+   }
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 81:
+    *
+    *     "For surfaces of type SURFTYPE_BUFFER: [0,2047] -> [1B, 2048B]
+    *      For surfaces of type SURFTYPE_STRBUF: [0,2047] -> [1B, 2048B]"
+    */
+   if (!info->struct_size || info->struct_size > 2048) {
+      ilo_warn("invalid buffer struct size\n");
+      return false;
+   }
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 68:
+    *
+    *     "The Base Address for linear render target surfaces and surfaces
+    *      accessed with the typed surface read/write data port messages must
+    *      be element-size aligned, for non-YUV surface formats, or a multiple
+    *      of 2 element-sizes for YUV surface formats.  Other linear surfaces
+    *      have no alignment requirements (byte alignment is sufficient)."
+    *
+    *     "Certain message types used to access surfaces have more stringent
+    *      alignment requirements. Please refer to the specific message
+    *      documentation for additional restrictions."
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 233, 235, and 237:
+    *
+    *     "the surface base address must be OWord aligned"
+    *
+    * for OWord Block Read/Write, Unaligned OWord Block Read, and OWord Dual
+    * Block Read/Write.
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 246 and 249:
+    *
+    *     "The surface base address must be DWord aligned"
+    *
+    * for DWord Scattered Read/Write and Byte Scattered Read/Write.
+    *
+    * We have to rely on users to correctly set info->struct_size here.  DWord
+    * Scattered Read/Write has conflicting pitch and alignment, but we do not
+    * use them yet so we are fine.
+    *
+    * It is unclear if sampling engine surfaces require aligned offsets.
+    */
+   if (info->access != ILO_STATE_SURFACE_ACCESS_DP_SVB) {
+      assert(info->struct_size % info->format_size == 0);
+
+      if (info->offset % info->struct_size) {
+         ilo_warn("bad buffer offset\n");
+         return false;
+      }
+   }
+
+   if (info->format == GEN6_FORMAT_RAW) {
+      /*
+       * From the Sandy Bridge PRM, volume 4 part 1, page 97:
+       *
+       *     ""RAW" is supported only with buffers and structured buffers
+       *      accessed via the untyped surface read/write and untyped atomic
+       *      operation messages, which do not have a column in the table."
+       *
+       * We do not have a specific access mode for untyped messages.
+       */
+      assert(info->access == ILO_STATE_SURFACE_ACCESS_DP_UNTYPED);
+
+      /*
+       * Nothing is said about Untyped* messages, but I guess they require the
+       * base address to be DWord aligned.
+       */
+      if (info->offset % 4) {
+         ilo_warn("bad RAW buffer offset\n");
+         return false;
+      }
+
+      if (info->struct_size > 1) {
+         /* no STRBUF on Gen6 */
+         if (ilo_dev_gen(dev) == ILO_GEN(6)) {
+            ilo_warn("no STRBUF support\n");
+            return false;
+         }
+
+         /*
+          * From the Ivy Bridge PRM, volume 4 part 1, page 70:
+          *
+          *     "For linear surfaces with Surface Type of SURFTYPE_STRBUF, the
+          *      pitch must be a multiple of 4 bytes."
+          */
+         if (info->struct_size % 4) {
+            ilo_warn("bad STRBUF pitch\n");
+            return false;
+         }
+      }
+   }
+
+   return true;
+}
+
+static bool
+surface_get_gen6_buffer_struct_count(const struct ilo_dev *dev,
+                                     const struct ilo_state_surface_buffer_info *info,
+                                     uint32_t *count)
+{
+   uint32_t max_struct, c;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   c = info->size / info->struct_size;
+   if (info->access == ILO_STATE_SURFACE_ACCESS_DP_SVB &&
+       info->format_size < info->size - info->struct_size * c)
+      c++;
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 77:
+    *
+    *     "For buffer surfaces, the number of entries in the buffer ranges
+    *      from 1 to 2^27."
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 68:
+    *
+    *     "For typed buffer and structured buffer surfaces, the number of
+    *      entries in the buffer ranges from 1 to 2^27.  For raw buffer
+    *      surfaces, the number of entries in the buffer is the number of
+    *      bytes which can range from 1 to 2^30."
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 69:
+    *
+    *      For SURFTYPE_BUFFER: The low two bits of this field (Width) must be
+    *      11 if the Surface Format is RAW (the size of the buffer must be a
+    *      multiple of 4 bytes)."
+    */
+   max_struct = 1 << 27;
+   if (info->format == GEN6_FORMAT_RAW && info->struct_size == 1) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(7))
+         max_struct = 1 << 30;
+
+      c &= ~3;
+   }
+
+   if (!c || c > max_struct) {
+      ilo_warn("too many or zero buffer structs\n");
+      return false;
+   }
+
+   *count = c - 1;
+
+   return true;
+}
+
+static bool
+surface_set_gen6_buffer_SURFACE_STATE(struct ilo_state_surface *surf,
+                                     const struct ilo_dev *dev,
+                                     const struct ilo_state_surface_buffer_info *info)
+{
+   uint32_t dw0, dw1, dw2, dw3;
+   uint32_t struct_count;
+   int width, height, depth;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   if (!surface_validate_gen6_buffer(dev, info) ||
+       !surface_get_gen6_buffer_struct_count(dev, info, &struct_count))
+      return false;
+
+   /* bits [6:0] */
+   width  = (struct_count & 0x0000007f);
+   /* bits [19:7] */
+   height = (struct_count & 0x000fff80) >> 7;
+   /* bits [26:20] */
+   depth  = (struct_count & 0x07f00000) >> 20;
+
+   dw0 = GEN6_SURFTYPE_BUFFER << GEN6_SURFACE_DW0_TYPE__SHIFT |
+         info->format << GEN6_SURFACE_DW0_FORMAT__SHIFT;
+   dw1 = info->offset;
+   dw2 = height << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
+         width << GEN6_SURFACE_DW2_WIDTH__SHIFT;
+   dw3 = depth << GEN6_SURFACE_DW3_DEPTH__SHIFT |
+         (info->struct_size - 1) << GEN6_SURFACE_DW3_PITCH__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(surf->surface) >= 6);
+   surf->surface[0] = dw0;
+   surf->surface[1] = dw1;
+   surf->surface[2] = dw2;
+   surf->surface[3] = dw3;
+   surf->surface[4] = 0;
+   surf->surface[5] = 0;
+
+   surf->type = GEN6_SURFTYPE_BUFFER;
+   surf->min_lod = 0;
+   surf->mip_count = 0;
+
+   return true;
+}
+
+static bool
+surface_set_gen7_buffer_SURFACE_STATE(struct ilo_state_surface *surf,
+                                     const struct ilo_dev *dev,
+                                     const struct ilo_state_surface_buffer_info *info)
+{
+   uint32_t dw0, dw1, dw2, dw3, dw7;
+   enum gen_surface_type type;
+   uint32_t struct_count;
+   int width, height, depth;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!surface_validate_gen6_buffer(dev, info) ||
+       !surface_get_gen6_buffer_struct_count(dev, info, &struct_count))
+      return false;
+
+   type = (info->format == GEN6_FORMAT_RAW && info->struct_size > 1) ?
+      GEN7_SURFTYPE_STRBUF : GEN6_SURFTYPE_BUFFER;
+
+   /* bits [6:0] */
+   width  = (struct_count & 0x0000007f);
+   /* bits [20:7] */
+   height = (struct_count & 0x001fff80) >> 7;
+   /* bits [30:21] */
+   depth  = (struct_count & 0x7fe00000) >> 21;
+
+   dw0 = type << GEN7_SURFACE_DW0_TYPE__SHIFT |
+         info->format << GEN7_SURFACE_DW0_FORMAT__SHIFT;
+   dw1 = (ilo_dev_gen(dev) >= ILO_GEN(8)) ? 0 : info->offset;
+   dw2 = GEN_SHIFT32(height, GEN7_SURFACE_DW2_HEIGHT) |
+         GEN_SHIFT32(width, GEN7_SURFACE_DW2_WIDTH);
+   dw3 = GEN_SHIFT32(depth, GEN7_SURFACE_DW3_DEPTH) |
+         GEN_SHIFT32(info->struct_size - 1, GEN7_SURFACE_DW3_PITCH);
+
+   dw7 = 0;
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
+      dw7 |= GEN_SHIFT32(GEN75_SCS_RED,   GEN75_SURFACE_DW7_SCS_R) |
+             GEN_SHIFT32(GEN75_SCS_GREEN, GEN75_SURFACE_DW7_SCS_G) |
+             GEN_SHIFT32(GEN75_SCS_BLUE,  GEN75_SURFACE_DW7_SCS_B) |
+             GEN_SHIFT32(GEN75_SCS_ALPHA, GEN75_SURFACE_DW7_SCS_A);
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(surf->surface) >= 13);
+   surf->surface[0] = dw0;
+   surf->surface[1] = dw1;
+   surf->surface[2] = dw2;
+   surf->surface[3] = dw3;
+   surf->surface[4] = 0;
+   surf->surface[5] = 0;
+   surf->surface[6] = 0;
+   surf->surface[7] = dw7;
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      surf->surface[8] = info->offset;
+      surf->surface[9] = 0;
+      surf->surface[10] = 0;
+      surf->surface[11] = 0;
+      surf->surface[12] = 0;
+   }
+
+   surf->type = type;
+   surf->min_lod = 0;
+   surf->mip_count = 0;
+
+   return true;
+}
+
+static enum gen_surface_type
+get_gen6_surface_type(const struct ilo_dev *dev, const struct ilo_image *img)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (img->target) {
+   case PIPE_TEXTURE_1D:
+   case PIPE_TEXTURE_1D_ARRAY:
+      return GEN6_SURFTYPE_1D;
+   case PIPE_TEXTURE_2D:
+   case PIPE_TEXTURE_CUBE:
+   case PIPE_TEXTURE_RECT:
+   case PIPE_TEXTURE_2D_ARRAY:
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      return GEN6_SURFTYPE_2D;
+   case PIPE_TEXTURE_3D:
+      return GEN6_SURFTYPE_3D;
+   default:
+      assert(!"unknown texture target");
+      return GEN6_SURFTYPE_NULL;
+   }
+}
+
+static bool
+surface_validate_gen6_image(const struct ilo_dev *dev,
+                            const struct ilo_state_surface_image_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (info->access) {
+   case ILO_STATE_SURFACE_ACCESS_SAMPLER:
+   case ILO_STATE_SURFACE_ACCESS_DP_RENDER:
+      break;
+   case ILO_STATE_SURFACE_ACCESS_DP_TYPED:
+      assert(ilo_dev_gen(dev) >= ILO_GEN(7));
+      break;
+   default:
+      assert(!"unsupported surface access");
+      break;
+   }
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 78:
+    *
+    *     "For surface types other than SURFTYPE_BUFFER, the Width specified
+    *      by this field must be less than or equal to the surface pitch
+    *      (specified in bytes via the Surface Pitch field)."
+    */
+   assert(info->img->bo_stride && info->img->bo_stride <= 512 * 1024 &&
+          info->img->width0 <= info->img->bo_stride);
+
+   if (info->is_cube_map) {
+      assert(get_gen6_surface_type(dev, info->img) == GEN6_SURFTYPE_2D);
+
+      /*
+       * From the Sandy Bridge PRM, volume 4 part 1, page 78:
+       *
+       *     "For cube maps, Width must be set equal to the Height."
+       */
+      assert(info->img->width0 == info->img->height0);
+   }
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 72:
+    *
+    *     "Tile Walk TILEWALK_YMAJOR is UNDEFINED for render target formats
+    *      that have 128 bits-per-element (BPE)."
+    *
+    *     "If Number of Multisamples is set to a value other than
+    *      MULTISAMPLECOUNT_1, this field cannot be set to the following
+    *      formats:
+    *
+    *      - any format with greater than 64 bits per element
+    *      - any compressed texture format (BC*)
+    *      - any YCRCB* format"
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
+    *
+    *      If Number of Multisamples is set to a value other than
+    *      MULTISAMPLECOUNT_1, this field cannot be set to the following
+    *      formats: any format with greater than 64 bits per element, if
+    *      Number of Multisamples is MULTISAMPLECOUNT_8, any compressed
+    *      texture format (BC*), and any YCRCB* format.
+    *
+    * TODO
+    */
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8) && info->img->tiling == GEN8_TILING_W) {
+      ilo_warn("tiling W is not supported\n");
+      return false;
+   }
+
+   return true;
+}
+
+static void
+get_gen6_max_extent(const struct ilo_dev *dev,
+                    const struct ilo_image *img,
+                    uint16_t *max_w, uint16_t *max_h)
+{
+   const uint16_t max_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (get_gen6_surface_type(dev, img)) {
+   case GEN6_SURFTYPE_1D:
+      *max_w = max_size;
+      *max_h = 1;
+      break;
+   case GEN6_SURFTYPE_2D:
+      *max_w = max_size;
+      *max_h = max_size;
+      break;
+   case GEN6_SURFTYPE_3D:
+      *max_w = 2048;
+      *max_h = 2048;
+      break;
+   default:
+      assert(!"invalid surface type");
+      *max_w = 1;
+      *max_h = 1;
+      break;
+   }
+}
+
+static bool
+surface_get_gen6_image_extent(const struct ilo_dev *dev,
+                              const struct ilo_state_surface_image_info *info,
+                              uint16_t *width, uint16_t *height)
+{
+   uint16_t w, h, max_w, max_h;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   w = info->img->width0;
+   h = info->img->height0;
+
+   get_gen6_max_extent(dev, info->img, &max_w, &max_h);
+   assert(w && h && w <= max_w && h <= max_h);
+
+   *width = w - 1;
+   *height = h - 1;
+
+   return true;
+}
+
+static bool
+surface_get_gen6_image_slices(const struct ilo_dev *dev,
+                              const struct ilo_state_surface_image_info *info,
+                              uint16_t *depth, uint16_t *min_array_elem,
+                              uint16_t *rt_view_extent)
+{
+   uint16_t max_slice, d;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
+    *
+    *     "If this field (Surface Array) is enabled, the Surface Type must be
+    *      SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is
+    *      disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or
+    *      SURFTYPE_CUBE, the Depth field must be set to zero."
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 69:
+    *
+    *     "This field (Depth) specifies the total number of levels for a
+    *      volume texture or the number of array elements allowed to be
+    *      accessed starting at the Minimum Array Element for arrayed
+    *      surfaces.  If the volume texture is MIP-mapped, this field
+    *      specifies the depth of the base MIP level."
+    *
+    *     "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of this
+    *      field is [0,340], indicating the number of cube array elements
+    *      (equal to the number of underlying 2D array elements divided by 6).
+    *      For other surfaces, this field must be zero."
+    *
+    *     "Errata: For SURFTYPE_CUBE sampling engine surfaces, the range of
+    *      this field is limited to [0,85].
+    *
+    *      Errata: If Surface Array is enabled, and Depth is between 1024 and
+    *      2047, an incorrect array slice may be accessed if the requested
+    *      array index in the message is greater than or equal to 4096."
+    *
+    * The errata are for Gen7-specific, and they limit the number of useable
+    * layers to (86 * 6), about 512.
+    */
+
+   switch (get_gen6_surface_type(dev, info->img)) {
+   case GEN6_SURFTYPE_1D:
+   case GEN6_SURFTYPE_2D:
+      max_slice = (ilo_dev_gen(dev) >= ILO_GEN(7.5)) ? 2048 : 512;
+
+      assert(info->img->array_size <= max_slice);
+      max_slice = info->img->array_size;
+
+      d = info->slice_count;
+      if (info->is_cube_map) {
+         if (info->access == ILO_STATE_SURFACE_ACCESS_SAMPLER) {
+            if (!d || d % 6) {
+               ilo_warn("invalid cube slice count\n");
+               return false;
+            }
+
+            if (ilo_dev_gen(dev) == ILO_GEN(7) && d > 86 * 6) {
+               ilo_warn("cube slice count exceeds Gen7 limit\n");
+               return false;
+            }
+         } else {
+            /*
+             * Minumum Array Element and Depth must be 0; Render Target View
+             * Extent is ignored.
+             */
+            if (info->slice_base || d != 6) {
+               ilo_warn("no cube RT array support in data port\n");
+               return false;
+            }
+         }
+
+         d /= 6;
+      }
+
+      if (!info->is_array && d > 1) {
+         ilo_warn("non-array surface with non-zero depth\n");
+         return false;
+      }
+      break;
+   case GEN6_SURFTYPE_3D:
+      max_slice = 2048;
+
+      assert(info->img->depth0 <= max_slice);
+      max_slice = u_minify(info->img->depth0, info->level_base);
+
+      d = info->img->depth0;
+
+      if (info->is_array) {
+         ilo_warn("3D surfaces cannot be arrays\n");
+         return false;
+      }
+      break;
+   default:
+      assert(!"invalid surface type");
+      return false;
+      break;
+   }
+
+   if (!info->slice_count ||
+       info->slice_base + info->slice_count > max_slice) {
+      ilo_warn("invalid slice range\n");
+      return false;
+   }
+
+   assert(d);
+   *depth = d - 1;
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 84:
+    *
+    *     "For Sampling Engine and Render Target 1D and 2D Surfaces:
+    *      This field (Minimum Array Element) indicates the minimum array
+    *      element that can be accessed as part of this surface.  This field
+    *      is added to the delivered array index before it is used to address
+    *      the surface.
+    *
+    *      For Render Target 3D Surfaces:
+    *      This field indicates the minimum `R' coordinate on the LOD
+    *      currently being rendered to.  This field is added to the delivered
+    *      array index before it is used to address the surface.
+    *
+    *      For Sampling Engine Cube Surfaces on [DevSNB+] only:
+    *      This field indicates the minimum array element in the underlying 2D
+    *      surface array that can be accessed as part of this surface (the
+    *      cube array index is multipled by 6 to compute this value, although
+    *      this field is not restricted to only multiples of 6). This field is
+    *      added to the delivered array index before it is used to address the
+    *      surface.
+    *
+    *      For Other Surfaces:
+    *      This field must be set to zero."
+    *
+    * On Gen7+, typed sufaces are treated like sampling engine 1D and 2D
+    * surfaces.
+    */
+   *min_array_elem = info->slice_base;
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 84:
+    *
+    *     "For Render Target 3D Surfaces:
+    *      This field (Render Target View Extent) indicates the extent of the
+    *      accessible `R' coordinates minus 1 on the LOD currently being
+    *      rendered to.
+    *
+    *      For Render Target 1D and 2D Surfaces:
+    *      This field must be set to the same value as the Depth field.
+    *
+    *      For Other Surfaces:
+    *      This field is ignored."
+    */
+   *rt_view_extent = info->slice_count - 1;
+
+   return true;
+}
+
+static bool
+surface_get_gen6_image_levels(const struct ilo_dev *dev,
+                              const struct ilo_state_surface_image_info *info,
+                              uint8_t *min_lod, uint8_t *mip_count)
+{
+   uint8_t max_level = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 15 : 14;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(info->img->level_count <= max_level);
+   max_level = info->img->level_count;
+
+   if (!info->level_count ||
+       info->level_base + info->level_count > max_level) {
+      ilo_warn("invalid level range\n");
+      return false;
+   }
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 79:
+    *
+    *     "For Sampling Engine Surfaces:
+    *      This field (MIP Count / LOD) indicates the number of MIP levels
+    *      allowed to be accessed starting at Surface Min LOD, which must be
+    *      less than or equal to the number of MIP levels actually stored in
+    *      memory for this surface.
+    *
+    *      Force the mip map access to be between the mipmap specified by the
+    *      integer bits of the Min LOD and the ceiling of the value specified
+    *      here.
+    *
+    *      For Render Target Surfaces:
+    *      This field defines the MIP level that is currently being rendered
+    *      into. This is the absolute MIP level on the surface and is not
+    *      relative to the Surface Min LOD field, which is ignored for render
+    *      target surfaces.
+    *
+    *      For Other Surfaces:
+    *      This field is reserved : MBZ"
+    *
+    * From the Sandy Bridge PRM, volume 4 part 1, page 83:
+    *
+    *     "For Sampling Engine Surfaces:
+    *
+    *      This field (Surface Min LOD) indicates the most detailed LOD that
+    *      can be accessed as part of this surface.  This field is added to
+    *      the delivered LOD (sample_l, ld, or resinfo message types) before
+    *      it is used to address the surface.
+    *
+    *      For Other Surfaces:
+    *      This field is ignored."
+    *
+    * On Gen7+, typed sufaces are treated like sampling engine surfaces.
+    */
+   if (info->access == ILO_STATE_SURFACE_ACCESS_DP_RENDER) {
+      assert(info->level_count == 1);
+
+      *min_lod = 0;
+      *mip_count = info->level_base;
+   } else {
+      *min_lod = info->level_base;
+      *mip_count = info->level_count - 1;
+   }
+
+   return true;
+}
+
+static bool
+surface_get_gen6_image_sample_count(const struct ilo_dev *dev,
+                                    const struct ilo_state_surface_image_info *info,
+                                    enum gen_sample_count *sample_count)
+{
+   int min_gen;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (info->img->sample_count) {
+   case 1:
+      *sample_count = GEN6_NUMSAMPLES_1;
+      min_gen = ILO_GEN(6);
+      break;
+   case 2:
+      *sample_count = GEN8_NUMSAMPLES_2;
+      min_gen = ILO_GEN(8);
+      break;
+   case 4:
+      *sample_count = GEN6_NUMSAMPLES_4;
+      min_gen = ILO_GEN(6);
+      break;
+   case 8:
+      *sample_count = GEN7_NUMSAMPLES_8;
+      min_gen = ILO_GEN(7);
+      break;
+   case 16:
+      *sample_count = GEN8_NUMSAMPLES_16;
+      min_gen = ILO_GEN(8);
+      break;
+   default:
+      assert(!"invalid sample count");
+      *sample_count = GEN6_NUMSAMPLES_1;
+      break;
+   }
+
+   assert(ilo_dev_gen(dev) >= min_gen);
+
+   return true;
+}
+
+static bool
+surface_get_gen6_image_alignments(const struct ilo_dev *dev,
+                                  const struct ilo_state_surface_image_info *info,
+                                  uint32_t *alignments)
+{
+   uint32_t a = 0;
+   bool err = false;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      switch (info->img->align_i) {
+      case 4:
+         a |= GEN8_SURFACE_DW0_HALIGN_4;
+         break;
+      case 8:
+         a |= GEN8_SURFACE_DW0_HALIGN_8;
+         break;
+      case 16:
+         a |= GEN8_SURFACE_DW0_HALIGN_16;
+         break;
+      default:
+         err = true;
+         break;
+      }
+
+      switch (info->img->align_j) {
+      case 4:
+         a |= GEN7_SURFACE_DW0_VALIGN_4;
+         break;
+      case 8:
+         a |= GEN8_SURFACE_DW0_VALIGN_8;
+         break;
+      case 16:
+         a |= GEN8_SURFACE_DW0_VALIGN_16;
+         break;
+      default:
+         err = true;
+         break;
+      }
+   } else if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      switch (info->img->align_i) {
+      case 4:
+         a |= GEN7_SURFACE_DW0_HALIGN_4;
+         break;
+      case 8:
+         a |= GEN7_SURFACE_DW0_HALIGN_8;
+         break;
+      default:
+         err = true;
+         break;
+      }
+
+      switch (info->img->align_j) {
+      case 2:
+         a |= GEN7_SURFACE_DW0_VALIGN_2;
+         break;
+      case 4:
+         a |= GEN7_SURFACE_DW0_VALIGN_4;
+         break;
+      default:
+         err = true;
+         break;
+      }
+   } else {
+      if (info->img->align_i != 4)
+         err = true;
+
+      switch (info->img->align_j) {
+      case 2:
+         a |= GEN6_SURFACE_DW5_VALIGN_2;
+         break;
+      case 4:
+         a |= GEN6_SURFACE_DW5_VALIGN_4;
+         break;
+      default:
+         err = true;
+         break;
+      }
+   }
+
+   if (err)
+      assert(!"invalid HALIGN or VALIGN");
+
+   *alignments = a;
+
+   return true;
+}
+
+static bool
+surface_set_gen6_image_SURFACE_STATE(struct ilo_state_surface *surf,
+                                     const struct ilo_dev *dev,
+                                     const struct ilo_state_surface_image_info *info)
+{
+   uint16_t width, height, depth, array_base, view_extent;
+   uint8_t min_lod, mip_count;
+   enum gen_sample_count sample_count;
+   uint32_t alignments;
+   enum gen_surface_type type;
+   uint32_t dw0, dw2, dw3, dw4, dw5;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   if (!surface_validate_gen6_image(dev, info) ||
+       !surface_get_gen6_image_extent(dev, info, &width, &height) ||
+       !surface_get_gen6_image_slices(dev, info, &depth, &array_base,
+                                      &view_extent) ||
+       !surface_get_gen6_image_levels(dev, info, &min_lod, &mip_count) ||
+       !surface_get_gen6_image_sample_count(dev, info, &sample_count) ||
+       !surface_get_gen6_image_alignments(dev, info, &alignments))
+      return false;
+
+   /* no ARYSPC_LOD0 */
+   assert(info->img->walk != ILO_IMAGE_WALK_LOD);
+   /* no UMS/CMS */
+   if (info->img->sample_count > 1)
+      assert(info->img->interleaved_samples);
+
+   type = (info->is_cube_map) ? GEN6_SURFTYPE_CUBE :
+      get_gen6_surface_type(dev, info->img);
+
+   dw0 = type << GEN6_SURFACE_DW0_TYPE__SHIFT |
+         info->format << GEN6_SURFACE_DW0_FORMAT__SHIFT |
+         GEN6_SURFACE_DW0_MIPLAYOUT_BELOW;
+
+   /*
+    * From the Sandy Bridge PRM, volume 4 part 1, page 74:
+    *
+    *     "CUBE_AVERAGE may only be selected if all of the Cube Face Enable
+    *      fields are equal to one."
+    *
+    * From the Sandy Bridge PRM, volume 4 part 1, page 75-76:
+    *
+    *     "For SURFTYPE_CUBE Surfaces accessed via the Sampling Engine:
+    *      Bits 5:0 of this field (Cube Face Enables) enable the individual
+    *      faces of a cube map.  Enabling a face indicates that the face is
+    *      present in the cube map, while disabling it indicates that that
+    *      face is represented by the texture map's border color. Refer to
+    *      Memory Data Formats for the correlation between faces and the cube
+    *      map memory layout. Note that storage for disabled faces must be
+    *      provided.
+    *
+    *      For other surfaces:
+    *      This field is reserved : MBZ"
+    *
+    *     "When TEXCOORDMODE_CLAMP is used when accessing a cube map, this
+    *      field must be programmed to 111111b (all faces enabled)."
+    */
+   if (info->is_cube_map &&
+       info->access == ILO_STATE_SURFACE_ACCESS_SAMPLER) {
+      dw0 |= GEN6_SURFACE_DW0_CUBE_MAP_CORNER_MODE_AVERAGE |
+             GEN6_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
+   }
+
+   dw2 = height << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
+         width << GEN6_SURFACE_DW2_WIDTH__SHIFT |
+         mip_count << GEN6_SURFACE_DW2_MIP_COUNT_LOD__SHIFT;
+
+   dw3 = depth << GEN6_SURFACE_DW3_DEPTH__SHIFT |
+         (info->img->bo_stride - 1) << GEN6_SURFACE_DW3_PITCH__SHIFT |
+         info->img->tiling << GEN6_SURFACE_DW3_TILING__SHIFT;
+
+   dw4 = min_lod << GEN6_SURFACE_DW4_MIN_LOD__SHIFT |
+         array_base << GEN6_SURFACE_DW4_MIN_ARRAY_ELEMENT__SHIFT |
+         view_extent << GEN6_SURFACE_DW4_RT_VIEW_EXTENT__SHIFT |
+         sample_count << GEN6_SURFACE_DW4_MULTISAMPLECOUNT__SHIFT;
+
+   dw5 = alignments;
+
+   STATIC_ASSERT(ARRAY_SIZE(surf->surface) >= 6);
+   surf->surface[0] = dw0;
+   surf->surface[1] = 0;
+   surf->surface[2] = dw2;
+   surf->surface[3] = dw3;
+   surf->surface[4] = dw4;
+   surf->surface[5] = dw5;
+
+   surf->type = type;
+   surf->min_lod = min_lod;
+   surf->mip_count = mip_count;
+
+   return true;
+}
+
+static bool
+surface_set_gen7_image_SURFACE_STATE(struct ilo_state_surface *surf,
+                                     const struct ilo_dev *dev,
+                                     const struct ilo_state_surface_image_info *info)
+{
+   uint16_t width, height, depth, array_base, view_extent;
+   uint8_t min_lod, mip_count;
+   uint32_t alignments;
+   enum gen_sample_count sample_count;
+   enum gen_surface_type type;
+   uint32_t dw0, dw1, dw2, dw3, dw4, dw5, dw7;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!surface_validate_gen6_image(dev, info) ||
+       !surface_get_gen6_image_extent(dev, info, &width, &height) ||
+       !surface_get_gen6_image_slices(dev, info, &depth, &array_base,
+                                      &view_extent) ||
+       !surface_get_gen6_image_levels(dev, info, &min_lod, &mip_count) ||
+       !surface_get_gen6_image_sample_count(dev, info, &sample_count) ||
+       !surface_get_gen6_image_alignments(dev, info, &alignments))
+      return false;
+
+   type = (info->is_cube_map) ? GEN6_SURFTYPE_CUBE :
+      get_gen6_surface_type(dev, info->img);
+
+   dw0 = type << GEN7_SURFACE_DW0_TYPE__SHIFT |
+         info->format << GEN7_SURFACE_DW0_FORMAT__SHIFT |
+         alignments;
+
+   if (info->is_array)
+      dw0 |= GEN7_SURFACE_DW0_IS_ARRAY;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      dw0 |= info->img->tiling << GEN8_SURFACE_DW0_TILING__SHIFT;
+   } else {
+      dw0 |= info->img->tiling << GEN7_SURFACE_DW0_TILING__SHIFT;
+
+      if (info->img->walk == ILO_IMAGE_WALK_LOD)
+         dw0 |= GEN7_SURFACE_DW0_ARYSPC_LOD0;
+      else
+         dw0 |= GEN7_SURFACE_DW0_ARYSPC_FULL;
+   }
+
+   /*
+    * From the Ivy Bridge PRM, volume 4 part 1, page 67:
+    *
+    *     "For SURFTYPE_CUBE Surfaces accessed via the Sampling Engine: Bits
+    *      5:0 of this field (Cube Face Enables) enable the individual faces
+    *      of a cube map. Enabling a face indicates that the face is present
+    *      in the cube map, while disabling it indicates that that face is
+    *      represented by the texture map's border color. Refer to Memory Data
+    *      Formats for the correlation between faces and the cube map memory
+    *      layout. Note that storage for disabled faces must be provided. For
+    *      other surfaces this field is reserved and MBZ."
+    *
+    *     "When TEXCOORDMODE_CLAMP is used when accessing a cube map, this
+    *      field must be programmed to 111111b (all faces enabled). This field
+    *      is ignored unless the Surface Type is SURFTYPE_CUBE."
+    */
+   if (info->is_cube_map &&
+       info->access == ILO_STATE_SURFACE_ACCESS_SAMPLER)
+      dw0 |= GEN7_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
+
+   dw1 = 0;
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      assert(info->img->walk_layer_height % 4 == 0);
+      dw1 |= info->img->walk_layer_height / 4 <<
+         GEN8_SURFACE_DW1_QPITCH__SHIFT;
+   }
+
+   dw2 = height << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
+         width << GEN7_SURFACE_DW2_WIDTH__SHIFT;
+
+   dw3 = depth << GEN7_SURFACE_DW3_DEPTH__SHIFT |
+         (info->img->bo_stride - 1) << GEN7_SURFACE_DW3_PITCH__SHIFT;
+
+   if (ilo_dev_gen(dev) == ILO_GEN(7.5))
+      dw3 |= 0 << GEN75_SURFACE_DW3_INTEGER_SURFACE_FORMAT__SHIFT;
+
+   dw4 = array_base << GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT__SHIFT |
+         view_extent << GEN7_SURFACE_DW4_RT_VIEW_EXTENT__SHIFT |
+         sample_count << GEN7_SURFACE_DW4_MULTISAMPLECOUNT__SHIFT;
+
+   /*
+    * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
+    * means the samples are interleaved.  The layouts are the same when the
+    * number of samples is 1.
+    */
+   if (info->img->interleaved_samples && info->img->sample_count > 1) {
+      assert(info->access != ILO_STATE_SURFACE_ACCESS_DP_RENDER);
+      dw4 |= GEN7_SURFACE_DW4_MSFMT_DEPTH_STENCIL;
+   } else {
+      dw4 |= GEN7_SURFACE_DW4_MSFMT_MSS;
+   }
+
+   dw5 = min_lod << GEN7_SURFACE_DW5_MIN_LOD__SHIFT |
+         mip_count << GEN7_SURFACE_DW5_MIP_COUNT_LOD__SHIFT;
+
+   dw7 = 0;
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
+      dw7 |= GEN_SHIFT32(GEN75_SCS_RED,   GEN75_SURFACE_DW7_SCS_R) |
+             GEN_SHIFT32(GEN75_SCS_GREEN, GEN75_SURFACE_DW7_SCS_G) |
+             GEN_SHIFT32(GEN75_SCS_BLUE,  GEN75_SURFACE_DW7_SCS_B) |
+             GEN_SHIFT32(GEN75_SCS_ALPHA, GEN75_SURFACE_DW7_SCS_A);
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(surf->surface) >= 13);
+   surf->surface[0] = dw0;
+   surf->surface[1] = dw1;
+   surf->surface[2] = dw2;
+   surf->surface[3] = dw3;
+   surf->surface[4] = dw4;
+   surf->surface[5] = dw5;
+   surf->surface[6] = 0;
+   surf->surface[7] = dw7;
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      surf->surface[8] = 0;
+      surf->surface[9] = 0;
+      surf->surface[10] = 0;
+      surf->surface[11] = 0;
+      surf->surface[12] = 0;
+   }
+
+   surf->type = type;
+   surf->min_lod = min_lod;
+   surf->mip_count = mip_count;
+
+   return true;
+}
+
+bool
+ilo_state_surface_init_for_null(struct ilo_state_surface *surf,
+                                const struct ilo_dev *dev)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(surf, sizeof(*surf)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      ret &= surface_set_gen7_null_SURFACE_STATE(surf, dev);
+   else
+      ret &= surface_set_gen6_null_SURFACE_STATE(surf, dev);
+
+   surf->type = GEN6_SURFTYPE_NULL;
+   surf->readonly = true;
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_surface_init_for_buffer(struct ilo_state_surface *surf,
+                                  const struct ilo_dev *dev,
+                                  const struct ilo_state_surface_buffer_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(surf, sizeof(*surf)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      ret &= surface_set_gen7_buffer_SURFACE_STATE(surf, dev, info);
+   else
+      ret &= surface_set_gen6_buffer_SURFACE_STATE(surf, dev, info);
+
+   surf->readonly = info->readonly;
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_surface_init_for_image(struct ilo_state_surface *surf,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_surface_image_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(surf, sizeof(*surf)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      ret &= surface_set_gen7_image_SURFACE_STATE(surf, dev, info);
+   else
+      ret &= surface_set_gen6_image_SURFACE_STATE(surf, dev, info);
+
+   surf->is_integer = info->is_integer;
+   surf->readonly = info->readonly;
+   surf->scanout = info->img->scanout;
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_surface_set_scs(struct ilo_state_surface *surf,
+                          const struct ilo_dev *dev,
+                          enum gen_surface_scs rgba[4])
+{
+   const uint32_t scs = GEN_SHIFT32(rgba[0], GEN75_SURFACE_DW7_SCS_R) |
+                        GEN_SHIFT32(rgba[1], GEN75_SURFACE_DW7_SCS_G) |
+                        GEN_SHIFT32(rgba[2], GEN75_SURFACE_DW7_SCS_B) |
+                        GEN_SHIFT32(rgba[3], GEN75_SURFACE_DW7_SCS_A);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(ilo_dev_gen(dev) >= ILO_GEN(7.5));
+
+   surf->surface[7] = (surf->surface[7] & ~GEN75_SURFACE_DW7_SCS__MASK) | scs;
+
+   return true;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_surface.h b/src/gallium/drivers/ilo/core/ilo_state_surface.h
new file mode 100644 (file)
index 0000000..9c02542
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_SURFACE_H
+#define ILO_STATE_SURFACE_H
+
+#include "genhw/genhw.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+struct ilo_buffer;
+struct ilo_image;
+
+enum ilo_state_surface_access {
+   ILO_STATE_SURFACE_ACCESS_SAMPLER,      /* sampling engine surfaces */
+   ILO_STATE_SURFACE_ACCESS_DP_RENDER,    /* render target surfaces */
+   ILO_STATE_SURFACE_ACCESS_DP_TYPED,     /* typed surfaces */
+   ILO_STATE_SURFACE_ACCESS_DP_UNTYPED,   /* untyped surfaces */
+   ILO_STATE_SURFACE_ACCESS_DP_DATA,
+   ILO_STATE_SURFACE_ACCESS_DP_SVB,
+};
+
+struct ilo_state_surface_buffer_info {
+   const struct ilo_buffer *buf;
+
+   enum ilo_state_surface_access access;
+
+   enum gen_surface_format format;
+   uint8_t format_size;
+
+   bool readonly;
+   uint16_t struct_size;
+
+   uint32_t offset;
+   uint32_t size;
+};
+
+struct ilo_state_surface_image_info {
+   const struct ilo_image *img;
+
+   enum ilo_state_surface_access access;
+
+   enum gen_surface_format format;
+   bool is_integer;
+
+   bool readonly;
+   bool is_cube_map;
+   bool is_array;
+
+   uint8_t level_base;
+   uint8_t level_count;
+   uint16_t slice_base;
+   uint16_t slice_count;
+};
+
+struct ilo_state_surface {
+   uint32_t surface[13];
+
+   enum gen_surface_type type;
+   uint8_t min_lod;
+   uint8_t mip_count;
+   bool is_integer;
+
+   bool readonly;
+   bool scanout;
+
+   /* managed by users */
+   struct intel_bo *bo;
+};
+
+bool
+ilo_state_surface_valid_format(const struct ilo_dev *dev,
+                               enum ilo_state_surface_access access,
+                               enum gen_surface_format format);
+
+bool
+ilo_state_surface_init_for_null(struct ilo_state_surface *surf,
+                                const struct ilo_dev *dev);
+
+bool
+ilo_state_surface_init_for_buffer(struct ilo_state_surface *surf,
+                                  const struct ilo_dev *dev,
+                                  const struct ilo_state_surface_buffer_info *info);
+
+bool
+ilo_state_surface_init_for_image(struct ilo_state_surface *surf,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_surface_image_info *info);
+
+bool
+ilo_state_surface_set_scs(struct ilo_state_surface *surf,
+                          const struct ilo_dev *dev,
+                          enum gen_surface_scs rgba[4]);
+
+#endif /* ILO_STATE_SURFACE_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_surface_format.c b/src/gallium/drivers/ilo/core/ilo_state_surface_format.c
new file mode 100644 (file)
index 0000000..a40c1b8
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "genhw/genhw.h"
+#include "ilo_state_surface.h"
+
+static bool
+surface_valid_sampler_format(const struct ilo_dev *dev,
+                             enum ilo_state_surface_access access,
+                             enum gen_surface_format format)
+{
+   /*
+    * This table is based on:
+    *
+    *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
+    *  - the Ivy Bridge PRM, volume 4 part 1, page 84-87
+    */
+   static const struct sampler_cap {
+      int sampling;
+      int filtering;
+      int shadow_map;
+      int chroma_key;
+   } caps[] = {
+#define CAP(sampling, filtering, shadow_map, chroma_key) \
+      { ILO_GEN(sampling), ILO_GEN(filtering), ILO_GEN(shadow_map), ILO_GEN(chroma_key) }
+      [GEN6_FORMAT_R32G32B32A32_FLOAT]       = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_R32G32B32A32_SINT]        = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32G32B32A32_UINT]        = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32G32B32X32_FLOAT]       = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_R32G32B32_FLOAT]          = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_R32G32B32_SINT]           = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32G32B32_UINT]           = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16G16B16A16_UNORM]       = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16G16B16A16_SNORM]       = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16G16B16A16_SINT]        = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16G16B16A16_UINT]        = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16G16B16A16_FLOAT]       = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R32G32_FLOAT]             = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_R32G32_SINT]              = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32G32_UINT]              = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32_FLOAT_X8X24_TYPELESS] = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_X32_TYPELESS_G8X24_UINT]  = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_L32A32_FLOAT]             = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_R16G16B16X16_UNORM]       = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16G16B16X16_FLOAT]       = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_A32X32_FLOAT]             = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_L32X32_FLOAT]             = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_I32X32_FLOAT]             = CAP(  1,   5,   0,   0),
+      [GEN6_FORMAT_B8G8R8A8_UNORM]           = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_B8G8R8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R10G10B10A2_UNORM]        = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R10G10B10A2_UNORM_SRGB]   = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R10G10B10A2_UINT]         = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R10G10B10_SNORM_A2_UNORM] = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8B8A8_UNORM]           = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8B8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8B8A8_SNORM]           = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8B8A8_SINT]            = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R8G8B8A8_UINT]            = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16G16_UNORM]             = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16G16_SNORM]             = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16G16_SINT]              = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16G16_UINT]              = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16G16_FLOAT]             = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B10G10R10A2_UNORM]        = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B10G10R10A2_UNORM_SRGB]   = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R11G11B10_FLOAT]          = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R32_SINT]                 = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32_UINT]                 = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R32_FLOAT]                = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_R24_UNORM_X8_TYPELESS]    = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_X24_TYPELESS_G8_UINT]     = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_L16A16_UNORM]             = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_I24X8_UNORM]              = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_L24X8_UNORM]              = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_A24X8_UNORM]              = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_I32_FLOAT]                = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_L32_FLOAT]                = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_A32_FLOAT]                = CAP(  1,   5,   1,   0),
+      [GEN6_FORMAT_B8G8R8X8_UNORM]           = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_B8G8R8X8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8B8X8_UNORM]           = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8B8X8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R9G9B9E5_SHAREDEXP]       = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B10G10R10X2_UNORM]        = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_L16A16_FLOAT]             = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B5G6R5_UNORM]             = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_B5G6R5_UNORM_SRGB]        = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B5G5R5A1_UNORM]           = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_B5G5R5A1_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B4G4R4A4_UNORM]           = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_B4G4R4A4_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8_UNORM]               = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8_SNORM]               = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_R8G8_SINT]                = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R8G8_UINT]                = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16_UNORM]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_R16_SNORM]                = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16_SINT]                 = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16_UINT]                 = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R16_FLOAT]                = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_A8P8_UNORM_PALETTE0]      = CAP(  5,   5,   0,   0),
+      [GEN6_FORMAT_A8P8_UNORM_PALETTE1]      = CAP(  5,   5,   0,   0),
+      [GEN6_FORMAT_I16_UNORM]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_L16_UNORM]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_A16_UNORM]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_L8A8_UNORM]               = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_I16_FLOAT]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_L16_FLOAT]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_A16_FLOAT]                = CAP(  1,   1,   1,   0),
+      [GEN6_FORMAT_L8A8_UNORM_SRGB]          = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_R5G5_SNORM_B6_UNORM]      = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_P8A8_UNORM_PALETTE0]      = CAP(  5,   5,   0,   0),
+      [GEN6_FORMAT_P8A8_UNORM_PALETTE1]      = CAP(  5,   5,   0,   0),
+      [GEN6_FORMAT_R8_UNORM]                 = CAP(  1,   1,   0, 4.5),
+      [GEN6_FORMAT_R8_SNORM]                 = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8_SINT]                  = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_R8_UINT]                  = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_A8_UNORM]                 = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_I8_UNORM]                 = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_L8_UNORM]                 = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_P4A4_UNORM_PALETTE0]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_A4P4_UNORM_PALETTE0]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_P8_UNORM_PALETTE0]        = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_L8_UNORM_SRGB]            = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_P8_UNORM_PALETTE1]        = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_P4A4_UNORM_PALETTE1]      = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_A4P4_UNORM_PALETTE1]      = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_DXT1_RGB_SRGB]            = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_R1_UNORM]                 = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_YCRCB_NORMAL]             = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_YCRCB_SWAPUVY]            = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_P2_UNORM_PALETTE0]        = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_P2_UNORM_PALETTE1]        = CAP(4.5, 4.5,   0,   0),
+      [GEN6_FORMAT_BC1_UNORM]                = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_BC2_UNORM]                = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_BC3_UNORM]                = CAP(  1,   1,   0,   1),
+      [GEN6_FORMAT_BC4_UNORM]                = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_BC5_UNORM]                = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_BC1_UNORM_SRGB]           = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_BC2_UNORM_SRGB]           = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_BC3_UNORM_SRGB]           = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_MONO8]                    = CAP(  1,   0,   0,   0),
+      [GEN6_FORMAT_YCRCB_SWAPUV]             = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_YCRCB_SWAPY]              = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_DXT1_RGB]                 = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_FXT1]                     = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_BC4_SNORM]                = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_BC5_SNORM]                = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R16G16B16_FLOAT]          = CAP(  5,   5,   0,   0),
+      [GEN6_FORMAT_BC6H_SF16]                = CAP(  7,   7,   0,   0),
+      [GEN6_FORMAT_BC7_UNORM]                = CAP(  7,   7,   0,   0),
+      [GEN6_FORMAT_BC7_UNORM_SRGB]           = CAP(  7,   7,   0,   0),
+      [GEN6_FORMAT_BC6H_UF16]                = CAP(  7,   7,   0,   0),
+#undef CAP
+   };
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return (format < ARRAY_SIZE(caps) && caps[format].sampling &&
+           ilo_dev_gen(dev) >= caps[format].sampling);
+}
+
+static bool
+surface_valid_dp_format(const struct ilo_dev *dev,
+                        enum ilo_state_surface_access access,
+                        enum gen_surface_format format)
+{
+   /*
+    * This table is based on:
+    *
+    *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
+    *  - the Ivy Bridge PRM, volume 4 part 1, page 172, 252-253, and 277-278
+    *  - the Haswell PRM, volume 7, page 262-264
+    */
+   static const struct dp_cap {
+      int rt_write;
+      int rt_write_blending;
+      int typed_write;
+      int media_color_processing;
+   } caps[] = {
+#define CAP(rt_write, rt_write_blending, typed_write, media_color_processing) \
+      { ILO_GEN(rt_write), ILO_GEN(rt_write_blending), ILO_GEN(typed_write), ILO_GEN(media_color_processing) }
+      [GEN6_FORMAT_R32G32B32A32_FLOAT]       = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_R32G32B32A32_SINT]        = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R32G32B32A32_UINT]        = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16G16B16A16_UNORM]       = CAP(  1, 4.5,   7,   6),
+      [GEN6_FORMAT_R16G16B16A16_SNORM]       = CAP(  1,   6,   7,   0),
+      [GEN6_FORMAT_R16G16B16A16_SINT]        = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16G16B16A16_UINT]        = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16G16B16A16_FLOAT]       = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_R32G32_FLOAT]             = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_R32G32_SINT]              = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R32G32_UINT]              = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_B8G8R8A8_UNORM]           = CAP(  1,   1,   7,   6),
+      [GEN6_FORMAT_B8G8R8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R10G10B10A2_UNORM]        = CAP(  1,   1,   7,   6),
+      [GEN6_FORMAT_R10G10B10A2_UNORM_SRGB]   = CAP(  0,   0,   0,   6),
+      [GEN6_FORMAT_R10G10B10A2_UINT]         = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R8G8B8A8_UNORM]           = CAP(  1,   1,   7,   6),
+      [GEN6_FORMAT_R8G8B8A8_UNORM_SRGB]      = CAP(  1,   1,   0,   6),
+      [GEN6_FORMAT_R8G8B8A8_SNORM]           = CAP(  1,   6,   7,   0),
+      [GEN6_FORMAT_R8G8B8A8_SINT]            = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R8G8B8A8_UINT]            = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16G16_UNORM]             = CAP(  1, 4.5,   7,   0),
+      [GEN6_FORMAT_R16G16_SNORM]             = CAP(  1,   6,   7,   0),
+      [GEN6_FORMAT_R16G16_SINT]              = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16G16_UINT]              = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16G16_FLOAT]             = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B10G10R10A2_UNORM]        = CAP(  1,   1,   7,   6),
+      [GEN6_FORMAT_B10G10R10A2_UNORM_SRGB]   = CAP(  1,   1,   0,   6),
+      [GEN6_FORMAT_R11G11B10_FLOAT]          = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_R32_SINT]                 = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R32_UINT]                 = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R32_FLOAT]                = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B8G8R8X8_UNORM]           = CAP(  0,   0,   0,   6),
+      [GEN6_FORMAT_B5G6R5_UNORM]             = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B5G6R5_UNORM_SRGB]        = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B5G5R5A1_UNORM]           = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B5G5R5A1_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_B4G4R4A4_UNORM]           = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B4G4R4A4_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8G8_UNORM]               = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_R8G8_SNORM]               = CAP(  1,   6,   7,   0),
+      [GEN6_FORMAT_R8G8_SINT]                = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R8G8_UINT]                = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16_UNORM]                = CAP(  1, 4.5,   7,   7),
+      [GEN6_FORMAT_R16_SNORM]                = CAP(  1,   6,   7,   0),
+      [GEN6_FORMAT_R16_SINT]                 = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16_UINT]                 = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R16_FLOAT]                = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B5G5R5X1_UNORM]           = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_B5G5R5X1_UNORM_SRGB]      = CAP(  1,   1,   0,   0),
+      [GEN6_FORMAT_R8_UNORM]                 = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_R8_SNORM]                 = CAP(  1,   6,   7,   0),
+      [GEN6_FORMAT_R8_SINT]                  = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_R8_UINT]                  = CAP(  1,   0,   7,   0),
+      [GEN6_FORMAT_A8_UNORM]                 = CAP(  1,   1,   7,   0),
+      [GEN6_FORMAT_YCRCB_NORMAL]             = CAP(  1,   0,   0,   6),
+      [GEN6_FORMAT_YCRCB_SWAPUVY]            = CAP(  1,   0,   0,   6),
+      [GEN6_FORMAT_YCRCB_SWAPUV]             = CAP(  1,   0,   0,   6),
+      [GEN6_FORMAT_YCRCB_SWAPY]              = CAP(  1,   0,   0,   6),
+#undef CAP
+   };
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (format >= ARRAY_SIZE(caps))
+      return false;
+
+   switch (access) {
+   case ILO_STATE_SURFACE_ACCESS_DP_RENDER:
+      return (caps[format].rt_write &&
+              ilo_dev_gen(dev) >= caps[format].rt_write);
+   case ILO_STATE_SURFACE_ACCESS_DP_TYPED:
+      return (caps[format].typed_write &&
+              ilo_dev_gen(dev) >= caps[format].typed_write);
+   case ILO_STATE_SURFACE_ACCESS_DP_UNTYPED:
+      return (format == GEN6_FORMAT_RAW);
+   case ILO_STATE_SURFACE_ACCESS_DP_DATA:
+      /* ignored, but can it be raw? */
+      assert(format != GEN6_FORMAT_RAW);
+      return true;
+   default:
+      return false;
+   }
+}
+
+static bool
+surface_valid_svb_format(const struct ilo_dev *dev,
+                         enum gen_surface_format format)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * This table is based on:
+    *
+    *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
+    *  - the Ivy Bridge PRM, volume 2 part 1, page 195
+    *  - the Haswell PRM, volume 7, page 535
+    */
+   switch (format) {
+   case GEN6_FORMAT_R32G32B32A32_FLOAT:
+   case GEN6_FORMAT_R32G32B32A32_SINT:
+   case GEN6_FORMAT_R32G32B32A32_UINT:
+   case GEN6_FORMAT_R32G32B32_FLOAT:
+   case GEN6_FORMAT_R32G32B32_SINT:
+   case GEN6_FORMAT_R32G32B32_UINT:
+   case GEN6_FORMAT_R32G32_FLOAT:
+   case GEN6_FORMAT_R32G32_SINT:
+   case GEN6_FORMAT_R32G32_UINT:
+   case GEN6_FORMAT_R32_SINT:
+   case GEN6_FORMAT_R32_UINT:
+   case GEN6_FORMAT_R32_FLOAT:
+      return true;
+   default:
+      return false;
+   }
+}
+
+bool
+ilo_state_surface_valid_format(const struct ilo_dev *dev,
+                               enum ilo_state_surface_access access,
+                               enum gen_surface_format format)
+{
+   bool valid;
+
+   switch (access) {
+   case ILO_STATE_SURFACE_ACCESS_SAMPLER:
+      valid = surface_valid_sampler_format(dev, access, format);
+      break;
+   case ILO_STATE_SURFACE_ACCESS_DP_RENDER:
+   case ILO_STATE_SURFACE_ACCESS_DP_TYPED:
+   case ILO_STATE_SURFACE_ACCESS_DP_UNTYPED:
+   case ILO_STATE_SURFACE_ACCESS_DP_DATA:
+      valid = surface_valid_dp_format(dev, access, format);
+      break;
+   case ILO_STATE_SURFACE_ACCESS_DP_SVB:
+      valid = surface_valid_svb_format(dev, format);
+      break;
+   default:
+      valid = false;
+      break;
+   }
+
+   return valid;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_urb.c b/src/gallium/drivers/ilo/core/ilo_state_urb.c
new file mode 100644 (file)
index 0000000..cbd150c
--- /dev/null
@@ -0,0 +1,769 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_urb.h"
+
+struct urb_configuration {
+   uint8_t vs_pcb_alloc_kb;
+   uint8_t hs_pcb_alloc_kb;
+   uint8_t ds_pcb_alloc_kb;
+   uint8_t gs_pcb_alloc_kb;
+   uint8_t ps_pcb_alloc_kb;
+
+   uint8_t urb_offset_8kb;
+
+   uint8_t vs_urb_alloc_8kb;
+   uint8_t hs_urb_alloc_8kb;
+   uint8_t ds_urb_alloc_8kb;
+   uint8_t gs_urb_alloc_8kb;
+
+   uint8_t vs_entry_rows;
+   uint8_t hs_entry_rows;
+   uint8_t ds_entry_rows;
+   uint8_t gs_entry_rows;
+
+   int vs_entry_count;
+   int hs_entry_count;
+   int ds_entry_count;
+   int gs_entry_count;
+};
+
+static void
+urb_alloc_gen7_pcb(const struct ilo_dev *dev,
+                   const struct ilo_state_urb_info *info,
+                   struct urb_configuration *conf)
+{
+   /*
+    * From the Haswell PRM, volume 2b, page 940:
+    *
+    *     "[0,16] (0KB - 16KB) Increments of 1KB DevHSW:GT1, DevHSW:GT2
+    *      [0,32] (0KB - 32KB) Increments of 2KB DevHSW:GT3"
+    */
+   const uint8_t increment_kb =
+      (ilo_dev_gen(dev) >= ILO_GEN(8) ||
+       (ilo_dev_gen(dev) == ILO_GEN(7.5) && dev->gt == 3)) ? 2 : 1;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /*
+    * Keep the strategy simple as we do not know the workloads and how
+    * expensive it is to change the configuration frequently.
+    */
+   if (info->hs_const_data || info->ds_const_data) {
+      conf->vs_pcb_alloc_kb = increment_kb * 4;
+      conf->hs_pcb_alloc_kb = increment_kb * 3;
+      conf->ds_pcb_alloc_kb = increment_kb * 3;
+      conf->gs_pcb_alloc_kb = increment_kb * 3;
+      conf->ps_pcb_alloc_kb = increment_kb * 3;
+   } else if (info->gs_const_data) {
+      conf->vs_pcb_alloc_kb = increment_kb * 6;
+      conf->gs_pcb_alloc_kb = increment_kb * 5;
+      conf->ps_pcb_alloc_kb = increment_kb * 5;
+   } else {
+      conf->vs_pcb_alloc_kb = increment_kb * 8;
+      conf->ps_pcb_alloc_kb = increment_kb * 8;
+   }
+
+   conf->urb_offset_8kb = increment_kb * 16 / 8;
+}
+
+static void
+urb_alloc_gen6_urb(const struct ilo_dev *dev,
+                   const struct ilo_state_urb_info *info,
+                   struct urb_configuration *conf)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 34:
+    *
+    *     "(VS URB Starting Address) Offset from the start of the URB memory
+    *      where VS starts its allocation, specified in multiples of 8 KB."
+    *
+    * Same for other stages.
+    */
+   const int space_avail_8kb = dev->urb_size / 8192 - conf->urb_offset_8kb;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 173:
+    *
+    *     "Programming Note: If the GS stage is enabled, software must always
+    *      allocate at least one GS URB Entry. This is true even if the GS
+    *      thread never needs to output vertices to the urb, e.g., when only
+    *      performing stream output. This is an artifact of the need to pass
+    *      the GS thread an initial destination URB handle."
+    */
+   const bool force_gs_alloc =
+      (ilo_dev_gen(dev) == ILO_GEN(6) && info->gs_enable);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (info->hs_entry_size || info->ds_entry_size) {
+      conf->vs_urb_alloc_8kb = space_avail_8kb / 4;
+      conf->hs_urb_alloc_8kb = space_avail_8kb / 4;
+      conf->ds_urb_alloc_8kb = space_avail_8kb / 4;
+      conf->gs_urb_alloc_8kb = space_avail_8kb / 4;
+
+      if (space_avail_8kb % 4) {
+         assert(space_avail_8kb % 2 == 0);
+         conf->vs_urb_alloc_8kb++;
+         conf->gs_urb_alloc_8kb++;
+      }
+   } else if (info->gs_entry_size || force_gs_alloc) {
+      assert(space_avail_8kb % 2 == 0);
+      conf->vs_urb_alloc_8kb = space_avail_8kb / 2;
+      conf->gs_urb_alloc_8kb = space_avail_8kb / 2;
+   } else {
+      conf->vs_urb_alloc_8kb = space_avail_8kb;
+   }
+}
+
+static bool
+urb_init_gen6_vs_entry(const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info,
+                       struct urb_configuration *conf)
+{
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 28:
+    *
+    *     "(VS URB Entry Allocation Size)
+    *      Range [0,4] = [1,5] 1024-bit URB rows"
+    *
+    *     "(VS Number of URB Entries)
+    *      Range [24,256] in multiples of 4
+    *            [24, 128] in multiples of 4[DevSNBGT1]"
+    */
+   const int max_entry_count = (dev->gt == 2) ? 256 : 252;
+   const int row_size = 1024 / 8;
+   int row_count, entry_count;
+   int entry_size;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   /* VE and VS share the same VUE for each vertex */
+   entry_size = info->vs_entry_size;
+   if (entry_size < info->ve_entry_size)
+      entry_size = info->ve_entry_size;
+
+   row_count = (entry_size + row_size - 1) / row_size;
+   if (row_count > 5)
+      return false;
+   else if (!row_count)
+      row_count++;
+
+   entry_count = conf->vs_urb_alloc_8kb * 8192 / (row_size * row_count);
+   if (entry_count > max_entry_count)
+      entry_count = max_entry_count;
+   entry_count &= ~3;
+   assert(entry_count >= 24);
+
+   conf->vs_entry_rows = row_count;
+   conf->vs_entry_count = entry_count;
+
+   return true;
+}
+
+static bool
+urb_init_gen6_gs_entry(const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info,
+                       struct urb_configuration *conf)
+{
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 29:
+    *
+    *     "(GS Number of URB Entries)
+    *      Range [0,256] in multiples of 4
+    *            [0, 254] in multiples of 4[DevSNBGT1]"
+    *
+    *     "(GS URB Entry Allocation Size)
+    *      Range [0,4] = [1,5] 1024-bit URB rows"
+    */
+   const int max_entry_count = (dev->gt == 2) ? 256 : 252;
+   const int row_size = 1024 / 8;
+   int row_count, entry_count;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   row_count = (info->gs_entry_size + row_size - 1) / row_size;
+   if (row_count > 5)
+      return false;
+   else if (!row_count)
+      row_count++;
+
+   entry_count = conf->gs_urb_alloc_8kb * 8192 / (row_size * row_count);
+   if (entry_count > max_entry_count)
+      entry_count = max_entry_count;
+   entry_count &= ~3;
+
+   conf->gs_entry_rows = row_count;
+   conf->gs_entry_count = entry_count;
+
+   return true;
+}
+
+static bool
+urb_init_gen7_vs_entry(const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info,
+                       struct urb_configuration *conf)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 34-35:
+    *
+    *     "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may
+    *      cause performance to decrease due to banking in the URB. Element
+    *      sizes of 16 to 20 should be programmed with six 512-bit URB rows."
+    *
+    *     "(VS URB Entry Allocation Size)
+    *      Format: U9-1 count of 512-bit units"
+    *
+    *     "(VS Number of URB Entries)
+    *      [32,704]
+    *      [32,512]
+    *
+    *      Programming Restriction: VS Number of URB Entries must be divisible
+    *      by 8 if the VS URB Entry Allocation Size is less than 9 512-bit URB
+    *      entries."2:0" = reserved "000b""
+    *
+    * From the Haswell PRM, volume 2b, page 847:
+    *
+    *     "(VS Number of URB Entries)
+    *      [64,1664] DevHSW:GT3
+    *      [64,1664] DevHSW:GT2
+    *      [32,640]  DevHSW:GT1"
+    */
+   const int row_size = 512 / 8;
+   int row_count, entry_count;
+   int entry_size;
+   int max_entry_count, min_entry_count;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 35:
+    *
+    *     "Programming Restriction: As the VS URB entry serves as both the
+    *      per-vertex input and output of the VS shader, the VS URB Allocation
+    *      Size must be sized to the maximum of the vertex input and output
+    *      structures."
+    *
+    * From the Ivy Bridge PRM, volume 2 part 1, page 42:
+    *
+    *     "If the VS function is enabled, the VF-written VUEs are not required
+    *      to have Vertex Headers, as the VS-incoming vertices are guaranteed
+    *      to be consumed by the VS (i.e., the VS thread is responsible for
+    *      overwriting the input vertex data)."
+    *
+    * VE and VS share the same VUE for each vertex.
+    */
+   entry_size = info->vs_entry_size;
+   if (entry_size < info->ve_entry_size)
+      entry_size = info->ve_entry_size;
+
+   row_count = (entry_size + row_size - 1) / row_size;
+   if (row_count == 5 || !row_count)
+      row_count++;
+
+   entry_count = conf->vs_urb_alloc_8kb * 8192 / (row_size * row_count);
+   if (row_count < 9)
+      entry_count &= ~7;
+
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+   case ILO_GEN(7.5):
+      max_entry_count = (dev->gt >= 2) ? 1664 : 640;
+      min_entry_count = (dev->gt >= 2) ? 64 : 32;
+      break;
+   case ILO_GEN(7):
+      max_entry_count = (dev->gt == 2) ? 704 : 512;
+      min_entry_count = 32;
+      break;
+   default:
+      assert(!"unexpected gen");
+      return false;
+      break;
+   }
+
+   if (entry_count > max_entry_count)
+      entry_count = max_entry_count;
+   else if (entry_count < min_entry_count)
+      return false;
+
+   conf->vs_entry_rows = row_count;
+   conf->vs_entry_count = entry_count;
+
+   return true;
+}
+
+static bool
+urb_init_gen7_hs_entry(const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info,
+                       struct urb_configuration *conf)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 37:
+    *
+    *     "HS Number of URB Entries must be divisible by 8 if the HS URB Entry
+    *      Allocation Size is less than 9 512-bit URB
+    *      entries."2:0" = reserved "000"
+    *
+    *      [0,64]
+    *      [0,32]"
+    *
+    * From the Haswell PRM, volume 2b, page 849:
+    *
+    *     "(HS Number of URB Entries)
+    *      [0,128] DevHSW:GT2
+    *      [0,64]  DevHSW:GT1"
+    */
+   const int row_size = 512 / 8;
+   int row_count, entry_count;
+   int max_entry_count;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   row_count = (info->hs_entry_size + row_size - 1) / row_size;
+   if (!row_count)
+      row_count++;
+
+   entry_count = conf->hs_urb_alloc_8kb * 8192 / (row_size * row_count);
+   if (row_count < 9)
+      entry_count &= ~7;
+
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+   case ILO_GEN(7.5):
+      max_entry_count = (dev->gt >= 2) ? 128 : 64;
+      break;
+   case ILO_GEN(7):
+      max_entry_count = (dev->gt == 2) ? 64 : 32;
+      break;
+   default:
+      assert(!"unexpected gen");
+      return false;
+      break;
+   }
+
+   if (entry_count > max_entry_count)
+      entry_count = max_entry_count;
+   else if (info->hs_entry_size && !entry_count)
+      return false;
+
+   conf->hs_entry_rows = row_count;
+   conf->hs_entry_count = entry_count;
+
+   return true;
+}
+
+static bool
+urb_init_gen7_ds_entry(const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info,
+                       struct urb_configuration *conf)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 38:
+    *
+    *     "(DS URB Entry Allocation Size)
+    *      [0,9]"
+    *
+    *     "(DS Number of URB Entries) If Domain Shader Thread Dispatch is
+    *      Enabled then the minimum number handles that must be allocated is
+    *      138 URB entries.
+    *      "2:0" = reserved "000"
+    *
+    *      [0,448]
+    *      [0,288]
+    *
+    *      DS Number of URB Entries must be divisible by 8 if the DS URB Entry
+    *      Allocation Size is less than 9 512-bit URB entries.If Domain Shader
+    *      Thread Dispatch is Enabled then the minimum number of handles that
+    *      must be allocated is 10 URB entries."
+    *
+    * From the Haswell PRM, volume 2b, page 851:
+    *
+    *     "(DS Number of URB Entries)
+    *      [0,960] DevHSW:GT2
+    *      [0,384] DevHSW:GT1"
+    */
+   const int row_size = 512 / 8;
+   int row_count, entry_count;
+   int max_entry_count;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   row_count = (info->ds_entry_size + row_size - 1) / row_size;
+   if (row_count > 10)
+      return false;
+   else if (!row_count)
+      row_count++;
+
+   entry_count = conf->ds_urb_alloc_8kb * 8192 / (row_size * row_count);
+   if (row_count < 9)
+      entry_count &= ~7;
+
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+   case ILO_GEN(7.5):
+      max_entry_count = (dev->gt >= 2) ? 960 : 384;
+      break;
+   case ILO_GEN(7):
+      max_entry_count = (dev->gt == 2) ? 448 : 288;
+      break;
+   default:
+      assert(!"unexpected gen");
+      return false;
+      break;
+   }
+
+   if (entry_count > max_entry_count)
+      entry_count = max_entry_count;
+   else if (info->ds_entry_size && entry_count < 10)
+      return false;
+
+   conf->ds_entry_rows = row_count;
+   conf->ds_entry_count = entry_count;
+
+   return true;
+}
+
+static bool
+urb_init_gen7_gs_entry(const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info,
+                       struct urb_configuration *conf)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 40:
+    *
+    *     "(GS Number of URB Entries) GS Number of URB Entries must be
+    *      divisible by 8 if the GS URB Entry Allocation Size is less than 9
+    *      512-bit URB entries.
+    *      "2:0" = reserved "000"
+    *
+    *      [0,320]
+    *      [0,192]"
+    *
+    * From the Ivy Bridge PRM, volume 2 part 1, page 171:
+    *
+    *     "(DUAL_INSTANCE and DUAL_OBJECT) The GS must be allocated at least
+    *      two URB handles or behavior is UNDEFINED."
+    *
+    * From the Haswell PRM, volume 2b, page 853:
+    *
+    *     "(GS Number of URB Entries)
+    *      [0,640] DevHSW:GT2
+    *      [0,256] DevHSW:GT1
+    *
+    *      Only if GS is disabled can this field be programmed to 0.  If GS is
+    *      enabled this field shall be programmed to a value greater than 0.
+    *      For GS Dispatch Mode "Single", this field shall be programmed to a
+    *      value greater than or equal to 1. For other GS Dispatch Modes,
+    *      refer to the definition of Dispatch Mode (3DSTATE_GS) for minimum
+    *      values of this field."
+    */
+   const int row_size = 512 / 8;
+   int row_count, entry_count;
+   int max_entry_count;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   row_count = (info->gs_entry_size + row_size - 1) / row_size;
+   if (!row_count)
+      row_count++;
+
+   entry_count = conf->gs_urb_alloc_8kb * 8192 / (row_size * row_count);
+   if (row_count < 9)
+      entry_count &= ~7;
+
+   switch (ilo_dev_gen(dev)) {
+   case ILO_GEN(8):
+   case ILO_GEN(7.5):
+      max_entry_count = (dev->gt >= 2) ? 640 : 256;
+      break;
+   case ILO_GEN(7):
+      max_entry_count = (dev->gt == 2) ? 320 : 192;
+      break;
+   default:
+      assert(!"unexpected gen");
+      return false;
+      break;
+   }
+
+   if (entry_count > max_entry_count)
+      entry_count = max_entry_count;
+   else if (info->gs_entry_size && entry_count < 2)
+      return false;
+
+   conf->gs_entry_rows = row_count;
+   conf->gs_entry_count = entry_count;
+
+   return true;
+}
+
+static bool
+urb_get_gen6_configuration(const struct ilo_dev *dev,
+                           const struct ilo_state_urb_info *info,
+                           struct urb_configuration *conf)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   memset(conf, 0, sizeof(*conf));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      urb_alloc_gen7_pcb(dev, info, conf);
+
+   urb_alloc_gen6_urb(dev, info, conf);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      if (!urb_init_gen7_vs_entry(dev, info, conf) ||
+          !urb_init_gen7_hs_entry(dev, info, conf) ||
+          !urb_init_gen7_ds_entry(dev, info, conf) ||
+          !urb_init_gen7_gs_entry(dev, info, conf))
+         return false;
+   } else {
+      if (!urb_init_gen6_vs_entry(dev, info, conf) ||
+          !urb_init_gen6_gs_entry(dev, info, conf))
+         return false;
+   }
+
+   return true;
+}
+
+static bool
+urb_set_gen7_3dstate_push_constant_alloc(struct ilo_state_urb *urb,
+                                         const struct ilo_dev *dev,
+                                         const struct ilo_state_urb_info *info,
+                                         const struct urb_configuration *conf)
+{
+   uint32_t dw1[5];
+   uint8_t sizes_kb[5], offset_kb;
+   int i;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   sizes_kb[0] = conf->vs_pcb_alloc_kb;
+   sizes_kb[1] = conf->hs_pcb_alloc_kb;
+   sizes_kb[2] = conf->ds_pcb_alloc_kb;
+   sizes_kb[3] = conf->gs_pcb_alloc_kb;
+   sizes_kb[4] = conf->ps_pcb_alloc_kb;
+   offset_kb = 0;
+
+   for (i = 0; i < 5; i++) {
+      /* careful for the valid range of offsets */
+      if (sizes_kb[i]) {
+         dw1[i] = offset_kb << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
+                  sizes_kb[i] << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
+         offset_kb += sizes_kb[i];
+      } else {
+         dw1[i] = 0;
+      }
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(urb->pcb) >= 5);
+   memcpy(urb->pcb, dw1, sizeof(dw1));
+
+   return true;
+}
+
+static bool
+urb_set_gen6_3DSTATE_URB(struct ilo_state_urb *urb,
+                         const struct ilo_dev *dev,
+                         const struct ilo_state_urb_info *info,
+                         const struct urb_configuration *conf)
+{
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   assert(conf->vs_entry_rows && conf->gs_entry_rows);
+
+   dw1 = (conf->vs_entry_rows - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
+         conf->vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
+   dw2 = conf->gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
+         (conf->gs_entry_rows - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(urb->urb) >= 2);
+   urb->urb[0] = dw1;
+   urb->urb[1] = dw2;
+
+   return true;
+}
+
+static bool
+urb_set_gen7_3dstate_urb(struct ilo_state_urb *urb,
+                         const struct ilo_dev *dev,
+                         const struct ilo_state_urb_info *info,
+                         const struct urb_configuration *conf)
+{
+   uint32_t dw1[4];
+   struct {
+      uint8_t alloc_8kb;
+      uint8_t entry_rows;
+      int entry_count;
+   } stages[4];
+   uint8_t offset_8kb;
+   int i;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   stages[0].alloc_8kb = conf->vs_urb_alloc_8kb;
+   stages[1].alloc_8kb = conf->hs_urb_alloc_8kb;
+   stages[2].alloc_8kb = conf->ds_urb_alloc_8kb;
+   stages[3].alloc_8kb = conf->gs_urb_alloc_8kb;
+
+   stages[0].entry_rows = conf->vs_entry_rows;
+   stages[1].entry_rows = conf->hs_entry_rows;
+   stages[2].entry_rows = conf->ds_entry_rows;
+   stages[3].entry_rows = conf->gs_entry_rows;
+
+   stages[0].entry_count = conf->vs_entry_count;
+   stages[1].entry_count = conf->hs_entry_count;
+   stages[2].entry_count = conf->ds_entry_count;
+   stages[3].entry_count = conf->gs_entry_count;
+
+   offset_8kb = conf->urb_offset_8kb;
+
+   for (i = 0; i < 4; i++) {
+      /* careful for the valid range of offsets */
+      if (stages[i].alloc_8kb) {
+         assert(stages[i].entry_rows);
+         dw1[i] =
+            offset_8kb << GEN7_URB_DW1_OFFSET__SHIFT |
+            (stages[i].entry_rows - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
+            stages[i].entry_count << GEN7_URB_DW1_ENTRY_COUNT__SHIFT;
+         offset_8kb += stages[i].alloc_8kb;
+      } else {
+         dw1[i] = 0;
+      }
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(urb->urb) >= 4);
+   memcpy(urb->urb, dw1, sizeof(dw1));
+
+   return true;
+}
+
+bool
+ilo_state_urb_init(struct ilo_state_urb *urb,
+                   const struct ilo_dev *dev,
+                   const struct ilo_state_urb_info *info)
+{
+   assert(ilo_is_zeroed(urb, sizeof(*urb)));
+   return ilo_state_urb_set_info(urb, dev, info);
+}
+
+bool
+ilo_state_urb_init_for_rectlist(struct ilo_state_urb *urb,
+                                const struct ilo_dev *dev,
+                                uint8_t vf_attr_count)
+{
+   struct ilo_state_urb_info info;
+
+   memset(&info, 0, sizeof(info));
+   info.ve_entry_size = sizeof(uint32_t) * 4 * vf_attr_count;
+
+   return ilo_state_urb_init(urb, dev, &info);
+}
+
+bool
+ilo_state_urb_set_info(struct ilo_state_urb *urb,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info)
+{
+   struct urb_configuration conf;
+   bool ret = true;
+
+   ret &= urb_get_gen6_configuration(dev, info, &conf);
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      ret &= urb_set_gen7_3dstate_push_constant_alloc(urb, dev, info, &conf);
+      ret &= urb_set_gen7_3dstate_urb(urb, dev, info, &conf);
+   } else {
+      ret &= urb_set_gen6_3DSTATE_URB(urb, dev, info, &conf);
+   }
+
+   assert(ret);
+
+   return ret;
+}
+
+void
+ilo_state_urb_full_delta(const struct ilo_state_urb *urb,
+                         const struct ilo_dev *dev,
+                         struct ilo_state_urb_delta *delta)
+{
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      delta->dirty = ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
+                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
+                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
+                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
+                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS |
+                     ILO_STATE_URB_3DSTATE_URB_VS |
+                     ILO_STATE_URB_3DSTATE_URB_HS |
+                     ILO_STATE_URB_3DSTATE_URB_DS |
+                     ILO_STATE_URB_3DSTATE_URB_GS;
+   } else {
+      delta->dirty = ILO_STATE_URB_3DSTATE_URB_VS |
+                     ILO_STATE_URB_3DSTATE_URB_GS;
+   }
+}
+
+void
+ilo_state_urb_get_delta(const struct ilo_state_urb *urb,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_urb *old,
+                        struct ilo_state_urb_delta *delta)
+{
+   delta->dirty = 0;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      if (memcmp(urb->pcb, old->pcb, sizeof(urb->pcb))) {
+         delta->dirty |= ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
+                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
+                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
+                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
+                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS;
+      }
+
+      /*
+       * From the Ivy Bridge PRM, volume 2 part 1, page 34:
+       *
+       *     "3DSTATE_URB_HS, 3DSTATE_URB_DS, and 3DSTATE_URB_GS must also be
+       *      programmed in order for the programming of this state
+       *      (3DSTATE_URB_VS) to be valid."
+       *
+       * The same is true for the other three states.
+       */
+      if (memcmp(urb->urb, old->urb, sizeof(urb->urb))) {
+         delta->dirty |= ILO_STATE_URB_3DSTATE_URB_VS |
+                         ILO_STATE_URB_3DSTATE_URB_HS |
+                         ILO_STATE_URB_3DSTATE_URB_DS |
+                         ILO_STATE_URB_3DSTATE_URB_GS;
+      }
+   } else {
+      if (memcmp(urb->urb, old->urb, sizeof(uint32_t) * 2)) {
+         delta->dirty |= ILO_STATE_URB_3DSTATE_URB_VS |
+                         ILO_STATE_URB_3DSTATE_URB_GS;
+      }
+   }
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_urb.h b/src/gallium/drivers/ilo/core/ilo_state_urb.h
new file mode 100644 (file)
index 0000000..9522b3b
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_URB_H
+#define ILO_STATE_URB_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+enum ilo_state_urb_dirty_bits {
+   ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS = (1 << 0),
+   ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS = (1 << 1),
+   ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS = (1 << 2),
+   ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS = (1 << 3),
+   ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS = (1 << 4),
+   ILO_STATE_URB_3DSTATE_URB_VS                 = (1 << 5),
+   ILO_STATE_URB_3DSTATE_URB_HS                 = (1 << 6),
+   ILO_STATE_URB_3DSTATE_URB_DS                 = (1 << 7),
+   ILO_STATE_URB_3DSTATE_URB_GS                 = (1 << 8),
+};
+
+/**
+ * URB entry allocation sizes and sizes of constant data extracted from PCBs
+ * to threads.
+ */
+struct ilo_state_urb_info {
+   bool gs_enable;
+
+   bool vs_const_data;
+   bool hs_const_data;
+   bool ds_const_data;
+   bool gs_const_data;
+   bool ps_const_data;
+
+   uint16_t ve_entry_size;
+   uint16_t vs_entry_size;
+   uint16_t hs_entry_size;
+   uint16_t ds_entry_size;
+   uint16_t gs_entry_size;
+};
+
+struct ilo_state_urb {
+   uint32_t pcb[5];
+   uint32_t urb[4];
+};
+
+struct ilo_state_urb_delta {
+   uint32_t dirty;
+};
+
+bool
+ilo_state_urb_init(struct ilo_state_urb *urb,
+                   const struct ilo_dev *dev,
+                   const struct ilo_state_urb_info *info);
+
+bool
+ilo_state_urb_init_for_rectlist(struct ilo_state_urb *urb,
+                                const struct ilo_dev *dev,
+                                uint8_t vf_attr_count);
+
+bool
+ilo_state_urb_set_info(struct ilo_state_urb *urb,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_urb_info *info);
+
+void
+ilo_state_urb_full_delta(const struct ilo_state_urb *urb,
+                         const struct ilo_dev *dev,
+                         struct ilo_state_urb_delta *delta);
+
+void
+ilo_state_urb_get_delta(const struct ilo_state_urb *urb,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_urb *old,
+                        struct ilo_state_urb_delta *delta);
+
+#endif /* ILO_STATE_URB_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.c b/src/gallium/drivers/ilo/core/ilo_state_vf.c
new file mode 100644 (file)
index 0000000..ddc7542
--- /dev/null
@@ -0,0 +1,984 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_buffer.h"
+#include "ilo_state_vf.h"
+
+static bool
+vf_validate_gen6_elements(const struct ilo_dev *dev,
+                          const struct ilo_state_vf_info *info)
+{
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 95:
+    *
+    *     "(Source Element Offset (in bytes))
+    *      Format: U11
+    *      Range [0,2047"
+    *
+    * From the Haswell PRM, volume 2d, page 415:
+    *
+    *     "(Source Element Offset)
+    *      Format: U12 byte offset
+    *      ...
+    *      [0,4095]"
+    *
+    * From the Broadwell PRM, volume 2d, page 469:
+    *
+    *     "(Source Element Offset)
+    *      Format: U12 byte offset
+    *      ...
+    *      [0,2047]"
+    */
+   const uint16_t max_vertex_offset =
+      (ilo_dev_gen(dev) == ILO_GEN(7.5)) ? 4096 : 2048;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(info->element_count <= ILO_STATE_VF_MAX_ELEMENT_COUNT);
+
+   for (i = 0; i < info->element_count; i++) {
+      const struct ilo_state_vf_element_info *elem = &info->elements[i];
+
+      assert(elem->buffer < ILO_STATE_VF_MAX_BUFFER_COUNT);
+      assert(elem->vertex_offset < max_vertex_offset);
+      assert(ilo_state_vf_valid_element_format(dev, elem->format));
+   }
+
+   return true;
+}
+
+static uint32_t
+get_gen6_component_controls(const struct ilo_dev *dev,
+                            enum gen_vf_component comp_x,
+                            enum gen_vf_component comp_y,
+                            enum gen_vf_component comp_z,
+                            enum gen_vf_component comp_w)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return comp_x << GEN6_VE_DW1_COMP0__SHIFT |
+          comp_y << GEN6_VE_DW1_COMP1__SHIFT |
+          comp_z << GEN6_VE_DW1_COMP2__SHIFT |
+          comp_w << GEN6_VE_DW1_COMP3__SHIFT;
+}
+
+static bool
+get_gen6_edge_flag_format(const struct ilo_dev *dev,
+                          const struct ilo_state_vf_element_info *elem,
+                          enum gen_surface_format *format)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 94:
+    *
+    *     "The Source Element Format must be set to the UINT format."
+    *
+    * From the Haswell PRM, volume 2d, page 413:
+    *
+    *     "The SourceElementFormat needs to be a single-component format with
+    *      an element which has edge flag enabled."
+    */
+   if (elem->component_count != 1)
+      return false;
+
+   /* pick the format we like */
+   switch (elem->format_size) {
+   case 1:
+      *format = GEN6_FORMAT_R8_UINT;
+      break;
+   case 2:
+      *format = GEN6_FORMAT_R16_UINT;
+      break;
+   case 4:
+      *format = GEN6_FORMAT_R32_UINT;
+      break;
+   default:
+      return false;
+      break;
+   }
+
+   return true;
+}
+
+static bool
+vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_state_vf *vf,
+                                    const struct ilo_dev *dev,
+                                    const struct ilo_state_vf_info *info)
+{
+   enum gen_surface_format edge_flag_format;
+   uint32_t dw0, dw1;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!vf_validate_gen6_elements(dev, info))
+      return false;
+
+   for (i = 0; i < info->element_count; i++) {
+      const struct ilo_state_vf_element_info *elem = &info->elements[i];
+      enum gen_vf_component components[4] = {
+         GEN6_VFCOMP_STORE_0,
+         GEN6_VFCOMP_STORE_0,
+         GEN6_VFCOMP_STORE_0,
+         (elem->is_integer) ? GEN6_VFCOMP_STORE_1_INT :
+                              GEN6_VFCOMP_STORE_1_FP,
+      };
+
+      switch (elem->component_count) {
+      case 4: components[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
+      case 3: components[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
+      case 2: components[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
+      case 1: components[0] = GEN6_VFCOMP_STORE_SRC; break;
+      default:
+              assert(!"unexpected component count");
+              break;
+      }
+
+      dw0 = elem->buffer << GEN6_VE_DW0_VB_INDEX__SHIFT |
+            GEN6_VE_DW0_VALID |
+            elem->format << GEN6_VE_DW0_FORMAT__SHIFT |
+            elem->vertex_offset << GEN6_VE_DW0_VB_OFFSET__SHIFT;
+      dw1 = get_gen6_component_controls(dev,
+            components[0], components[1],
+            components[2], components[3]);
+
+      STATIC_ASSERT(ARRAY_SIZE(vf->user_ve[i]) >= 2);
+      vf->user_ve[i][0] = dw0;
+      vf->user_ve[i][1] = dw1;
+   }
+
+   vf->user_ve_count = i;
+
+   vf->edge_flag_supported = (i && get_gen6_edge_flag_format(dev,
+         &info->elements[i - 1], &edge_flag_format));
+   if (vf->edge_flag_supported) {
+      const struct ilo_state_vf_element_info *elem = &info->elements[i - 1];
+
+      /* without edge flag enable */
+      vf->last_user_ve[0][0] = dw0;
+      vf->last_user_ve[0][1] = dw1;
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 94:
+       *
+       *     "This bit (Edge Flag Enable) must only be ENABLED on the last
+       *      valid VERTEX_ELEMENT structure.
+       *
+       *      When set, Component 0 Control must be set to
+       *      VFCOMP_STORE_SRC, and Component 1-3 Control must be set to
+       *      VFCOMP_NOSTORE."
+       */
+      dw0 = elem->buffer << GEN6_VE_DW0_VB_INDEX__SHIFT |
+            GEN6_VE_DW0_VALID |
+            edge_flag_format << GEN6_VE_DW0_FORMAT__SHIFT |
+            GEN6_VE_DW0_EDGE_FLAG_ENABLE |
+            elem->vertex_offset << GEN6_VE_DW0_VB_OFFSET__SHIFT;
+      dw1 = get_gen6_component_controls(dev, GEN6_VFCOMP_STORE_SRC,
+            GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE);
+
+      /* with edge flag enable */
+      vf->last_user_ve[1][0] = dw0;
+      vf->last_user_ve[1][1] = dw1;
+   }
+
+   return true;
+}
+
+static bool
+vf_set_gen6_vertex_buffer_state(struct ilo_state_vf *vf,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_vf_info *info)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 7.5);
+
+   memset(vf->vb_to_first_elem, -1, sizeof(vf->vb_to_first_elem));
+
+   for (i = 0; i < info->element_count; i++) {
+      const struct ilo_state_vf_element_info *elem = &info->elements[i];
+
+      STATIC_ASSERT(ARRAY_SIZE(vf->user_instancing[i]) >= 2);
+      /* instancing enable only */
+      vf->user_instancing[i][0] = (elem->instancing_enable) ?
+         GEN6_VB_DW0_ACCESS_INSTANCEDATA :
+         GEN6_VB_DW0_ACCESS_VERTEXDATA;
+      vf->user_instancing[i][1] = elem->instancing_step_rate;
+
+      /*
+       * Instancing is per VB, not per VE, before Gen8.  Set up a VB-to-VE
+       * mapping as well.
+       */
+      if (vf->vb_to_first_elem[elem->buffer] < 0) {
+         vf->vb_to_first_elem[elem->buffer] = i;
+      } else {
+         const struct ilo_state_vf_element_info *first =
+            &info->elements[vf->vb_to_first_elem[elem->buffer]];
+
+         assert(elem->instancing_enable == first->instancing_enable &&
+                elem->instancing_step_rate == first->instancing_step_rate);
+      }
+   }
+
+   return true;
+}
+
+static bool
+vf_set_gen8_3DSTATE_VF_INSTANCING(struct ilo_state_vf *vf,
+                                  const struct ilo_dev *dev,
+                                  const struct ilo_state_vf_info *info)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   for (i = 0; i < info->element_count; i++) {
+      const struct ilo_state_vf_element_info *elem = &info->elements[i];
+
+      STATIC_ASSERT(ARRAY_SIZE(vf->user_instancing[i]) >= 2);
+      vf->user_instancing[i][0] = (elem->instancing_enable) ?
+         GEN8_INSTANCING_DW1_ENABLE : 0;
+      vf->user_instancing[i][1] = elem->instancing_step_rate;
+   }
+
+   return true;
+}
+
+static uint32_t
+get_gen6_component_zeros(const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return get_gen6_component_controls(dev,
+         GEN6_VFCOMP_STORE_0,
+         GEN6_VFCOMP_STORE_0,
+         GEN6_VFCOMP_STORE_0,
+         GEN6_VFCOMP_STORE_0);
+}
+
+static uint32_t
+get_gen6_component_ids(const struct ilo_dev *dev,
+                       bool vertexid, bool instanceid)
+{
+   ILO_DEV_ASSERT(dev, 6, 7.5);
+
+   return get_gen6_component_controls(dev,
+      (vertexid) ? GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0,
+      (instanceid) ? GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_STORE_0,
+      GEN6_VFCOMP_STORE_0,
+      GEN6_VFCOMP_STORE_0);
+}
+
+static bool
+vf_params_set_gen6_internal_ve(struct ilo_state_vf *vf,
+                               const struct ilo_dev *dev,
+                               const struct ilo_state_vf_params_info *params,
+                               uint8_t user_ve_count)
+{
+   const bool prepend_ids =
+      (params->prepend_vertexid || params->prepend_instanceid);
+   uint8_t internal_ve_count = 0, i;
+   uint32_t dw1[2];
+
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 92:
+    *
+    *     "- At least one VERTEX_ELEMENT_STATE structure must be included.
+    *
+    *      - Inclusion of partial VERTEX_ELEMENT_STATE structures is
+    *        UNDEFINED.
+    *
+    *      - SW must ensure that at least one vertex element is defined prior
+    *        to issuing a 3DPRIMTIVE command, or operation is UNDEFINED.
+    *
+    *      - There are no "holes" allowed in the destination vertex: NOSTORE
+    *        components must be overwritten by subsequent components unless
+    *        they are the trailing DWords of the vertex.  Software must
+    *        explicitly chose some value (probably 0) to be written into
+    *        DWords that would otherwise be "holes"."
+    *
+    *      - ...
+    *
+    *      - [DevILK+] Element[0] must be valid."
+    */
+   if (params->prepend_zeros || (!user_ve_count && !prepend_ids))
+      dw1[internal_ve_count++] = get_gen6_component_zeros(dev);
+
+   if (prepend_ids) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+         /* placeholder for 3DSTATE_VF_SGVS */
+         dw1[internal_ve_count++] = get_gen6_component_zeros(dev);
+      } else {
+         dw1[internal_ve_count++] = get_gen6_component_ids(dev,
+               params->prepend_vertexid, params->prepend_instanceid);
+      }
+   }
+
+   for (i = 0; i < internal_ve_count; i++) {
+      STATIC_ASSERT(ARRAY_SIZE(vf->internal_ve[i]) >= 2);
+      vf->internal_ve[i][0] = GEN6_VE_DW0_VALID;
+      vf->internal_ve[i][1] = dw1[i];
+   }
+
+   vf->internal_ve_count = internal_ve_count;
+
+   return true;
+}
+
+static bool
+vf_params_set_gen8_3DSTATE_VF_SGVS(struct ilo_state_vf *vf,
+                                   const struct ilo_dev *dev,
+                                   const struct ilo_state_vf_params_info *params)
+{
+   const uint8_t attr = (params->prepend_zeros) ? 1 : 0;
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw1 = 0;
+
+   if (params->prepend_instanceid) {
+      dw1 |= GEN8_SGVS_DW1_IID_ENABLE |
+             1 << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT |
+             attr << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT;
+   }
+
+   if (params->prepend_vertexid) {
+      dw1 |= GEN8_SGVS_DW1_VID_ENABLE |
+             0 << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT |
+             attr << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(vf->sgvs) >= 1);
+   vf->sgvs[0] = dw1;
+
+   return true;
+}
+
+static uint32_t
+get_gen6_fixed_cut_index(const struct ilo_dev *dev,
+                         enum gen_index_format format)
+{
+   const uint32_t fixed = ~0u;
+
+   ILO_DEV_ASSERT(dev, 6, 7);
+
+   switch (format) {
+   case GEN6_INDEX_BYTE:   return (uint8_t)  fixed;
+   case GEN6_INDEX_WORD:   return (uint16_t) fixed;
+   case GEN6_INDEX_DWORD:  return (uint32_t) fixed;
+   default:
+      assert(!"unknown index format");
+      return fixed;
+   }
+}
+
+static bool
+get_gen6_cut_index_supported(const struct ilo_dev *dev,
+                             enum gen_3dprim_type topology)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * See the Sandy Bridge PRM, volume 2 part 1, page 80 and the Haswell PRM,
+    * volume 7, page 456.
+    */
+   switch (topology) {
+   case GEN6_3DPRIM_TRIFAN:
+   case GEN6_3DPRIM_QUADLIST:
+   case GEN6_3DPRIM_QUADSTRIP:
+   case GEN6_3DPRIM_POLYGON:
+   case GEN6_3DPRIM_LINELOOP:
+      return (ilo_dev_gen(dev) >= ILO_GEN(7.5));
+   case GEN6_3DPRIM_RECTLIST:
+   case GEN6_3DPRIM_TRIFAN_NOSTIPPLE:
+      return false;
+   default:
+      return true;
+   }
+}
+
+static bool
+vf_params_set_gen6_3dstate_index_buffer(struct ilo_state_vf *vf,
+                                        const struct ilo_dev *dev,
+                                        const struct ilo_state_vf_params_info *params)
+{
+   uint32_t dw0 = 0;
+
+   ILO_DEV_ASSERT(dev, 6, 7);
+
+   /* cut index only, as in 3DSTATE_VF */
+   if (params->cut_index_enable) {
+      assert(get_gen6_cut_index_supported(dev, params->cv_topology));
+      assert(get_gen6_fixed_cut_index(dev, params->cv_index_format) ==
+            params->cut_index);
+
+      dw0 |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(vf->cut) >= 1);
+   vf->cut[0] = dw0;
+
+   return true;
+}
+
+static bool
+vf_params_set_gen75_3DSTATE_VF(struct ilo_state_vf *vf,
+                               const struct ilo_dev *dev,
+                               const struct ilo_state_vf_params_info *params)
+{
+   uint32_t dw0 = 0;
+
+   ILO_DEV_ASSERT(dev, 7.5, 8);
+
+   if (params->cut_index_enable) {
+      assert(get_gen6_cut_index_supported(dev, params->cv_topology));
+      dw0 |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(vf->cut) >= 2);
+   vf->cut[0] = dw0;
+   vf->cut[1] = params->cut_index;
+
+   return true;
+}
+
+static bool
+vertex_buffer_validate_gen6(const struct ilo_dev *dev,
+                            const struct ilo_state_vertex_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (info->buf)
+      assert(info->offset < info->buf->bo_size && info->size);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 86:
+    *
+    *     "(Buffer Pitch)
+    *      Range  [DevCTG+]: [0,2048] Bytes"
+    */
+   assert(info->stride <= 2048);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 86:
+    *
+    *     "64-bit floating point values must be 64-bit aligned in memory, or
+    *      UNPREDICTABLE data will be fetched. When accessing an element
+    *      containing 64-bit floating point values, the Buffer Starting
+    *      Address and Source Element Offset values must add to a 64-bit
+    *      aligned address, and BufferPitch must be a multiple of 64-bits."
+    */
+   if (info->cv_has_double) {
+      assert(info->stride % 8 == 0);
+      assert((info->offset + info->cv_double_vertex_offset_mod_8) % 8 == 0);
+   }
+
+   return true;
+}
+
+static uint32_t
+vertex_buffer_get_gen6_size(const struct ilo_dev *dev,
+                            const struct ilo_state_vertex_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!info->buf)
+      return 0;
+
+   return (info->offset + info->size <= info->buf->bo_size) ? info->size :
+      info->buf->bo_size - info->offset;
+}
+
+static bool
+vertex_buffer_set_gen8_vertex_buffer_state(struct ilo_state_vertex_buffer *vb,
+                                           const struct ilo_dev *dev,
+                                           const struct ilo_state_vertex_buffer_info *info)
+{
+   const uint32_t size = vertex_buffer_get_gen6_size(dev, info);
+   uint32_t dw0;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!vertex_buffer_validate_gen6(dev, info))
+      return false;
+
+   dw0 = info->stride << GEN6_VB_DW0_PITCH__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      dw0 |= GEN7_VB_DW0_ADDR_MODIFIED;
+   if (!info->buf)
+      dw0 |= GEN6_VB_DW0_IS_NULL;
+
+   STATIC_ASSERT(ARRAY_SIZE(vb->vb) >= 3);
+   vb->vb[0] = dw0;
+   vb->vb[1] = info->offset;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      vb->vb[2] = size;
+   } else {
+      /* address of the last valid byte */
+      vb->vb[2] = (size) ? info->offset + size - 1 : 0;
+   }
+
+   vb->need_bo = (info->buf != NULL);
+
+   return true;
+}
+
+static uint32_t
+get_index_format_size(enum gen_index_format format)
+{
+   switch (format) {
+   case GEN6_INDEX_BYTE:   return 1;
+   case GEN6_INDEX_WORD:   return 2;
+   case GEN6_INDEX_DWORD:  return 4;
+   default:
+      assert(!"unknown index format");
+      return 1;
+   }
+}
+
+static bool
+index_buffer_validate_gen6(const struct ilo_dev *dev,
+                           const struct ilo_state_index_buffer_info *info)
+{
+   const uint32_t format_size = get_index_format_size(info->format);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 79:
+    *
+    *     "This field (Buffer Starting Address) contains the size-aligned (as
+    *      specified by Index Format) Graphics Address of the first element of
+    *      interest within the index buffer."
+    */
+   assert(info->offset % format_size == 0);
+
+   if (info->buf)
+      assert(info->offset < info->buf->bo_size && info->size);
+
+   return true;
+}
+
+static uint32_t
+index_buffer_get_gen6_size(const struct ilo_dev *dev,
+                           const struct ilo_state_index_buffer_info *info)
+{
+   uint32_t size;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!info->buf)
+      return 0;
+
+   size = (info->offset + info->size <= info->buf->bo_size) ? info->size :
+      info->buf->bo_size - info->offset;
+
+   if (ilo_dev_gen(dev) < ILO_GEN(8)) {
+      const uint32_t format_size = get_index_format_size(info->format);
+      size -= (size % format_size);
+   }
+
+   return size;
+}
+
+static bool
+index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(struct ilo_state_index_buffer *ib,
+                                           const struct ilo_dev *dev,
+                                           const struct ilo_state_index_buffer_info *info)
+{
+   const uint32_t size = index_buffer_get_gen6_size(dev, info);
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!index_buffer_validate_gen6(dev, info))
+      return false;
+
+   STATIC_ASSERT(ARRAY_SIZE(ib->ib) >= 3);
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      ib->ib[0] = info->format << GEN8_IB_DW1_FORMAT__SHIFT;
+      ib->ib[1] = info->offset;
+      ib->ib[2] = size;
+   } else {
+      ib->ib[0] = info->format << GEN6_IB_DW0_FORMAT__SHIFT;
+      ib->ib[1] = info->offset;
+      /* address of the last valid byte, or 0 */
+      ib->ib[2] = (size) ? info->offset + size - 1 : 0;
+   }
+
+   ib->need_bo = (info->buf != NULL);
+
+   return true;
+}
+
+bool
+ilo_state_vf_valid_element_format(const struct ilo_dev *dev,
+                                  enum gen_surface_format format)
+{
+   /*
+    * This table is based on:
+    *
+    *  - the Sandy Bridge PRM, volume 4 part 1, page 88-97
+    *  - the Ivy Bridge PRM, volume 2 part 1, page 97-99
+    *  - the Haswell PRM, volume 7, page 467-470
+    */
+   static const int vf_element_formats[] = {
+      [GEN6_FORMAT_R32G32B32A32_FLOAT]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_SINT]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_UINT]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_UNORM]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_SNORM]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R64G64_FLOAT]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_SSCALED]     = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_USCALED]     = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32A32_SFIXED]      = ILO_GEN(7.5),
+      [GEN6_FORMAT_R32G32B32_FLOAT]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_SINT]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_UINT]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_UNORM]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_SNORM]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_SSCALED]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_USCALED]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32B32_SFIXED]         = ILO_GEN(7.5),
+      [GEN6_FORMAT_R16G16B16A16_UNORM]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16A16_SNORM]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16A16_SINT]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16A16_UINT]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16A16_FLOAT]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_FLOAT]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_SINT]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_UINT]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_UNORM]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_SNORM]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R64_FLOAT]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16A16_SSCALED]     = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16A16_USCALED]     = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_SSCALED]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_USCALED]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R32G32_SFIXED]            = ILO_GEN(7.5),
+      [GEN6_FORMAT_B8G8R8A8_UNORM]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R10G10B10A2_UNORM]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R10G10B10A2_UINT]         = ILO_GEN(  1),
+      [GEN6_FORMAT_R10G10B10_SNORM_A2_UNORM] = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8A8_UNORM]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8A8_SNORM]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8A8_SINT]            = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8A8_UINT]            = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_UNORM]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_SNORM]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_SINT]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_UINT]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_FLOAT]             = ILO_GEN(  1),
+      [GEN6_FORMAT_B10G10R10A2_UNORM]        = ILO_GEN(7.5),
+      [GEN6_FORMAT_R11G11B10_FLOAT]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_SINT]                 = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_UINT]                 = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_FLOAT]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_UNORM]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_SNORM]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R10G10B10X2_USCALED]      = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8A8_SSCALED]         = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8A8_USCALED]         = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_SSCALED]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16_USCALED]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_SSCALED]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R32_USCALED]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8_UNORM]               = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8_SNORM]               = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8_SINT]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8_UINT]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_UNORM]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_SNORM]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_SINT]                 = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_UINT]                 = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_FLOAT]                = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8_SSCALED]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8_USCALED]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_SSCALED]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R16_USCALED]              = ILO_GEN(  1),
+      [GEN6_FORMAT_R8_UNORM]                 = ILO_GEN(  1),
+      [GEN6_FORMAT_R8_SNORM]                 = ILO_GEN(  1),
+      [GEN6_FORMAT_R8_SINT]                  = ILO_GEN(  1),
+      [GEN6_FORMAT_R8_UINT]                  = ILO_GEN(  1),
+      [GEN6_FORMAT_R8_SSCALED]               = ILO_GEN(  1),
+      [GEN6_FORMAT_R8_USCALED]               = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8_UNORM]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8_SNORM]             = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8_SSCALED]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R8G8B8_USCALED]           = ILO_GEN(  1),
+      [GEN6_FORMAT_R64G64B64A64_FLOAT]       = ILO_GEN(  1),
+      [GEN6_FORMAT_R64G64B64_FLOAT]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16_FLOAT]          = ILO_GEN(  6),
+      [GEN6_FORMAT_R16G16B16_UNORM]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16_SNORM]          = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16_SSCALED]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16_USCALED]        = ILO_GEN(  1),
+      [GEN6_FORMAT_R16G16B16_UINT]           = ILO_GEN(7.5),
+      [GEN6_FORMAT_R16G16B16_SINT]           = ILO_GEN(7.5),
+      [GEN6_FORMAT_R32_SFIXED]               = ILO_GEN(7.5),
+      [GEN6_FORMAT_R10G10B10A2_SNORM]        = ILO_GEN(7.5),
+      [GEN6_FORMAT_R10G10B10A2_USCALED]      = ILO_GEN(7.5),
+      [GEN6_FORMAT_R10G10B10A2_SSCALED]      = ILO_GEN(7.5),
+      [GEN6_FORMAT_R10G10B10A2_SINT]         = ILO_GEN(7.5),
+      [GEN6_FORMAT_B10G10R10A2_SNORM]        = ILO_GEN(7.5),
+      [GEN6_FORMAT_B10G10R10A2_USCALED]      = ILO_GEN(7.5),
+      [GEN6_FORMAT_B10G10R10A2_SSCALED]      = ILO_GEN(7.5),
+      [GEN6_FORMAT_B10G10R10A2_UINT]         = ILO_GEN(7.5),
+      [GEN6_FORMAT_B10G10R10A2_SINT]         = ILO_GEN(7.5),
+      [GEN6_FORMAT_R8G8B8_UINT]              = ILO_GEN(7.5),
+      [GEN6_FORMAT_R8G8B8_SINT]              = ILO_GEN(7.5),
+   };
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   return (format < ARRAY_SIZE(vf_element_formats) &&
+           vf_element_formats[format] &&
+           ilo_dev_gen(dev) >= vf_element_formats[format]);
+}
+
+bool
+ilo_state_vf_init(struct ilo_state_vf *vf,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_vf_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(vf, sizeof(*vf)));
+   assert(ilo_is_zeroed(info->data, info->data_size));
+
+   assert(ilo_state_vf_data_size(dev, info->element_count) <=
+         info->data_size);
+   vf->user_ve = (uint32_t (*)[2]) info->data;
+   vf->user_instancing =
+      (uint32_t (*)[2]) (vf->user_ve + info->element_count);
+
+   ret &= vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(vf, dev, info);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      ret &= vf_set_gen8_3DSTATE_VF_INSTANCING(vf, dev, info);
+   else
+      ret &= vf_set_gen6_vertex_buffer_state(vf, dev, info);
+
+   ret &= ilo_state_vf_set_params(vf, dev, &info->params);
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_vf_init_for_rectlist(struct ilo_state_vf *vf,
+                               const struct ilo_dev *dev,
+                               void *data, size_t data_size,
+                               const struct ilo_state_vf_element_info *elements,
+                               uint8_t element_count)
+{
+   struct ilo_state_vf_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   info.data = data;
+   info.data_size = data_size;
+
+   info.elements = elements;
+   info.element_count = element_count;
+
+   /*
+    * For VUE header,
+    *
+    *   DW0: Reserved: MBZ
+    *   DW1: Render Target Array Index
+    *   DW2: Viewport Index
+    *   DW3: Point Width
+    */
+   info.params.prepend_zeros = true;
+
+   return ilo_state_vf_init(vf, dev, &info);
+}
+
+bool
+ilo_state_vf_set_params(struct ilo_state_vf *vf,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_vf_params_info *params)
+{
+   bool ret = true;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   ret &= vf_params_set_gen6_internal_ve(vf, dev, params, vf->user_ve_count);
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      ret &= vf_params_set_gen8_3DSTATE_VF_SGVS(vf, dev, params);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 94:
+    *
+    *     "Edge flags are supported for the following primitive topology types
+    *      only, otherwise EdgeFlagEnable must not be ENABLED.
+    *
+    *      - 3DPRIM_TRILIST*
+    *      - 3DPRIM_TRISTRIP*
+    *      - 3DPRIM_TRIFAN*
+    *      - 3DPRIM_POLYGON"
+    *
+    *     "[DevSNB]: Edge Flags are not supported for QUADLIST primitives.
+    *      Software may elect to convert QUADLIST primitives to some set of
+    *      corresponding edge-flag-supported primitive types (e.g., POLYGONs)
+    *      prior to submission to the 3D vf."
+    *
+    * From the Ivy Bridge PRM, volume 2 part 1, page 86:
+    *
+    *     "Edge flags are supported for all primitive topology types."
+    *
+    * Both PRMs are confusing...
+    */
+   if (params->last_element_edge_flag) {
+      assert(vf->edge_flag_supported);
+      if (ilo_dev_gen(dev) == ILO_GEN(6))
+         assert(params->cv_topology != GEN6_3DPRIM_QUADLIST);
+   }
+
+   if (vf->edge_flag_supported) {
+      assert(vf->user_ve_count);
+      memcpy(vf->user_ve[vf->user_ve_count - 1],
+            vf->last_user_ve[params->last_element_edge_flag],
+            sizeof(vf->user_ve[vf->user_ve_count - 1]));
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      ret &= vf_params_set_gen75_3DSTATE_VF(vf, dev, params);
+   else
+      ret &= vf_params_set_gen6_3dstate_index_buffer(vf, dev, params);
+
+   assert(ret);
+
+   return ret;
+}
+
+void
+ilo_state_vf_full_delta(const struct ilo_state_vf *vf,
+                        const struct ilo_dev *dev,
+                        struct ilo_state_vf_delta *delta)
+{
+   delta->dirty = ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS |
+                      ILO_STATE_VF_3DSTATE_VF_INSTANCING;
+   } else {
+      delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      delta->dirty |= ILO_STATE_VF_3DSTATE_VF;
+   else
+      delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER;
+}
+
+void
+ilo_state_vf_get_delta(const struct ilo_state_vf *vf,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_vf *old,
+                       struct ilo_state_vf_delta *delta)
+{
+   /* no shallow copying */
+   assert(vf->user_ve != old->user_ve &&
+          vf->user_instancing != old->user_instancing);
+
+   delta->dirty = 0;
+
+   if (vf->internal_ve_count != old->internal_ve_count ||
+       vf->user_ve_count != old->user_ve_count ||
+       memcmp(vf->internal_ve, old->internal_ve,
+          sizeof(vf->internal_ve[0]) * vf->internal_ve_count) ||
+       memcmp(vf->user_ve, old->user_ve,
+          sizeof(vf->user_ve[0]) * vf->user_ve_count))
+      delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS;
+
+   if (vf->user_ve_count != old->user_ve_count ||
+       memcmp(vf->user_instancing, old->user_instancing,
+          sizeof(vf->user_instancing[0]) * vf->user_ve_count)) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(8))
+         delta->dirty |= ILO_STATE_VF_3DSTATE_VF_INSTANCING;
+      else
+         delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      if (vf->sgvs[0] != old->sgvs[0])
+         delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS;
+   }
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) {
+      if (memcmp(vf->cut, old->cut, sizeof(vf->cut)))
+         delta->dirty |= ILO_STATE_VF_3DSTATE_VF;
+   } else {
+      if (vf->cut[0] != old->cut[0])
+         delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER;
+   }
+}
+
+/**
+ * No need to initialize first.
+ */
+bool
+ilo_state_vertex_buffer_set_info(struct ilo_state_vertex_buffer *vb,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_vertex_buffer_info *info)
+{
+   bool ret = true;
+
+   ret &= vertex_buffer_set_gen8_vertex_buffer_state(vb, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
+
+/**
+ * No need to initialize first.
+ */
+bool
+ilo_state_index_buffer_set_info(struct ilo_state_index_buffer *ib,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_index_buffer_info *info)
+{
+   bool ret = true;
+
+   ret &= index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(ib, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.h b/src/gallium/drivers/ilo/core/ilo_state_vf.h
new file mode 100644 (file)
index 0000000..f15c63a
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_VF_H
+#define ILO_STATE_VF_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 93:
+ *
+ *     "Up to 34 (DevSNB+) vertex elements are supported."
+ *
+ *     "Up to 33 VBs are supported"
+ *
+ * Reserve two VEs and one VB for internal use.
+ */
+#define ILO_STATE_VF_MAX_ELEMENT_COUNT (34 - 2)
+#define ILO_STATE_VF_MAX_BUFFER_COUNT (33 - 1)
+
+enum ilo_state_vf_dirty_bits {
+   ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS            = (1 << 0),
+   ILO_STATE_VF_3DSTATE_VF_SGVS                    = (1 << 1),
+   ILO_STATE_VF_3DSTATE_VF_INSTANCING              = (1 << 2),
+   ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS             = (1 << 3),
+   ILO_STATE_VF_3DSTATE_VF                         = (1 << 4),
+   ILO_STATE_VF_3DSTATE_INDEX_BUFFER               = (1 << 5),
+};
+
+/**
+ * Fetch a 128-bit vertex attribute.
+ */
+struct ilo_state_vf_element_info {
+   uint8_t buffer;
+   uint16_t vertex_offset;
+   enum gen_surface_format format;
+
+   uint8_t format_size;
+   uint8_t component_count;
+   bool is_integer;
+
+   /* must be the same for those share the same buffer before Gen8 */
+   bool instancing_enable;
+   uint32_t instancing_step_rate;
+};
+
+/**
+ * VF parameters.
+ */
+struct ilo_state_vf_params_info {
+   enum gen_3dprim_type cv_topology;
+
+   /* prepend an attribute of zeros */
+   bool prepend_zeros;
+
+   /* prepend an attribute of VertexID and/or InstanceID */
+   bool prepend_vertexid;
+   bool prepend_instanceid;
+
+   bool last_element_edge_flag;
+
+   enum gen_index_format cv_index_format;
+   bool cut_index_enable;
+   uint32_t cut_index;
+};
+
+/**
+ * Vertex fetch.
+ */
+struct ilo_state_vf_info {
+   void *data;
+   size_t data_size;
+
+   const struct ilo_state_vf_element_info *elements;
+   uint8_t element_count;
+
+   struct ilo_state_vf_params_info params;
+};
+
+struct ilo_state_vf {
+   uint32_t (*user_ve)[2];
+   uint32_t (*user_instancing)[2];
+   int8_t vb_to_first_elem[ILO_STATE_VF_MAX_BUFFER_COUNT];
+   uint8_t user_ve_count;
+
+   bool edge_flag_supported;
+   uint32_t last_user_ve[2][2];
+
+   /* two VEs are reserved for internal use */
+   uint32_t internal_ve[2][2];
+   uint8_t internal_ve_count;
+
+   uint32_t sgvs[1];
+
+   uint32_t cut[2];
+};
+
+struct ilo_state_vf_delta {
+   uint32_t dirty;
+};
+
+struct ilo_buffer;
+
+struct ilo_state_vertex_buffer_info {
+   const struct ilo_buffer *buf;
+   uint32_t offset;
+   uint32_t size;
+
+   uint16_t stride;
+
+   /* doubles must be at 64-bit aligned addresses */
+   bool cv_has_double;
+   uint8_t cv_double_vertex_offset_mod_8;
+};
+
+struct ilo_state_vertex_buffer {
+   uint32_t vb[3];
+
+   bool need_bo;
+
+   /* managed by users */
+   struct intel_bo *bo;
+};
+
+struct ilo_state_index_buffer_info {
+   const struct ilo_buffer *buf;
+   uint32_t offset;
+   uint32_t size;
+
+   enum gen_index_format format;
+};
+
+struct ilo_state_index_buffer {
+   uint32_t ib[3];
+
+   bool need_bo;
+
+   /* managed by users */
+   struct intel_bo *bo;
+};
+
+static inline size_t
+ilo_state_vf_data_size(const struct ilo_dev *dev, uint8_t element_count)
+{
+   const struct ilo_state_vf *vf = NULL;
+   return (sizeof(vf->user_ve[0]) +
+           sizeof(vf->user_instancing[0])) * element_count;
+}
+
+bool
+ilo_state_vf_valid_element_format(const struct ilo_dev *dev,
+                                  enum gen_surface_format format);
+
+bool
+ilo_state_vf_init(struct ilo_state_vf *vf,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_vf_info *info);
+
+bool
+ilo_state_vf_init_for_rectlist(struct ilo_state_vf *vf,
+                               const struct ilo_dev *dev,
+                               void *data, size_t data_size,
+                               const struct ilo_state_vf_element_info *elements,
+                               uint8_t element_count);
+
+bool
+ilo_state_vf_set_params(struct ilo_state_vf *vf,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_vf_params_info *params);
+
+/**
+ * Return the number of attributes in the VUE.
+ */
+static inline uint8_t
+ilo_state_vf_get_attr_count(const struct ilo_state_vf *vf)
+{
+   return vf->internal_ve_count + vf->user_ve_count;
+}
+
+void
+ilo_state_vf_full_delta(const struct ilo_state_vf *vf,
+                        const struct ilo_dev *dev,
+                        struct ilo_state_vf_delta *delta);
+
+void
+ilo_state_vf_get_delta(const struct ilo_state_vf *vf,
+                       const struct ilo_dev *dev,
+                       const struct ilo_state_vf *old,
+                       struct ilo_state_vf_delta *delta);
+
+bool
+ilo_state_vertex_buffer_set_info(struct ilo_state_vertex_buffer *vb,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_vertex_buffer_info *info);
+
+bool
+ilo_state_index_buffer_set_info(struct ilo_state_index_buffer *ib,
+                                const struct ilo_dev *dev,
+                                const struct ilo_state_index_buffer_info *info);
+
+#endif /* ILO_STATE_VF_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_viewport.c b/src/gallium/drivers/ilo/core/ilo_state_viewport.c
new file mode 100644 (file)
index 0000000..aae5733
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_debug.h"
+#include "ilo_state_viewport.h"
+
+static void
+viewport_matrix_get_gen6_guardband(const struct ilo_dev *dev,
+                                   const struct ilo_state_viewport_matrix_info *mat,
+                                   float *min_gbx, float *max_gbx,
+                                   float *min_gby, float *max_gby)
+{
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 234:
+    *
+    *     "Per-Device Guardband Extents
+    *
+    *       - Supported X,Y ScreenSpace "Guardband" Extent: [-16K,16K-1]
+    *       - Maximum Post-Clamp Delta (X or Y): 16K"
+    *
+    *     "In addition, in order to be correctly rendered, objects must have a
+    *      screenspace bounding box not exceeding 8K in the X or Y direction.
+    *      This additional restriction must also be comprehended by software,
+    *      i.e., enforced by use of clipping."
+    *
+    * From the Ivy Bridge PRM, volume 2 part 1, page 248:
+    *
+    *     "Per-Device Guardband Extents
+    *
+    *       - Supported X,Y ScreenSpace "Guardband" Extent: [-32K,32K-1]
+    *       - Maximum Post-Clamp Delta (X or Y): N/A"
+    *
+    *     "In addition, in order to be correctly rendered, objects must have a
+    *      screenspace bounding box not exceeding 8K in the X or Y direction.
+    *      This additional restriction must also be comprehended by software,
+    *      i.e., enforced by use of clipping."
+    *
+    * Combined, the bounding box of any object can not exceed 8K in both
+    * width and height.
+    *
+    * Below we set the guardband as a squre of length 8K, centered at where
+    * the viewport is.  This makes sure all objects passing the GB test are
+    * valid to the renderer, and those failing the XY clipping have a
+    * better chance of passing the GB test.
+    */
+   const int max_extent = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 32768 : 16384;
+   const int half_len = 8192 / 2;
+   int center_x = (int) mat->translate[0];
+   int center_y = (int) mat->translate[1];
+   float scale_x, scale_y;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /* make sure the guardband is within the valid range */
+   if (center_x - half_len < -max_extent)
+      center_x = -max_extent + half_len;
+   else if (center_x + half_len > max_extent - 1)
+      center_x = max_extent - half_len;
+
+   if (center_y - half_len < -max_extent)
+      center_y = -max_extent + half_len;
+   else if (center_y + half_len > max_extent - 1)
+      center_y = max_extent - half_len;
+
+   scale_x = fabsf(mat->scale[0]);
+   scale_y = fabsf(mat->scale[1]);
+   /*
+    * From the Haswell PRM, volume 2d, page 292-293:
+    *
+    *     "Note: Minimum allowed value for this field (X/Y Min Clip Guardband)
+    *      is -16384."
+    *
+    *     "Note: Maximum allowed value for this field (X/Y Max Clip Guardband)
+    *      is 16383."
+    *
+    * Avoid small scales.
+    */
+   if (scale_x < 1.0f)
+      scale_x = 1.0f;
+   if (scale_y < 1.0f)
+      scale_y = 1.0f;
+
+   /* in NDC space */
+   *min_gbx = ((float) (center_x - half_len) - mat->translate[0]) / scale_x;
+   *max_gbx = ((float) (center_x + half_len) - mat->translate[0]) / scale_x;
+   *min_gby = ((float) (center_y - half_len) - mat->translate[1]) / scale_y;
+   *max_gby = ((float) (center_y + half_len) - mat->translate[1]) / scale_y;
+}
+
+static void
+viewport_matrix_get_extent(const struct ilo_state_viewport_matrix_info *mat,
+                           int axis, float *min, float *max)
+{
+   const float scale_abs = fabsf(mat->scale[axis]);
+
+   *min = -1.0f * scale_abs + mat->translate[axis];
+   *max =  1.0f * scale_abs + mat->translate[axis];
+}
+
+static bool
+viewport_matrix_set_gen7_SF_CLIP_VIEWPORT(struct ilo_state_viewport *vp,
+                                          const struct ilo_dev *dev,
+                                          const struct ilo_state_viewport_matrix_info *matrices,
+                                          uint8_t count)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   for (i = 0; i < count; i++) {
+      const struct ilo_state_viewport_matrix_info *mat = &matrices[i];
+      float min_gbx, max_gbx, min_gby, max_gby;
+      uint32_t dw[16];
+
+      viewport_matrix_get_gen6_guardband(dev, mat,
+            &min_gbx, &max_gbx, &min_gby, &max_gby);
+
+      dw[0] = fui(mat->scale[0]);
+      dw[1] = fui(mat->scale[1]);
+      dw[2] = fui(mat->scale[2]);
+      dw[3] = fui(mat->translate[0]);
+      dw[4] = fui(mat->translate[1]);
+      dw[5] = fui(mat->translate[2]);
+      dw[6] = 0;
+      dw[7] = 0;
+
+      dw[8] = fui(min_gbx);
+      dw[9] = fui(max_gbx);
+      dw[10] = fui(min_gby);
+      dw[11] = fui(max_gby);
+
+      if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+         float min_x, max_x, min_y, max_y;
+
+         viewport_matrix_get_extent(mat, 0, &min_x, &max_x);
+         viewport_matrix_get_extent(mat, 1, &min_y, &max_y);
+
+         dw[12] = fui(min_x);
+         dw[13] = fui(max_x - 1.0f);
+         dw[14] = fui(min_y);
+         dw[15] = fui(max_y - 1.0f);
+      } else {
+         dw[12] = 0;
+         dw[13] = 0;
+         dw[14] = 0;
+         dw[15] = 0;
+      }
+
+      STATIC_ASSERT(ARRAY_SIZE(vp->sf_clip[i]) >= 16);
+      memcpy(vp->sf_clip[i], dw, sizeof(dw));
+   }
+
+   return true;
+}
+
+static bool
+viewport_matrix_set_gen6_CC_VIEWPORT(struct ilo_state_viewport *vp,
+                                     const struct ilo_dev *dev,
+                                     const struct ilo_state_viewport_matrix_info *matrices,
+                                     uint8_t count)
+{
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   for (i = 0; i < count; i++) {
+      const struct ilo_state_viewport_matrix_info *mat = &matrices[i];
+      float min_z, max_z;
+
+      viewport_matrix_get_extent(mat, 2, &min_z, &max_z);
+
+      STATIC_ASSERT(ARRAY_SIZE(vp->cc[i]) >= 2);
+      vp->cc[i][0] = fui(min_z);
+      vp->cc[i][1] = fui(max_z);
+   }
+
+   return true;
+}
+
+static bool
+viewport_scissor_set_gen6_SCISSOR_RECT(struct ilo_state_viewport *vp,
+                                       const struct ilo_dev *dev,
+                                       const struct ilo_state_viewport_scissor_info *scissors,
+                                       uint8_t count)
+{
+   const uint16_t max_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192;
+   uint8_t i;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   for (i = 0; i < count; i++) {
+      const struct ilo_state_viewport_scissor_info *scissor = &scissors[i];
+      uint16_t min_x, min_y, max_x, max_y;
+      uint32_t dw0, dw1;
+
+      min_x = (scissor->min_x < max_size) ? scissor->min_x : max_size - 1;
+      min_y = (scissor->min_y < max_size) ? scissor->min_y : max_size - 1;
+      max_x = (scissor->max_x < max_size) ? scissor->max_x : max_size - 1;
+      max_y = (scissor->max_y < max_size) ? scissor->max_y : max_size - 1;
+
+      dw0 = min_y << GEN6_SCISSOR_DW0_MIN_Y__SHIFT |
+            min_x << GEN6_SCISSOR_DW0_MIN_X__SHIFT;
+      dw1 = max_y << GEN6_SCISSOR_DW1_MAX_Y__SHIFT |
+            max_x << GEN6_SCISSOR_DW1_MAX_X__SHIFT;
+
+      STATIC_ASSERT(ARRAY_SIZE(vp->scissor[i]) >= 2);
+      vp->scissor[i][0] = dw0;
+      vp->scissor[i][1] = dw1;
+   }
+
+   return true;
+}
+
+bool
+ilo_state_viewport_init(struct ilo_state_viewport *vp,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_viewport_info *info)
+{
+   const size_t elem_size = ilo_state_viewport_data_size(dev, 1);
+
+   assert(ilo_is_zeroed(vp, sizeof(*vp)));
+   assert(ilo_is_zeroed(info->data, info->data_size));
+
+   vp->data = info->data;
+
+   if (info->data_size / elem_size < ILO_STATE_VIEWPORT_MAX_COUNT)
+      vp->array_size = info->data_size / elem_size;
+   else
+      vp->array_size = ILO_STATE_VIEWPORT_MAX_COUNT;
+
+   return ilo_state_viewport_set_params(vp, dev, &info->params, false);
+}
+
+bool
+ilo_state_viewport_init_data_only(struct ilo_state_viewport *vp,
+                                  const struct ilo_dev *dev,
+                                  void *data, size_t data_size)
+{
+   struct ilo_state_viewport_info info;
+
+   memset(&info, 0, sizeof(info));
+   info.data = data;
+   info.data_size = data_size;
+
+   return ilo_state_viewport_init(vp, dev, &info);
+}
+
+bool
+ilo_state_viewport_init_for_rectlist(struct ilo_state_viewport *vp,
+                                     const struct ilo_dev *dev,
+                                     void *data, size_t data_size)
+{
+   struct ilo_state_viewport_info info;
+   struct ilo_state_viewport_matrix_info mat;
+   struct ilo_state_viewport_scissor_info sci;
+
+   memset(&info, 0, sizeof(info));
+   memset(&mat, 0, sizeof(mat));
+   memset(&sci, 0, sizeof(sci));
+
+   info.data = data;
+   info.data_size = data_size;
+   info.params.matrices = &mat;
+   info.params.scissors = &sci;
+   info.params.count = 1;
+
+   mat.scale[0] = 1.0f;
+   mat.scale[1] = 1.0f;
+   mat.scale[2] = 1.0f;
+
+   return ilo_state_viewport_init(vp, dev, &info);
+}
+
+static void
+viewport_set_count(struct ilo_state_viewport *vp,
+                   const struct ilo_dev *dev,
+                   uint8_t count)
+{
+   assert(count <= vp->array_size);
+
+   vp->count = count;
+   vp->sf_clip = (uint32_t (*)[16]) vp->data;
+   vp->cc =      (uint32_t (*)[ 2]) (vp->sf_clip + count);
+   vp->scissor = (uint32_t (*)[ 2]) (vp->cc + count);
+}
+
+bool
+ilo_state_viewport_set_params(struct ilo_state_viewport *vp,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_viewport_params_info *params,
+                              bool scissors_only)
+{
+   bool ret = true;
+
+   if (scissors_only) {
+      assert(vp->count == params->count);
+
+      ret &= viewport_scissor_set_gen6_SCISSOR_RECT(vp, dev,
+            params->scissors, params->count);
+   } else {
+      viewport_set_count(vp, dev, params->count);
+
+      ret &= viewport_matrix_set_gen7_SF_CLIP_VIEWPORT(vp, dev,
+            params->matrices, params->count);
+      ret &= viewport_matrix_set_gen6_CC_VIEWPORT(vp, dev,
+            params->matrices, params->count);
+      ret &= viewport_scissor_set_gen6_SCISSOR_RECT(vp, dev,
+            params->scissors, params->count);
+   }
+
+   assert(ret);
+
+   return ret;
+}
+
+void
+ilo_state_viewport_full_delta(const struct ilo_state_viewport *vp,
+                              const struct ilo_dev *dev,
+                              struct ilo_state_viewport_delta *delta)
+{
+   delta->dirty = ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT |
+                  ILO_STATE_VIEWPORT_CC_VIEWPORT |
+                  ILO_STATE_VIEWPORT_SCISSOR_RECT;
+}
+
+void
+ilo_state_viewport_get_delta(const struct ilo_state_viewport *vp,
+                             const struct ilo_dev *dev,
+                             const struct ilo_state_viewport *old,
+                             struct ilo_state_viewport_delta *delta)
+{
+   const size_t sf_clip_size = sizeof(vp->sf_clip[0]) * vp->count;
+   const size_t cc_size = sizeof(vp->cc[0]) * vp->count;
+   const size_t scissor_size = sizeof(vp->scissor[0]) * vp->count;
+
+   /* no shallow copying */
+   assert(vp->data != old->data);
+
+   if (vp->count != old->count) {
+      ilo_state_viewport_full_delta(vp, dev, delta);
+      return;
+   }
+
+   delta->dirty = 0;
+
+   if (memcmp(vp->sf_clip, old->sf_clip, sf_clip_size))
+      delta->dirty |= ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT;
+
+   if (memcmp(vp->cc, old->cc, cc_size))
+      delta->dirty |= ILO_STATE_VIEWPORT_CC_VIEWPORT;
+
+   if (memcmp(vp->scissor, old->scissor, scissor_size))
+      delta->dirty |= ILO_STATE_VIEWPORT_SCISSOR_RECT;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_viewport.h b/src/gallium/drivers/ilo/core/ilo_state_viewport.h
new file mode 100644 (file)
index 0000000..b42ad65
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_VIEWPORT_H
+#define ILO_STATE_VIEWPORT_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+/*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 38:
+ *
+ *     "... 16 sets of viewport (VP) state parameters in the Clip unit's
+ *      VertexClipTest function and in the SF unit's ViewportMapping and
+ *      Scissor functions."
+ */
+#define ILO_STATE_VIEWPORT_MAX_COUNT 16
+
+enum ilo_state_viewport_dirty_bits {
+   ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT             = (1 << 0),
+   ILO_STATE_VIEWPORT_CC_VIEWPORT                  = (1 << 1),
+   ILO_STATE_VIEWPORT_SCISSOR_RECT                 = (1 << 2),
+};
+
+struct ilo_state_viewport_matrix_info {
+   float scale[3];
+   float translate[3];
+};
+
+struct ilo_state_viewport_scissor_info {
+   /* all inclusive */
+   uint16_t min_x;
+   uint16_t min_y;
+   uint16_t max_x;
+   uint16_t max_y;
+};
+
+struct ilo_state_viewport_params_info {
+   const struct ilo_state_viewport_matrix_info *matrices;
+   const struct ilo_state_viewport_scissor_info *scissors;
+   uint8_t count;
+};
+
+struct ilo_state_viewport_info {
+   void *data;
+   size_t data_size;
+
+   struct ilo_state_viewport_params_info params;
+};
+
+struct ilo_state_viewport {
+   void *data;
+   uint8_t array_size;
+
+   uint8_t count;
+   uint32_t (*sf_clip)[16];
+   uint32_t (*cc)[2];
+   uint32_t (*scissor)[2];
+};
+
+struct ilo_state_viewport_delta {
+   uint32_t dirty;
+};
+
+static inline size_t
+ilo_state_viewport_data_size(const struct ilo_dev *dev, uint8_t array_size)
+{
+   const struct ilo_state_viewport *vp = NULL;
+   return (sizeof(vp->sf_clip[0]) +
+           sizeof(vp->cc[0]) +
+           sizeof(vp->scissor[0])) * array_size;
+}
+
+bool
+ilo_state_viewport_init(struct ilo_state_viewport *vp,
+                        const struct ilo_dev *dev,
+                        const struct ilo_state_viewport_info *info);
+
+bool
+ilo_state_viewport_init_data_only(struct ilo_state_viewport *vp,
+                                  const struct ilo_dev *dev,
+                                  void *data, size_t data_size);
+
+bool
+ilo_state_viewport_init_for_rectlist(struct ilo_state_viewport *vp,
+                                     const struct ilo_dev *dev,
+                                     void *data, size_t data_size);
+
+bool
+ilo_state_viewport_set_params(struct ilo_state_viewport *vp,
+                              const struct ilo_dev *dev,
+                              const struct ilo_state_viewport_params_info *params,
+                              bool scissors_only);
+
+void
+ilo_state_viewport_full_delta(const struct ilo_state_viewport *vp,
+                              const struct ilo_dev *dev,
+                              struct ilo_state_viewport_delta *delta);
+
+void
+ilo_state_viewport_get_delta(const struct ilo_state_viewport *vp,
+                             const struct ilo_dev *dev,
+                             const struct ilo_state_viewport *old,
+                             struct ilo_state_viewport_delta *delta);
+
+#endif /* ILO_STATE_VIEWPORT_H */
diff --git a/src/gallium/drivers/ilo/core/ilo_state_zs.c b/src/gallium/drivers/ilo/core/ilo_state_zs.c
new file mode 100644 (file)
index 0000000..901fedb
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "intel_winsys.h"
+
+#include "ilo_debug.h"
+#include "ilo_image.h"
+#include "ilo_state_zs.h"
+
+static bool
+zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
+                                      const struct ilo_dev *dev)
+{
+   const enum gen_depth_format format = GEN6_ZFORMAT_D32_FLOAT;
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      dw1 = GEN6_SURFTYPE_NULL << GEN7_DEPTH_DW1_TYPE__SHIFT |
+            format << GEN7_DEPTH_DW1_FORMAT__SHIFT;
+   } else {
+      dw1 = GEN6_SURFTYPE_NULL << GEN6_DEPTH_DW1_TYPE__SHIFT |
+            GEN6_TILING_Y << GEN6_DEPTH_DW1_TILING__SHIFT |
+            format << GEN6_DEPTH_DW1_FORMAT__SHIFT;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
+   zs->depth[0] = dw1;
+   zs->depth[1] = 0;
+   zs->depth[2] = 0;
+   zs->depth[3] = 0;
+   zs->depth[4] = 0;
+
+   zs->depth_format = format;
+
+   return true;
+}
+
+static enum gen_surface_type
+get_gen6_surface_type(const struct ilo_dev *dev, const struct ilo_image *img)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (img->target) {
+   case PIPE_TEXTURE_1D:
+   case PIPE_TEXTURE_1D_ARRAY:
+      return GEN6_SURFTYPE_1D;
+   case PIPE_TEXTURE_2D:
+   case PIPE_TEXTURE_CUBE:
+   case PIPE_TEXTURE_RECT:
+   case PIPE_TEXTURE_2D_ARRAY:
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      return GEN6_SURFTYPE_2D;
+   case PIPE_TEXTURE_3D:
+      return GEN6_SURFTYPE_3D;
+   default:
+      assert(!"unknown texture target");
+      return GEN6_SURFTYPE_NULL;
+   }
+}
+
+static enum gen_depth_format
+get_gen6_depth_format(const struct ilo_dev *dev, const struct ilo_image *img)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      switch (img->format) {
+      case PIPE_FORMAT_Z32_FLOAT:
+         return GEN6_ZFORMAT_D32_FLOAT;
+      case PIPE_FORMAT_Z24X8_UNORM:
+         return GEN6_ZFORMAT_D24_UNORM_X8_UINT;
+      case PIPE_FORMAT_Z16_UNORM:
+         return GEN6_ZFORMAT_D16_UNORM;
+      default:
+         assert(!"unknown depth format");
+         return GEN6_ZFORMAT_D32_FLOAT;
+      }
+   } else {
+      switch (img->format) {
+      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+         return GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT;
+      case PIPE_FORMAT_Z32_FLOAT:
+         return GEN6_ZFORMAT_D32_FLOAT;
+      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+         return GEN6_ZFORMAT_D24_UNORM_S8_UINT;
+      case PIPE_FORMAT_Z24X8_UNORM:
+         return GEN6_ZFORMAT_D24_UNORM_X8_UINT;
+      case PIPE_FORMAT_Z16_UNORM:
+         return GEN6_ZFORMAT_D16_UNORM;
+      default:
+         assert(!"unknown depth format");
+         return GEN6_ZFORMAT_D32_FLOAT;
+      }
+   }
+}
+
+static bool
+zs_validate_gen6(const struct ilo_dev *dev,
+                 const struct ilo_state_zs_info *info)
+{
+   const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 315:
+    *
+    *      The stencil buffer has a format of S8_UINT, and shares Surface
+    *      Type, Height, Width, and Depth, Minimum Array Element, Render
+    *      Target View Extent, Depth Coordinate Offset X/Y, LOD, and Depth
+    *      Buffer Object Control State fields of the depth buffer.
+    */
+   if (info->z_img == info->s_img) {
+      assert(info->z_img->target == info->s_img->target &&
+             info->z_img->width0 == info->s_img->width0 &&
+             info->z_img->height0 == info->s_img->height0 &&
+             info->z_img->depth0 == info->s_img->depth0);
+   }
+
+   assert(info->level < img->level_count);
+   assert(img->bo_stride);
+
+   if (info->hiz_enable) {
+      assert(info->z_img &&
+             ilo_image_can_enable_aux(info->z_img, info->level));
+   }
+
+   if (info->is_cube_map) {
+      assert(get_gen6_surface_type(dev, img) == GEN6_SURFTYPE_2D);
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 323:
+       *
+       *     "For cube maps, Width must be set equal to Height."
+       */
+      assert(img->width0 == img->height0);
+   }
+
+   if (info->z_img)
+      assert(info->z_img->tiling == GEN6_TILING_Y);
+   if (info->s_img)
+      assert(info->s_img->tiling == GEN8_TILING_W);
+
+   return true;
+}
+
+static void
+get_gen6_max_extent(const struct ilo_dev *dev,
+                    const struct ilo_image *img,
+                    uint16_t *max_w, uint16_t *max_h)
+{
+   const uint16_t max_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   switch (get_gen6_surface_type(dev, img)) {
+   case GEN6_SURFTYPE_1D:
+      *max_w = max_size;
+      *max_h = 1;
+      break;
+   case GEN6_SURFTYPE_2D:
+      *max_w = max_size;
+      *max_h = max_size;
+      break;
+   case GEN6_SURFTYPE_3D:
+      *max_w = 2048;
+      *max_h = 2048;
+      break;
+   default:
+      assert(!"invalid surface type");
+      *max_w = 1;
+      *max_h = 1;
+      break;
+   }
+}
+
+static void
+get_gen6_hiz_alignments(const struct ilo_dev *dev,
+                        const struct ilo_image *img,
+                        uint16_t *align_w, uint16_t *align_h)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 313:
+    *
+    *     "A rectangle primitive representing the clear area is delivered. The
+    *      primitive must adhere to the following restrictions on size:
+    *
+    *      - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be
+    *        aligned to an 8x4 pixel block relative to the upper left corner
+    *        of the depth buffer, and contain an integer number of these pixel
+    *        blocks, and all 8x4 pixels must be lit.
+    *      - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be
+    *        aligned to a 4x2 pixel block (8x4 sample block) relative to the
+    *        upper left corner of the depth buffer, and contain an integer
+    *        number of these pixel blocks, and all samples of the 4x2 pixels
+    *        must be lit
+    *      - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be
+    *        aligned to a 2x2 pixel block (8x4 sample block) relative to the
+    *        upper left corner of the depth buffer, and contain an integer
+    *        number of these pixel blocks, and all samples of the 2x2 pixels
+    *        must be list."
+    *
+    * Experiments on Gen7.5 show that HiZ resolve also requires the rectangle
+    * to be aligned to 8x4 sample blocks.  But to be on the safe side, we
+    * always require a level to be aligned when HiZ is enabled.
+    */
+   switch (img->sample_count) {
+   case 1:
+      *align_w = 8;
+      *align_h = 4;
+      break;
+   case 2:
+      *align_w = 4;
+      *align_h = 4;
+      break;
+   case 4:
+      *align_w = 4;
+      *align_h = 2;
+      break;
+   case 8:
+      *align_w = 2;
+      *align_h = 2;
+      break;
+   case 16:
+      *align_w = 2;
+      *align_h = 1;
+      break;
+   default:
+      assert(!"unknown sample count");
+      *align_w = 1;
+      *align_h = 1;
+      break;
+   }
+}
+
+static bool
+zs_get_gen6_depth_extent(const struct ilo_dev *dev,
+                         const struct ilo_state_zs_info *info,
+                         uint16_t *width, uint16_t *height)
+{
+   const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
+   uint16_t w, h, max_w, max_h;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   w = img->width0;
+   h = img->height0;
+
+   if (info->hiz_enable) {
+      uint16_t align_w, align_h;
+
+      get_gen6_hiz_alignments(dev, info->z_img, &align_w, &align_h);
+
+      /*
+       * We want to force 8x4 alignment, but we can do so only for level 0 and
+       * only when it is padded.  ilo_image should know all these.
+       */
+      if (info->level)
+         assert(w % align_w == 0 && h % align_h == 0);
+
+      w = align(w, align_w);
+      h = align(h, align_h);
+   }
+
+   get_gen6_max_extent(dev, img, &max_w, &max_h);
+   assert(w && h && w <= max_w && h <= max_h);
+
+   *width = w - 1;
+   *height = h - 1;
+
+   return true;
+}
+
+static bool
+zs_get_gen6_depth_slices(const struct ilo_dev *dev,
+                         const struct ilo_state_zs_info *info,
+                         uint16_t *depth, uint16_t *min_array_elem,
+                         uint16_t *rt_view_extent)
+{
+   const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
+   uint16_t max_slice, d;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 325:
+    *
+    *     "This field (Depth) specifies the total number of levels for a
+    *      volume texture or the number of array elements allowed to be
+    *      accessed starting at the Minimum Array Element for arrayed
+    *      surfaces. If the volume texture is MIP-mapped, this field specifies
+    *      the depth of the base MIP level."
+    */
+   switch (get_gen6_surface_type(dev, img)) {
+   case GEN6_SURFTYPE_1D:
+   case GEN6_SURFTYPE_2D:
+      max_slice = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 2048 : 512;
+
+      assert(img->array_size <= max_slice);
+      max_slice = img->array_size;
+
+      d = info->slice_count;
+      if (info->is_cube_map) {
+         /*
+          * Minumum Array Element and Depth must be 0; Render Target View
+          * Extent is ignored.
+          */
+         if (info->slice_base || d != 6) {
+            ilo_warn("no cube array dpeth buffer\n");
+            return false;
+         }
+
+         d /= 6;
+      }
+      break;
+   case GEN6_SURFTYPE_3D:
+      max_slice = 2048;
+
+      assert(img->depth0 <= max_slice);
+      max_slice = u_minify(img->depth0, info->level);
+
+      d = img->depth0;
+      break;
+   default:
+      assert(!"invalid surface type");
+      return false;
+      break;
+   }
+
+   if (!info->slice_count ||
+       info->slice_base + info->slice_count > max_slice) {
+      ilo_warn("invalid slice range\n");
+      return false;
+   }
+
+   assert(d);
+   *depth = d - 1;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 325:
+    *
+    *     "For 1D and 2D Surfaces:
+    *      This field (Minimum Array Element) indicates the minimum array
+    *      element that can be accessed as part of this surface. The delivered
+    *      array index is added to this field before being used to address the
+    *      surface.
+    *
+    *      For 3D Surfaces:
+    *      This field indicates the minimum `R' coordinate on the LOD
+    *      currently being rendered to.  This field is added to the delivered
+    *      array index before it is used to address the surface.
+    *
+    *      For Other Surfaces:
+    *      This field is ignored."
+    */
+   *min_array_elem = info->slice_base;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 326:
+    *
+    *     "For 3D Surfaces:
+    *      This field (Render Target View Extent) indicates the extent of the
+    *      accessible `R' coordinates minus 1 on the LOD currently being
+    *      rendered to.
+    *
+    *      For 1D and 2D Surfaces:
+    *      This field must be set to the same value as the Depth field.
+    *
+    *      For Other Surfaces:
+    *      This field is ignored."
+    */
+   *rt_view_extent = info->slice_count - 1;
+
+   return true;
+}
+
+static bool
+zs_set_gen6_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_zs_info *info)
+{
+   uint16_t width, height, depth, array_base, view_extent;
+   enum gen_surface_type type;
+   enum gen_depth_format format;
+   uint32_t dw1, dw2, dw3, dw4;
+
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   if (!zs_validate_gen6(dev, info) ||
+       !zs_get_gen6_depth_extent(dev, info, &width, &height) ||
+       !zs_get_gen6_depth_slices(dev, info, &depth, &array_base,
+                                 &view_extent))
+      return false;
+
+   type = (info->is_cube_map) ? GEN6_SURFTYPE_CUBE :
+          (info->z_img) ? get_gen6_surface_type(dev, info->z_img) :
+                          get_gen6_surface_type(dev, info->s_img);
+
+   format = (info->z_img) ? get_gen6_depth_format(dev, info->z_img) :
+      GEN6_ZFORMAT_D32_FLOAT;
+
+   /*
+    * From the Ironlake PRM, volume 2 part 1, page 330:
+    *
+    *     "If this field (Separate Stencil Buffer Enable) is disabled, the
+    *      Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 321:
+    *
+    *     "[DevSNB]: This field (Separate Stencil Buffer Enable) must be set
+    *      to the same value (enabled or disabled) as Hierarchical Depth
+    *      Buffer Enable."
+    */
+   if (!info->hiz_enable && format == GEN6_ZFORMAT_D24_UNORM_X8_UINT)
+      format = GEN6_ZFORMAT_D24_UNORM_S8_UINT;
+
+   /* info->z_readonly and info->s_readonly are ignored on Gen6 */
+   dw1 = type << GEN6_DEPTH_DW1_TYPE__SHIFT |
+         GEN6_TILING_Y << GEN6_DEPTH_DW1_TILING__SHIFT |
+         format << GEN6_DEPTH_DW1_FORMAT__SHIFT;
+
+   if (info->z_img)
+      dw1 |= (info->z_img->bo_stride - 1) << GEN6_DEPTH_DW1_PITCH__SHIFT;
+
+   if (info->hiz_enable || !info->z_img) {
+      dw1 |= GEN6_DEPTH_DW1_HIZ_ENABLE |
+             GEN6_DEPTH_DW1_SEPARATE_STENCIL;
+   }
+
+   dw2 = 0;
+   dw3 = height << GEN6_DEPTH_DW3_HEIGHT__SHIFT |
+         width << GEN6_DEPTH_DW3_WIDTH__SHIFT |
+         info->level << GEN6_DEPTH_DW3_LOD__SHIFT |
+         GEN6_DEPTH_DW3_MIPLAYOUT_BELOW;
+   dw4 = depth << GEN6_DEPTH_DW4_DEPTH__SHIFT |
+         array_base << GEN6_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT |
+         view_extent << GEN6_DEPTH_DW4_RT_VIEW_EXTENT__SHIFT;
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
+   zs->depth[0] = dw1;
+   zs->depth[1] = dw2;
+   zs->depth[2] = dw3;
+   zs->depth[3] = dw4;
+   zs->depth[4] = 0;
+
+   zs->depth_format = format;
+
+   return true;
+}
+
+static bool
+zs_set_gen7_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_zs_info *info)
+{
+   enum gen_surface_type type;
+   enum gen_depth_format format;
+   uint16_t width, height, depth;
+   uint16_t array_base, view_extent;
+   uint32_t dw1, dw2, dw3, dw4, dw6;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (!zs_validate_gen6(dev, info) ||
+       !zs_get_gen6_depth_extent(dev, info, &width, &height) ||
+       !zs_get_gen6_depth_slices(dev, info, &depth, &array_base,
+                                 &view_extent))
+      return false;
+
+   type = (info->is_cube_map) ? GEN6_SURFTYPE_CUBE :
+          (info->z_img) ? get_gen6_surface_type(dev, info->z_img) :
+                          get_gen6_surface_type(dev, info->s_img);
+
+   format = (info->z_img) ? get_gen6_depth_format(dev, info->z_img) :
+      GEN6_ZFORMAT_D32_FLOAT;
+
+   dw1 = type << GEN7_DEPTH_DW1_TYPE__SHIFT |
+         format << GEN7_DEPTH_DW1_FORMAT__SHIFT;
+
+   if (info->z_img) {
+      if (!info->z_readonly)
+         dw1 |= GEN7_DEPTH_DW1_DEPTH_WRITE_ENABLE;
+      if (info->hiz_enable)
+         dw1 |= GEN7_DEPTH_DW1_HIZ_ENABLE;
+
+      dw1 |= (info->z_img->bo_stride - 1) << GEN7_DEPTH_DW1_PITCH__SHIFT;
+   }
+
+   if (info->s_img && !info->s_readonly)
+      dw1 |= GEN7_DEPTH_DW1_STENCIL_WRITE_ENABLE;
+
+   dw2 = 0;
+   dw3 = height << GEN7_DEPTH_DW3_HEIGHT__SHIFT |
+         width << GEN7_DEPTH_DW3_WIDTH__SHIFT |
+         info->level << GEN7_DEPTH_DW3_LOD__SHIFT;
+   dw4 = depth << GEN7_DEPTH_DW4_DEPTH__SHIFT |
+         array_base << GEN7_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT;
+   dw6 = view_extent << GEN7_DEPTH_DW6_RT_VIEW_EXTENT__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8) && info->z_img) {
+      assert(info->z_img->walk_layer_height % 4 == 0);
+      /* note that DW is off-by-one for Gen8+ */
+      dw6 |= (info->z_img->walk_layer_height / 4) <<
+         GEN8_DEPTH_DW7_QPITCH__SHIFT;
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
+   zs->depth[0] = dw1;
+   zs->depth[1] = dw2;
+   zs->depth[2] = dw3;
+   zs->depth[3] = dw4;
+   zs->depth[4] = dw6;
+
+   zs->depth_format = format;
+
+   return true;
+}
+
+static bool
+zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs *zs,
+                                        const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->stencil) >= 3);
+   zs->stencil[0] = 0;
+   zs->stencil[1] = 0;
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      zs->stencil[2] = 0;
+
+   return true;
+}
+
+static bool
+zs_set_gen6_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs *zs,
+                                   const struct ilo_dev *dev,
+                                   const struct ilo_state_zs_info *info)
+{
+   const struct ilo_image *img = info->s_img;
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(img->bo_stride);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 329:
+    *
+    *     "The pitch must be set to 2x the value computed based on width, as
+    *      the stencil buffer is stored with two rows interleaved."
+    *
+    * For Gen7+, we still dobule the stride because we did not double the
+    * slice widths when initializing ilo_image.
+    */
+   dw1 = (img->bo_stride * 2 - 1) << GEN6_STENCIL_DW1_PITCH__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+      dw1 |= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE;
+
+   dw2 = 0;
+   /* offset to the level as Gen6 does not support mipmapped stencil */
+   if (ilo_dev_gen(dev) == ILO_GEN(6)) {
+      unsigned x, y;
+
+      ilo_image_get_slice_pos(img, info->level, 0, &x, &y);
+      ilo_image_pos_to_mem(img, x, y, &x, &y);
+      dw2 |= ilo_image_mem_to_raw(img, x, y);
+   }
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->stencil) >= 3);
+   zs->stencil[0] = dw1;
+   zs->stencil[1] = dw2;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      uint32_t dw4;
+
+      assert(img->walk_layer_height % 4 == 0);
+      dw4 = (img->walk_layer_height / 4) << GEN8_STENCIL_DW4_QPITCH__SHIFT;
+
+      zs->stencil[2] = dw4;
+   }
+
+   return true;
+}
+
+static bool
+zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs *zs,
+                                           const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->hiz) >= 3);
+   zs->hiz[0] = 0;
+   zs->hiz[1] = 0;
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      zs->hiz[2] = 0;
+
+   return true;
+}
+
+static bool
+zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs *zs,
+                                      const struct ilo_dev *dev,
+                                      const struct ilo_state_zs_info *info)
+{
+   const struct ilo_image *img = info->z_img;
+   uint32_t dw1, dw2;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   assert(img->aux.bo_stride);
+
+   dw1 = (img->aux.bo_stride - 1) << GEN6_HIZ_DW1_PITCH__SHIFT;
+
+   dw2 = 0;
+   /* offset to the level as Gen6 does not support mipmapped HiZ */
+   if (ilo_dev_gen(dev) == ILO_GEN(6))
+      dw2 |= img->aux.walk_lod_offsets[info->level];
+
+   STATIC_ASSERT(ARRAY_SIZE(zs->hiz) >= 3);
+   zs->hiz[0] = dw1;
+   zs->hiz[1] = dw2;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      uint32_t dw4;
+
+      assert(img->aux.walk_layer_height % 4 == 0);
+      dw4 = (img->aux.walk_layer_height / 4) << GEN8_HIZ_DW4_QPITCH__SHIFT;
+
+      zs->hiz[2] = dw4;
+   }
+
+   return true;
+}
+
+bool
+ilo_state_zs_init(struct ilo_state_zs *zs, const struct ilo_dev *dev,
+                  const struct ilo_state_zs_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(zs, sizeof(*zs)));
+
+   if (info->z_img || info->s_img) {
+      if (ilo_dev_gen(dev) >= ILO_GEN(7))
+         ret &= zs_set_gen7_3DSTATE_DEPTH_BUFFER(zs, dev, info);
+      else
+         ret &= zs_set_gen6_3DSTATE_DEPTH_BUFFER(zs, dev, info);
+   } else {
+      ret &= zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(zs, dev);
+   }
+
+   if (info->s_img)
+      ret &= zs_set_gen6_3DSTATE_STENCIL_BUFFER(zs, dev, info);
+   else
+      ret &= zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(zs, dev);
+
+   if (info->z_img && info->hiz_enable)
+      ret &= zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(zs, dev, info);
+   else
+      ret &= zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs, dev);
+
+   zs->z_readonly = info->z_readonly;
+   zs->s_readonly = info->s_readonly;
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_zs_init_for_null(struct ilo_state_zs *zs,
+                           const struct ilo_dev *dev)
+{
+   struct ilo_state_zs_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_zs_init(zs, dev, &info);
+}
+
+bool
+ilo_state_zs_disable_hiz(struct ilo_state_zs *zs,
+                         const struct ilo_dev *dev)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * Separate stencil must be disabled simultaneously on Gen6.  We can make
+    * it work when there is no stencil buffer, but it is probably not worth
+    * it.
+    */
+   assert(ilo_dev_gen(dev) >= ILO_GEN(7));
+
+   zs->depth[0] &= ~GEN7_DEPTH_DW1_HIZ_ENABLE;
+   zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs, dev);
+
+   return true;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_zs.h b/src/gallium/drivers/ilo/core/ilo_state_zs.h
new file mode 100644 (file)
index 0000000..98212da
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_STATE_ZS_H
+#define ILO_STATE_ZS_H
+
+#include "genhw/genhw.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+
+struct ilo_image;
+
+struct ilo_state_zs_info {
+   /* both are optional */
+   const struct ilo_image *z_img;
+   const struct ilo_image *s_img;
+
+   /* ignored prior to Gen7 */
+   bool z_readonly;
+   bool s_readonly;
+
+   bool hiz_enable;
+   bool is_cube_map;
+
+   uint8_t level;
+   uint16_t slice_base;
+   uint16_t slice_count;
+};
+
+struct ilo_state_zs {
+   uint32_t depth[5];
+   uint32_t stencil[3];
+   uint32_t hiz[3];
+
+   /* TODO move this to ilo_image */
+   enum gen_depth_format depth_format;
+
+   bool z_readonly;
+   bool s_readonly;
+
+   /* managed by users */
+   struct intel_bo *depth_bo;
+   struct intel_bo *stencil_bo;
+   struct intel_bo *hiz_bo;
+};
+
+bool
+ilo_state_zs_init(struct ilo_state_zs *zs,
+                  const struct ilo_dev *dev,
+                  const struct ilo_state_zs_info *info);
+
+bool
+ilo_state_zs_init_for_null(struct ilo_state_zs *zs,
+                           const struct ilo_dev *dev);
+
+bool
+ilo_state_zs_disable_hiz(struct ilo_state_zs *zs,
+                         const struct ilo_dev *dev);
+
+static inline enum gen_depth_format
+ilo_state_zs_get_depth_format(const struct ilo_state_zs *zs,
+                              const struct ilo_dev *dev)
+{
+   return zs->depth_format;
+}
+
+#endif /* ILO_STATE_ZS_H */
index 24d726adcb34153bc173ece670b050ab3023e414..5a0bb4f8d778def81f6021f9f278de7107c67a51 100644 (file)
@@ -97,6 +97,9 @@ enum gen_mi_alu_operand {
 #define GEN6_MI_LENGTH__MASK                                   0x0000003f
 #define GEN6_MI_LENGTH__SHIFT                                  0
 #define GEN6_MI_NOOP__SIZE                                     1
+#define GEN6_MI_NOOP_DW0_WRITE_NOPID                           (0x1 << 22)
+#define GEN6_MI_NOOP_DW0_VALUE__MASK                           0x003fffff
+#define GEN6_MI_NOOP_DW0_VALUE__SHIFT                          0
 
 #define GEN75_MI_SET_PREDICATE__SIZE                           1
 #define GEN75_MI_SET_PREDICATE_DW0_PREDICATE__MASK             0x00000003
index 2bdd72b29bcaf0c33a7904a64db7f900b45b3762..c51e4f78bc085c97a622aa756733c12aa2ca5fe2 100644 (file)
@@ -35,6 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define GEN6_REG_MASK__MASK                                    0xffff0000
 #define GEN6_REG_MASK__SHIFT                                   16
 #define GEN6_REG__SIZE                                         0x400000
+#define GEN6_REG_NOPID                                         0x2094
+
 #define GEN7_REG_HS_INVOCATION_COUNT                           0x2300
 
 #define GEN7_REG_DS_INVOCATION_COUNT                           0x2308
index d25542e8cc2ed4ea2b033d567f9ef6d579780854..52173fe5d07eabce2f5ca839a72daf5dcf0aecd7 100644 (file)
@@ -32,7 +32,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 
-enum gen_prim_type {
+enum gen_3dprim_type {
     GEN6_3DPRIM_POINTLIST                                    = 0x1,
     GEN6_3DPRIM_LINELIST                                     = 0x2,
     GEN6_3DPRIM_LINESTRIP                                    = 0x3,
@@ -105,6 +105,12 @@ enum gen_state_alignment {
     GEN8_ALIGNMENT_SURFACE_STATE                             = 0x40,
 };
 
+enum gen_index_format {
+    GEN6_INDEX_BYTE                                          = 0x0,
+    GEN6_INDEX_WORD                                          = 0x1,
+    GEN6_INDEX_DWORD                                         = 0x2,
+};
+
 enum gen_vf_component {
     GEN6_VFCOMP_NOSTORE                                              = 0x0,
     GEN6_VFCOMP_STORE_SRC                                    = 0x1,
@@ -123,6 +129,87 @@ enum gen_depth_format {
     GEN6_ZFORMAT_D16_UNORM                                   = 0x5,
 };
 
+enum gen_reorder_mode {
+    GEN7_REORDER_LEADING                                     = 0x0,
+    GEN7_REORDER_TRAILING                                    = 0x1,
+};
+
+enum gen_clip_mode {
+    GEN6_CLIPMODE_NORMAL                                     = 0x0,
+    GEN6_CLIPMODE_REJECT_ALL                                 = 0x3,
+    GEN6_CLIPMODE_ACCEPT_ALL                                 = 0x4,
+};
+
+enum gen_front_winding {
+    GEN6_FRONTWINDING_CW                                     = 0x0,
+    GEN6_FRONTWINDING_CCW                                    = 0x1,
+};
+
+enum gen_fill_mode {
+    GEN6_FILLMODE_SOLID                                              = 0x0,
+    GEN6_FILLMODE_WIREFRAME                                  = 0x1,
+    GEN6_FILLMODE_POINT                                              = 0x2,
+};
+
+enum gen_cull_mode {
+    GEN6_CULLMODE_BOTH                                       = 0x0,
+    GEN6_CULLMODE_NONE                                       = 0x1,
+    GEN6_CULLMODE_FRONT                                              = 0x2,
+    GEN6_CULLMODE_BACK                                       = 0x3,
+};
+
+enum gen_pixel_location {
+    GEN6_PIXLOC_CENTER                                       = 0x0,
+    GEN6_PIXLOC_UL_CORNER                                    = 0x1,
+};
+
+enum gen_sample_count {
+    GEN6_NUMSAMPLES_1                                        = 0x0,
+    GEN8_NUMSAMPLES_2                                        = 0x1,
+    GEN6_NUMSAMPLES_4                                        = 0x2,
+    GEN7_NUMSAMPLES_8                                        = 0x3,
+    GEN8_NUMSAMPLES_16                                       = 0x4,
+};
+
+enum gen_inputattr_select {
+    GEN6_INPUTATTR_NORMAL                                    = 0x0,
+    GEN6_INPUTATTR_FACING                                    = 0x1,
+    GEN6_INPUTATTR_W                                         = 0x2,
+    GEN6_INPUTATTR_FACING_W                                  = 0x3,
+};
+
+enum gen_zw_interp {
+    GEN6_ZW_INTERP_PIXEL                                     = 0x0,
+    GEN6_ZW_INTERP_CENTROID                                  = 0x2,
+    GEN6_ZW_INTERP_SAMPLE                                    = 0x3,
+};
+
+enum gen_position_offset {
+    GEN6_POSOFFSET_NONE                                              = 0x0,
+    GEN6_POSOFFSET_CENTROID                                  = 0x2,
+    GEN6_POSOFFSET_SAMPLE                                    = 0x3,
+};
+
+enum gen_edsc_mode {
+    GEN7_EDSC_NORMAL                                         = 0x0,
+    GEN7_EDSC_PSEXEC                                         = 0x1,
+    GEN7_EDSC_PREPS                                          = 0x2,
+};
+
+enum gen_pscdepth_mode {
+    GEN7_PSCDEPTH_OFF                                        = 0x0,
+    GEN7_PSCDEPTH_ON                                         = 0x1,
+    GEN7_PSCDEPTH_ON_GE                                              = 0x2,
+    GEN7_PSCDEPTH_ON_LE                                              = 0x3,
+};
+
+enum gen_msrast_mode {
+    GEN6_MSRASTMODE_OFF_PIXEL                                = 0x0,
+    GEN6_MSRASTMODE_OFF_PATTERN                                      = 0x1,
+    GEN6_MSRASTMODE_ON_PIXEL                                 = 0x2,
+    GEN6_MSRASTMODE_ON_PATTERN                               = 0x3,
+};
+
 #define GEN6_INTERP_NONPERSPECTIVE_SAMPLE                      (0x1 << 5)
 #define GEN6_INTERP_NONPERSPECTIVE_CENTROID                    (0x1 << 4)
 #define GEN6_INTERP_NONPERSPECTIVE_PIXEL                       (0x1 << 3)
@@ -285,9 +372,6 @@ enum gen_depth_format {
 #define GEN6_IB_DW0_CUT_INDEX_ENABLE                           (0x1 << 10)
 #define GEN6_IB_DW0_FORMAT__MASK                               0x00000300
 #define GEN6_IB_DW0_FORMAT__SHIFT                              8
-#define GEN6_IB_DW0_FORMAT_BYTE                                        (0x0 << 8)
-#define GEN6_IB_DW0_FORMAT_WORD                                        (0x1 << 8)
-#define GEN6_IB_DW0_FORMAT_DWORD                               (0x2 << 8)
 
 
 
@@ -295,9 +379,6 @@ enum gen_depth_format {
 
 #define GEN8_IB_DW1_FORMAT__MASK                               0x00000300
 #define GEN8_IB_DW1_FORMAT__SHIFT                              8
-#define GEN8_IB_DW1_FORMAT_BYTE                                        (0x0 << 8)
-#define GEN8_IB_DW1_FORMAT_WORD                                        (0x1 << 8)
-#define GEN8_IB_DW1_FORMAT_DWORD                               (0x2 << 8)
 #define GEN8_IB_DW1_MOCS__MASK                                 0x0000007f
 #define GEN8_IB_DW1_MOCS__SHIFT                                        0
 
@@ -313,8 +394,8 @@ enum gen_depth_format {
 
 
 #define GEN8_INSTANCING_DW1_ENABLE                             (0x1 << 8)
-#define GEN8_INSTANCING_DW1_VB_INDEX__MASK                     0x0000003f
-#define GEN8_INSTANCING_DW1_VB_INDEX__SHIFT                    0
+#define GEN8_INSTANCING_DW1_VE_INDEX__MASK                     0x0000003f
+#define GEN8_INSTANCING_DW1_VE_INDEX__SHIFT                    0
 
 
 #define GEN8_3DSTATE_VF_SGVS__SIZE                             2
@@ -614,7 +695,7 @@ enum gen_depth_format {
 #define GEN6_GS_DW5_SO_STATISTICS                              (0x1 << 9)
 #define GEN6_GS_DW5_RENDER_ENABLE                              (0x1 << 8)
 
-#define GEN6_GS_DW6_REORDER_ENABLE                             (0x1 << 30)
+#define GEN6_GS_DW6_REORDER_LEADING_ENABLE                     (0x1 << 30)
 #define GEN6_GS_DW6_DISCARD_ADJACENCY                          (0x1 << 29)
 #define GEN6_GS_DW6_SVBI_PAYLOAD_ENABLE                                (0x1 << 28)
 #define GEN6_GS_DW6_SVBI_POST_INC_ENABLE                       (0x1 << 27)
@@ -666,11 +747,9 @@ enum gen_depth_format {
 #define GEN7_GS_DW5_INVOCATION_INCR__SHIFT                     5
 #define GEN7_GS_DW5_INCLUDE_PRIMITIVE_ID                       (0x1 << 4)
 #define GEN7_GS_DW5_HINT                                       (0x1 << 3)
-#define GEN7_GS_DW5_REORDER_ENABLE                             (0x1 << 2)
-#define GEN75_GS_DW5_REORDER__MASK                             0x00000004
-#define GEN75_GS_DW5_REORDER__SHIFT                            2
-#define GEN75_GS_DW5_REORDER_LEADING                           (0x0 << 2)
-#define GEN75_GS_DW5_REORDER_TRAILING                          (0x1 << 2)
+#define GEN7_GS_DW5_REORDER_LEADING_ENABLE                     (0x1 << 2)
+#define GEN75_GS_DW5_REORDER_MODE__MASK                                0x00000004
+#define GEN75_GS_DW5_REORDER_MODE__SHIFT                       2
 #define GEN7_GS_DW5_DISCARD_ADJACENCY                          (0x1 << 1)
 #define GEN7_GS_DW5_GS_ENABLE                                  (0x1 << 0)
 
@@ -727,10 +806,8 @@ enum gen_depth_format {
 #define GEN8_GS_DW7_INVOCATION_INCR__SHIFT                     5
 #define GEN8_GS_DW7_INCLUDE_PRIMITIVE_ID                       (0x1 << 4)
 #define GEN8_GS_DW7_HINT                                       (0x1 << 3)
-#define GEN8_GS_DW7_REORDER__MASK                              0x00000004
-#define GEN8_GS_DW7_REORDER__SHIFT                             2
-#define GEN8_GS_DW7_REORDER_LEADING                            (0x0 << 2)
-#define GEN8_GS_DW7_REORDER_TRAILING                           (0x1 << 2)
+#define GEN8_GS_DW7_REORDER_MODE__MASK                         0x00000004
+#define GEN8_GS_DW7_REORDER_MODE__SHIFT                                2
 #define GEN8_GS_DW7_DISCARD_ADJACENCY                          (0x1 << 1)
 #define GEN8_GS_DW7_GS_ENABLE                                  (0x1 << 0)
 
@@ -758,10 +835,8 @@ enum gen_depth_format {
 #define GEN7_SO_DW1_RENDER_DISABLE                             (0x1 << 30)
 #define GEN7_SO_DW1_RENDER_STREAM_SELECT__MASK                 0x18000000
 #define GEN7_SO_DW1_RENDER_STREAM_SELECT__SHIFT                        27
-#define GEN7_SO_DW1_REORDER__MASK                              0x04000000
-#define GEN7_SO_DW1_REORDER__SHIFT                             26
-#define GEN7_SO_DW1_REORDER_LEADING                            (0x0 << 26)
-#define GEN7_SO_DW1_REORDER_TRAILING                           (0x1 << 26)
+#define GEN7_SO_DW1_REORDER_MODE__MASK                         0x04000000
+#define GEN7_SO_DW1_REORDER_MODE__SHIFT                                26
 #define GEN7_SO_DW1_STATISTICS                                 (0x1 << 25)
 #define GEN7_SO_DW1_BUFFER_ENABLES__MASK                       0x00000f00
 #define GEN7_SO_DW1_BUFFER_ENABLES__SHIFT                      8
@@ -862,21 +937,15 @@ enum gen_depth_format {
 #define GEN6_3DSTATE_CLIP__SIZE                                        4
 
 
-#define GEN7_CLIP_DW1_FRONTWINDING__MASK                       0x00100000
-#define GEN7_CLIP_DW1_FRONTWINDING__SHIFT                      20
-#define GEN7_CLIP_DW1_FRONTWINDING_CW                          (0x0 << 20)
-#define GEN7_CLIP_DW1_FRONTWINDING_CCW                         (0x1 << 20)
+#define GEN7_CLIP_DW1_FRONT_WINDING__MASK                      0x00100000
+#define GEN7_CLIP_DW1_FRONT_WINDING__SHIFT                     20
 #define GEN7_CLIP_DW1_SUBPIXEL__MASK                           0x00080000
 #define GEN7_CLIP_DW1_SUBPIXEL__SHIFT                          19
 #define GEN7_CLIP_DW1_SUBPIXEL_8BITS                           (0x0 << 19)
 #define GEN7_CLIP_DW1_SUBPIXEL_4BITS                           (0x1 << 19)
 #define GEN7_CLIP_DW1_EARLY_CULL_ENABLE                                (0x1 << 18)
-#define GEN7_CLIP_DW1_CULLMODE__MASK                           0x00030000
-#define GEN7_CLIP_DW1_CULLMODE__SHIFT                          16
-#define GEN7_CLIP_DW1_CULLMODE_BOTH                            (0x0 << 16)
-#define GEN7_CLIP_DW1_CULLMODE_NONE                            (0x1 << 16)
-#define GEN7_CLIP_DW1_CULLMODE_FRONT                           (0x2 << 16)
-#define GEN7_CLIP_DW1_CULLMODE_BACK                            (0x3 << 16)
+#define GEN7_CLIP_DW1_CULL_MODE__MASK                          0x00030000
+#define GEN7_CLIP_DW1_CULL_MODE__SHIFT                         16
 #define GEN6_CLIP_DW1_STATISTICS                               (0x1 << 10)
 #define GEN6_CLIP_DW1_UCP_CULL_ENABLES__MASK                   0x000000ff
 #define GEN6_CLIP_DW1_UCP_CULL_ENABLES__SHIFT                  0
@@ -891,11 +960,8 @@ enum gen_depth_format {
 #define GEN6_CLIP_DW2_GB_TEST_ENABLE                           (0x1 << 26)
 #define GEN6_CLIP_DW2_UCP_CLIP_ENABLES__MASK                   0x00ff0000
 #define GEN6_CLIP_DW2_UCP_CLIP_ENABLES__SHIFT                  16
-#define GEN6_CLIP_DW2_CLIPMODE__MASK                           0x0000e000
-#define GEN6_CLIP_DW2_CLIPMODE__SHIFT                          13
-#define GEN6_CLIP_DW2_CLIPMODE_NORMAL                          (0x0 << 13)
-#define GEN6_CLIP_DW2_CLIPMODE_REJECT_ALL                      (0x3 << 13)
-#define GEN6_CLIP_DW2_CLIPMODE_ACCEPT_ALL                      (0x4 << 13)
+#define GEN6_CLIP_DW2_CLIP_MODE__MASK                          0x0000e000
+#define GEN6_CLIP_DW2_CLIP_MODE__SHIFT                         13
 #define GEN6_CLIP_DW2_PERSPECTIVE_DIVIDE_DISABLE               (0x1 << 9)
 #define GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE                (0x1 << 8)
 #define GEN6_CLIP_DW2_TRI_PROVOKE__MASK                                0x00000030
@@ -911,7 +977,7 @@ enum gen_depth_format {
 #define GEN6_CLIP_DW3_MAX_POINT_WIDTH__MASK                    0x0001ffc0
 #define GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT                   6
 #define GEN6_CLIP_DW3_MAX_POINT_WIDTH__RADIX                   3
-#define GEN6_CLIP_DW3_RTAINDEX_FORCED_ZERO                     (0x1 << 5)
+#define GEN6_CLIP_DW3_FORCE_RTAINDEX_ZERO                      (0x1 << 5)
 #define GEN6_CLIP_DW3_MAX_VPINDEX__MASK                                0x0000000f
 #define GEN6_CLIP_DW3_MAX_VPINDEX__SHIFT                       0
 
@@ -927,29 +993,17 @@ enum gen_depth_format {
 #define GEN7_SF_DW1_DEPTH_OFFSET_SOLID                         (0x1 << 9)
 #define GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME                     (0x1 << 8)
 #define GEN7_SF_DW1_DEPTH_OFFSET_POINT                         (0x1 << 7)
-#define GEN7_SF_DW1_FRONTFACE__MASK                            0x00000060
-#define GEN7_SF_DW1_FRONTFACE__SHIFT                           5
-#define GEN7_SF_DW1_FRONTFACE_SOLID                            (0x0 << 5)
-#define GEN7_SF_DW1_FRONTFACE_WIREFRAME                                (0x1 << 5)
-#define GEN7_SF_DW1_FRONTFACE_POINT                            (0x2 << 5)
-#define GEN7_SF_DW1_BACKFACE__MASK                             0x00000018
-#define GEN7_SF_DW1_BACKFACE__SHIFT                            3
-#define GEN7_SF_DW1_BACKFACE_SOLID                             (0x0 << 3)
-#define GEN7_SF_DW1_BACKFACE_WIREFRAME                         (0x1 << 3)
-#define GEN7_SF_DW1_BACKFACE_POINT                             (0x2 << 3)
-#define GEN7_SF_DW1_VIEWPORT_ENABLE                            (0x1 << 1)
-#define GEN7_SF_DW1_FRONTWINDING__MASK                         0x00000001
-#define GEN7_SF_DW1_FRONTWINDING__SHIFT                                0
-#define GEN7_SF_DW1_FRONTWINDING_CW                            0x0
-#define GEN7_SF_DW1_FRONTWINDING_CCW                           0x1
+#define GEN7_SF_DW1_FILL_MODE_FRONT__MASK                      0x00000060
+#define GEN7_SF_DW1_FILL_MODE_FRONT__SHIFT                     5
+#define GEN7_SF_DW1_FILL_MODE_BACK__MASK                       0x00000018
+#define GEN7_SF_DW1_FILL_MODE_BACK__SHIFT                      3
+#define GEN7_SF_DW1_VIEWPORT_TRANSFORM                         (0x1 << 1)
+#define GEN7_SF_DW1_FRONT_WINDING__MASK                                0x00000001
+#define GEN7_SF_DW1_FRONT_WINDING__SHIFT                       0
 
 #define GEN7_SF_DW2_AA_LINE_ENABLE                             (0x1 << 31)
-#define GEN7_SF_DW2_CULLMODE__MASK                             0x60000000
-#define GEN7_SF_DW2_CULLMODE__SHIFT                            29
-#define GEN7_SF_DW2_CULLMODE_BOTH                              (0x0 << 29)
-#define GEN7_SF_DW2_CULLMODE_NONE                              (0x1 << 29)
-#define GEN7_SF_DW2_CULLMODE_FRONT                             (0x2 << 29)
-#define GEN7_SF_DW2_CULLMODE_BACK                              (0x3 << 29)
+#define GEN7_SF_DW2_CULL_MODE__MASK                            0x60000000
+#define GEN7_SF_DW2_CULL_MODE__SHIFT                           29
 #define GEN7_SF_DW2_LINE_WIDTH__MASK                           0x0ffc0000
 #define GEN7_SF_DW2_LINE_WIDTH__SHIFT                          18
 #define GEN7_SF_DW2_LINE_WIDTH__RADIX                          7
@@ -963,10 +1017,6 @@ enum gen_depth_format {
 #define GEN7_SF_DW2_SCISSOR_ENABLE                             (0x1 << 11)
 #define GEN7_SF_DW2_MSRASTMODE__MASK                           0x00000300
 #define GEN7_SF_DW2_MSRASTMODE__SHIFT                          8
-#define GEN7_SF_DW2_MSRASTMODE_OFF_PIXEL                       (0x0 << 8)
-#define GEN7_SF_DW2_MSRASTMODE_OFF_PATTERN                     (0x1 << 8)
-#define GEN7_SF_DW2_MSRASTMODE_ON_PIXEL                                (0x2 << 8)
-#define GEN7_SF_DW2_MSRASTMODE_ON_PATTERN                      (0x3 << 8)
 
 #define GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE                     (0x1 << 31)
 #define GEN7_SF_DW3_TRI_PROVOKE__MASK                          0x60000000
@@ -1021,14 +1071,10 @@ enum gen_depth_format {
 #define GEN8_SBE_SWIZ_CONST_0001_FLOAT                         (0x1 << 9)
 #define GEN8_SBE_SWIZ_CONST_1111_FLOAT                         (0x2 << 9)
 #define GEN8_SBE_SWIZ_CONST_PRIM_ID                            (0x3 << 9)
-#define GEN8_SBE_SWIZ_INPUTATTR__MASK                          0x000000c0
-#define GEN8_SBE_SWIZ_INPUTATTR__SHIFT                         6
-#define GEN8_SBE_SWIZ_INPUTATTR_NORMAL                         (0x0 << 6)
-#define GEN8_SBE_SWIZ_INPUTATTR_FACING                         (0x1 << 6)
-#define GEN8_SBE_SWIZ_INPUTATTR_W                              (0x2 << 6)
-#define GEN8_SBE_SWIZ_INPUTATTR_FACING_W                       (0x3 << 6)
-#define GEN8_SBE_SWIZ_URB_ENTRY_OFFSET__MASK                   0x0000001f
-#define GEN8_SBE_SWIZ_URB_ENTRY_OFFSET__SHIFT                  0
+#define GEN8_SBE_SWIZ_SWIZZLE_SELECT__MASK                     0x000000c0
+#define GEN8_SBE_SWIZ_SWIZZLE_SELECT__SHIFT                    6
+#define GEN8_SBE_SWIZ_SRC_ATTR__MASK                           0x0000001f
+#define GEN8_SBE_SWIZ_SRC_ATTR__SHIFT                          0
 
 #define GEN6_3DSTATE_SF__SIZE                                  20
 
@@ -1080,31 +1126,19 @@ enum gen_depth_format {
 
 
 #define GEN9_RASTER_DW1_Z_TEST_FAR_ENABLE                      (0x1 << 26)
-#define GEN8_RASTER_DW1_FRONTWINDING__MASK                     0x00200000
-#define GEN8_RASTER_DW1_FRONTWINDING__SHIFT                    21
-#define GEN8_RASTER_DW1_FRONTWINDING_CW                                (0x0 << 21)
-#define GEN8_RASTER_DW1_FRONTWINDING_CCW                       (0x1 << 21)
-#define GEN8_RASTER_DW1_CULLMODE__MASK                         0x00030000
-#define GEN8_RASTER_DW1_CULLMODE__SHIFT                                16
-#define GEN8_RASTER_DW1_CULLMODE_BOTH                          (0x0 << 16)
-#define GEN8_RASTER_DW1_CULLMODE_NONE                          (0x1 << 16)
-#define GEN8_RASTER_DW1_CULLMODE_FRONT                         (0x2 << 16)
-#define GEN8_RASTER_DW1_CULLMODE_BACK                          (0x3 << 16)
+#define GEN8_RASTER_DW1_FRONT_WINDING__MASK                    0x00200000
+#define GEN8_RASTER_DW1_FRONT_WINDING__SHIFT                   21
+#define GEN8_RASTER_DW1_CULL_MODE__MASK                                0x00030000
+#define GEN8_RASTER_DW1_CULL_MODE__SHIFT                       16
 #define GEN8_RASTER_DW1_SMOOTH_POINT_ENABLE                    (0x1 << 13)
 #define GEN8_RASTER_DW1_API_MULTISAMPLE_ENABLE                 (0x1 << 12)
 #define GEN8_RASTER_DW1_DEPTH_OFFSET_SOLID                     (0x1 << 9)
 #define GEN8_RASTER_DW1_DEPTH_OFFSET_WIREFRAME                 (0x1 << 8)
 #define GEN8_RASTER_DW1_DEPTH_OFFSET_POINT                     (0x1 << 7)
-#define GEN8_RASTER_DW1_FRONTFACE__MASK                                0x00000060
-#define GEN8_RASTER_DW1_FRONTFACE__SHIFT                       5
-#define GEN8_RASTER_DW1_FRONTFACE_SOLID                                (0x0 << 5)
-#define GEN8_RASTER_DW1_FRONTFACE_WIREFRAME                    (0x1 << 5)
-#define GEN8_RASTER_DW1_FRONTFACE_POINT                                (0x2 << 5)
-#define GEN8_RASTER_DW1_BACKFACE__MASK                         0x00000018
-#define GEN8_RASTER_DW1_BACKFACE__SHIFT                                3
-#define GEN8_RASTER_DW1_BACKFACE_SOLID                         (0x0 << 3)
-#define GEN8_RASTER_DW1_BACKFACE_WIREFRAME                     (0x1 << 3)
-#define GEN8_RASTER_DW1_BACKFACE_POINT                         (0x2 << 3)
+#define GEN8_RASTER_DW1_FILL_MODE_FRONT__MASK                  0x00000060
+#define GEN8_RASTER_DW1_FILL_MODE_FRONT__SHIFT                 5
+#define GEN8_RASTER_DW1_FILL_MODE_BACK__MASK                   0x00000018
+#define GEN8_RASTER_DW1_FILL_MODE_BACK__SHIFT                  3
 #define GEN8_RASTER_DW1_AA_LINE_ENABLE                         (0x1 << 2)
 #define GEN8_RASTER_DW1_SCISSOR_ENABLE                         (0x1 << 1)
 #define GEN8_RASTER_DW1_Z_TEST_ENABLE                          (0x1 << 0)
@@ -1164,14 +1198,8 @@ enum gen_depth_format {
 #define GEN6_WM_DW6_SF_ATTR_COUNT__SHIFT                       20
 #define GEN6_WM_DW6_PS_POSOFFSET__MASK                         0x000c0000
 #define GEN6_WM_DW6_PS_POSOFFSET__SHIFT                                18
-#define GEN6_WM_DW6_PS_POSOFFSET_NONE                          (0x0 << 18)
-#define GEN6_WM_DW6_PS_POSOFFSET_CENTROID                      (0x2 << 18)
-#define GEN6_WM_DW6_PS_POSOFFSET_SAMPLE                                (0x3 << 18)
 #define GEN6_WM_DW6_ZW_INTERP__MASK                            0x00030000
 #define GEN6_WM_DW6_ZW_INTERP__SHIFT                           16
-#define GEN6_WM_DW6_ZW_INTERP_PIXEL                            (0x0 << 16)
-#define GEN6_WM_DW6_ZW_INTERP_CENTROID                         (0x2 << 16)
-#define GEN6_WM_DW6_ZW_INTERP_SAMPLE                           (0x3 << 16)
 #define GEN6_WM_DW6_BARYCENTRIC_INTERP__MASK                   0x0000fc00
 #define GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT                  10
 #define GEN6_WM_DW6_POINT_RASTRULE__MASK                       0x00000200
@@ -1180,10 +1208,6 @@ enum gen_depth_format {
 #define GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT                 (0x1 << 9)
 #define GEN6_WM_DW6_MSRASTMODE__MASK                           0x00000006
 #define GEN6_WM_DW6_MSRASTMODE__SHIFT                          1
-#define GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL                       (0x0 << 1)
-#define GEN6_WM_DW6_MSRASTMODE_OFF_PATTERN                     (0x1 << 1)
-#define GEN6_WM_DW6_MSRASTMODE_ON_PIXEL                                (0x2 << 1)
-#define GEN6_WM_DW6_MSRASTMODE_ON_PATTERN                      (0x3 << 1)
 #define GEN6_WM_DW6_MSDISPMODE__MASK                           0x00000001
 #define GEN6_WM_DW6_MSDISPMODE__SHIFT                          0
 #define GEN6_WM_DW6_MSDISPMODE_PERSAMPLE                       0x0
@@ -1207,22 +1231,12 @@ enum gen_depth_format {
 #define GEN7_WM_DW1_PS_KILL_PIXEL                              (0x1 << 25)
 #define GEN7_WM_DW1_PSCDEPTH__MASK                             0x01800000
 #define GEN7_WM_DW1_PSCDEPTH__SHIFT                            23
-#define GEN7_WM_DW1_PSCDEPTH_OFF                               (0x0 << 23)
-#define GEN7_WM_DW1_PSCDEPTH_ON                                        (0x1 << 23)
-#define GEN7_WM_DW1_PSCDEPTH_ON_GE                             (0x2 << 23)
-#define GEN7_WM_DW1_PSCDEPTH_ON_LE                             (0x3 << 23)
 #define GEN7_WM_DW1_EDSC__MASK                                 0x00600000
 #define GEN7_WM_DW1_EDSC__SHIFT                                        21
-#define GEN7_WM_DW1_EDSC_NORMAL                                        (0x0 << 21)
-#define GEN7_WM_DW1_EDSC_PSEXEC                                        (0x1 << 21)
-#define GEN7_WM_DW1_EDSC_PREPS                                 (0x2 << 21)
 #define GEN7_WM_DW1_PS_USE_DEPTH                               (0x1 << 20)
 #define GEN7_WM_DW1_PS_USE_W                                   (0x1 << 19)
 #define GEN7_WM_DW1_ZW_INTERP__MASK                            0x00060000
 #define GEN7_WM_DW1_ZW_INTERP__SHIFT                           17
-#define GEN7_WM_DW1_ZW_INTERP_PIXEL                            (0x0 << 17)
-#define GEN7_WM_DW1_ZW_INTERP_CENTROID                         (0x2 << 17)
-#define GEN7_WM_DW1_ZW_INTERP_SAMPLE                           (0x3 << 17)
 #define GEN7_WM_DW1_BARYCENTRIC_INTERP__MASK                   0x0001f800
 #define GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT                  11
 #define GEN7_WM_DW1_PS_USE_COVERAGE_MASK                       (0x1 << 10)
@@ -1247,10 +1261,6 @@ enum gen_depth_format {
 #define GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT                 (0x1 << 2)
 #define GEN7_WM_DW1_MSRASTMODE__MASK                           0x00000003
 #define GEN7_WM_DW1_MSRASTMODE__SHIFT                          0
-#define GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL                       0x0
-#define GEN7_WM_DW1_MSRASTMODE_OFF_PATTERN                     0x1
-#define GEN7_WM_DW1_MSRASTMODE_ON_PIXEL                                0x2
-#define GEN7_WM_DW1_MSRASTMODE_ON_PATTERN                      0x3
 
 #define GEN7_WM_DW2_MSDISPMODE__MASK                           0x80000000
 #define GEN7_WM_DW2_MSDISPMODE__SHIFT                          31
@@ -1265,12 +1275,12 @@ enum gen_depth_format {
 #define GEN8_3DSTATE_WM_DEPTH_STENCIL__SIZE                    4
 
 
-#define GEN8_ZS_DW1_STENCIL0_FAIL_OP__MASK                     0xe0000000
-#define GEN8_ZS_DW1_STENCIL0_FAIL_OP__SHIFT                    29
-#define GEN8_ZS_DW1_STENCIL0_ZFAIL_OP__MASK                    0x1c000000
-#define GEN8_ZS_DW1_STENCIL0_ZFAIL_OP__SHIFT                   26
-#define GEN8_ZS_DW1_STENCIL0_ZPASS_OP__MASK                    0x03800000
-#define GEN8_ZS_DW1_STENCIL0_ZPASS_OP__SHIFT                   23
+#define GEN8_ZS_DW1_STENCIL_FAIL_OP__MASK                      0xe0000000
+#define GEN8_ZS_DW1_STENCIL_FAIL_OP__SHIFT                     29
+#define GEN8_ZS_DW1_STENCIL_ZFAIL_OP__MASK                     0x1c000000
+#define GEN8_ZS_DW1_STENCIL_ZFAIL_OP__SHIFT                    26
+#define GEN8_ZS_DW1_STENCIL_ZPASS_OP__MASK                     0x03800000
+#define GEN8_ZS_DW1_STENCIL_ZPASS_OP__SHIFT                    23
 #define GEN8_ZS_DW1_STENCIL1_FUNC__MASK                                0x00700000
 #define GEN8_ZS_DW1_STENCIL1_FUNC__SHIFT                       20
 #define GEN8_ZS_DW1_STENCIL1_FAIL_OP__MASK                     0x000e0000
@@ -1279,8 +1289,8 @@ enum gen_depth_format {
 #define GEN8_ZS_DW1_STENCIL1_ZFAIL_OP__SHIFT                   14
 #define GEN8_ZS_DW1_STENCIL1_ZPASS_OP__MASK                    0x00003800
 #define GEN8_ZS_DW1_STENCIL1_ZPASS_OP__SHIFT                   11
-#define GEN8_ZS_DW1_STENCIL0_FUNC__MASK                                0x00000700
-#define GEN8_ZS_DW1_STENCIL0_FUNC__SHIFT                       8
+#define GEN8_ZS_DW1_STENCIL_FUNC__MASK                         0x00000700
+#define GEN8_ZS_DW1_STENCIL_FUNC__SHIFT                                8
 #define GEN8_ZS_DW1_DEPTH_FUNC__MASK                           0x000000e0
 #define GEN8_ZS_DW1_DEPTH_FUNC__SHIFT                          5
 #define GEN8_ZS_DW1_STENCIL1_ENABLE                            (0x1 << 4)
@@ -1289,17 +1299,17 @@ enum gen_depth_format {
 #define GEN8_ZS_DW1_DEPTH_TEST_ENABLE                          (0x1 << 1)
 #define GEN8_ZS_DW1_DEPTH_WRITE_ENABLE                         (0x1 << 0)
 
-#define GEN8_ZS_DW2_STENCIL0_VALUEMASK__MASK                   0xff000000
-#define GEN8_ZS_DW2_STENCIL0_VALUEMASK__SHIFT                  24
-#define GEN8_ZS_DW2_STENCIL0_WRITEMASK__MASK                   0x00ff0000
-#define GEN8_ZS_DW2_STENCIL0_WRITEMASK__SHIFT                  16
-#define GEN8_ZS_DW2_STENCIL1_VALUEMASK__MASK                   0x0000ff00
-#define GEN8_ZS_DW2_STENCIL1_VALUEMASK__SHIFT                  8
-#define GEN8_ZS_DW2_STENCIL1_WRITEMASK__MASK                   0x000000ff
-#define GEN8_ZS_DW2_STENCIL1_WRITEMASK__SHIFT                  0
-
-#define GEN9_ZS_DW3_STENCIL0_REF__MASK                         0x0000ff00
-#define GEN9_ZS_DW3_STENCIL0_REF__SHIFT                                8
+#define GEN8_ZS_DW2_STENCIL_TEST_MASK__MASK                    0xff000000
+#define GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT                   24
+#define GEN8_ZS_DW2_STENCIL_WRITE_MASK__MASK                   0x00ff0000
+#define GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT                  16
+#define GEN8_ZS_DW2_STENCIL1_TEST_MASK__MASK                   0x0000ff00
+#define GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT                  8
+#define GEN8_ZS_DW2_STENCIL1_WRITE_MASK__MASK                  0x000000ff
+#define GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT                 0
+
+#define GEN9_ZS_DW3_STENCIL_REF__MASK                          0x0000ff00
+#define GEN9_ZS_DW3_STENCIL_REF__SHIFT                         8
 #define GEN9_ZS_DW3_STENCIL1_REF__MASK                         0x000000ff
 #define GEN9_ZS_DW3_STENCIL1_REF__SHIFT                                0
 
@@ -1314,13 +1324,8 @@ enum gen_depth_format {
 #define GEN8_WM_HZ_DW1_FULL_SURFACE_DEPTH_CLEAR                        (0x1 << 25)
 #define GEN8_WM_HZ_DW1_STENCIL_CLEAR_VALUE__MASK               0x00ff0000
 #define GEN8_WM_HZ_DW1_STENCIL_CLEAR_VALUE__SHIFT              16
-#define GEN8_WM_HZ_DW1_NUMSAMPLES__MASK                                0x0000e000
-#define GEN8_WM_HZ_DW1_NUMSAMPLES__SHIFT                       13
-#define GEN8_WM_HZ_DW1_NUMSAMPLES_1                            (0x0 << 13)
-#define GEN8_WM_HZ_DW1_NUMSAMPLES_2                            (0x1 << 13)
-#define GEN8_WM_HZ_DW1_NUMSAMPLES_4                            (0x2 << 13)
-#define GEN8_WM_HZ_DW1_NUMSAMPLES_8                            (0x3 << 13)
-#define GEN8_WM_HZ_DW1_NUMSAMPLES_16                           (0x4 << 13)
+#define GEN8_WM_HZ_DW1_NUM_SAMPLES__MASK                       0x0000e000
+#define GEN8_WM_HZ_DW1_NUM_SAMPLES__SHIFT                      13
 
 #define GEN8_WM_HZ_DW2_RECT_MIN_Y__MASK                                0xffff0000
 #define GEN8_WM_HZ_DW2_RECT_MIN_Y__SHIFT                       16
@@ -1359,9 +1364,6 @@ enum gen_depth_format {
 #define GEN75_PS_DW4_ACCESS_UAV                                        (0x1 << 5)
 #define GEN7_PS_DW4_POSOFFSET__MASK                            0x00000018
 #define GEN7_PS_DW4_POSOFFSET__SHIFT                           3
-#define GEN7_PS_DW4_POSOFFSET_NONE                             (0x0 << 3)
-#define GEN7_PS_DW4_POSOFFSET_CENTROID                         (0x2 << 3)
-#define GEN7_PS_DW4_POSOFFSET_SAMPLE                           (0x3 << 3)
 #define GEN7_PS_DW4_DISPATCH_MODE__MASK                                0x00000007
 #define GEN7_PS_DW4_DISPATCH_MODE__SHIFT                       0
 
@@ -1397,9 +1399,6 @@ enum gen_depth_format {
 #define GEN8_PS_DW6_RT_RESOLVE                                 (0x1 << 6)
 #define GEN8_PS_DW6_POSOFFSET__MASK                            0x00000018
 #define GEN8_PS_DW6_POSOFFSET__SHIFT                           3
-#define GEN8_PS_DW6_POSOFFSET_NONE                             (0x0 << 3)
-#define GEN8_PS_DW6_POSOFFSET_CENTROID                         (0x2 << 3)
-#define GEN8_PS_DW6_POSOFFSET_SAMPLE                           (0x3 << 3)
 #define GEN8_PS_DW6_DISPATCH_MODE__MASK                                0x00000007
 #define GEN8_PS_DW6_DISPATCH_MODE__SHIFT                       0
 
@@ -1423,16 +1422,12 @@ enum gen_depth_format {
 #define GEN8_3DSTATE_PS_EXTRA__SIZE                            2
 
 
-#define GEN8_PSX_DW1_DISPATCH_ENABLE                           (0x1 << 31)
+#define GEN8_PSX_DW1_VALID                                     (0x1 << 31)
 #define GEN8_PSX_DW1_UAV_ONLY                                  (0x1 << 30)
 #define GEN8_PSX_DW1_COMPUTE_OMASK                             (0x1 << 29)
 #define GEN8_PSX_DW1_KILL_PIXEL                                        (0x1 << 28)
 #define GEN8_PSX_DW1_PSCDEPTH__MASK                            0x0c000000
 #define GEN8_PSX_DW1_PSCDEPTH__SHIFT                           26
-#define GEN8_PSX_DW1_PSCDEPTH_OFF                              (0x0 << 26)
-#define GEN8_PSX_DW1_PSCDEPTH_ON                               (0x1 << 26)
-#define GEN8_PSX_DW1_PSCDEPTH_ON_GE                            (0x2 << 26)
-#define GEN8_PSX_DW1_PSCDEPTH_ON_LE                            (0x3 << 26)
 #define GEN8_PSX_DW1_FORCE_COMPUTE_DEPTH                       (0x1 << 25)
 #define GEN8_PSX_DW1_USE_DEPTH                                 (0x1 << 24)
 #define GEN8_PSX_DW1_USE_W                                     (0x1 << 23)
@@ -1696,17 +1691,10 @@ enum gen_depth_format {
 
 
 #define GEN75_MULTISAMPLE_DW1_DX9_MULTISAMPLE_ENABLE           (0x1 << 5)
-#define GEN6_MULTISAMPLE_DW1_PIXLOC__MASK                      0x00000010
-#define GEN6_MULTISAMPLE_DW1_PIXLOC__SHIFT                     4
-#define GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER                     (0x0 << 4)
-#define GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER                  (0x1 << 4)
-#define GEN6_MULTISAMPLE_DW1_NUMSAMPLES__MASK                  0x0000000e
-#define GEN6_MULTISAMPLE_DW1_NUMSAMPLES__SHIFT                 1
-#define GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1                      (0x0 << 1)
-#define GEN8_MULTISAMPLE_DW1_NUMSAMPLES_2                      (0x1 << 1)
-#define GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4                      (0x2 << 1)
-#define GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8                      (0x3 << 1)
-#define GEN8_MULTISAMPLE_DW1_NUMSAMPLES_16                     (0x4 << 1)
+#define GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__MASK              0x00000010
+#define GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__SHIFT             4
+#define GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__MASK                 0x0000000e
+#define GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__SHIFT                        1
 
 
 
index 6d815beecb3a5c2c835fc0237345c233c842570b..b65b704adc6d7b6b9b03c132f148d2c7db7fb4a1 100644 (file)
@@ -84,7 +84,7 @@ enum gen_blend_function {
     GEN6_BLENDFUNCTION_MAX                                   = 0x4,
 };
 
-enum gen_logicop_function {
+enum gen_logic_op {
     GEN6_LOGICOP_CLEAR                                       = 0x0,
     GEN6_LOGICOP_NOR                                         = 0x1,
     GEN6_LOGICOP_AND_INVERTED                                = 0x2,
@@ -103,20 +103,31 @@ enum gen_logicop_function {
     GEN6_LOGICOP_SET                                         = 0xf,
 };
 
-enum gen_sampler_mip_filter {
+enum gen_mip_filter {
     GEN6_MIPFILTER_NONE                                              = 0x0,
     GEN6_MIPFILTER_NEAREST                                   = 0x1,
     GEN6_MIPFILTER_LINEAR                                    = 0x3,
 };
 
-enum gen_sampler_map_filter {
+enum gen_map_filter {
     GEN6_MAPFILTER_NEAREST                                   = 0x0,
     GEN6_MAPFILTER_LINEAR                                    = 0x1,
     GEN6_MAPFILTER_ANISOTROPIC                               = 0x2,
     GEN6_MAPFILTER_MONO                                              = 0x6,
 };
 
-enum gen_sampler_aniso_ratio {
+enum gen_prefilter_op {
+    GEN6_PREFILTEROP_ALWAYS                                  = 0x0,
+    GEN6_PREFILTEROP_NEVER                                   = 0x1,
+    GEN6_PREFILTEROP_LESS                                    = 0x2,
+    GEN6_PREFILTEROP_EQUAL                                   = 0x3,
+    GEN6_PREFILTEROP_LEQUAL                                  = 0x4,
+    GEN6_PREFILTEROP_GREATER                                 = 0x5,
+    GEN6_PREFILTEROP_NOTEQUAL                                = 0x6,
+    GEN6_PREFILTEROP_GEQUAL                                  = 0x7,
+};
+
+enum gen_aniso_ratio {
     GEN6_ANISORATIO_2                                        = 0x0,
     GEN6_ANISORATIO_4                                        = 0x1,
     GEN6_ANISORATIO_6                                        = 0x2,
@@ -127,7 +138,7 @@ enum gen_sampler_aniso_ratio {
     GEN6_ANISORATIO_16                                       = 0x7,
 };
 
-enum gen_sampler_texcoord_mode {
+enum gen_texcoord_mode {
     GEN6_TEXCOORDMODE_WRAP                                   = 0x0,
     GEN6_TEXCOORDMODE_MIRROR                                 = 0x1,
     GEN6_TEXCOORDMODE_CLAMP                                  = 0x2,
@@ -137,15 +148,15 @@ enum gen_sampler_texcoord_mode {
     GEN8_TEXCOORDMODE_HALF_BORDER                            = 0x6,
 };
 
-enum gen_sampler_key_filter {
+enum gen_key_filter {
     GEN6_KEYFILTER_KILL_ON_ANY_MATCH                         = 0x0,
     GEN6_KEYFILTER_REPLACE_BLACK                             = 0x1,
 };
 
 #define GEN6_COLOR_CALC_STATE__SIZE                            6
 
-#define GEN6_CC_DW0_STENCIL0_REF__MASK                         0xff000000
-#define GEN6_CC_DW0_STENCIL0_REF__SHIFT                                24
+#define GEN6_CC_DW0_STENCIL_REF__MASK                          0xff000000
+#define GEN6_CC_DW0_STENCIL_REF__SHIFT                         24
 #define GEN6_CC_DW0_STENCIL1_REF__MASK                         0x00ff0000
 #define GEN6_CC_DW0_STENCIL1_REF__SHIFT                                16
 #define GEN6_CC_DW0_ROUND_DISABLE_DISABLE                      (0x1 << 15)
@@ -162,14 +173,14 @@ enum gen_sampler_key_filter {
 #define GEN6_DEPTH_STENCIL_STATE__SIZE                         3
 
 #define GEN6_ZS_DW0_STENCIL_TEST_ENABLE                                (0x1 << 31)
-#define GEN6_ZS_DW0_STENCIL0_FUNC__MASK                                0x70000000
-#define GEN6_ZS_DW0_STENCIL0_FUNC__SHIFT                       28
-#define GEN6_ZS_DW0_STENCIL0_FAIL_OP__MASK                     0x0e000000
-#define GEN6_ZS_DW0_STENCIL0_FAIL_OP__SHIFT                    25
-#define GEN6_ZS_DW0_STENCIL0_ZFAIL_OP__MASK                    0x01c00000
-#define GEN6_ZS_DW0_STENCIL0_ZFAIL_OP__SHIFT                   22
-#define GEN6_ZS_DW0_STENCIL0_ZPASS_OP__MASK                    0x00380000
-#define GEN6_ZS_DW0_STENCIL0_ZPASS_OP__SHIFT                   19
+#define GEN6_ZS_DW0_STENCIL_FUNC__MASK                         0x70000000
+#define GEN6_ZS_DW0_STENCIL_FUNC__SHIFT                                28
+#define GEN6_ZS_DW0_STENCIL_FAIL_OP__MASK                      0x0e000000
+#define GEN6_ZS_DW0_STENCIL_FAIL_OP__SHIFT                     25
+#define GEN6_ZS_DW0_STENCIL_ZFAIL_OP__MASK                     0x01c00000
+#define GEN6_ZS_DW0_STENCIL_ZFAIL_OP__SHIFT                    22
+#define GEN6_ZS_DW0_STENCIL_ZPASS_OP__MASK                     0x00380000
+#define GEN6_ZS_DW0_STENCIL_ZPASS_OP__SHIFT                    19
 #define GEN6_ZS_DW0_STENCIL_WRITE_ENABLE                       (0x1 << 18)
 #define GEN6_ZS_DW0_STENCIL1_ENABLE                            (0x1 << 15)
 #define GEN6_ZS_DW0_STENCIL1_FUNC__MASK                                0x00007000
@@ -181,14 +192,14 @@ enum gen_sampler_key_filter {
 #define GEN6_ZS_DW0_STENCIL1_ZPASS_OP__MASK                    0x00000038
 #define GEN6_ZS_DW0_STENCIL1_ZPASS_OP__SHIFT                   3
 
-#define GEN6_ZS_DW1_STENCIL0_VALUEMASK__MASK                   0xff000000
-#define GEN6_ZS_DW1_STENCIL0_VALUEMASK__SHIFT                  24
-#define GEN6_ZS_DW1_STENCIL0_WRITEMASK__MASK                   0x00ff0000
-#define GEN6_ZS_DW1_STENCIL0_WRITEMASK__SHIFT                  16
-#define GEN6_ZS_DW1_STENCIL1_VALUEMASK__MASK                   0x0000ff00
-#define GEN6_ZS_DW1_STENCIL1_VALUEMASK__SHIFT                  8
-#define GEN6_ZS_DW1_STENCIL1_WRITEMASK__MASK                   0x000000ff
-#define GEN6_ZS_DW1_STENCIL1_WRITEMASK__SHIFT                  0
+#define GEN6_ZS_DW1_STENCIL_TEST_MASK__MASK                    0xff000000
+#define GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT                   24
+#define GEN6_ZS_DW1_STENCIL_WRITE_MASK__MASK                   0x00ff0000
+#define GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT                  16
+#define GEN6_ZS_DW1_STENCIL1_TEST_MASK__MASK                   0x0000ff00
+#define GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT                  8
+#define GEN6_ZS_DW1_STENCIL1_WRITE_MASK__MASK                  0x000000ff
+#define GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT                 0
 
 #define GEN6_ZS_DW2_DEPTH_TEST_ENABLE                          (0x1 << 31)
 #define GEN6_ZS_DW2_DEPTH_FUNC__MASK                           0x38000000
@@ -216,10 +227,12 @@ enum gen_sampler_key_filter {
 #define GEN6_RT_DW1_ALPHA_TO_COVERAGE                          (0x1 << 31)
 #define GEN6_RT_DW1_ALPHA_TO_ONE                               (0x1 << 30)
 #define GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER                   (0x1 << 29)
-#define GEN6_RT_DW1_WRITE_DISABLE_A                            (0x1 << 27)
-#define GEN6_RT_DW1_WRITE_DISABLE_R                            (0x1 << 26)
-#define GEN6_RT_DW1_WRITE_DISABLE_G                            (0x1 << 25)
-#define GEN6_RT_DW1_WRITE_DISABLE_B                            (0x1 << 24)
+#define GEN6_RT_DW1_WRITE_DISABLES__MASK                       0x0f000000
+#define GEN6_RT_DW1_WRITE_DISABLES__SHIFT                      24
+#define GEN6_RT_DW1_WRITE_DISABLES_A                           (0x1 << 27)
+#define GEN6_RT_DW1_WRITE_DISABLES_R                           (0x1 << 26)
+#define GEN6_RT_DW1_WRITE_DISABLES_G                           (0x1 << 25)
+#define GEN6_RT_DW1_WRITE_DISABLES_B                           (0x1 << 24)
 #define GEN6_RT_DW1_LOGICOP_ENABLE                             (0x1 << 22)
 #define GEN6_RT_DW1_LOGICOP_FUNC__MASK                         0x003c0000
 #define GEN6_RT_DW1_LOGICOP_FUNC__SHIFT                                18
@@ -267,10 +280,12 @@ enum gen_sampler_key_filter {
 #define GEN8_RT_DW0_DST_ALPHA_FACTOR__SHIFT                    8
 #define GEN8_RT_DW0_ALPHA_FUNC__MASK                           0x000000e0
 #define GEN8_RT_DW0_ALPHA_FUNC__SHIFT                          5
-#define GEN8_RT_DW0_WRITE_DISABLE_A                            (0x1 << 3)
-#define GEN8_RT_DW0_WRITE_DISABLE_R                            (0x1 << 2)
-#define GEN8_RT_DW0_WRITE_DISABLE_G                            (0x1 << 1)
-#define GEN8_RT_DW0_WRITE_DISABLE_B                            (0x1 << 0)
+#define GEN8_RT_DW0_WRITE_DISABLES__MASK                       0x0000000f
+#define GEN8_RT_DW0_WRITE_DISABLES__SHIFT                      0
+#define GEN8_RT_DW0_WRITE_DISABLES_A                           (0x1 << 3)
+#define GEN8_RT_DW0_WRITE_DISABLES_R                           (0x1 << 2)
+#define GEN8_RT_DW0_WRITE_DISABLES_G                           (0x1 << 1)
+#define GEN8_RT_DW0_WRITE_DISABLES_B                           (0x1 << 0)
 
 #define GEN8_RT_DW1_LOGICOP_ENABLE                             (0x1 << 31)
 #define GEN8_RT_DW1_LOGICOP_FUNC__MASK                         0x78000000
@@ -419,6 +434,7 @@ enum gen_sampler_key_filter {
 #define GEN8_SAMPLER_DW0_LOD_PRECLAMP_ENABLE__SHIFT            27
 #define GEN6_SAMPLER_DW0_BASE_LOD__MASK                                0x07c00000
 #define GEN6_SAMPLER_DW0_BASE_LOD__SHIFT                       22
+#define GEN6_SAMPLER_DW0_BASE_LOD__RADIX                       1
 #define GEN6_SAMPLER_DW0_MIP_FILTER__MASK                      0x00300000
 #define GEN6_SAMPLER_DW0_MIP_FILTER__SHIFT                     20
 #define GEN6_SAMPLER_DW0_MAG_FILTER__MASK                      0x000e0000
index 7c2349f2447f345ab0a111385dbd80744c63a061..b5d09f6442944eaa6525cb57282e9a8781e319b2 100644 (file)
@@ -299,7 +299,10 @@ enum gen_surface_scs {
 #define GEN6_SURFACE_DW0_MIPLAYOUT__SHIFT                      10
 #define GEN6_SURFACE_DW0_MIPLAYOUT_BELOW                       (0x0 << 10)
 #define GEN6_SURFACE_DW0_MIPLAYOUT_RIGHT                       (0x1 << 10)
-#define GEN6_SURFACE_DW0_CUBE_MAP_CORNER_MODE                  (0x1 << 9)
+#define GEN6_SURFACE_DW0_CUBE_MAP_CORNER_MODE__MASK            0x00000200
+#define GEN6_SURFACE_DW0_CUBE_MAP_CORNER_MODE__SHIFT           9
+#define GEN6_SURFACE_DW0_CUBE_MAP_CORNER_MODE_REPLICATE                (0x0 << 9)
+#define GEN6_SURFACE_DW0_CUBE_MAP_CORNER_MODE_AVERAGE          (0x1 << 9)
 #define GEN6_SURFACE_DW0_RENDER_CACHE_RW                       (0x1 << 8)
 #define GEN6_SURFACE_DW0_MEDIA_BOUNDARY_PIXEL_MODE__MASK       0x000000c0
 #define GEN6_SURFACE_DW0_MEDIA_BOUNDARY_PIXEL_MODE__SHIFT      6
@@ -485,6 +488,8 @@ enum gen_surface_scs {
 #define GEN7_SURFACE_DW7_CC_B__SHIFT                           29
 #define GEN7_SURFACE_DW7_CC_A__MASK                            0x10000000
 #define GEN7_SURFACE_DW7_CC_A__SHIFT                           28
+#define GEN75_SURFACE_DW7_SCS__MASK                            0x0fff0000
+#define GEN75_SURFACE_DW7_SCS__SHIFT                           16
 #define GEN75_SURFACE_DW7_SCS_R__MASK                          0x0e000000
 #define GEN75_SURFACE_DW7_SCS_R__SHIFT                         25
 #define GEN75_SURFACE_DW7_SCS_G__MASK                          0x01c00000
index 9e05bf5beca875c84b9b1dfb68a88504a28a2e37..3a777a18c2a550df8cfb1f2cb0291ca4f302363d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * Mesa 3-D graphics library
- *
  * Copyright (C) 2014 LunarG, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,8 +23,9 @@
 #ifndef GENHW_H
 #define GENHW_H
 
-#include "pipe/p_compiler.h"
-#include "util/u_debug.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <assert.h>
 
 #include "gen_regs.xml.h"
 #include "gen_mi.xml.h"
index 4284f415c1cf8947c2d053497f2cb5b18d5c19e1..4eba8481c2856f73a2a9d516ec46d6643ed7fe85 100644 (file)
@@ -39,12 +39,6 @@ enum ilo_blitter_uses {
    ILO_BLITTER_USE_FB_STENCIL    = 1 << 4,
 };
 
-enum ilo_blitter_rectlist_op {
-   ILO_BLITTER_RECTLIST_CLEAR_ZS,
-   ILO_BLITTER_RECTLIST_RESOLVE_Z,
-   ILO_BLITTER_RECTLIST_RESOLVE_HIZ,
-};
-
 struct blitter_context;
 struct pipe_resource;
 struct pipe_surface;
@@ -57,30 +51,42 @@ struct ilo_blitter {
    /*
     * A minimal context with the goal to send RECTLISTs down the pipeline.
     */
-   enum ilo_blitter_rectlist_op op;
+   enum ilo_state_raster_earlyz_op earlyz_op;
+   bool earlyz_stencil_clear;
    uint32_t uses;
 
    bool initialized;
 
    float vertices[3][2];
-   struct ilo_ve_state ve;
-   struct pipe_draw_info draw;
+   struct gen6_3dprimitive_info draw_info;
 
-   struct ilo_viewport_cso viewport;
-   struct ilo_dsa_state dsa;
+   uint32_t vf_data[4];
+   struct ilo_state_vf vf;
 
-   struct {
-      struct pipe_stencil_ref stencil_ref;
-      ubyte alpha_ref;
-      struct pipe_blend_color blend_color;
-   } cc;
+   struct ilo_state_vs vs;
+   struct ilo_state_hs hs;
+   struct ilo_state_ds ds;
+   struct ilo_state_gs gs;
+
+   struct ilo_state_sol sol;
+
+   struct ilo_state_viewport vp;
+   uint32_t vp_data[20];
+
+   struct ilo_state_sbe sbe;
+   struct ilo_state_ps ps;
+   struct ilo_state_cc cc;
 
    uint32_t depth_clear_value;
 
+   struct ilo_state_urb urb;
+
    struct {
       struct ilo_surface_cso dst;
       unsigned width, height;
       unsigned num_samples;
+
+      struct ilo_state_raster rs;
    } fb;
 };
 
index c4c02bd3e53451f159ded7f76f40c8ba48598834..0bfe7827f11d77f3fedd64889b74d4c5d7c73a7d 100644 (file)
@@ -63,7 +63,7 @@ ilo_blitter_pipe_begin(struct ilo_blitter *blitter,
    util_blitter_save_viewport(b, &vec->viewport.viewport0);
 
    if (scissor_enable)
-      util_blitter_save_scissor(b, &vec->scissor.scissor0);
+      util_blitter_save_scissor(b, &vec->viewport.scissor0);
 
    switch (op) {
    case ILO_BLITTER_PIPE_BLIT:
index 6d8afed9dca2ae2f3418427a03c0308cda4b6323..13c8f50068034ec7af0ac7b40f7d18acc3910137 100644 (file)
@@ -25,7 +25,6 @@
  *    Chia-I Wu <olv@lunarg.com>
  */
 
-#include "core/ilo_state_3d.h"
 #include "util/u_draw.h"
 #include "util/u_pack_color.h"
 
 static bool
 ilo_blitter_set_invariants(struct ilo_blitter *blitter)
 {
-   struct pipe_vertex_element velem;
-   struct pipe_viewport_state vp;
+   struct ilo_state_vf_element_info elem;
 
    if (blitter->initialized)
       return true;
 
+   /* a rectangle has 3 vertices in a RECTLIST */
+   blitter->draw_info.topology = GEN6_3DPRIM_RECTLIST;
+   blitter->draw_info.vertex_count = 3;
+   blitter->draw_info.instance_count = 1;
+
+   memset(&elem, 0, sizeof(elem));
    /* only vertex X and Y */
-   memset(&velem, 0, sizeof(velem));
-   velem.src_format = PIPE_FORMAT_R32G32_FLOAT;
-   ilo_gpe_init_ve(blitter->ilo->dev, 1, &velem, &blitter->ve);
-
-   /* generate VUE header */
-   ilo_gpe_init_ve_nosrc(blitter->ilo->dev,
-         GEN6_VFCOMP_STORE_0, /* Reserved */
-         GEN6_VFCOMP_STORE_0, /* Render Target Array Index */
-         GEN6_VFCOMP_STORE_0, /* Viewport Index */
-         GEN6_VFCOMP_STORE_0, /* Point Width */
-         &blitter->ve.nosrc_cso);
-   blitter->ve.prepend_nosrc_cso = true;
+   elem.format = GEN6_FORMAT_R32G32_FLOAT;
+   elem.format_size = 8;
+   elem.component_count = 2;
 
-   /* a rectangle has 3 vertices in a RECTLIST */
-   util_draw_init_info(&blitter->draw);
-   blitter->draw.mode = ILO_PRIM_RECTANGLES;
-   blitter->draw.count = 3;
+   ilo_state_vf_init_for_rectlist(&blitter->vf, blitter->ilo->dev,
+         blitter->vf_data, sizeof(blitter->vf_data), &elem, 1);
+
+   ilo_state_vs_init_disabled(&blitter->vs, blitter->ilo->dev);
+   ilo_state_hs_init_disabled(&blitter->hs, blitter->ilo->dev);
+   ilo_state_ds_init_disabled(&blitter->ds, blitter->ilo->dev);
+   ilo_state_gs_init_disabled(&blitter->gs, blitter->ilo->dev);
+   ilo_state_sol_init_disabled(&blitter->sol, blitter->ilo->dev, false);
 
    /**
     * From the Haswell PRM, volume 7, page 615:
     *
     *     "The clear value must be between the min and max depth values
-    *     (inclusive) defined in the CC_VIEWPORT."
+    *      (inclusive) defined in the CC_VIEWPORT."
     *
     * Even though clipping and viewport transformation will be disabled, we
     * still need to set up the viewport states.
     */
-   memset(&vp, 0, sizeof(vp));
-   vp.scale[0] = 1.0f;
-   vp.scale[1] = 1.0f;
-   vp.scale[2] = 1.0f;
-   ilo_gpe_set_viewport_cso(blitter->ilo->dev, &vp, &blitter->viewport);
+   ilo_state_viewport_init_for_rectlist(&blitter->vp, blitter->ilo->dev,
+         blitter->vp_data, sizeof(blitter->vp_data));
+
+   ilo_state_sbe_init_for_rectlist(&blitter->sbe, blitter->ilo->dev, 0, 0);
+   ilo_state_ps_init_disabled(&blitter->ps, blitter->ilo->dev);
+
+   ilo_state_urb_init_for_rectlist(&blitter->urb, blitter->ilo->dev,
+         ilo_state_vf_get_attr_count(&blitter->vf));
 
    blitter->initialized = true;
 
@@ -86,10 +88,12 @@ ilo_blitter_set_invariants(struct ilo_blitter *blitter)
 }
 
 static void
-ilo_blitter_set_op(struct ilo_blitter *blitter,
-                   enum ilo_blitter_rectlist_op op)
+ilo_blitter_set_earlyz_op(struct ilo_blitter *blitter,
+                          enum ilo_state_raster_earlyz_op op,
+                          bool earlyz_stencil_clear)
 {
-   blitter->op = op;
+   blitter->earlyz_op = op;
+   blitter->earlyz_stencil_clear = earlyz_stencil_clear;
 }
 
 /**
@@ -117,18 +121,27 @@ ilo_blitter_set_rectlist(struct ilo_blitter *blitter,
 }
 
 static void
-ilo_blitter_set_clear_values(struct ilo_blitter *blitter,
-                             uint32_t depth, ubyte stencil)
+ilo_blitter_set_depth_clear_value(struct ilo_blitter *blitter,
+                                  uint32_t depth)
 {
    blitter->depth_clear_value = depth;
-   blitter->cc.stencil_ref.ref_value[0] = stencil;
 }
 
 static void
-ilo_blitter_set_dsa(struct ilo_blitter *blitter,
-                    const struct pipe_depth_stencil_alpha_state *state)
+ilo_blitter_set_cc(struct ilo_blitter *blitter,
+                   const struct ilo_state_cc_info *info)
+{
+   memset(&blitter->cc, 0, sizeof(blitter->cc));
+   ilo_state_cc_init(&blitter->cc, blitter->ilo->dev, info);
+}
+
+static void
+ilo_blitter_set_fb_rs(struct ilo_blitter *blitter)
 {
-   ilo_gpe_init_dsa(blitter->ilo->dev, state, &blitter->dsa);
+   memset(&blitter->fb.rs, 0, sizeof(blitter->fb.rs));
+   ilo_state_raster_init_for_rectlist(&blitter->fb.rs, blitter->ilo->dev,
+         blitter->fb.num_samples, blitter->earlyz_op,
+         blitter->earlyz_stencil_clear);
 }
 
 static void
@@ -146,6 +159,8 @@ ilo_blitter_set_fb(struct ilo_blitter *blitter,
       blitter->fb.num_samples = 1;
 
    memcpy(&blitter->fb.dst, cso, sizeof(*cso));
+
+   ilo_blitter_set_fb_rs(blitter);
 }
 
 static void
@@ -191,9 +206,9 @@ hiz_align_fb(struct ilo_blitter *blitter)
 {
    unsigned align_w, align_h;
 
-   switch (blitter->op) {
-   case ILO_BLITTER_RECTLIST_CLEAR_ZS:
-   case ILO_BLITTER_RECTLIST_RESOLVE_Z:
+   switch (blitter->earlyz_op) {
+   case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
+   case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
       break;
    default:
       return;
@@ -328,7 +343,7 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
                               double depth, unsigned stencil)
 {
    struct ilo_texture *tex = ilo_texture(zs->texture);
-   struct pipe_depth_stencil_alpha_state dsa_state;
+   struct ilo_state_cc_info info;
    uint32_t uses, clear_value;
 
    if (!ilo_image_can_enable_aux(&tex->image, zs->u.tex.level))
@@ -368,17 +383,20 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
     *      - [DevSNB] errata: For stencil buffer only clear, the previous
     *        depth clear value must be delivered during the clear."
     */
-   memset(&dsa_state, 0, sizeof(dsa_state));
+   memset(&info, 0, sizeof(info));
 
-   if (clear_flags & PIPE_CLEAR_DEPTH)
-      dsa_state.depth.writemask = true;
+   if (clear_flags & PIPE_CLEAR_DEPTH) {
+      info.depth.cv_has_buffer = true;
+      info.depth.write_enable = true;
+   }
 
    if (clear_flags & PIPE_CLEAR_STENCIL) {
-      dsa_state.stencil[0].enabled = true;
-      dsa_state.stencil[0].func = PIPE_FUNC_ALWAYS;
-      dsa_state.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-      dsa_state.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-      dsa_state.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+      info.stencil.cv_has_buffer = true;
+      info.stencil.test_enable = true;
+      info.stencil.front.test_func = GEN6_COMPAREFUNCTION_ALWAYS;
+      info.stencil.front.fail_op = GEN6_STENCILOP_KEEP;
+      info.stencil.front.zfail_op = GEN6_STENCILOP_KEEP;
+      info.stencil.front.zpass_op = GEN6_STENCILOP_REPLACE;
 
       /*
        * From the Ivy Bridge PRM, volume 2 part 1, page 277:
@@ -389,18 +407,21 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
        *      - DEPTH_STENCIL_STATE::Stencil Test Mask must be 0xFF
        *      - DEPTH_STENCIL_STATE::Back Face Stencil Write Mask must be 0xFF
        *      - DEPTH_STENCIL_STATE::Back Face Stencil Test Mask must be 0xFF"
+       *
+       * Back frace masks will be copied from front face masks.
        */
-      dsa_state.stencil[0].valuemask = 0xff;
-      dsa_state.stencil[0].writemask = 0xff;
-      dsa_state.stencil[1].valuemask = 0xff;
-      dsa_state.stencil[1].writemask = 0xff;
+      info.params.stencil_front.test_ref = (uint8_t) stencil;
+      info.params.stencil_front.test_mask = 0xff;
+      info.params.stencil_front.write_mask = 0xff;
    }
 
    ilo_blitter_set_invariants(blitter);
-   ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_CLEAR_ZS);
+   ilo_blitter_set_earlyz_op(blitter,
+         ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR,
+         clear_flags & PIPE_CLEAR_STENCIL);
 
-   ilo_blitter_set_dsa(blitter, &dsa_state);
-   ilo_blitter_set_clear_values(blitter, clear_value, (ubyte) stencil);
+   ilo_blitter_set_cc(blitter, &info);
+   ilo_blitter_set_depth_clear_value(blitter, clear_value);
    ilo_blitter_set_fb_from_surface(blitter, zs);
 
    uses = ILO_BLITTER_USE_DSA;
@@ -421,7 +442,7 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter,
                                unsigned level, unsigned slice)
 {
    struct ilo_texture *tex = ilo_texture(res);
-   struct pipe_depth_stencil_alpha_state dsa_state;
+   struct ilo_state_cc_info info;
    const struct ilo_texture_slice *s =
       ilo_texture_get_slice(tex, level, slice);
 
@@ -435,16 +456,18 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter,
     *      to NEVER. Depth Buffer Write Enable must be enabled. Stencil Test
     *      Enable and Stencil Buffer Write Enable must be disabled."
     */
-   memset(&dsa_state, 0, sizeof(dsa_state));
-   dsa_state.depth.writemask = true;
-   dsa_state.depth.enabled = true;
-   dsa_state.depth.func = PIPE_FUNC_NEVER;
+   memset(&info, 0, sizeof(info));
+   info.depth.cv_has_buffer = true;
+   info.depth.test_enable = true;
+   info.depth.write_enable = true;
+   info.depth.test_func = GEN6_COMPAREFUNCTION_NEVER;
 
    ilo_blitter_set_invariants(blitter);
-   ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_RESOLVE_Z);
+   ilo_blitter_set_earlyz_op(blitter,
+         ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE, false);
 
-   ilo_blitter_set_dsa(blitter, &dsa_state);
-   ilo_blitter_set_clear_values(blitter, s->clear_value, 0);
+   ilo_blitter_set_cc(blitter, &info);
+   ilo_blitter_set_depth_clear_value(blitter, s->clear_value);
    ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice);
    ilo_blitter_set_uses(blitter,
          ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH);
@@ -458,7 +481,7 @@ ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter,
                                  unsigned level, unsigned slice)
 {
    struct ilo_texture *tex = ilo_texture(res);
-   struct pipe_depth_stencil_alpha_state dsa_state;
+   struct ilo_state_cc_info info;
 
    if (!ilo_image_can_enable_aux(&tex->image, level))
       return;
@@ -470,13 +493,15 @@ ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter,
     *      disabled. Depth Buffer Write Enable must be enabled. Stencil Test
     *      Enable and Stencil Buffer Write Enable must be disabled."
     */
-   memset(&dsa_state, 0, sizeof(dsa_state));
-   dsa_state.depth.writemask = true;
+   memset(&info, 0, sizeof(info));
+   info.depth.cv_has_buffer = true;
+   info.depth.write_enable = true;
 
    ilo_blitter_set_invariants(blitter);
-   ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_RESOLVE_HIZ);
+   ilo_blitter_set_earlyz_op(blitter,
+         ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE, false);
 
-   ilo_blitter_set_dsa(blitter, &dsa_state);
+   ilo_blitter_set_cc(blitter, &info);
    ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice);
    ilo_blitter_set_uses(blitter,
          ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH);
index fc91fd312d22c7ee835d13ce09c835fb5850575d..e8e1a4cd14ce0a8f031910d822ace8192fa50963 100644 (file)
@@ -452,12 +452,12 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
    } u;
 
    /* we will draw with IB mapped */
-   if (ib->buffer) {
-      u.ptr = intel_bo_map(ilo_buffer(ib->buffer)->bo, false);
+   if (ib->state.buffer) {
+      u.ptr = intel_bo_map(ilo_buffer(ib->state.buffer)->bo, false);
       if (u.ptr)
-         u.u8 += ib->offset;
+         u.u8 += ib->state.offset;
    } else {
-      u.ptr = ib->user_buffer;
+      u.ptr = ib->state.user_buffer;
    }
 
    if (!u.ptr)
@@ -483,7 +483,7 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
       (pipe)->draw_vbo(pipe, &subinfo);                  \
 } while (0)
 
-   switch (ib->index_size) {
+   switch (ib->state.index_size) {
    case 1:
       DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u8);
       break;
@@ -500,8 +500,8 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
 
 #undef DRAW_VBO_WITH_SW_RESTART
 
-   if (ib->buffer)
-      intel_bo_unmap(ilo_buffer(ib->buffer)->bo);
+   if (ib->state.buffer)
+      intel_bo_unmap(ilo_buffer(ib->state.buffer)->bo);
 }
 
 static bool
@@ -511,9 +511,9 @@ draw_vbo_need_sw_restart(const struct ilo_context *ilo,
    /* the restart index is fixed prior to GEN7.5 */
    if (ilo_dev_gen(ilo->dev) < ILO_GEN(7.5)) {
       const unsigned cut_index =
-         (ilo->state_vector.ib.index_size == 1) ? 0xff :
-         (ilo->state_vector.ib.index_size == 2) ? 0xffff :
-         (ilo->state_vector.ib.index_size == 4) ? 0xffffffff : 0;
+         (ilo->state_vector.ib.state.index_size == 1) ? 0xff :
+         (ilo->state_vector.ib.state.index_size == 2) ? 0xffff :
+         (ilo->state_vector.ib.state.index_size == 4) ? 0xffffffff : 0;
 
       if (info->restart_index < cut_index)
          return true;
diff --git a/src/gallium/drivers/ilo/ilo_format.c b/src/gallium/drivers/ilo/ilo_format.c
new file mode 100644 (file)
index 0000000..ca7e6b5
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "genhw/genhw.h"
+#include "core/ilo_state_surface.h"
+#include "core/ilo_state_vf.h"
+#include "ilo_format.h"
+
+bool
+ilo_format_support_vb(const struct ilo_dev *dev,
+                      enum pipe_format format)
+{
+   const int idx = ilo_format_translate(dev, format, PIPE_BIND_VERTEX_BUFFER);
+
+   return (idx >= 0 && ilo_state_vf_valid_element_format(dev, idx));
+}
+
+bool
+ilo_format_support_sol(const struct ilo_dev *dev,
+                       enum pipe_format format)
+{
+   const int idx = ilo_format_translate(dev, format, PIPE_BIND_STREAM_OUTPUT);
+
+   return (idx >= 0 && ilo_state_surface_valid_format(dev,
+            ILO_STATE_SURFACE_ACCESS_DP_SVB, idx));
+}
+
+bool
+ilo_format_support_sampler(const struct ilo_dev *dev,
+                           enum pipe_format format)
+{
+   const int idx = ilo_format_translate(dev, format, PIPE_BIND_SAMPLER_VIEW);
+
+   return (idx >= 0 && ilo_state_surface_valid_format(dev,
+            ILO_STATE_SURFACE_ACCESS_SAMPLER, idx));
+}
+
+bool
+ilo_format_support_rt(const struct ilo_dev *dev,
+                      enum pipe_format format)
+{
+   const int idx = ilo_format_translate(dev, format, PIPE_BIND_RENDER_TARGET);
+
+   return (idx >= 0 && ilo_state_surface_valid_format(dev,
+            ILO_STATE_SURFACE_ACCESS_DP_RENDER, idx));
+}
+
+bool
+ilo_format_support_zs(const struct ilo_dev *dev,
+                      enum pipe_format format)
+{
+   switch (format) {
+   case PIPE_FORMAT_Z16_UNORM:
+   case PIPE_FORMAT_Z24X8_UNORM:
+   case PIPE_FORMAT_Z32_FLOAT:
+   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      return true;
+   case PIPE_FORMAT_S8_UINT:
+      /* TODO separate stencil */
+   default:
+      return false;
+   }
+}
+
+/**
+ * Translate a color (non-depth/stencil) pipe format to the matching hardware
+ * format.  Return -1 on errors.
+ */
+int
+ilo_format_translate_color(const struct ilo_dev *dev,
+                           enum pipe_format format)
+{
+   static const int format_mapping[PIPE_FORMAT_COUNT] = {
+      [PIPE_FORMAT_NONE]                  = 0,
+      [PIPE_FORMAT_B8G8R8A8_UNORM]        = GEN6_FORMAT_B8G8R8A8_UNORM,
+      [PIPE_FORMAT_B8G8R8X8_UNORM]        = GEN6_FORMAT_B8G8R8X8_UNORM,
+      [PIPE_FORMAT_A8R8G8B8_UNORM]        = 0,
+      [PIPE_FORMAT_X8R8G8B8_UNORM]        = 0,
+      [PIPE_FORMAT_B5G5R5A1_UNORM]        = GEN6_FORMAT_B5G5R5A1_UNORM,
+      [PIPE_FORMAT_B4G4R4A4_UNORM]        = GEN6_FORMAT_B4G4R4A4_UNORM,
+      [PIPE_FORMAT_B5G6R5_UNORM]          = GEN6_FORMAT_B5G6R5_UNORM,
+      [PIPE_FORMAT_R10G10B10A2_UNORM]     = GEN6_FORMAT_R10G10B10A2_UNORM,
+      [PIPE_FORMAT_L8_UNORM]              = GEN6_FORMAT_L8_UNORM,
+      [PIPE_FORMAT_A8_UNORM]              = GEN6_FORMAT_A8_UNORM,
+      [PIPE_FORMAT_I8_UNORM]              = GEN6_FORMAT_I8_UNORM,
+      [PIPE_FORMAT_L8A8_UNORM]            = GEN6_FORMAT_L8A8_UNORM,
+      [PIPE_FORMAT_L16_UNORM]             = GEN6_FORMAT_L16_UNORM,
+      [PIPE_FORMAT_UYVY]                  = GEN6_FORMAT_YCRCB_SWAPUVY,
+      [PIPE_FORMAT_YUYV]                  = GEN6_FORMAT_YCRCB_NORMAL,
+      [PIPE_FORMAT_Z16_UNORM]             = 0,
+      [PIPE_FORMAT_Z32_UNORM]             = 0,
+      [PIPE_FORMAT_Z32_FLOAT]             = 0,
+      [PIPE_FORMAT_Z24_UNORM_S8_UINT]     = 0,
+      [PIPE_FORMAT_S8_UINT_Z24_UNORM]     = 0,
+      [PIPE_FORMAT_Z24X8_UNORM]           = 0,
+      [PIPE_FORMAT_X8Z24_UNORM]           = 0,
+      [PIPE_FORMAT_S8_UINT]               = 0,
+      [PIPE_FORMAT_R64_FLOAT]             = GEN6_FORMAT_R64_FLOAT,
+      [PIPE_FORMAT_R64G64_FLOAT]          = GEN6_FORMAT_R64G64_FLOAT,
+      [PIPE_FORMAT_R64G64B64_FLOAT]       = GEN6_FORMAT_R64G64B64_FLOAT,
+      [PIPE_FORMAT_R64G64B64A64_FLOAT]    = GEN6_FORMAT_R64G64B64A64_FLOAT,
+      [PIPE_FORMAT_R32_FLOAT]             = GEN6_FORMAT_R32_FLOAT,
+      [PIPE_FORMAT_R32G32_FLOAT]          = GEN6_FORMAT_R32G32_FLOAT,
+      [PIPE_FORMAT_R32G32B32_FLOAT]       = GEN6_FORMAT_R32G32B32_FLOAT,
+      [PIPE_FORMAT_R32G32B32A32_FLOAT]    = GEN6_FORMAT_R32G32B32A32_FLOAT,
+      [PIPE_FORMAT_R32_UNORM]             = GEN6_FORMAT_R32_UNORM,
+      [PIPE_FORMAT_R32G32_UNORM]          = GEN6_FORMAT_R32G32_UNORM,
+      [PIPE_FORMAT_R32G32B32_UNORM]       = GEN6_FORMAT_R32G32B32_UNORM,
+      [PIPE_FORMAT_R32G32B32A32_UNORM]    = GEN6_FORMAT_R32G32B32A32_UNORM,
+      [PIPE_FORMAT_R32_USCALED]           = GEN6_FORMAT_R32_USCALED,
+      [PIPE_FORMAT_R32G32_USCALED]        = GEN6_FORMAT_R32G32_USCALED,
+      [PIPE_FORMAT_R32G32B32_USCALED]     = GEN6_FORMAT_R32G32B32_USCALED,
+      [PIPE_FORMAT_R32G32B32A32_USCALED]  = GEN6_FORMAT_R32G32B32A32_USCALED,
+      [PIPE_FORMAT_R32_SNORM]             = GEN6_FORMAT_R32_SNORM,
+      [PIPE_FORMAT_R32G32_SNORM]          = GEN6_FORMAT_R32G32_SNORM,
+      [PIPE_FORMAT_R32G32B32_SNORM]       = GEN6_FORMAT_R32G32B32_SNORM,
+      [PIPE_FORMAT_R32G32B32A32_SNORM]    = GEN6_FORMAT_R32G32B32A32_SNORM,
+      [PIPE_FORMAT_R32_SSCALED]           = GEN6_FORMAT_R32_SSCALED,
+      [PIPE_FORMAT_R32G32_SSCALED]        = GEN6_FORMAT_R32G32_SSCALED,
+      [PIPE_FORMAT_R32G32B32_SSCALED]     = GEN6_FORMAT_R32G32B32_SSCALED,
+      [PIPE_FORMAT_R32G32B32A32_SSCALED]  = GEN6_FORMAT_R32G32B32A32_SSCALED,
+      [PIPE_FORMAT_R16_UNORM]             = GEN6_FORMAT_R16_UNORM,
+      [PIPE_FORMAT_R16G16_UNORM]          = GEN6_FORMAT_R16G16_UNORM,
+      [PIPE_FORMAT_R16G16B16_UNORM]       = GEN6_FORMAT_R16G16B16_UNORM,
+      [PIPE_FORMAT_R16G16B16A16_UNORM]    = GEN6_FORMAT_R16G16B16A16_UNORM,
+      [PIPE_FORMAT_R16_USCALED]           = GEN6_FORMAT_R16_USCALED,
+      [PIPE_FORMAT_R16G16_USCALED]        = GEN6_FORMAT_R16G16_USCALED,
+      [PIPE_FORMAT_R16G16B16_USCALED]     = GEN6_FORMAT_R16G16B16_USCALED,
+      [PIPE_FORMAT_R16G16B16A16_USCALED]  = GEN6_FORMAT_R16G16B16A16_USCALED,
+      [PIPE_FORMAT_R16_SNORM]             = GEN6_FORMAT_R16_SNORM,
+      [PIPE_FORMAT_R16G16_SNORM]          = GEN6_FORMAT_R16G16_SNORM,
+      [PIPE_FORMAT_R16G16B16_SNORM]       = GEN6_FORMAT_R16G16B16_SNORM,
+      [PIPE_FORMAT_R16G16B16A16_SNORM]    = GEN6_FORMAT_R16G16B16A16_SNORM,
+      [PIPE_FORMAT_R16_SSCALED]           = GEN6_FORMAT_R16_SSCALED,
+      [PIPE_FORMAT_R16G16_SSCALED]        = GEN6_FORMAT_R16G16_SSCALED,
+      [PIPE_FORMAT_R16G16B16_SSCALED]     = GEN6_FORMAT_R16G16B16_SSCALED,
+      [PIPE_FORMAT_R16G16B16A16_SSCALED]  = GEN6_FORMAT_R16G16B16A16_SSCALED,
+      [PIPE_FORMAT_R8_UNORM]              = GEN6_FORMAT_R8_UNORM,
+      [PIPE_FORMAT_R8G8_UNORM]            = GEN6_FORMAT_R8G8_UNORM,
+      [PIPE_FORMAT_R8G8B8_UNORM]          = GEN6_FORMAT_R8G8B8_UNORM,
+      [PIPE_FORMAT_R8G8B8A8_UNORM]        = GEN6_FORMAT_R8G8B8A8_UNORM,
+      [PIPE_FORMAT_X8B8G8R8_UNORM]        = 0,
+      [PIPE_FORMAT_R8_USCALED]            = GEN6_FORMAT_R8_USCALED,
+      [PIPE_FORMAT_R8G8_USCALED]          = GEN6_FORMAT_R8G8_USCALED,
+      [PIPE_FORMAT_R8G8B8_USCALED]        = GEN6_FORMAT_R8G8B8_USCALED,
+      [PIPE_FORMAT_R8G8B8A8_USCALED]      = GEN6_FORMAT_R8G8B8A8_USCALED,
+      [PIPE_FORMAT_R8_SNORM]              = GEN6_FORMAT_R8_SNORM,
+      [PIPE_FORMAT_R8G8_SNORM]            = GEN6_FORMAT_R8G8_SNORM,
+      [PIPE_FORMAT_R8G8B8_SNORM]          = GEN6_FORMAT_R8G8B8_SNORM,
+      [PIPE_FORMAT_R8G8B8A8_SNORM]        = GEN6_FORMAT_R8G8B8A8_SNORM,
+      [PIPE_FORMAT_R8_SSCALED]            = GEN6_FORMAT_R8_SSCALED,
+      [PIPE_FORMAT_R8G8_SSCALED]          = GEN6_FORMAT_R8G8_SSCALED,
+      [PIPE_FORMAT_R8G8B8_SSCALED]        = GEN6_FORMAT_R8G8B8_SSCALED,
+      [PIPE_FORMAT_R8G8B8A8_SSCALED]      = GEN6_FORMAT_R8G8B8A8_SSCALED,
+      [PIPE_FORMAT_R32_FIXED]             = GEN6_FORMAT_R32_SFIXED,
+      [PIPE_FORMAT_R32G32_FIXED]          = GEN6_FORMAT_R32G32_SFIXED,
+      [PIPE_FORMAT_R32G32B32_FIXED]       = GEN6_FORMAT_R32G32B32_SFIXED,
+      [PIPE_FORMAT_R32G32B32A32_FIXED]    = GEN6_FORMAT_R32G32B32A32_SFIXED,
+      [PIPE_FORMAT_R16_FLOAT]             = GEN6_FORMAT_R16_FLOAT,
+      [PIPE_FORMAT_R16G16_FLOAT]          = GEN6_FORMAT_R16G16_FLOAT,
+      [PIPE_FORMAT_R16G16B16_FLOAT]       = GEN6_FORMAT_R16G16B16_FLOAT,
+      [PIPE_FORMAT_R16G16B16A16_FLOAT]    = GEN6_FORMAT_R16G16B16A16_FLOAT,
+      [PIPE_FORMAT_L8_SRGB]               = GEN6_FORMAT_L8_UNORM_SRGB,
+      [PIPE_FORMAT_L8A8_SRGB]             = GEN6_FORMAT_L8A8_UNORM_SRGB,
+      [PIPE_FORMAT_R8G8B8_SRGB]           = GEN6_FORMAT_R8G8B8_UNORM_SRGB,
+      [PIPE_FORMAT_A8B8G8R8_SRGB]         = 0,
+      [PIPE_FORMAT_X8B8G8R8_SRGB]         = 0,
+      [PIPE_FORMAT_B8G8R8A8_SRGB]         = GEN6_FORMAT_B8G8R8A8_UNORM_SRGB,
+      [PIPE_FORMAT_B8G8R8X8_SRGB]         = GEN6_FORMAT_B8G8R8X8_UNORM_SRGB,
+      [PIPE_FORMAT_A8R8G8B8_SRGB]         = 0,
+      [PIPE_FORMAT_X8R8G8B8_SRGB]         = 0,
+      [PIPE_FORMAT_R8G8B8A8_SRGB]         = GEN6_FORMAT_R8G8B8A8_UNORM_SRGB,
+      [PIPE_FORMAT_DXT1_RGB]              = GEN6_FORMAT_DXT1_RGB,
+      [PIPE_FORMAT_DXT1_RGBA]             = GEN6_FORMAT_BC1_UNORM,
+      [PIPE_FORMAT_DXT3_RGBA]             = GEN6_FORMAT_BC2_UNORM,
+      [PIPE_FORMAT_DXT5_RGBA]             = GEN6_FORMAT_BC3_UNORM,
+      [PIPE_FORMAT_DXT1_SRGB]             = GEN6_FORMAT_DXT1_RGB_SRGB,
+      [PIPE_FORMAT_DXT1_SRGBA]            = GEN6_FORMAT_BC1_UNORM_SRGB,
+      [PIPE_FORMAT_DXT3_SRGBA]            = GEN6_FORMAT_BC2_UNORM_SRGB,
+      [PIPE_FORMAT_DXT5_SRGBA]            = GEN6_FORMAT_BC3_UNORM_SRGB,
+      [PIPE_FORMAT_RGTC1_UNORM]           = GEN6_FORMAT_BC4_UNORM,
+      [PIPE_FORMAT_RGTC1_SNORM]           = GEN6_FORMAT_BC4_SNORM,
+      [PIPE_FORMAT_RGTC2_UNORM]           = GEN6_FORMAT_BC5_UNORM,
+      [PIPE_FORMAT_RGTC2_SNORM]           = GEN6_FORMAT_BC5_SNORM,
+      [PIPE_FORMAT_R8G8_B8G8_UNORM]       = 0,
+      [PIPE_FORMAT_G8R8_G8B8_UNORM]       = 0,
+      [PIPE_FORMAT_R8SG8SB8UX8U_NORM]     = 0,
+      [PIPE_FORMAT_R5SG5SB6U_NORM]        = 0,
+      [PIPE_FORMAT_A8B8G8R8_UNORM]        = 0,
+      [PIPE_FORMAT_B5G5R5X1_UNORM]        = GEN6_FORMAT_B5G5R5X1_UNORM,
+      [PIPE_FORMAT_R10G10B10A2_USCALED]   = GEN6_FORMAT_R10G10B10A2_USCALED,
+      [PIPE_FORMAT_R11G11B10_FLOAT]       = GEN6_FORMAT_R11G11B10_FLOAT,
+      [PIPE_FORMAT_R9G9B9E5_FLOAT]        = GEN6_FORMAT_R9G9B9E5_SHAREDEXP,
+      [PIPE_FORMAT_Z32_FLOAT_S8X24_UINT]  = 0,
+      [PIPE_FORMAT_R1_UNORM]              = GEN6_FORMAT_R1_UNORM,
+      [PIPE_FORMAT_R10G10B10X2_USCALED]   = GEN6_FORMAT_R10G10B10X2_USCALED,
+      [PIPE_FORMAT_R10G10B10X2_SNORM]     = 0,
+      [PIPE_FORMAT_L4A4_UNORM]            = 0,
+      [PIPE_FORMAT_B10G10R10A2_UNORM]     = GEN6_FORMAT_B10G10R10A2_UNORM,
+      [PIPE_FORMAT_R10SG10SB10SA2U_NORM]  = 0,
+      [PIPE_FORMAT_R8G8Bx_SNORM]          = 0,
+      [PIPE_FORMAT_R8G8B8X8_UNORM]        = GEN6_FORMAT_R8G8B8X8_UNORM,
+      [PIPE_FORMAT_B4G4R4X4_UNORM]        = 0,
+      [PIPE_FORMAT_X24S8_UINT]            = 0,
+      [PIPE_FORMAT_S8X24_UINT]            = 0,
+      [PIPE_FORMAT_X32_S8X24_UINT]        = 0,
+      [PIPE_FORMAT_B2G3R3_UNORM]          = 0,
+      [PIPE_FORMAT_L16A16_UNORM]          = GEN6_FORMAT_L16A16_UNORM,
+      [PIPE_FORMAT_A16_UNORM]             = GEN6_FORMAT_A16_UNORM,
+      [PIPE_FORMAT_I16_UNORM]             = GEN6_FORMAT_I16_UNORM,
+      [PIPE_FORMAT_LATC1_UNORM]           = 0,
+      [PIPE_FORMAT_LATC1_SNORM]           = 0,
+      [PIPE_FORMAT_LATC2_UNORM]           = 0,
+      [PIPE_FORMAT_LATC2_SNORM]           = 0,
+      [PIPE_FORMAT_A8_SNORM]              = 0,
+      [PIPE_FORMAT_L8_SNORM]              = 0,
+      [PIPE_FORMAT_L8A8_SNORM]            = 0,
+      [PIPE_FORMAT_I8_SNORM]              = 0,
+      [PIPE_FORMAT_A16_SNORM]             = 0,
+      [PIPE_FORMAT_L16_SNORM]             = 0,
+      [PIPE_FORMAT_L16A16_SNORM]          = 0,
+      [PIPE_FORMAT_I16_SNORM]             = 0,
+      [PIPE_FORMAT_A16_FLOAT]             = GEN6_FORMAT_A16_FLOAT,
+      [PIPE_FORMAT_L16_FLOAT]             = GEN6_FORMAT_L16_FLOAT,
+      [PIPE_FORMAT_L16A16_FLOAT]          = GEN6_FORMAT_L16A16_FLOAT,
+      [PIPE_FORMAT_I16_FLOAT]             = GEN6_FORMAT_I16_FLOAT,
+      [PIPE_FORMAT_A32_FLOAT]             = GEN6_FORMAT_A32_FLOAT,
+      [PIPE_FORMAT_L32_FLOAT]             = GEN6_FORMAT_L32_FLOAT,
+      [PIPE_FORMAT_L32A32_FLOAT]          = GEN6_FORMAT_L32A32_FLOAT,
+      [PIPE_FORMAT_I32_FLOAT]             = GEN6_FORMAT_I32_FLOAT,
+      [PIPE_FORMAT_YV12]                  = 0,
+      [PIPE_FORMAT_YV16]                  = 0,
+      [PIPE_FORMAT_IYUV]                  = 0,
+      [PIPE_FORMAT_NV12]                  = 0,
+      [PIPE_FORMAT_NV21]                  = 0,
+      [PIPE_FORMAT_A4R4_UNORM]            = 0,
+      [PIPE_FORMAT_R4A4_UNORM]            = 0,
+      [PIPE_FORMAT_R8A8_UNORM]            = 0,
+      [PIPE_FORMAT_A8R8_UNORM]            = 0,
+      [PIPE_FORMAT_R10G10B10A2_SSCALED]   = GEN6_FORMAT_R10G10B10A2_SSCALED,
+      [PIPE_FORMAT_R10G10B10A2_SNORM]     = GEN6_FORMAT_R10G10B10A2_SNORM,
+      [PIPE_FORMAT_B10G10R10A2_USCALED]   = GEN6_FORMAT_B10G10R10A2_USCALED,
+      [PIPE_FORMAT_B10G10R10A2_SSCALED]   = GEN6_FORMAT_B10G10R10A2_SSCALED,
+      [PIPE_FORMAT_B10G10R10A2_SNORM]     = GEN6_FORMAT_B10G10R10A2_SNORM,
+      [PIPE_FORMAT_R8_UINT]               = GEN6_FORMAT_R8_UINT,
+      [PIPE_FORMAT_R8G8_UINT]             = GEN6_FORMAT_R8G8_UINT,
+      [PIPE_FORMAT_R8G8B8_UINT]           = GEN6_FORMAT_R8G8B8_UINT,
+      [PIPE_FORMAT_R8G8B8A8_UINT]         = GEN6_FORMAT_R8G8B8A8_UINT,
+      [PIPE_FORMAT_R8_SINT]               = GEN6_FORMAT_R8_SINT,
+      [PIPE_FORMAT_R8G8_SINT]             = GEN6_FORMAT_R8G8_SINT,
+      [PIPE_FORMAT_R8G8B8_SINT]           = GEN6_FORMAT_R8G8B8_SINT,
+      [PIPE_FORMAT_R8G8B8A8_SINT]         = GEN6_FORMAT_R8G8B8A8_SINT,
+      [PIPE_FORMAT_R16_UINT]              = GEN6_FORMAT_R16_UINT,
+      [PIPE_FORMAT_R16G16_UINT]           = GEN6_FORMAT_R16G16_UINT,
+      [PIPE_FORMAT_R16G16B16_UINT]        = GEN6_FORMAT_R16G16B16_UINT,
+      [PIPE_FORMAT_R16G16B16A16_UINT]     = GEN6_FORMAT_R16G16B16A16_UINT,
+      [PIPE_FORMAT_R16_SINT]              = GEN6_FORMAT_R16_SINT,
+      [PIPE_FORMAT_R16G16_SINT]           = GEN6_FORMAT_R16G16_SINT,
+      [PIPE_FORMAT_R16G16B16_SINT]        = GEN6_FORMAT_R16G16B16_SINT,
+      [PIPE_FORMAT_R16G16B16A16_SINT]     = GEN6_FORMAT_R16G16B16A16_SINT,
+      [PIPE_FORMAT_R32_UINT]              = GEN6_FORMAT_R32_UINT,
+      [PIPE_FORMAT_R32G32_UINT]           = GEN6_FORMAT_R32G32_UINT,
+      [PIPE_FORMAT_R32G32B32_UINT]        = GEN6_FORMAT_R32G32B32_UINT,
+      [PIPE_FORMAT_R32G32B32A32_UINT]     = GEN6_FORMAT_R32G32B32A32_UINT,
+      [PIPE_FORMAT_R32_SINT]              = GEN6_FORMAT_R32_SINT,
+      [PIPE_FORMAT_R32G32_SINT]           = GEN6_FORMAT_R32G32_SINT,
+      [PIPE_FORMAT_R32G32B32_SINT]        = GEN6_FORMAT_R32G32B32_SINT,
+      [PIPE_FORMAT_R32G32B32A32_SINT]     = GEN6_FORMAT_R32G32B32A32_SINT,
+      [PIPE_FORMAT_A8_UINT]               = 0,
+      [PIPE_FORMAT_I8_UINT]               = GEN6_FORMAT_I8_UINT,
+      [PIPE_FORMAT_L8_UINT]               = GEN6_FORMAT_L8_UINT,
+      [PIPE_FORMAT_L8A8_UINT]             = GEN6_FORMAT_L8A8_UINT,
+      [PIPE_FORMAT_A8_SINT]               = 0,
+      [PIPE_FORMAT_I8_SINT]               = GEN6_FORMAT_I8_SINT,
+      [PIPE_FORMAT_L8_SINT]               = GEN6_FORMAT_L8_SINT,
+      [PIPE_FORMAT_L8A8_SINT]             = GEN6_FORMAT_L8A8_SINT,
+      [PIPE_FORMAT_A16_UINT]              = 0,
+      [PIPE_FORMAT_I16_UINT]              = 0,
+      [PIPE_FORMAT_L16_UINT]              = 0,
+      [PIPE_FORMAT_L16A16_UINT]           = 0,
+      [PIPE_FORMAT_A16_SINT]              = 0,
+      [PIPE_FORMAT_I16_SINT]              = 0,
+      [PIPE_FORMAT_L16_SINT]              = 0,
+      [PIPE_FORMAT_L16A16_SINT]           = 0,
+      [PIPE_FORMAT_A32_UINT]              = 0,
+      [PIPE_FORMAT_I32_UINT]              = 0,
+      [PIPE_FORMAT_L32_UINT]              = 0,
+      [PIPE_FORMAT_L32A32_UINT]           = 0,
+      [PIPE_FORMAT_A32_SINT]              = 0,
+      [PIPE_FORMAT_I32_SINT]              = 0,
+      [PIPE_FORMAT_L32_SINT]              = 0,
+      [PIPE_FORMAT_L32A32_SINT]           = 0,
+      [PIPE_FORMAT_B10G10R10A2_UINT]      = GEN6_FORMAT_B10G10R10A2_UINT,
+      [PIPE_FORMAT_ETC1_RGB8]             = GEN6_FORMAT_ETC1_RGB8,
+      [PIPE_FORMAT_R8G8_R8B8_UNORM]       = 0,
+      [PIPE_FORMAT_G8R8_B8R8_UNORM]       = 0,
+      [PIPE_FORMAT_R8G8B8X8_SNORM]        = 0,
+      [PIPE_FORMAT_R8G8B8X8_SRGB]         = 0,
+      [PIPE_FORMAT_R8G8B8X8_UINT]         = 0,
+      [PIPE_FORMAT_R8G8B8X8_SINT]         = 0,
+      [PIPE_FORMAT_B10G10R10X2_UNORM]     = GEN6_FORMAT_B10G10R10X2_UNORM,
+      [PIPE_FORMAT_R16G16B16X16_UNORM]    = GEN6_FORMAT_R16G16B16X16_UNORM,
+      [PIPE_FORMAT_R16G16B16X16_SNORM]    = 0,
+      [PIPE_FORMAT_R16G16B16X16_FLOAT]    = GEN6_FORMAT_R16G16B16X16_FLOAT,
+      [PIPE_FORMAT_R16G16B16X16_UINT]     = 0,
+      [PIPE_FORMAT_R16G16B16X16_SINT]     = 0,
+      [PIPE_FORMAT_R32G32B32X32_FLOAT]    = GEN6_FORMAT_R32G32B32X32_FLOAT,
+      [PIPE_FORMAT_R32G32B32X32_UINT]     = 0,
+      [PIPE_FORMAT_R32G32B32X32_SINT]     = 0,
+      [PIPE_FORMAT_R8A8_SNORM]            = 0,
+      [PIPE_FORMAT_R16A16_UNORM]          = 0,
+      [PIPE_FORMAT_R16A16_SNORM]          = 0,
+      [PIPE_FORMAT_R16A16_FLOAT]          = 0,
+      [PIPE_FORMAT_R32A32_FLOAT]          = 0,
+      [PIPE_FORMAT_R8A8_UINT]             = 0,
+      [PIPE_FORMAT_R8A8_SINT]             = 0,
+      [PIPE_FORMAT_R16A16_UINT]           = 0,
+      [PIPE_FORMAT_R16A16_SINT]           = 0,
+      [PIPE_FORMAT_R32A32_UINT]           = 0,
+      [PIPE_FORMAT_R32A32_SINT]           = 0,
+      [PIPE_FORMAT_R10G10B10A2_UINT]      = GEN6_FORMAT_R10G10B10A2_UINT,
+      [PIPE_FORMAT_B5G6R5_SRGB]           = GEN6_FORMAT_B5G6R5_UNORM_SRGB,
+   };
+   int sfmt = format_mapping[format];
+
+   /* GEN6_FORMAT_R32G32B32A32_FLOAT happens to be 0 */
+   if (!sfmt && format != PIPE_FORMAT_R32G32B32A32_FLOAT)
+      sfmt = -1;
+
+   return sfmt;
+}
diff --git a/src/gallium/drivers/ilo/ilo_format.h b/src/gallium/drivers/ilo/ilo_format.h
new file mode 100644 (file)
index 0000000..4e955c0
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_FORMAT_H
+#define ILO_FORMAT_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_common.h"
+
+bool
+ilo_format_support_vb(const struct ilo_dev *dev,
+                      enum pipe_format format);
+
+bool
+ilo_format_support_sol(const struct ilo_dev *dev,
+                       enum pipe_format format);
+
+bool
+ilo_format_support_sampler(const struct ilo_dev *dev,
+                           enum pipe_format format);
+
+bool
+ilo_format_support_rt(const struct ilo_dev *dev,
+                      enum pipe_format format);
+
+bool
+ilo_format_support_zs(const struct ilo_dev *dev,
+                      enum pipe_format format);
+
+int
+ilo_format_translate_color(const struct ilo_dev *dev,
+                           enum pipe_format format);
+
+/**
+ * Translate a pipe format to a hardware surface format suitable for
+ * the given purpose.  Return -1 on errors.
+ *
+ * This is an inline function not only for performance reasons.  There are
+ * caveats that the callers should be aware of before calling this function.
+ */
+static inline int
+ilo_format_translate(const struct ilo_dev *dev,
+                     enum pipe_format format, unsigned bind)
+{
+   switch (bind) {
+   case PIPE_BIND_RENDER_TARGET:
+      /*
+       * Some RGBX formats are not supported as render target formats.  But we
+       * can use their RGBA counterparts and force the destination alpha to be
+       * one when blending is enabled.
+       */
+      switch (format) {
+      case PIPE_FORMAT_B8G8R8X8_UNORM:
+         return GEN6_FORMAT_B8G8R8A8_UNORM;
+      default:
+         return ilo_format_translate_color(dev, format);
+      }
+      break;
+   case PIPE_BIND_SAMPLER_VIEW:
+      /*
+       * For depth formats, we want the depth values to be returned as R
+       * values.  But we assume in many places that the depth values are
+       * returned as I values (util_make_fragment_tex_shader_writedepth() is
+       * one such example).  We have to live with that at least for now.
+       *
+       * For ETC1 format, the texture data will be decompressed before being
+       * written to the bo.  See tex_staging_sys_convert_write().
+       */
+      switch (format) {
+      case PIPE_FORMAT_Z16_UNORM:
+         return GEN6_FORMAT_I16_UNORM;
+      case PIPE_FORMAT_Z32_FLOAT:
+         return GEN6_FORMAT_I32_FLOAT;
+      case PIPE_FORMAT_Z24X8_UNORM:
+      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+         return GEN6_FORMAT_I24X8_UNORM;
+      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+         return GEN6_FORMAT_I32X32_FLOAT;
+      case PIPE_FORMAT_ETC1_RGB8:
+         return GEN6_FORMAT_R8G8B8X8_UNORM;
+      default:
+         return ilo_format_translate_color(dev, format);
+      }
+      break;
+   case PIPE_BIND_VERTEX_BUFFER:
+      if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
+         return ilo_format_translate_color(dev, format);
+
+      /*
+       * Some 3-component formats are not supported as vertex element formats.
+       * But since we move between vertices using vb->stride, we should be
+       * good to use their 4-component counterparts if we force the W
+       * component to be one.  The only exception is that the vb boundary
+       * check for the last vertex may fail.
+       */
+      switch (format) {
+      case PIPE_FORMAT_R16G16B16_FLOAT:
+         return GEN6_FORMAT_R16G16B16A16_FLOAT;
+      case PIPE_FORMAT_R16G16B16_UINT:
+         return GEN6_FORMAT_R16G16B16A16_UINT;
+      case PIPE_FORMAT_R16G16B16_SINT:
+         return GEN6_FORMAT_R16G16B16A16_SINT;
+      case PIPE_FORMAT_R8G8B8_UINT:
+         return GEN6_FORMAT_R8G8B8A8_UINT;
+      case PIPE_FORMAT_R8G8B8_SINT:
+         return GEN6_FORMAT_R8G8B8A8_SINT;
+      default:
+         return ilo_format_translate_color(dev, format);
+      }
+      break;
+   case PIPE_BIND_STREAM_OUTPUT:
+      return ilo_format_translate_color(dev, format);
+      break;
+   default:
+      assert(!"cannot translate format");
+      break;
+   }
+
+   return -1;
+}
+
+static inline int
+ilo_format_translate_render(const struct ilo_dev *dev,
+                            enum pipe_format format)
+{
+   return ilo_format_translate(dev, format, PIPE_BIND_RENDER_TARGET);
+}
+
+static inline int
+ilo_format_translate_texture(const struct ilo_dev *dev,
+                             enum pipe_format format)
+{
+   return ilo_format_translate(dev, format, PIPE_BIND_SAMPLER_VIEW);
+}
+
+static inline int
+ilo_format_translate_vertex(const struct ilo_dev *dev,
+                            enum pipe_format format)
+{
+   return ilo_format_translate(dev, format, PIPE_BIND_VERTEX_BUFFER);
+}
+
+#endif /* ILO_FORMAT_H */
index f5be3360f05a84b956f4e242f937b2a2ace4ef17..21f75de11a05b5c4da5a3a4fdbeab93662a24412 100644 (file)
 #include "ilo_query.h"
 #include "ilo_render_gen.h"
 
-/* in S1.3 */
-struct sample_position {
-   int8_t x, y;
-};
-
-static const struct sample_position ilo_sample_pattern_1x[1] = {
-   {  0,  0 },
-};
-
-static const struct sample_position ilo_sample_pattern_2x[2] = {
-   { -4, -4 },
-   {  4,  4 },
-};
-
-static const struct sample_position ilo_sample_pattern_4x[4] = {
-   { -2, -6 },
-   {  6, -2 },
-   { -6,  2 },
-   {  2,  6 },
-};
-
-/* \see brw_multisample_positions_8x */
-static const struct sample_position ilo_sample_pattern_8x[8] = {
-   { -1,  1 },
-   {  1,  5 },
-   {  3, -5 },
-   {  5,  3 },
-   { -7, -1 },
-   { -3, -7 },
-   {  7, -3 },
-   { -5,  7 },
-};
-
-static const struct sample_position ilo_sample_pattern_16x[16] = {
-   {  0,  2 },
-   {  3,  0 },
-   { -3, -2 },
-   { -2, -4 },
-   {  4,  3 },
-   {  5,  1 },
-   {  6, -1 },
-   {  2, -6 },
-   { -4,  5 },
-   { -5, -5 },
-   { -1, -7 },
-   {  7, -3 },
-   { -7,  4 },
-   {  1, -8 },
-   { -6,  6 },
-   { -8,  7 },
-};
-
-static uint8_t
-pack_sample_position(const struct sample_position *pos)
-{
-   return (pos->x + 8) << 4 | (pos->y + 8);
-}
-
-static void
-get_sample_position(const struct sample_position *pos, float *x, float *y)
-{
-   *x = (float) (pos->x + 8) / 16.0f;
-   *y = (float) (pos->y + 8) / 16.0f;
-}
-
 struct ilo_render *
 ilo_render_create(struct ilo_builder *builder)
 {
    struct ilo_render *render;
-   int i;
 
    render = CALLOC_STRUCT(ilo_render);
    if (!render)
@@ -121,29 +55,8 @@ ilo_render_create(struct ilo_builder *builder)
       return NULL;
    }
 
-   /* pack into dwords */
-   render->sample_pattern_1x = pack_sample_position(ilo_sample_pattern_1x);
-   render->sample_pattern_2x =
-      pack_sample_position(&ilo_sample_pattern_2x[1]) << 8 |
-      pack_sample_position(&ilo_sample_pattern_2x[0]);
-   for (i = 0; i < 4; i++) {
-      render->sample_pattern_4x |=
-         pack_sample_position(&ilo_sample_pattern_4x[i]) << (8 * i);
-
-      render->sample_pattern_8x[0] |=
-         pack_sample_position(&ilo_sample_pattern_8x[i]) << (8 * i);
-      render->sample_pattern_8x[1] |=
-         pack_sample_position(&ilo_sample_pattern_8x[i + 4]) << (8 * i);
-
-      render->sample_pattern_16x[0] |=
-         pack_sample_position(&ilo_sample_pattern_16x[i]) << (8 * i);
-      render->sample_pattern_16x[1] |=
-         pack_sample_position(&ilo_sample_pattern_16x[i + 4]) << (8 * i);
-      render->sample_pattern_16x[2] |=
-         pack_sample_position(&ilo_sample_pattern_16x[i + 8]) << (8 * i);
-      render->sample_pattern_16x[3] |=
-         pack_sample_position(&ilo_sample_pattern_16x[i + 12]) << (8 * i);
-   }
+   ilo_state_sample_pattern_init_default(&render->sample_pattern,
+         render->dev);
 
    ilo_render_invalidate_hw(render);
    ilo_render_invalidate_builder(render);
@@ -164,38 +77,13 @@ ilo_render_get_sample_position(const struct ilo_render *render,
                                unsigned sample_index,
                                float *x, float *y)
 {
-   const struct sample_position *pattern;
+   uint8_t off_x, off_y;
 
-   switch (sample_count) {
-   case 1:
-      assert(sample_index < Elements(ilo_sample_pattern_1x));
-      pattern = ilo_sample_pattern_1x;
-      break;
-   case 2:
-      assert(sample_index < Elements(ilo_sample_pattern_2x));
-      pattern = ilo_sample_pattern_2x;
-      break;
-   case 4:
-      assert(sample_index < Elements(ilo_sample_pattern_4x));
-      pattern = ilo_sample_pattern_4x;
-      break;
-   case 8:
-      assert(sample_index < Elements(ilo_sample_pattern_8x));
-      pattern = ilo_sample_pattern_8x;
-      break;
-   case 16:
-      assert(sample_index < Elements(ilo_sample_pattern_16x));
-      pattern = ilo_sample_pattern_16x;
-      break;
-   default:
-      assert(!"unknown sample count");
-      *x = 0.5f;
-      *y = 0.5f;
-      return;
-      break;
-   }
+   ilo_state_sample_pattern_get_offset(&render->sample_pattern, render->dev,
+         sample_count, sample_index, &off_x, &off_y);
 
-   get_sample_position(&pattern[sample_index], x, y);
+   *x = (float) off_x / 16.0f;
+   *y = (float) off_y / 16.0f;
 }
 
 void
@@ -446,12 +334,44 @@ draw_session_prepare(struct ilo_render *render,
       render->instruction_bo_changed = true;
 
       session->prim_changed = true;
-      session->primitive_restart_changed = true;
+
+      ilo_state_urb_full_delta(&vec->urb, render->dev, &session->urb_delta);
+      ilo_state_vf_full_delta(&vec->ve->vf, render->dev, &session->vf_delta);
+
+      ilo_state_raster_full_delta(&vec->rasterizer->rs, render->dev,
+            &session->rs_delta);
+
+      ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev,
+            &session->vp_delta);
+
+      ilo_state_cc_full_delta(&vec->blend->cc, render->dev,
+            &session->cc_delta);
    } else {
       session->prim_changed =
          (render->state.reduced_prim != session->reduced_prim);
-      session->primitive_restart_changed =
-         (render->state.primitive_restart != vec->draw->primitive_restart);
+
+      ilo_state_urb_get_delta(&vec->urb, render->dev,
+            &render->state.urb, &session->urb_delta);
+
+      if (vec->dirty & ILO_DIRTY_VE) {
+         ilo_state_vf_full_delta(&vec->ve->vf, render->dev,
+               &session->vf_delta);
+      }
+
+      if (vec->dirty & ILO_DIRTY_RASTERIZER) {
+         ilo_state_raster_get_delta(&vec->rasterizer->rs, render->dev,
+               &render->state.rs, &session->rs_delta);
+      }
+
+      if (vec->dirty & ILO_DIRTY_VIEWPORT) {
+         ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev,
+               &session->vp_delta);
+      }
+
+      if (vec->dirty & ILO_DIRTY_BLEND) {
+         ilo_state_cc_get_delta(&vec->blend->cc, render->dev,
+               &render->state.cc, &session->cc_delta);
+      }
    }
 }
 
@@ -467,7 +387,10 @@ draw_session_end(struct ilo_render *render,
    render->instruction_bo_changed = false;
 
    render->state.reduced_prim = session->reduced_prim;
-   render->state.primitive_restart = vec->draw->primitive_restart;
+
+   render->state.urb = vec->urb;
+   render->state.rs = vec->rasterizer->rs;
+   render->state.cc = vec->blend->cc;
 }
 
 void
index a85b2800fb1373f934461739135b175ec9e9a968..098af73ec9b5195869255ea6a501a3e80210d471 100644 (file)
@@ -43,9 +43,6 @@ ilo_render_create(struct ilo_builder *builder);
 void
 ilo_render_destroy(struct ilo_render *render);
 
-/**
- * Estimate the size of an action.
- */
 void
 ilo_render_get_sample_position(const struct ilo_render *render,
                                unsigned sample_count,
index ef92b12da83d4102b9700028beb3a6121e631e34..3b4c80227a604326cfbcc8a40cf3dcef1bd22acc 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "ilo_common.h"
 #include "ilo_blitter.h"
+#include "ilo_shader.h"
 #include "ilo_state.h"
 #include "ilo_render_gen.h"
 
@@ -42,16 +43,14 @@ gen6_emit_draw_dynamic_viewports(struct ilo_render *r,
 {
    ILO_DEV_ASSERT(r->dev, 6, 6);
 
-   /* SF_VIEWPORT, CLIP_VIEWPORT, and CC_VIEWPORT */
-   if (DIRTY(VIEWPORT)) {
+   /* CLIP_VIEWPORT, SF_VIEWPORT, and CC_VIEWPORT */
+   if ((session->vp_delta.dirty & (ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT |
+                                   ILO_STATE_VIEWPORT_CC_VIEWPORT)) ||
+       r->state_bo_changed) {
       r->state.CLIP_VIEWPORT = gen6_CLIP_VIEWPORT(r->builder,
-            vec->viewport.cso, vec->viewport.count);
-
-      r->state.SF_VIEWPORT = gen6_SF_VIEWPORT(r->builder,
-            vec->viewport.cso, vec->viewport.count);
-
-      r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder,
-            vec->viewport.cso, vec->viewport.count);
+            &vec->viewport.vp);
+      r->state.SF_VIEWPORT = gen6_SF_VIEWPORT(r->builder, &vec->viewport.vp);
+      r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, &vec->viewport.vp);
 
       session->viewport_changed = true;
    }
@@ -65,12 +64,12 @@ gen7_emit_draw_dynamic_viewports(struct ilo_render *r,
    ILO_DEV_ASSERT(r->dev, 7, 8);
 
    /* SF_CLIP_VIEWPORT and CC_VIEWPORT */
-   if (DIRTY(VIEWPORT)) {
+   if ((session->vp_delta.dirty & (ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT |
+                                   ILO_STATE_VIEWPORT_CC_VIEWPORT)) ||
+       r->state_bo_changed) {
       r->state.SF_CLIP_VIEWPORT = gen7_SF_CLIP_VIEWPORT(r->builder,
-            vec->viewport.cso, vec->viewport.count);
-
-      r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder,
-            vec->viewport.cso, vec->viewport.count);
+            &vec->viewport.vp);
+      r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, &vec->viewport.vp);
 
       session->viewport_changed = true;
    }
@@ -84,10 +83,10 @@ gen6_emit_draw_dynamic_scissors(struct ilo_render *r,
    ILO_DEV_ASSERT(r->dev, 6, 8);
 
    /* SCISSOR_RECT */
-   if (DIRTY(SCISSOR) || DIRTY(VIEWPORT)) {
-      /* there should be as many scissors as there are viewports */
+   if ((session->vp_delta.dirty & ILO_STATE_VIEWPORT_SCISSOR_RECT) ||
+       r->state_bo_changed) {
       r->state.SCISSOR_RECT = gen6_SCISSOR_RECT(r->builder,
-            &vec->scissor, vec->viewport.count);
+            &vec->viewport.vp);
 
       session->scissor_changed = true;
    }
@@ -101,32 +100,30 @@ gen6_emit_draw_dynamic_cc(struct ilo_render *r,
    ILO_DEV_ASSERT(r->dev, 6, 8);
 
    /* BLEND_STATE */
-   if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA)) {
-      if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
-         r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder,
-               vec->blend, &vec->fb, vec->dsa);
-      } else {
-         r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder,
-               vec->blend, &vec->fb, vec->dsa);
-      }
+   if ((session->cc_delta.dirty & ILO_STATE_CC_BLEND_STATE) ||
+        r->state_bo_changed) {
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder, &vec->blend->cc);
+      else
+         r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder, &vec->blend->cc);
 
       session->blend_changed = true;
    }
 
    /* COLOR_CALC_STATE */
-   if (DIRTY(DSA) || DIRTY(STENCIL_REF) || DIRTY(BLEND_COLOR)) {
+   if ((session->cc_delta.dirty & ILO_STATE_CC_COLOR_CALC_STATE) ||
+       r->state_bo_changed) {
       r->state.COLOR_CALC_STATE =
-         gen6_COLOR_CALC_STATE(r->builder, &vec->stencil_ref,
-               vec->dsa->alpha_ref, &vec->blend_color);
-
+         gen6_COLOR_CALC_STATE(r->builder, &vec->blend->cc);
       session->cc_changed = true;
    }
 
    /* DEPTH_STENCIL_STATE */
-   if (ilo_dev_gen(r->dev) < ILO_GEN(8) && DIRTY(DSA)) {
+   if (ilo_dev_gen(r->dev) < ILO_GEN(8) &&
+       ((session->cc_delta.dirty & ILO_STATE_CC_DEPTH_STENCIL_STATE) ||
+        r->state_bo_changed)) {
       r->state.DEPTH_STENCIL_STATE =
-         gen6_DEPTH_STENCIL_STATE(r->builder, vec->dsa);
-
+         gen6_DEPTH_STENCIL_STATE(r->builder, &vec->blend->cc);
       session->dsa_changed = true;
    }
 }
@@ -137,12 +134,11 @@ gen6_emit_draw_dynamic_samplers(struct ilo_render *r,
                                 int shader_type,
                                 struct ilo_render_draw_session *session)
 {
-   const struct ilo_sampler_cso * const *samplers =
-      vec->sampler[shader_type].cso;
-   const struct pipe_sampler_view * const *views =
-      (const struct pipe_sampler_view **) vec->view[shader_type].states;
+   const struct ilo_view_cso * const *views =
+      (const struct ilo_view_cso **) vec->view[shader_type].states;
+   struct ilo_state_sampler samplers[ILO_MAX_SAMPLERS];
    uint32_t *sampler_state, *border_color_state;
-   int sampler_count;
+   int sampler_count, i;
    bool emit_border_color = false;
    bool skip = false;
 
@@ -194,16 +190,28 @@ gen6_emit_draw_dynamic_samplers(struct ilo_render *r,
           sampler_count <= Elements(vec->sampler[shader_type].cso));
 
    if (emit_border_color) {
-      int i;
-
       for (i = 0; i < sampler_count; i++) {
-         border_color_state[i] = (samplers[i]) ?
-            gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, samplers[i]) : 0;
+         const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
+
+         border_color_state[i] = (cso) ?
+            gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, &cso->border) : 0;
+      }
+   }
+
+   for (i = 0; i < sampler_count; i++) {
+      const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
+
+      if (cso && views[i]) {
+         samplers[i] = cso->sampler;
+         ilo_state_sampler_set_surface(&samplers[i],
+               r->dev, &views[i]->surface);
+      } else {
+         samplers[i] = vec->disabled_sampler;
       }
    }
 
-   *sampler_state = gen6_SAMPLER_STATE(r->builder,
-         samplers, views, border_color_state, sampler_count);
+   *sampler_state = gen6_SAMPLER_STATE(r->builder, samplers,
+         border_color_state, sampler_count);
 }
 
 static void
@@ -234,13 +242,13 @@ gen6_emit_draw_dynamic_pcb(struct ilo_render *r,
             const struct ilo_cbuf_state *cbuf =
                &vec->cbuf[PIPE_SHADER_VERTEX];
 
-            if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
+            if (cbuf0_size <= cbuf->cso[0].info.size) {
                memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
             } else {
                memcpy(pcb, cbuf->cso[0].user_buffer,
-                     cbuf->cso[0].user_buffer_size);
-               memset(pcb + cbuf->cso[0].user_buffer_size, 0,
-                     cbuf0_size - cbuf->cso[0].user_buffer_size);
+                     cbuf->cso[0].info.size);
+               memset(pcb + cbuf->cso[0].info.size, 0,
+                     cbuf0_size - cbuf->cso[0].info.size);
             }
 
             pcb += cbuf0_size;
@@ -271,13 +279,13 @@ gen6_emit_draw_dynamic_pcb(struct ilo_render *r,
             gen6_push_constant_buffer(r->builder, cbuf0_size, &pcb);
          r->state.wm.PUSH_CONSTANT_BUFFER_size = cbuf0_size;
 
-         if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
+         if (cbuf0_size <= cbuf->cso[0].info.size) {
             memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
          } else {
             memcpy(pcb, cbuf->cso[0].user_buffer,
-                  cbuf->cso[0].user_buffer_size);
-            memset(pcb + cbuf->cso[0].user_buffer_size, 0,
-                  cbuf0_size - cbuf->cso[0].user_buffer_size);
+                  cbuf->cso[0].info.size);
+            memset(pcb + cbuf->cso[0].info.size, 0,
+                  cbuf0_size - cbuf->cso[0].info.size);
          }
 
          session->pcb_fs_changed = true;
@@ -441,18 +449,17 @@ ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render,
 
    if (blitter->uses & ILO_BLITTER_USE_DSA) {
       render->state.DEPTH_STENCIL_STATE =
-         gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->dsa);
+         gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->cc);
    }
 
    if (blitter->uses & ILO_BLITTER_USE_CC) {
       render->state.COLOR_CALC_STATE =
-         gen6_COLOR_CALC_STATE(render->builder, &blitter->cc.stencil_ref,
-               blitter->cc.alpha_ref, &blitter->cc.blend_color);
+         gen6_COLOR_CALC_STATE(render->builder, &blitter->cc);
    }
 
    if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) {
       render->state.CC_VIEWPORT =
-         gen6_CC_VIEWPORT(render->builder, &blitter->viewport, 1);
+         gen6_CC_VIEWPORT(render->builder, &blitter->vp);
    }
 
    assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used +
@@ -466,10 +473,9 @@ gen6_emit_launch_grid_dynamic_samplers(struct ilo_render *r,
 {
    const unsigned shader_type = PIPE_SHADER_COMPUTE;
    const struct ilo_shader_state *cs = vec->cs;
-   const struct ilo_sampler_cso * const *samplers =
-      vec->sampler[shader_type].cso;
-   const struct pipe_sampler_view * const *views =
-      (const struct pipe_sampler_view **) vec->view[shader_type].states;
+   const struct ilo_view_cso * const *views =
+      (const struct ilo_view_cso **) vec->view[shader_type].states;
+   struct ilo_state_sampler samplers[ILO_MAX_SAMPLERS];
    int sampler_count, i;
 
    ILO_DEV_ASSERT(r->dev, 7, 7.5);
@@ -480,11 +486,25 @@ gen6_emit_launch_grid_dynamic_samplers(struct ilo_render *r,
           sampler_count <= Elements(vec->sampler[shader_type].cso));
 
    for (i = 0; i < sampler_count; i++) {
-      r->state.cs.SAMPLER_BORDER_COLOR_STATE[i] = (samplers[i]) ?
-         gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, samplers[i]) : 0;
+      const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
+
+      r->state.cs.SAMPLER_BORDER_COLOR_STATE[i] = (cso) ?
+         gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, &cso->border) : 0;
    }
 
-   r->state.cs.SAMPLER_STATE = gen6_SAMPLER_STATE(r->builder, samplers, views,
+   for (i = 0; i < sampler_count; i++) {
+      const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
+
+      if (cso && views[i]) {
+         samplers[i] = cso->sampler;
+         ilo_state_sampler_set_surface(&samplers[i],
+               r->dev, &views[i]->surface);
+      } else {
+         samplers[i] = vec->disabled_sampler;
+      }
+   }
+
+   r->state.cs.SAMPLER_STATE = gen6_SAMPLER_STATE(r->builder, samplers,
          r->state.cs.SAMPLER_BORDER_COLOR_STATE, sampler_count);
 }
 
@@ -503,20 +523,39 @@ gen6_emit_launch_grid_dynamic_idrt(struct ilo_render *r,
                                    struct ilo_render_launch_grid_session *session)
 {
    const struct ilo_shader_state *cs = vec->cs;
-   struct gen6_idrt_data data;
+   struct ilo_state_compute_interface_info interface;
+   struct ilo_state_compute_info info;
+   uint32_t kernel_offset;
 
    ILO_DEV_ASSERT(r->dev, 7, 7.5);
 
-   memset(&data, 0, sizeof(data));
+   memset(&interface, 0, sizeof(interface));
+
+   interface.sampler_count =
+      ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);
+   interface.surface_count =
+      ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
+   interface.thread_group_size = session->thread_group_size;
+   interface.slm_size =
+      ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_LOCAL_SIZE);
+   interface.curbe_read_length = r->state.cs.PUSH_CONSTANT_BUFFER_size;
+
+   memset(&info, 0, sizeof(info));
+   info.data = session->compute_data;
+   info.data_size = sizeof(session->compute_data);
+   info.interfaces = &interface;
+   info.interface_count = 1;
+   info.cv_urb_alloc_size = r->dev->urb_size;
+   info.curbe_alloc_size = r->state.cs.PUSH_CONSTANT_BUFFER_size;
+
+   ilo_state_compute_init(&session->compute, r->dev, &info);
 
-   data.cs = cs;
-   data.sampler_offset = r->state.cs.SAMPLER_STATE;
-   data.binding_table_offset = r->state.cs.BINDING_TABLE_STATE;
+   kernel_offset = ilo_shader_get_kernel_offset(cs);
 
-   data.curbe_size = r->state.cs.PUSH_CONSTANT_BUFFER_size;
-   data.thread_group_size = session->thread_group_size;
+   session->idrt = gen6_INTERFACE_DESCRIPTOR_DATA(r->builder,
+         &session->compute, &kernel_offset,
+         &r->state.cs.SAMPLER_STATE, &r->state.cs.BINDING_TABLE_STATE);
 
-   session->idrt = gen6_INTERFACE_DESCRIPTOR_DATA(r->builder, &data, 1);
    session->idrt_size = 32;
 }
 
index acfe8be3088a417b2c70c883f8b0e2ee2b98c191..6b1337500438f61619ccb1bd17bf09ed6b10b07d 100644 (file)
@@ -31,6 +31,7 @@
 #include "core/ilo_builder.h"
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_render.h"
+#include "core/ilo_state_raster.h"
 
 #include "ilo_common.h"
 #include "ilo_state.h"
@@ -50,11 +51,7 @@ struct ilo_render {
 
    struct intel_bo *workaround_bo;
 
-   uint32_t sample_pattern_1x;
-   uint32_t sample_pattern_2x;
-   uint32_t sample_pattern_4x;
-   uint32_t sample_pattern_8x[2];
-   uint32_t sample_pattern_16x[4];
+   struct ilo_state_sample_pattern sample_pattern;
 
    bool hw_ctx_changed;
 
@@ -85,10 +82,13 @@ struct ilo_render {
        */
       uint32_t deferred_pipe_control_dw1;
 
-      bool primitive_restart;
       int reduced_prim;
       int so_max_vertices;
 
+      struct ilo_state_urb urb;
+      struct ilo_state_raster rs;
+      struct ilo_state_cc cc;
+
       uint32_t SF_VIEWPORT;
       uint32_t CLIP_VIEWPORT;
       uint32_t SF_CLIP_VIEWPORT; /* GEN7+ */
@@ -142,7 +142,12 @@ struct ilo_render_draw_session {
    int reduced_prim;
 
    bool prim_changed;
-   bool primitive_restart_changed;
+
+   struct ilo_state_urb_delta urb_delta;
+   struct ilo_state_vf_delta vf_delta;
+   struct ilo_state_raster_delta rs_delta;
+   struct ilo_state_viewport_delta vp_delta;
+   struct ilo_state_cc_delta cc_delta;
 
    /* dynamic states */
    bool viewport_changed;
@@ -180,6 +185,9 @@ struct ilo_render_launch_grid_session {
 
    uint32_t idrt;
    int idrt_size;
+
+   uint32_t compute_data[6];
+   struct ilo_state_compute compute;
 };
 
 int
@@ -381,8 +389,7 @@ ilo_render_pipe_control(struct ilo_render *r, uint32_t dw1)
  */
 static inline void
 ilo_render_3dprimitive(struct ilo_render *r,
-                       const struct pipe_draw_info *info,
-                       const struct ilo_ib_state *ib)
+                       const struct gen6_3dprimitive_info *info)
 {
    ILO_DEV_ASSERT(r->dev, 6, 8);
 
@@ -391,9 +398,9 @@ ilo_render_3dprimitive(struct ilo_render *r,
 
    /* 3DPRIMITIVE */
    if (ilo_dev_gen(r->dev) >= ILO_GEN(7))
-      gen7_3DPRIMITIVE(r->builder, info, ib);
+      gen7_3DPRIMITIVE(r->builder, info);
    else
-      gen6_3DPRIMITIVE(r->builder, info, ib);
+      gen6_3DPRIMITIVE(r->builder, info);
 
    r->state.current_pipe_control_dw1 = 0;
    assert(!r->state.deferred_pipe_control_dw1);
index 47f711e7956b7ef0f64f6d5c4683df3271d144ea..c1f759f304377d0827ba1f0d01c9a8398536d965 100644 (file)
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_mi.h"
 #include "core/ilo_builder_render.h"
-#include "util/u_dual_blend.h"
 #include "util/u_prim.h"
 
 #include "ilo_blitter.h"
 #include "ilo_query.h"
+#include "ilo_resource.h"
 #include "ilo_shader.h"
 #include "ilo_state.h"
 #include "ilo_render_gen.h"
@@ -330,64 +330,19 @@ gen6_draw_common_urb(struct ilo_render *r,
                      const struct ilo_state_vector *vec,
                      struct ilo_render_draw_session *session)
 {
-   /* 3DSTATE_URB */
-   if (DIRTY(VE) || DIRTY(VS) || DIRTY(GS)) {
-      const bool gs_active = (vec->gs || (vec->vs &&
-               ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)));
-      int vs_entry_size, gs_entry_size;
-      int vs_total_size, gs_total_size;
-
-      vs_entry_size = (vec->vs) ?
-         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_OUTPUT_COUNT) : 0;
+   const bool gs_active = (vec->gs || (vec->vs &&
+            ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)));
 
-      /*
-       * As indicated by 2e712e41db0c0676e9f30fc73172c0e8de8d84d4, VF and VS
-       * share VUE handles.  The VUE allocation size must be large enough to
-       * store either VF outputs (number of VERTEX_ELEMENTs) and VS outputs.
-       *
-       * I am not sure if the PRM explicitly states that VF and VS share VUE
-       * handles.  But here is a citation that implies so:
-       *
-       * From the Sandy Bridge PRM, volume 2 part 1, page 44:
-       *
-       *     "Once a FF stage that spawn threads has sufficient input to
-       *      initiate a thread, it must guarantee that it is safe to request
-       *      the thread initiation. For all these FF stages, this check is
-       *      based on :
-       *
-       *      - The availability of output URB entries:
-       *        - VS: As the input URB entries are overwritten with the
-       *          VS-generated output data, output URB availability isn't a
-       *          factor."
-       */
-      if (vs_entry_size < vec->ve->count + vec->ve->prepend_nosrc_cso)
-         vs_entry_size = vec->ve->count + vec->ve->prepend_nosrc_cso;
-
-      gs_entry_size = (vec->gs) ?
-         ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_OUTPUT_COUNT) :
-         (gs_active) ? vs_entry_size : 0;
-
-      /* in bytes */
-      vs_entry_size *= sizeof(float) * 4;
-      gs_entry_size *= sizeof(float) * 4;
-      vs_total_size = r->dev->urb_size;
-
-      if (gs_active) {
-         vs_total_size /= 2;
-         gs_total_size = vs_total_size;
-      }
-      else {
-         gs_total_size = 0;
-      }
-
-      gen6_3DSTATE_URB(r->builder, vs_total_size, gs_total_size,
-            vs_entry_size, gs_entry_size);
+   /* 3DSTATE_URB */
+   if (session->urb_delta.dirty & (ILO_STATE_URB_3DSTATE_URB_VS |
+                                   ILO_STATE_URB_3DSTATE_URB_GS)) {
+      gen6_3DSTATE_URB(r->builder, &vec->urb);
 
       if (r->state.gs.active && !gs_active)
          gen6_wa_post_3dstate_urb_no_gs(r);
-
-      r->state.gs.active = gs_active;
    }
+
+   r->state.gs.active = gs_active;
 }
 
 static void
@@ -459,33 +414,30 @@ gen6_draw_vf(struct ilo_render *r,
 {
    if (ilo_dev_gen(r->dev) >= ILO_GEN(7.5)) {
       /* 3DSTATE_INDEX_BUFFER */
-      if (DIRTY(IB) || r->batch_bo_changed) {
-         gen6_3DSTATE_INDEX_BUFFER(r->builder,
-               &vec->ib, false);
-      }
+      if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
+          DIRTY(IB) || r->batch_bo_changed)
+         gen6_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
 
       /* 3DSTATE_VF */
-      if (session->primitive_restart_changed) {
-         gen75_3DSTATE_VF(r->builder, vec->draw->primitive_restart,
-               vec->draw->restart_index);
-      }
-   }
-   else {
+      if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF)
+         gen75_3DSTATE_VF(r->builder, &vec->ve->vf);
+   } else {
       /* 3DSTATE_INDEX_BUFFER */
-      if (DIRTY(IB) || session->primitive_restart_changed ||
-          r->batch_bo_changed) {
-         gen6_3DSTATE_INDEX_BUFFER(r->builder,
-               &vec->ib, vec->draw->primitive_restart);
-      }
+      if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
+          DIRTY(IB) || r->batch_bo_changed)
+         gen6_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
    }
 
    /* 3DSTATE_VERTEX_BUFFERS */
-   if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed)
-      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, vec->ve, &vec->vb);
+   if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
+       DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
+      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
+            vec->vb.vb, vec->ve->vb_count);
+   }
 
    /* 3DSTATE_VERTEX_ELEMENTS */
-   if (DIRTY(VE))
-      gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, vec->ve);
+   if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS)
+      gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf);
 }
 
 void
@@ -516,10 +468,17 @@ gen6_draw_vs(struct ilo_render *r,
 
    /* 3DSTATE_VS */
    if (DIRTY(VS) || r->instruction_bo_changed) {
+      const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->vs);
+      const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->vs);
+
       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
          gen6_wa_pre_3dstate_vs_toggle(r);
 
-      gen6_3DSTATE_VS(r->builder, vec->vs);
+      if (ilo_dev_gen(r->dev) == ILO_GEN(6) &&
+          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO))
+         gen6_3DSTATE_VS(r->builder, &cso->vs_sol.vs, kernel_offset);
+      else
+         gen6_3DSTATE_VS(r->builder, &cso->vs, kernel_offset);
    }
 }
 
@@ -535,14 +494,39 @@ gen6_draw_gs(struct ilo_render *r,
    /* 3DSTATE_GS */
    if (DIRTY(GS) || DIRTY(VS) ||
        session->prim_changed || r->instruction_bo_changed) {
+      const union ilo_shader_cso *cso;
+      uint32_t kernel_offset;
+
       if (vec->gs) {
-         gen6_3DSTATE_GS(r->builder, vec->gs);
-      } else if (vec->vs &&
+         cso = ilo_shader_get_kernel_cso(vec->gs);
+         kernel_offset = ilo_shader_get_kernel_offset(vec->gs);
+
+         gen6_3DSTATE_GS(r->builder, &cso->gs, kernel_offset);
+      } else if (ilo_dev_gen(r->dev) == ILO_GEN(6) &&
             ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)) {
-         const int verts_per_prim = u_vertices_per_prim(session->reduced_prim);
-         gen6_so_3DSTATE_GS(r->builder, vec->vs, verts_per_prim);
+         const int verts_per_prim =
+            u_vertices_per_prim(session->reduced_prim);
+         enum ilo_kernel_param param;
+
+         switch (verts_per_prim) {
+         case 1:
+            param = ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET;
+            break;
+         case 2:
+            param = ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET;
+            break;
+         default:
+            param = ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET;
+            break;
+         }
+
+         cso = ilo_shader_get_kernel_cso(vec->vs);
+         kernel_offset = ilo_shader_get_kernel_offset(vec->vs) +
+            ilo_shader_get_kernel_param(vec->vs, param);
+
+         gen6_3DSTATE_GS(r->builder, &cso->vs_sol.sol, kernel_offset);
       } else {
-         gen6_disable_3DSTATE_GS(r->builder);
+         gen6_3DSTATE_GS(r->builder, &vec->disabled_gs, 0);
       }
    }
 }
@@ -633,30 +617,8 @@ gen6_draw_clip(struct ilo_render *r,
                struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_CLIP */
-   if (DIRTY(RASTERIZER) || DIRTY(FS) || DIRTY(VIEWPORT) || DIRTY(FB)) {
-      bool enable_guardband = true;
-      unsigned i;
-
-      /*
-       * Gen8+ has viewport extent test.  Guard band test can be enabled on
-       * prior Gens only when the viewport is larger than the framebuffer,
-       * unless we emulate viewport extent test on them.
-       */
-      if (ilo_dev_gen(r->dev) < ILO_GEN(8)) {
-         for (i = 0; i < vec->viewport.count; i++) {
-            const struct ilo_viewport_cso *vp = &vec->viewport.cso[i];
-
-            if (vp->min_x > 0.0f || vp->max_x < vec->fb.state.width ||
-                vp->min_y > 0.0f || vp->max_y < vec->fb.state.height) {
-               enable_guardband = false;
-               break;
-            }
-         }
-      }
-
-      gen6_3DSTATE_CLIP(r->builder, vec->rasterizer,
-            vec->fs, enable_guardband, 1);
-   }
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_CLIP)
+      gen6_3DSTATE_CLIP(r->builder, &vec->rasterizer->rs);
 }
 
 static void
@@ -665,9 +627,9 @@ gen6_draw_sf(struct ilo_render *r,
              struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_SF */
-   if (DIRTY(RASTERIZER) || DIRTY(FS) || DIRTY(FB)) {
-      gen6_3DSTATE_SF(r->builder, vec->rasterizer, vec->fs,
-            vec->fb.num_samples);
+   if ((session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF) || DIRTY(FS)) {
+      const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
+      gen6_3DSTATE_SF(r->builder, &vec->rasterizer->rs, sbe);
    }
 }
 
@@ -700,17 +662,17 @@ gen6_draw_wm(struct ilo_render *r,
    }
 
    /* 3DSTATE_WM */
-   if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) ||
-       DIRTY(RASTERIZER) || r->instruction_bo_changed) {
-      const bool dual_blend = vec->blend->dual_blend;
-      const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
-                                vec->blend->alpha_to_coverage);
+   if (DIRTY(FS) ||
+       (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM) ||
+       r->instruction_bo_changed) {
+      const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
+      const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
 
       if (ilo_dev_gen(r->dev) == ILO_GEN(6) && r->hw_ctx_changed)
          gen6_wa_pre_3dstate_wm_max_threads(r);
 
-      gen6_3DSTATE_WM(r->builder, vec->fs,
-            vec->rasterizer, dual_blend, cc_may_kill);
+      gen6_3DSTATE_WM(r->builder, &vec->rasterizer->rs,
+            &cso->ps, kernel_offset);
    }
 }
 
@@ -719,25 +681,23 @@ gen6_draw_wm_multisample(struct ilo_render *r,
                          const struct ilo_state_vector *vec,
                          struct ilo_render_draw_session *session)
 {
-   /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
-   if (DIRTY(SAMPLE_MASK) || DIRTY(FB)) {
-      const uint32_t *pattern;
-
-      pattern = (vec->fb.num_samples > 1) ?
-         &r->sample_pattern_4x : &r->sample_pattern_1x;
+   /* 3DSTATE_MULTISAMPLE */
+   if (DIRTY(FB) || (session->rs_delta.dirty &
+            ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
+      const uint8_t sample_count = (vec->fb.num_samples > 1) ? 4 : 1;
 
       if (ilo_dev_gen(r->dev) == ILO_GEN(6)) {
          gen6_wa_pre_non_pipelined(r);
          gen6_wa_pre_3dstate_multisample(r);
       }
 
-      gen6_3DSTATE_MULTISAMPLE(r->builder,
-            vec->fb.num_samples, pattern,
-            vec->rasterizer->state.half_pixel_center);
-
-      gen6_3DSTATE_SAMPLE_MASK(r->builder,
-            (vec->fb.num_samples > 1) ? vec->sample_mask : 0x1);
+      gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
+            &r->sample_pattern, sample_count);
    }
+
+   /* 3DSTATE_SAMPLE_MASK */
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
+      gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
 }
 
 static void
@@ -747,7 +707,7 @@ gen6_draw_wm_depth(struct ilo_render *r,
 {
    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    if (DIRTY(FB) || r->batch_bo_changed) {
-      const struct ilo_zs_surface *zs;
+      const struct ilo_state_zs *zs;
       uint32_t clear_params;
 
       if (vec->fb.state.zsbuf) {
@@ -772,7 +732,7 @@ gen6_draw_wm_depth(struct ilo_render *r,
          gen6_wa_pre_depth(r);
       }
 
-      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs, false);
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
       gen6_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
@@ -790,10 +750,8 @@ gen6_draw_wm_raster(struct ilo_render *r,
       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
          gen6_wa_pre_non_pipelined(r);
 
-      gen6_3DSTATE_POLY_STIPPLE_PATTERN(r->builder,
-            &vec->poly_stipple);
-
-      gen6_3DSTATE_POLY_STIPPLE_OFFSET(r->builder, 0, 0);
+      gen6_3DSTATE_POLY_STIPPLE_PATTERN(r->builder, &vec->poly_stipple);
+      gen6_3DSTATE_POLY_STIPPLE_OFFSET(r->builder, &vec->poly_stipple);
    }
 
    /* 3DSTATE_LINE_STIPPLE */
@@ -801,17 +759,16 @@ gen6_draw_wm_raster(struct ilo_render *r,
       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
          gen6_wa_pre_non_pipelined(r);
 
-      gen6_3DSTATE_LINE_STIPPLE(r->builder,
-            vec->rasterizer->state.line_stipple_pattern,
-            vec->rasterizer->state.line_stipple_factor + 1);
+      gen6_3DSTATE_LINE_STIPPLE(r->builder, &vec->line_stipple);
    }
 
    /* 3DSTATE_AA_LINE_PARAMETERS */
-   if (DIRTY(RASTERIZER) && vec->rasterizer->state.line_smooth) {
+   if (session->rs_delta.dirty &
+         ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS) {
       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
          gen6_wa_pre_non_pipelined(r);
 
-      gen6_3DSTATE_AA_LINE_PARAMETERS(r->builder);
+      gen6_3DSTATE_AA_LINE_PARAMETERS(r->builder, &vec->rasterizer->rs);
    }
 }
 
@@ -849,7 +806,7 @@ ilo_render_emit_draw_commands_gen6(struct ilo_render *render,
    gen6_draw_sf_rect(render, vec, session);
    gen6_draw_vf(render, vec, session);
 
-   ilo_render_3dprimitive(render, vec->draw, &vec->ib);
+   ilo_render_3dprimitive(render, &vec->draw_info);
 }
 
 static void
@@ -860,40 +817,23 @@ gen6_rectlist_vs_to_sf(struct ilo_render *r,
    gen6_wa_post_3dstate_constant_vs(r);
 
    gen6_wa_pre_3dstate_vs_toggle(r);
-   gen6_disable_3DSTATE_VS(r->builder);
+   gen6_3DSTATE_VS(r->builder, &blitter->vs, 0);
 
    gen6_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);
-   gen6_disable_3DSTATE_GS(r->builder);
+   gen6_3DSTATE_GS(r->builder, &blitter->gs, 0);
 
-   gen6_disable_3DSTATE_CLIP(r->builder);
-   gen6_3DSTATE_SF(r->builder, NULL, NULL, blitter->fb.num_samples);
+   gen6_3DSTATE_CLIP(r->builder, &blitter->fb.rs);
+   gen6_3DSTATE_SF(r->builder, &blitter->fb.rs, &blitter->sbe);
 }
 
 static void
 gen6_rectlist_wm(struct ilo_render *r,
                  const struct ilo_blitter *blitter)
 {
-   uint32_t hiz_op;
-
-   switch (blitter->op) {
-   case ILO_BLITTER_RECTLIST_CLEAR_ZS:
-      hiz_op = GEN6_WM_DW4_DEPTH_CLEAR;
-      break;
-   case ILO_BLITTER_RECTLIST_RESOLVE_Z:
-      hiz_op = GEN6_WM_DW4_DEPTH_RESOLVE;
-      break;
-   case ILO_BLITTER_RECTLIST_RESOLVE_HIZ:
-      hiz_op = GEN6_WM_DW4_HIZ_RESOLVE;
-      break;
-   default:
-      hiz_op = 0;
-      break;
-   }
-
    gen6_3DSTATE_CONSTANT_PS(r->builder, NULL, NULL, 0);
 
    gen6_wa_pre_3dstate_wm_max_threads(r);
-   gen6_hiz_3DSTATE_WM(r->builder, hiz_op);
+   gen6_3DSTATE_WM(r->builder, &blitter->fb.rs, &blitter->ps, 0);
 }
 
 static void
@@ -903,10 +843,8 @@ gen6_rectlist_wm_depth(struct ilo_render *r,
    gen6_wa_pre_depth(r);
 
    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
-                        ILO_BLITTER_USE_FB_STENCIL)) {
-      gen6_3DSTATE_DEPTH_BUFFER(r->builder,
-            &blitter->fb.dst.u.zs, true);
-   }
+                        ILO_BLITTER_USE_FB_STENCIL))
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
 
    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
@@ -926,16 +864,12 @@ static void
 gen6_rectlist_wm_multisample(struct ilo_render *r,
                              const struct ilo_blitter *blitter)
 {
-   const uint32_t *pattern = (blitter->fb.num_samples > 1) ?
-      &r->sample_pattern_4x : &r->sample_pattern_1x;
+   const uint8_t sample_count = (blitter->fb.num_samples > 1) ? 4 : 1;
 
    gen6_wa_pre_3dstate_multisample(r);
 
-   gen6_3DSTATE_MULTISAMPLE(r->builder, blitter->fb.num_samples,
-         pattern, true);
-
-   gen6_3DSTATE_SAMPLE_MASK(r->builder,
-         (1 << blitter->fb.num_samples) - 1);
+   gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs, &r->sample_pattern, sample_count);
+   gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
 }
 
 int
@@ -964,11 +898,9 @@ ilo_render_emit_rectlist_commands_gen6(struct ilo_render *r,
          session->vb_start, session->vb_end,
          sizeof(blitter->vertices[0]));
 
-   gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->ve);
+   gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf);
 
-   gen6_3DSTATE_URB(r->builder, r->dev->urb_size, 0,
-         (blitter->ve.count + blitter->ve.prepend_nosrc_cso) * 4 * sizeof(float),
-         0);
+   gen6_3DSTATE_URB(r->builder, &blitter->urb);
 
    if (r->state.gs.active) {
       gen6_wa_post_3dstate_urb_no_gs(r);
@@ -994,7 +926,7 @@ ilo_render_emit_rectlist_commands_gen6(struct ilo_render *r,
    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
          blitter->fb.width, blitter->fb.height);
 
-   ilo_render_3dprimitive(r, &blitter->draw, NULL);
+   ilo_render_3dprimitive(r, &blitter->draw_info);
 }
 
 int
index 07fe7c8353605fef6e278df76acb4a32d8592321..6623a8bcb43616eaed9af1dbf201f43072ec365a 100644 (file)
@@ -28,9 +28,9 @@
 #include "genhw/genhw.h"
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_render.h"
-#include "util/u_dual_blend.h"
 
 #include "ilo_blitter.h"
+#include "ilo_resource.h"
 #include "ilo_shader.h"
 #include "ilo_state.h"
 #include "ilo_render_gen.h"
@@ -201,40 +201,17 @@ gen7_draw_common_urb(struct ilo_render *r,
                      struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_URB_{VS,GS,HS,DS} */
-   if (DIRTY(VE) || DIRTY(VS)) {
-      /* the first 16KB are reserved for VS and PS PCBs */
-      const int offset =
-         (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
-          (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
-          32768 : 16384;
-      int vs_entry_size, vs_total_size;
-
-      vs_entry_size = (vec->vs) ?
-         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_OUTPUT_COUNT) : 0;
-
-      /*
-       * From the Ivy Bridge PRM, volume 2 part 1, page 35:
-       *
-       *     "Programming Restriction: As the VS URB entry serves as both the
-       *      per-vertex input and output of the VS shader, the VS URB
-       *      Allocation Size must be sized to the maximum of the vertex input
-       *      and output structures."
-       */
-      if (vs_entry_size < vec->ve->count + vec->ve->prepend_nosrc_cso)
-         vs_entry_size = vec->ve->count + vec->ve->prepend_nosrc_cso;
-
-      vs_entry_size *= sizeof(float) * 4;
-      vs_total_size = r->dev->urb_size - offset;
-
+   if (session->urb_delta.dirty & (ILO_STATE_URB_3DSTATE_URB_VS |
+                                   ILO_STATE_URB_3DSTATE_URB_HS |
+                                   ILO_STATE_URB_3DSTATE_URB_DS |
+                                   ILO_STATE_URB_3DSTATE_URB_GS)) {
       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
          gen7_wa_pre_vs(r);
 
-      gen7_3DSTATE_URB_VS(r->builder,
-            offset, vs_total_size, vs_entry_size);
-
-      gen7_3DSTATE_URB_GS(r->builder, offset, 0, 0);
-      gen7_3DSTATE_URB_HS(r->builder, offset, 0, 0);
-      gen7_3DSTATE_URB_DS(r->builder, offset, 0, 0);
+      gen7_3DSTATE_URB_VS(r->builder, &vec->urb);
+      gen7_3DSTATE_URB_GS(r->builder, &vec->urb);
+      gen7_3DSTATE_URB_HS(r->builder, &vec->urb);
+      gen7_3DSTATE_URB_DS(r->builder, &vec->urb);
    }
 }
 
@@ -244,22 +221,15 @@ gen7_draw_common_pcb_alloc(struct ilo_render *r,
                            struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_PUSH_CONSTANT_ALLOC_{VS,PS} */
-   if (r->hw_ctx_changed) {
-      /*
-       * Push constant buffers are only allowed to take up at most the first
-       * 16KB of the URB.  Split the space evenly for VS and FS.
-       */
-      const int max_size =
-         (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
-          (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
-          32768 : 16384;
-      const int size = max_size / 2;
-      int offset = 0;
-
-      gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, offset, size);
-      offset += size;
-
-      gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, offset, size);
+   if (session->urb_delta.dirty &
+         (ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
+          ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
+          ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
+          ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
+          ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS)) {
+      gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, &vec->urb);
+      gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(r->builder, &vec->urb);
+      gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, &vec->urb);
 
       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
          gen7_wa_post_3dstate_push_constant_alloc_ps(r);
@@ -344,14 +314,14 @@ gen7_draw_vs(struct ilo_render *r,
    }
 
    /* 3DSTATE_VS */
-   if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
-      if (emit_3dstate_vs || DIRTY(RASTERIZER)) {
-         gen8_3DSTATE_VS(r->builder, vec->vs,
-               vec->rasterizer->state.clip_plane_enable);
-      }
-   } else {
-      if (emit_3dstate_vs)
-         gen6_3DSTATE_VS(r->builder, vec->vs);
+   if (emit_3dstate_vs) {
+      const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->vs);
+      const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->vs);
+
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         gen8_3DSTATE_VS(r->builder, &cso->vs, kernel_offset);
+      else
+         gen6_3DSTATE_VS(r->builder, &cso->vs, kernel_offset);
    }
 }
 
@@ -362,8 +332,15 @@ gen7_draw_hs(struct ilo_render *r,
 {
    /* 3DSTATE_CONSTANT_HS and 3DSTATE_HS */
    if (r->hw_ctx_changed) {
+      const struct ilo_state_hs *hs = &vec->disabled_hs;
+      const uint32_t kernel_offset = 0;
+
       gen7_3DSTATE_CONSTANT_HS(r->builder, 0, 0, 0);
-      gen7_disable_3DSTATE_HS(r->builder);
+
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         gen8_3DSTATE_HS(r->builder, hs, kernel_offset);
+      else
+         gen7_3DSTATE_HS(r->builder, hs, kernel_offset);
    }
 
    /* 3DSTATE_BINDING_TABLE_POINTERS_HS */
@@ -377,8 +354,10 @@ gen7_draw_te(struct ilo_render *r,
              struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_TE */
-   if (r->hw_ctx_changed)
-      gen7_3DSTATE_TE(r->builder);
+   if (r->hw_ctx_changed) {
+      const struct ilo_state_ds *ds = &vec->disabled_ds;
+      gen7_3DSTATE_TE(r->builder, ds);
+   }
 }
 
 void
@@ -388,8 +367,15 @@ gen7_draw_ds(struct ilo_render *r,
 {
    /* 3DSTATE_CONSTANT_DS and 3DSTATE_DS */
    if (r->hw_ctx_changed) {
+      const struct ilo_state_ds *ds = &vec->disabled_ds;
+      const uint32_t kernel_offset = 0;
+
       gen7_3DSTATE_CONSTANT_DS(r->builder, 0, 0, 0);
-      gen7_disable_3DSTATE_DS(r->builder);
+
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         gen8_3DSTATE_DS(r->builder, ds, kernel_offset);
+      else
+         gen7_3DSTATE_DS(r->builder, ds, kernel_offset);
    }
 
    /* 3DSTATE_BINDING_TABLE_POINTERS_DS */
@@ -405,8 +391,15 @@ gen7_draw_gs(struct ilo_render *r,
 {
    /* 3DSTATE_CONSTANT_GS and 3DSTATE_GS */
    if (r->hw_ctx_changed) {
+      const struct ilo_state_gs *gs = &vec->disabled_gs;
+      const uint32_t kernel_offset = 0;
+
       gen7_3DSTATE_CONSTANT_GS(r->builder, 0, 0, 0);
-      gen7_disable_3DSTATE_GS(r->builder);
+
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         gen8_3DSTATE_GS(r->builder, gs, kernel_offset);
+      else
+         gen7_3DSTATE_GS(r->builder, gs, kernel_offset);
    }
 
    /* 3DSTATE_BINDING_TABLE_POINTERS_GS */
@@ -421,7 +414,7 @@ gen7_draw_sol(struct ilo_render *r,
               const struct ilo_state_vector *vec,
               struct ilo_render_draw_session *session)
 {
-   const struct pipe_stream_output_info *so_info;
+   const struct ilo_state_sol *sol;
    const struct ilo_shader_state *shader;
    bool dirty_sh = false;
 
@@ -434,41 +427,54 @@ gen7_draw_sol(struct ilo_render *r,
       dirty_sh = DIRTY(VS);
    }
 
-   so_info = ilo_shader_get_kernel_so_info(shader);
+   sol = ilo_shader_get_kernel_sol(shader);
 
    /* 3DSTATE_SO_BUFFER */
    if ((DIRTY(SO) || dirty_sh || r->batch_bo_changed) &&
        vec->so.enabled) {
       int i;
 
-      for (i = 0; i < vec->so.count; i++) {
-         const int stride = so_info->stride[i] * 4; /* in bytes */
-
-         gen7_3DSTATE_SO_BUFFER(r->builder, i, stride, vec->so.states[i]);
+      for (i = 0; i < ILO_STATE_SOL_MAX_BUFFER_COUNT; i++) {
+         const struct pipe_stream_output_target *target =
+            (i < vec->so.count && vec->so.states[i]) ?
+            vec->so.states[i] : NULL;
+         const struct ilo_state_sol_buffer *sb = (target) ?
+            &((const struct ilo_stream_output_target *) target)->sb :
+            &vec->so.dummy_sb;
+
+         if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+            gen8_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
+         else
+            gen7_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
       }
-
-      for (; i < 4; i++)
-         gen7_disable_3DSTATE_SO_BUFFER(r->builder, i);
    }
 
    /* 3DSTATE_SO_DECL_LIST */
    if (dirty_sh && vec->so.enabled)
-      gen7_3DSTATE_SO_DECL_LIST(r->builder, so_info);
-
-   /* 3DSTATE_STREAMOUT */
-   if (DIRTY(SO) || DIRTY(RASTERIZER) || dirty_sh) {
-      const int output_count = ilo_shader_get_kernel_param(shader,
-            ILO_KERNEL_OUTPUT_COUNT);
-      int buf_strides[4] = { 0, 0, 0, 0 };
-      int i;
+      gen7_3DSTATE_SO_DECL_LIST(r->builder, sol);
 
-      for (i = 0; i < vec->so.count; i++)
-         buf_strides[i] = so_info->stride[i] * 4;
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 196-197:
+    *
+    *     "Anytime the SOL unit MMIO registers or non-pipeline state are
+    *      written, the SOL unit needs to receive a pipeline state update with
+    *      SOL unit dirty state for information programmed in MMIO/NP to get
+    *      loaded into the SOL unit.
+    *
+    *      The SOL unit incorrectly double buffers MMIO/NP registers and only
+    *      moves them into the design for usage when control topology is
+    *      received with the SOL unit dirty state.
+    *
+    *      If the state does not change, need to resend the same state.
+    *
+    *      Because of corruption, software must flush the whole fixed function
+    *      pipeline when 3DSTATE_STREAMOUT changes state."
+    *
+    * The first and fourth paragraphs are gone on Gen7.5+.
+    */
 
-      gen7_3DSTATE_STREAMOUT(r->builder, 0,
-            vec->rasterizer->state.rasterizer_discard,
-            output_count, buf_strides);
-   }
+   /* 3DSTATE_STREAMOUT */
+   gen7_3DSTATE_STREAMOUT(r->builder, sol);
 }
 
 static void
@@ -477,22 +483,17 @@ gen7_draw_sf(struct ilo_render *r,
              struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_SBE */
-   if (DIRTY(RASTERIZER) || DIRTY(FS)) {
-      gen7_3DSTATE_SBE(r->builder, vec->fs, (vec->rasterizer) ?
-            vec->rasterizer->state.sprite_coord_mode : 0);
+   if (DIRTY(FS)) {
+      const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
+      gen7_3DSTATE_SBE(r->builder, sbe);
    }
 
    /* 3DSTATE_SF */
-   if (DIRTY(RASTERIZER) || DIRTY(FB)) {
-      struct pipe_surface *zs = vec->fb.state.zsbuf;
-
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF) {
       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
          gen7_wa_pre_3dstate_sf_depth_bias(r);
 
-      gen7_3DSTATE_SF(r->builder,
-            (vec->rasterizer) ? &vec->rasterizer->sf : NULL,
-            (zs) ? zs->format : PIPE_FORMAT_NONE,
-            vec->fb.num_samples);
+      gen7_3DSTATE_SF(r->builder, &vec->rasterizer->rs);
    }
 }
 
@@ -501,13 +502,12 @@ gen7_draw_wm(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
 {
-   /* 3DSTATE_WM */
-   if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) || DIRTY(RASTERIZER)) {
-      const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
-                                vec->blend->alpha_to_coverage);
+   const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
+   const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
 
-      gen7_3DSTATE_WM(r->builder, vec->fs, vec->rasterizer, cc_may_kill);
-   }
+   /* 3DSTATE_WM */
+   if (DIRTY(FS) || (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM))
+      gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, &cso->ps);
 
    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
    if (session->binding_table_fs_changed) {
@@ -530,13 +530,11 @@ gen7_draw_wm(struct ilo_render *r,
    }
 
    /* 3DSTATE_PS */
-   if (DIRTY(FS) || DIRTY(BLEND) || r->instruction_bo_changed) {
-      const bool dual_blend = vec->blend->dual_blend;
-
+   if (DIRTY(FS) || r->instruction_bo_changed) {
       if (r->hw_ctx_changed)
          gen7_wa_pre_3dstate_ps_max_threads(r);
 
-      gen7_3DSTATE_PS(r->builder, vec->fs, dual_blend);
+      gen7_3DSTATE_PS(r->builder, &cso->ps, kernel_offset);
    }
 
    /* 3DSTATE_SCISSOR_STATE_POINTERS */
@@ -569,7 +567,7 @@ gen7_draw_wm(struct ilo_render *r,
 
    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    if (DIRTY(FB) || r->batch_bo_changed) {
-      const struct ilo_zs_surface *zs;
+      const struct ilo_state_zs *zs;
       uint32_t clear_params;
 
       if (vec->fb.state.zsbuf) {
@@ -588,7 +586,7 @@ gen7_draw_wm(struct ilo_render *r,
          clear_params = 0;
       }
 
-      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs, false);
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
       gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
@@ -600,24 +598,21 @@ gen7_draw_wm_multisample(struct ilo_render *r,
                          const struct ilo_state_vector *vec,
                          struct ilo_render_draw_session *session)
 {
-   /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
-   if (DIRTY(SAMPLE_MASK) || DIRTY(FB)) {
-      const uint32_t *pattern;
+   /* 3DSTATE_MULTISAMPLE */
+   if (DIRTY(FB) || (session->rs_delta.dirty &
+            ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
+      const uint8_t sample_count = (vec->fb.num_samples > 4) ? 8 :
+                                   (vec->fb.num_samples > 1) ? 4 : 1;
 
       gen7_wa_pre_3dstate_multisample(r);
 
-      pattern = (vec->fb.num_samples > 4) ? r->sample_pattern_8x :
-                (vec->fb.num_samples > 1) ? &r->sample_pattern_4x :
-                &r->sample_pattern_1x;
-
-      gen6_3DSTATE_MULTISAMPLE(r->builder,
-            vec->fb.num_samples, pattern,
-            vec->rasterizer->state.half_pixel_center);
-
-      gen7_3DSTATE_SAMPLE_MASK(r->builder,
-            (vec->fb.num_samples > 1) ? vec->sample_mask : 0x1,
-            vec->fb.num_samples);
+      gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
+            &r->sample_pattern, sample_count);
    }
+
+   /* 3DSTATE_SAMPLE_MASK */
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
+      gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
 }
 
 void
@@ -654,28 +649,15 @@ ilo_render_emit_draw_commands_gen7(struct ilo_render *render,
    gen6_draw_sf_rect(render, vec, session);
    gen6_draw_vf(render, vec, session);
 
-   ilo_render_3dprimitive(render, vec->draw, &vec->ib);
+   ilo_render_3dprimitive(render, &vec->draw_info);
 }
 
 static void
 gen7_rectlist_pcb_alloc(struct ilo_render *r,
                         const struct ilo_blitter *blitter)
 {
-   /*
-    * Push constant buffers are only allowed to take up at most the first
-    * 16KB of the URB.  Split the space evenly for VS and FS.
-    */
-   const int max_size =
-      (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
-       (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
-       32768 : 16384;
-   const int size = max_size / 2;
-   int offset = 0;
-
-   gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, offset, size);
-   offset += size;
-
-   gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, offset, size);
+   gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, &blitter->urb);
+   gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, &blitter->urb);
 
    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
       gen7_wa_post_3dstate_push_constant_alloc_ps(r);
@@ -685,19 +667,10 @@ static void
 gen7_rectlist_urb(struct ilo_render *r,
                   const struct ilo_blitter *blitter)
 {
-   /* the first 16KB are reserved for VS and PS PCBs */
-   const int offset =
-      (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
-       (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
-       32768 : 16384;
-
-   gen7_3DSTATE_URB_VS(r->builder, offset, r->dev->urb_size - offset,
-         (blitter->ve.count + blitter->ve.prepend_nosrc_cso) *
-         4 * sizeof(float));
-
-   gen7_3DSTATE_URB_GS(r->builder, offset, 0, 0);
-   gen7_3DSTATE_URB_HS(r->builder, offset, 0, 0);
-   gen7_3DSTATE_URB_DS(r->builder, offset, 0, 0);
+   gen7_3DSTATE_URB_VS(r->builder, &blitter->urb);
+   gen7_3DSTATE_URB_GS(r->builder, &blitter->urb);
+   gen7_3DSTATE_URB_HS(r->builder, &blitter->urb);
+   gen7_3DSTATE_URB_DS(r->builder, &blitter->urb);
 }
 
 static void
@@ -705,58 +678,40 @@ gen7_rectlist_vs_to_sf(struct ilo_render *r,
                        const struct ilo_blitter *blitter)
 {
    gen7_3DSTATE_CONSTANT_VS(r->builder, NULL, NULL, 0);
-   gen6_disable_3DSTATE_VS(r->builder);
+   gen6_3DSTATE_VS(r->builder, &blitter->vs, 0);
 
    gen7_3DSTATE_CONSTANT_HS(r->builder, NULL, NULL, 0);
-   gen7_disable_3DSTATE_HS(r->builder);
+   gen7_3DSTATE_HS(r->builder, &blitter->hs, 0);
 
-   gen7_3DSTATE_TE(r->builder);
+   gen7_3DSTATE_TE(r->builder, &blitter->ds);
 
    gen7_3DSTATE_CONSTANT_DS(r->builder, NULL, NULL, 0);
-   gen7_disable_3DSTATE_DS(r->builder);
+   gen7_3DSTATE_DS(r->builder, &blitter->ds, 0);
 
    gen7_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);
-   gen7_disable_3DSTATE_GS(r->builder);
+   gen7_3DSTATE_GS(r->builder, &blitter->gs, 0);
 
-   gen7_3DSTATE_STREAMOUT(r->builder, 0, false, 0x0, 0);
+   gen7_3DSTATE_STREAMOUT(r->builder, &blitter->sol);
 
-   gen6_disable_3DSTATE_CLIP(r->builder);
+   gen6_3DSTATE_CLIP(r->builder, &blitter->fb.rs);
 
    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
       gen7_wa_pre_3dstate_sf_depth_bias(r);
 
-   gen7_3DSTATE_SF(r->builder, NULL, blitter->fb.dst.base.format,
-         blitter->fb.num_samples);
-   gen7_3DSTATE_SBE(r->builder, NULL, 0);
+   gen7_3DSTATE_SF(r->builder, &blitter->fb.rs);
+   gen7_3DSTATE_SBE(r->builder, &blitter->sbe);
 }
 
 static void
 gen7_rectlist_wm(struct ilo_render *r,
                  const struct ilo_blitter *blitter)
 {
-   uint32_t hiz_op;
-
-   switch (blitter->op) {
-   case ILO_BLITTER_RECTLIST_CLEAR_ZS:
-      hiz_op = GEN7_WM_DW1_DEPTH_CLEAR;
-      break;
-   case ILO_BLITTER_RECTLIST_RESOLVE_Z:
-      hiz_op = GEN7_WM_DW1_DEPTH_RESOLVE;
-      break;
-   case ILO_BLITTER_RECTLIST_RESOLVE_HIZ:
-      hiz_op = GEN7_WM_DW1_HIZ_RESOLVE;
-      break;
-   default:
-      hiz_op = 0;
-      break;
-   }
-
-   gen7_hiz_3DSTATE_WM(r->builder, hiz_op);
+   gen7_3DSTATE_WM(r->builder, &blitter->fb.rs, &blitter->ps);
 
    gen7_3DSTATE_CONSTANT_PS(r->builder, NULL, NULL, 0);
 
    gen7_wa_pre_3dstate_ps_max_threads(r);
-   gen7_disable_3DSTATE_PS(r->builder);
+   gen7_3DSTATE_PS(r->builder, &blitter->ps, 0);
 }
 
 static void
@@ -766,10 +721,8 @@ gen7_rectlist_wm_depth(struct ilo_render *r,
    gen7_wa_pre_depth(r);
 
    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
-                        ILO_BLITTER_USE_FB_STENCIL)) {
-      gen6_3DSTATE_DEPTH_BUFFER(r->builder,
-            &blitter->fb.dst.u.zs, true);
-   }
+                        ILO_BLITTER_USE_FB_STENCIL))
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
 
    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
@@ -789,18 +742,15 @@ static void
 gen7_rectlist_wm_multisample(struct ilo_render *r,
                              const struct ilo_blitter *blitter)
 {
-   const uint32_t *pattern =
-      (blitter->fb.num_samples > 4) ? r->sample_pattern_8x :
-      (blitter->fb.num_samples > 1) ? &r->sample_pattern_4x :
-      &r->sample_pattern_1x;
+   const uint8_t sample_count = (blitter->fb.num_samples > 4) ? 8 :
+                                (blitter->fb.num_samples > 1) ? 4 : 1;
 
    gen7_wa_pre_3dstate_multisample(r);
 
-   gen6_3DSTATE_MULTISAMPLE(r->builder, blitter->fb.num_samples,
-         pattern, true);
+   gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs,
+         &r->sample_pattern, sample_count);
 
-   gen7_3DSTATE_SAMPLE_MASK(r->builder,
-         (1 << blitter->fb.num_samples) - 1, blitter->fb.num_samples);
+   gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
 }
 
 void
@@ -818,7 +768,7 @@ ilo_render_emit_rectlist_commands_gen7(struct ilo_render *r,
          session->vb_start, session->vb_end,
          sizeof(blitter->vertices[0]));
 
-   gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->ve);
+   gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf);
 
    gen7_rectlist_pcb_alloc(r, blitter);
 
@@ -854,7 +804,7 @@ ilo_render_emit_rectlist_commands_gen7(struct ilo_render *r,
    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
       gen7_wa_post_ps_and_later(r);
 
-   ilo_render_3dprimitive(r, &blitter->draw, NULL);
+   ilo_render_3dprimitive(r, &blitter->draw_info);
 }
 
 int
index 715b93611f1b63ea3867a1d8694758fc36bac889..65494b4058a19689700b9126e189bb5fd9ab247a 100644 (file)
@@ -28,9 +28,9 @@
 #include "genhw/genhw.h"
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_render.h"
-#include "util/u_dual_blend.h"
 
 #include "ilo_blitter.h"
+#include "ilo_resource.h"
 #include "ilo_shader.h"
 #include "ilo_state.h"
 #include "ilo_render_gen.h"
@@ -66,26 +66,20 @@ gen8_draw_sf(struct ilo_render *r,
              struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_RASTER */
-   if (DIRTY(RASTERIZER)) {
-      gen8_3DSTATE_RASTER(r->builder, (vec->rasterizer) ?
-            &vec->rasterizer->sf : NULL);
-   }
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_RASTER)
+      gen8_3DSTATE_RASTER(r->builder, &vec->rasterizer->rs);
 
-   /* 3DSTATE_SBE */
-   if (DIRTY(RASTERIZER) || DIRTY(FS)) {
-      gen8_3DSTATE_SBE(r->builder, vec->fs, (vec->rasterizer) ?
-            vec->rasterizer->state.sprite_coord_mode : 0);
-   }
+   /* 3DSTATE_SBE and 3DSTATE_SBE_SWIZ */
+   if (DIRTY(FS)) {
+      const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
 
-   /* 3DSTATE_SBE_SWIZ */
-   if (DIRTY(FS))
-      gen8_3DSTATE_SBE_SWIZ(r->builder, vec->fs);
+      gen8_3DSTATE_SBE(r->builder, sbe);
+      gen8_3DSTATE_SBE_SWIZ(r->builder, sbe);
+   }
 
    /* 3DSTATE_SF */
-   if (DIRTY(RASTERIZER)) {
-      gen8_3DSTATE_SF(r->builder, (vec->rasterizer) ?
-            &vec->rasterizer->sf : NULL);
-   }
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF)
+      gen7_3DSTATE_SF(r->builder, &vec->rasterizer->rs);
 }
 
 static void
@@ -93,12 +87,15 @@ gen8_draw_wm(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
 {
+   const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
+   const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
+
    /* 3DSTATE_WM */
-   if (DIRTY(FS) || DIRTY(RASTERIZER))
-      gen8_3DSTATE_WM(r->builder, vec->fs, vec->rasterizer);
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM)
+      gen8_3DSTATE_WM(r->builder, &vec->rasterizer->rs);
 
-   if (DIRTY(DSA))
-      gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, vec->dsa);
+   if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL)
+      gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, &vec->blend->cc);
 
    /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */
    if (r->hw_ctx_changed) {
@@ -128,18 +125,15 @@ gen8_draw_wm(struct ilo_render *r,
 
    /* 3DSTATE_PS */
    if (DIRTY(FS) || r->instruction_bo_changed)
-      gen8_3DSTATE_PS(r->builder, vec->fs);
+      gen8_3DSTATE_PS(r->builder, &cso->ps, kernel_offset);
 
    /* 3DSTATE_PS_EXTRA */
-   if (DIRTY(FS) || DIRTY(DSA) || DIRTY(BLEND)) {
-      const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
-                                vec->blend->alpha_to_coverage);
-      gen8_3DSTATE_PS_EXTRA(r->builder, vec->fs, cc_may_kill, false);
-   }
+   if (DIRTY(FS))
+      gen8_3DSTATE_PS_EXTRA(r->builder, &cso->ps);
 
    /* 3DSTATE_PS_BLEND */
-   if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA))
-      gen8_3DSTATE_PS_BLEND(r->builder, vec->blend, &vec->fb, vec->dsa);
+   if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_PS_BLEND)
+      gen8_3DSTATE_PS_BLEND(r->builder, &vec->blend->cc);
 
    /* 3DSTATE_SCISSOR_STATE_POINTERS */
    if (session->scissor_changed) {
@@ -149,7 +143,7 @@ gen8_draw_wm(struct ilo_render *r,
 
    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    if (DIRTY(FB) || r->batch_bo_changed) {
-      const struct ilo_zs_surface *zs;
+      const struct ilo_state_zs *zs;
       uint32_t clear_params;
 
       if (vec->fb.state.zsbuf) {
@@ -170,7 +164,7 @@ gen8_draw_wm(struct ilo_render *r,
 
       gen8_wa_pre_depth(r);
 
-      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs, false);
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
       gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
@@ -183,14 +177,8 @@ gen8_draw_wm_sample_pattern(struct ilo_render *r,
                             struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_SAMPLE_PATTERN */
-   if (r->hw_ctx_changed) {
-      gen8_3DSTATE_SAMPLE_PATTERN(r->builder,
-            &r->sample_pattern_1x,
-            &r->sample_pattern_2x,
-            &r->sample_pattern_4x,
-            r->sample_pattern_8x,
-            r->sample_pattern_16x);
-   }
+   if (r->hw_ctx_changed)
+      gen8_3DSTATE_SAMPLE_PATTERN(r->builder, &r->sample_pattern);
 }
 
 static void
@@ -198,15 +186,13 @@ gen8_draw_wm_multisample(struct ilo_render *r,
                          const struct ilo_state_vector *vec,
                          struct ilo_render_draw_session *session)
 {
-   /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
-   if (DIRTY(SAMPLE_MASK) || DIRTY(FB) || DIRTY(RASTERIZER)) {
-      gen8_3DSTATE_MULTISAMPLE(r->builder, vec->fb.num_samples,
-            vec->rasterizer->state.half_pixel_center);
-
-      gen7_3DSTATE_SAMPLE_MASK(r->builder,
-            (vec->fb.num_samples > 1) ? vec->sample_mask : 0x1,
-            vec->fb.num_samples);
-   }
+   /* 3DSTATE_MULTISAMPLE */
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)
+      gen8_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs);
+
+   /* 3DSTATE_SAMPLE_MASK */
+   if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
+      gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
 }
 
 static void
@@ -214,36 +200,38 @@ gen8_draw_vf(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
 {
-   int i;
-
    /* 3DSTATE_INDEX_BUFFER */
-   if (DIRTY(IB) || r->batch_bo_changed)
-      gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ib);
+   if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
+       DIRTY(IB) || r->batch_bo_changed)
+      gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
 
    /* 3DSTATE_VF */
-   if (session->primitive_restart_changed) {
-      gen75_3DSTATE_VF(r->builder, vec->draw->primitive_restart,
-            vec->draw->restart_index);
-   }
+   if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF)
+      gen75_3DSTATE_VF(r->builder, &vec->ve->vf);
 
    /* 3DSTATE_VERTEX_BUFFERS */
-   if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed)
-      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, vec->ve, &vec->vb);
+   if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
+       DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
+      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
+            vec->vb.vb, vec->ve->vb_count);
+   }
 
    /* 3DSTATE_VERTEX_ELEMENTS */
-   if (DIRTY(VE))
-      gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, vec->ve);
+   if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS)
+      gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf);
+
+   gen8_3DSTATE_VF_TOPOLOGY(r->builder, vec->draw_info.topology);
 
-   gen8_3DSTATE_VF_TOPOLOGY(r->builder, vec->draw->mode);
+   if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_INSTANCING) {
+      const uint8_t attr_count = ilo_state_vf_get_attr_count(&vec->ve->vf);
+      uint8_t i;
 
-   for (i = 0; i < vec->ve->vb_count; i++) {
-      gen8_3DSTATE_VF_INSTANCING(r->builder, i,
-            vec->ve->instance_divisors[i]);
+      for (i = 0; i < attr_count; i++)
+         gen8_3DSTATE_VF_INSTANCING(r->builder, &vec->ve->vf, i);
    }
 
-   gen8_3DSTATE_VF_SGVS(r->builder,
-         false, 0, 0,
-         false, 0, 0);
+   if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_SGVS)
+      gen8_3DSTATE_VF_SGVS(r->builder, &vec->ve->vf);
 }
 
 void
@@ -281,7 +269,7 @@ ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
    gen6_draw_sf_rect(render, vec, session);
    gen8_draw_vf(render, vec, session);
 
-   ilo_render_3dprimitive(render, vec->draw, &vec->ib);
+   ilo_render_3dprimitive(render, &vec->draw_info);
 }
 
 int
@@ -365,17 +353,13 @@ ilo_render_emit_rectlist_commands_gen8(struct ilo_render *r,
                                        const struct ilo_blitter *blitter,
                                        const struct ilo_render_rectlist_session *session)
 {
-   uint32_t op;
-
    ILO_DEV_ASSERT(r->dev, 8, 8);
 
    gen8_wa_pre_depth(r);
 
    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
-                        ILO_BLITTER_USE_FB_STENCIL)) {
-      gen6_3DSTATE_DEPTH_BUFFER(r->builder,
-            &blitter->fb.dst.u.zs, true);
-   }
+                        ILO_BLITTER_USE_FB_STENCIL))
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
 
    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
@@ -393,27 +377,8 @@ ilo_render_emit_rectlist_commands_gen8(struct ilo_render *r,
    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
          blitter->fb.width, blitter->fb.height);
 
-   switch (blitter->op) {
-   case ILO_BLITTER_RECTLIST_CLEAR_ZS:
-      op = 0;
-      if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH)
-         op |= GEN8_WM_HZ_DW1_DEPTH_CLEAR;
-      if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL)
-         op |= GEN8_WM_HZ_DW1_STENCIL_CLEAR;
-      break;
-   case ILO_BLITTER_RECTLIST_RESOLVE_Z:
-      op = GEN8_WM_HZ_DW1_DEPTH_RESOLVE;
-      break;
-   case ILO_BLITTER_RECTLIST_RESOLVE_HIZ:
-      op = GEN8_WM_HZ_DW1_HIZ_RESOLVE;
-      break;
-   default:
-      op = 0;
-      break;
-   }
-
-   gen8_3DSTATE_WM_HZ_OP(r->builder, op, blitter->fb.width,
-         blitter->fb.height, blitter->fb.num_samples);
+   gen8_3DSTATE_WM_HZ_OP(r->builder, &blitter->fb.rs,
+         blitter->fb.width, blitter->fb.height);
 
    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_WRITE_IMM);
 
index 387920a912c447dcdec47acca3a0886673a466ed..a0de0024d6194285010a8ec5dc0ee988f5383bd2 100644 (file)
@@ -30,6 +30,7 @@
 #include "core/ilo_builder_mi.h"
 #include "core/ilo_builder_render.h"
 
+#include "ilo_shader.h"
 #include "ilo_state.h"
 #include "ilo_render_gen.h"
 
@@ -206,7 +207,7 @@ ilo_render_emit_launch_grid_commands(struct ilo_render *render,
 
    gen6_state_base_address(render->builder, true);
 
-   gen6_MEDIA_VFE_STATE(render->builder, pcb_size, use_slm);
+   gen6_MEDIA_VFE_STATE(render->builder, &session->compute);
 
    if (pcb_size)
       gen6_MEDIA_CURBE_LOAD(render->builder, pcb, pcb_size);
index b345dfb4fc4ca5dfd8968d6441f2b4a1f5913182..ad053564294f037f62d1987238607712037d62b3 100644 (file)
 
 #include "ilo_common.h"
 #include "ilo_blitter.h"
+#include "ilo_resource.h"
+#include "ilo_shader.h"
 #include "ilo_state.h"
 #include "ilo_render_gen.h"
 
 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
 
+static inline uint32_t
+gen6_so_SURFACE_STATE(struct ilo_builder *builder,
+                      const struct pipe_stream_output_target *so,
+                      const struct pipe_stream_output_info *so_info,
+                      int so_index)
+{
+   struct ilo_buffer *buf = ilo_buffer(so->buffer);
+   struct ilo_state_surface_buffer_info info;
+   struct ilo_state_surface surf;
+
+   ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+   memset(&info, 0, sizeof(info));
+   info.buf = buf;
+   info.access = ILO_STATE_SURFACE_ACCESS_DP_SVB;
+
+   switch (so_info->output[so_index].num_components) {
+   case 1:
+      info.format = GEN6_FORMAT_R32_FLOAT;
+      info.format_size = 4;
+      break;
+   case 2:
+      info.format = GEN6_FORMAT_R32G32_FLOAT;
+      info.format_size = 8;
+      break;
+   case 3:
+      info.format = GEN6_FORMAT_R32G32B32_FLOAT;
+      info.format_size = 12;
+      break;
+   case 4:
+      info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
+      info.format_size = 16;
+      break;
+   default:
+      assert(!"unexpected SO components length");
+      info.format = GEN6_FORMAT_R32_FLOAT;
+      info.format_size = 4;
+      break;
+   }
+
+   info.struct_size =
+      so_info->stride[so_info->output[so_index].output_buffer] * 4;
+   info.offset = so->buffer_offset + so_info->output[so_index].dst_offset * 4;
+   info.size = so->buffer_size - so_info->output[so_index].dst_offset * 4;
+
+   memset(&surf, 0, sizeof(surf));
+   ilo_state_surface_init_for_buffer(&surf, builder->dev, &info);
+   surf.bo = info.buf->bo;
+
+   return gen6_SURFACE_STATE(builder, &surf);
+}
+
 static void
 gen6_emit_draw_surface_rt(struct ilo_render *r,
                           const struct ilo_state_vector *vec,
@@ -64,11 +118,9 @@ gen6_emit_draw_surface_rt(struct ilo_render *r,
             (const struct ilo_surface_cso *) fb->state.cbufs[i];
 
          assert(surface->is_rt);
-         surface_state[i] =
-            gen6_SURFACE_STATE(r->builder, &surface->u.rt, true);
+         surface_state[i] = gen6_SURFACE_STATE(r->builder, &surface->u.rt);
       } else {
-         surface_state[i] =
-            gen6_SURFACE_STATE(r->builder, &fb->null_rt, true);
+         surface_state[i] = gen6_SURFACE_STATE(r->builder, &fb->null_rt);
       }
    }
 }
@@ -173,8 +225,7 @@ gen6_emit_draw_surface_view(struct ilo_render *r,
          const struct ilo_view_cso *cso =
             (const struct ilo_view_cso *) view->states[i];
 
-         surface_state[i] =
-            gen6_SURFACE_STATE(r->builder, &cso->surface, false);
+         surface_state[i] = gen6_SURFACE_STATE(r->builder, &cso->surface);
       } else {
          surface_state[i] = 0;
       }
@@ -228,12 +279,10 @@ gen6_emit_draw_surface_const(struct ilo_render *r,
    for (i = 0; i < count; i++) {
       const struct ilo_cbuf_cso *cso = &cbuf->cso[i];
 
-      if (cso->resource) {
-         surface_state[i] = gen6_SURFACE_STATE(r->builder,
-               &cso->surface, false);
-      } else {
+      if (cso->resource)
+         surface_state[i] = gen6_SURFACE_STATE(r->builder, &cso->surface);
+      else
          surface_state[i] = 0;
-      }
    }
 }
 
@@ -406,8 +455,7 @@ gen6_emit_launch_grid_surface_view(struct ilo_render *r,
          const struct ilo_view_cso *cso =
             (const struct ilo_view_cso *) view->states[i];
 
-         surface_state[i] =
-            gen6_SURFACE_STATE(r->builder, &cso->surface, false);
+         surface_state[i] = gen6_SURFACE_STATE(r->builder, &cso->surface);
       } else {
          surface_state[i] = 0;
       }
@@ -421,7 +469,8 @@ gen6_emit_launch_grid_surface_const(struct ilo_render *r,
 {
    const struct ilo_shader_state *cs = vec->cs;
    uint32_t *surface_state = r->state.cs.SURFACE_STATE;
-   struct ilo_view_surface view;
+   struct ilo_state_surface_buffer_info info;
+   struct ilo_state_surface surf;
    int base, count;
 
    ILO_DEV_ASSERT(r->dev, 7, 7.5);
@@ -432,15 +481,22 @@ gen6_emit_launch_grid_surface_const(struct ilo_render *r,
    if (!count)
       return;
 
-   ilo_gpe_init_view_surface_for_buffer(r->dev,
-         ilo_buffer(session->input->buffer),
-         session->input->buffer_offset,
-         session->input->buffer_size,
-         1, PIPE_FORMAT_NONE,
-         false, false, &view);
+   memset(&info, 0, sizeof(info));
+   info.buf = ilo_buffer(session->input->buffer);
+   info.access = ILO_STATE_SURFACE_ACCESS_DP_UNTYPED;
+   info.format = GEN6_FORMAT_RAW;
+   info.format_size = 1;
+   info.struct_size = 1;
+   info.readonly = true;
+   info.offset = session->input->buffer_offset;
+   info.size = session->input->buffer_size;
+
+   memset(&surf, 0, sizeof(surf));
+   ilo_state_surface_init_for_buffer(&surf, r->dev, &info);
+   surf.bo = info.buf->bo;
 
    assert(count == 1 && session->input->buffer);
-   surface_state[base] = gen6_SURFACE_STATE(r->builder, &view, false);
+   surface_state[base] = gen6_SURFACE_STATE(r->builder, &surf);
 }
 
 static void
@@ -483,14 +539,24 @@ gen6_emit_launch_grid_surface_global(struct ilo_render *r,
    for (i = 0; i < count; i++) {
       if (i < vec->global_binding.count && bindings[i].resource) {
          const struct ilo_buffer *buf = ilo_buffer(bindings[i].resource);
-         struct ilo_view_surface view;
+         struct ilo_state_surface_buffer_info info;
+         struct ilo_state_surface surf;
 
          assert(bindings[i].resource->target == PIPE_BUFFER);
 
-         ilo_gpe_init_view_surface_for_buffer(r->dev, buf, 0, buf->bo_size,
-               1, PIPE_FORMAT_NONE, true, true, &view);
-         surface_state[i] =
-            gen6_SURFACE_STATE(r->builder, &view, true);
+         memset(&info, 0, sizeof(info));
+         info.buf = buf;
+         info.access = ILO_STATE_SURFACE_ACCESS_DP_UNTYPED;
+         info.format = GEN6_FORMAT_RAW;
+         info.format_size = 1;
+         info.struct_size = 1;
+         info.size = buf->bo_size;
+
+         memset(&surf, 0, sizeof(surf));
+         ilo_state_surface_init_for_buffer(&surf, r->dev, &info);
+         surf.bo = info.buf->bo;
+
+         surface_state[i] = gen6_SURFACE_STATE(r->builder, &surf);
       } else {
          surface_state[i] = 0;
       }
index ad4852278d02d7ad3647c4f96c71e43d28cfcded..be9fd10a84c6ea5c75b41d88f055c7b454518929 100644 (file)
@@ -178,8 +178,8 @@ tex_create_bo(struct ilo_texture *tex)
    if (!bo)
       return false;
 
-   ilo_image_set_bo(&tex->image, bo);
-   intel_bo_unref(bo);
+   intel_bo_unref(tex->image.bo);
+   tex->image.bo = bo;
 
    return true;
 }
@@ -223,7 +223,7 @@ tex_create_hiz(struct ilo_texture *tex)
    if (!bo)
       return false;
 
-   ilo_image_set_aux_bo(&tex->image, bo);
+   tex->image.aux.bo = bo;
 
    if (tex->imported) {
       unsigned lv;
@@ -256,7 +256,7 @@ tex_create_mcs(struct ilo_texture *tex)
    if (!bo)
       return false;
 
-   ilo_image_set_aux_bo(&tex->image, bo);
+   tex->image.aux.bo = bo;
 
    return true;
 }
@@ -267,7 +267,8 @@ tex_destroy(struct ilo_texture *tex)
    if (tex->separate_s8)
       tex_destroy(tex->separate_s8);
 
-   ilo_image_cleanup(&tex->image);
+   intel_bo_unref(tex->image.bo);
+   intel_bo_unref(tex->image.aux.bo);
 
    tex_free_slices(tex);
    FREE(tex);
@@ -287,15 +288,13 @@ tex_alloc_bos(struct ilo_texture *tex)
 
    switch (tex->image.aux.type) {
    case ILO_IMAGE_AUX_HIZ:
-      if (!tex_create_hiz(tex)) {
-         /* Separate Stencil Buffer requires HiZ to be enabled */
-         if (ilo_dev_gen(&is->dev) == ILO_GEN(6) &&
-             tex->image.separate_stencil)
-            return false;
-      }
+      if (!tex_create_hiz(tex) &&
+          !ilo_image_disable_aux(&tex->image, &is->dev))
+         return false;
       break;
    case ILO_IMAGE_AUX_MCS:
-      if (!tex_create_mcs(tex))
+      if (!tex_create_mcs(tex) &&
+          !ilo_image_disable_aux(&tex->image, &is->dev))
          return false;
       break;
    default:
@@ -328,8 +327,7 @@ tex_import_handle(struct ilo_texture *tex,
       return false;
    }
 
-   ilo_image_set_bo(&tex->image, bo);
-   intel_bo_unref(bo);
+   tex->image.bo = bo;
 
    tex->imported = true;
 
@@ -427,8 +425,8 @@ buf_create_bo(struct ilo_buffer_resource *buf)
    if (!bo)
       return false;
 
-   ilo_buffer_set_bo(&buf->buffer, bo);
-   intel_bo_unref(bo);
+   intel_bo_unref(buf->buffer.bo);
+   buf->buffer.bo = bo;
 
    return true;
 }
@@ -436,7 +434,7 @@ buf_create_bo(struct ilo_buffer_resource *buf)
 static void
 buf_destroy(struct ilo_buffer_resource *buf)
 {
-   ilo_buffer_cleanup(&buf->buffer);
+   intel_bo_unref(buf->buffer.bo);
    FREE(buf);
 }
 
@@ -445,6 +443,7 @@ buf_create(struct pipe_screen *screen, const struct pipe_resource *templ)
 {
    const struct ilo_screen *is = ilo_screen(screen);
    struct ilo_buffer_resource *buf;
+   unsigned size;
 
    buf = CALLOC_STRUCT(ilo_buffer_resource);
    if (!buf)
@@ -454,8 +453,25 @@ buf_create(struct pipe_screen *screen, const struct pipe_resource *templ)
    buf->base.screen = screen;
    pipe_reference_init(&buf->base.reference, 1);
 
-   ilo_buffer_init(&buf->buffer, &is->dev,
-         templ->width0, templ->bind, templ->flags);
+   size = templ->width0;
+
+   /*
+    * As noted in ilo_format_translate(), we treat some 3-component formats as
+    * 4-component formats to work around hardware limitations.  Imagine the
+    * case where the vertex buffer holds a single PIPE_FORMAT_R16G16B16_FLOAT
+    * vertex, and buf->bo_size is 6.  The hardware would fail to fetch it at
+    * boundary check because the vertex buffer is expected to hold a
+    * PIPE_FORMAT_R16G16B16A16_FLOAT vertex and that takes at least 8 bytes.
+    *
+    * For the workaround to work, we should add 2 to the bo size.  But that
+    * would waste a page when the bo size is already page aligned.  Let's
+    * round it to page size for now and revisit this when needed.
+    */
+   if ((templ->bind & PIPE_BIND_VERTEX_BUFFER) &&
+       ilo_dev_gen(&is->dev) < ILO_GEN(7.5))
+      size = align(size, 4096);
+
+   ilo_buffer_init(&buf->buffer, &is->dev, size, templ->bind, templ->flags);
 
    if (buf->buffer.bo_size < templ->width0 ||
        buf->buffer.bo_size > ilo_max_resource_size ||
index 918af0820de846ad8f2426cfab993b1deb34528b..94105559b80d3e1bacf537406d85a5add7ccb2c5 100644 (file)
 #include "vl/vl_decoder.h"
 #include "vl/vl_video_buffer.h"
 #include "genhw/genhw.h" /* for GEN6_REG_TIMESTAMP */
-#include "core/ilo_fence.h"
-#include "core/ilo_format.h"
 #include "core/intel_winsys.h"
 
 #include "ilo_context.h"
+#include "ilo_format.h"
 #include "ilo_resource.h"
 #include "ilo_transfer.h" /* for ILO_TRANSFER_MAP_BUFFER_ALIGNMENT */
 #include "ilo_public.h"
@@ -43,8 +42,7 @@
 
 struct pipe_fence_handle {
    struct pipe_reference reference;
-
-   struct ilo_fence fence;
+   struct intel_bo *seqno_bo;
 };
 
 static float
@@ -347,7 +345,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_INDEP_BLEND_FUNC:
       return true;
    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
-      return (ilo_dev_gen(&is->dev) >= ILO_GEN(7)) ? 2048 : 512;
+      return (ilo_dev_gen(&is->dev) >= ILO_GEN(7.5)) ? 2048 : 512;
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
@@ -458,6 +456,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_SAMPLER_VIEW_TARGET:
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
@@ -641,7 +640,7 @@ ilo_screen_fence_reference(struct pipe_screen *screen,
 
    STATIC_ASSERT(&((struct pipe_fence_handle *) NULL)->reference == NULL);
    if (pipe_reference(&old->reference, &fence->reference)) {
-      ilo_fence_cleanup(&old->fence);
+      intel_bo_unref(old->seqno_bo);
       FREE(old);
    }
 }
@@ -654,10 +653,14 @@ ilo_screen_fence_finish(struct pipe_screen *screen,
    const int64_t wait_timeout = (timeout > INT64_MAX) ? -1 : timeout;
    bool signaled;
 
-   signaled = ilo_fence_wait(&fence->fence, wait_timeout);
+   signaled = (!fence->seqno_bo ||
+         intel_bo_wait(fence->seqno_bo, wait_timeout) == 0);
+
    /* XXX not thread safe */
-   if (signaled)
-      ilo_fence_set_seq_bo(&fence->fence, NULL);
+   if (signaled && fence->seqno_bo) {
+      intel_bo_unref(fence->seqno_bo);
+      fence->seqno_bo = NULL;
+   }
 
    return signaled;
 }
@@ -676,7 +679,6 @@ ilo_screen_fence_signalled(struct pipe_screen *screen,
 struct pipe_fence_handle *
 ilo_screen_fence_create(struct pipe_screen *screen, struct intel_bo *bo)
 {
-   struct ilo_screen *is = ilo_screen(screen);
    struct pipe_fence_handle *fence;
 
    fence = CALLOC_STRUCT(pipe_fence_handle);
@@ -685,8 +687,7 @@ ilo_screen_fence_create(struct pipe_screen *screen, struct intel_bo *bo)
 
    pipe_reference_init(&fence->reference, 1);
 
-   ilo_fence_init(&fence->fence, &is->dev);
-   ilo_fence_set_seq_bo(&fence->fence, bo);
+   fence->seqno_bo = intel_bo_ref(bo);
 
    return fence;
 }
@@ -696,7 +697,7 @@ ilo_screen_destroy(struct pipe_screen *screen)
 {
    struct ilo_screen *is = ilo_screen(screen);
 
-   ilo_dev_cleanup(&is->dev);
+   intel_winsys_destroy(is->dev.winsys);
 
    FREE(is);
 }
index 799db2cbfcb1cd93e07fe67d84baa7a0b7b16cad..5f2b01017e23da1215be155e57e7a1b1373ff56a 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "genhw/genhw.h" /* for SBE setup */
 #include "core/ilo_builder.h"
-#include "core/ilo_state_3d.h"
 #include "core/intel_winsys.h"
 #include "shader/ilo_shader_internal.h"
 #include "tgsi/tgsi_parse.h"
@@ -557,39 +556,255 @@ ilo_shader_state_search_variant(struct ilo_shader_state *state,
 }
 
 static void
-copy_so_info(struct ilo_shader *sh,
-             const struct pipe_stream_output_info *so_info)
+init_shader_urb(const struct ilo_shader *kernel,
+                const struct ilo_shader_state *state,
+                struct ilo_state_shader_urb_info *urb)
 {
-   unsigned i, attr;
+   urb->cv_input_attr_count = kernel->in.count;
+   urb->read_base = 0;
+   urb->read_count = kernel->in.count;
 
-   if (!so_info->num_outputs)
+   urb->output_attr_count = kernel->out.count;
+   urb->user_cull_enables = 0x0;
+   urb->user_clip_enables = 0x0;
+}
+
+static void
+init_shader_kernel(const struct ilo_shader *kernel,
+                   const struct ilo_shader_state *state,
+                   struct ilo_state_shader_kernel_info *kern)
+{
+   kern->offset = 0;
+   kern->grf_start = kernel->in.start_grf;
+   kern->pcb_attr_count =
+      (kernel->pcb.cbuf0_size + kernel->pcb.clip_state_size + 15) / 16;
+   kern->scratch_size = 0;
+}
+
+static void
+init_shader_resource(const struct ilo_shader *kernel,
+                     const struct ilo_shader_state *state,
+                     struct ilo_state_shader_resource_info *resource)
+{
+   resource->sampler_count = state->info.num_samplers;
+   resource->surface_count = 0;
+   resource->has_uav = false;
+}
+
+static void
+init_vs(struct ilo_shader *kernel,
+        const struct ilo_shader_state *state)
+{
+   struct ilo_state_vs_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   init_shader_urb(kernel, state, &info.urb);
+   init_shader_kernel(kernel, state, &info.kernel);
+   init_shader_resource(kernel, state, &info.resource);
+   info.dispatch_enable = true;
+   info.stats_enable = true;
+
+   if (ilo_dev_gen(state->info.dev) == ILO_GEN(6) && kernel->stream_output) {
+      struct ilo_state_gs_info gs_info;
+
+      memset(&gs_info, 0, sizeof(gs_info));
+
+      gs_info.urb.cv_input_attr_count = kernel->out.count;
+      gs_info.urb.read_count = kernel->out.count;
+      gs_info.kernel.grf_start = kernel->gs_start_grf;
+      gs_info.sol.sol_enable = true;
+      gs_info.sol.stats_enable = true;
+      gs_info.sol.render_disable = kernel->variant.u.vs.rasterizer_discard;
+      gs_info.sol.svbi_post_inc = kernel->svbi_post_inc;
+      gs_info.sol.tristrip_reorder = GEN7_REORDER_LEADING;
+      gs_info.dispatch_enable = true;
+      gs_info.stats_enable = true;
+
+      ilo_state_vs_init(&kernel->cso.vs_sol.vs, state->info.dev, &info);
+      ilo_state_gs_init(&kernel->cso.vs_sol.sol, state->info.dev, &gs_info);
+   } else {
+      ilo_state_vs_init(&kernel->cso.vs, state->info.dev, &info);
+   }
+}
+
+static void
+init_gs(struct ilo_shader *kernel,
+        const struct ilo_shader_state *state)
+{
+   const struct pipe_stream_output_info *so_info = &state->info.stream_output;
+   struct ilo_state_gs_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   init_shader_urb(kernel, state, &info.urb);
+   init_shader_kernel(kernel, state, &info.kernel);
+   init_shader_resource(kernel, state, &info.resource);
+   info.dispatch_enable = true;
+   info.stats_enable = true;
+
+   if (so_info->num_outputs > 0) {
+      info.sol.sol_enable = true;
+      info.sol.stats_enable = true;
+      info.sol.render_disable = kernel->variant.u.gs.rasterizer_discard;
+      info.sol.tristrip_reorder = GEN7_REORDER_LEADING;
+   }
+
+   ilo_state_gs_init(&kernel->cso.gs, state->info.dev, &info);
+}
+
+static void
+init_ps(struct ilo_shader *kernel,
+        const struct ilo_shader_state *state)
+{
+   struct ilo_state_ps_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   init_shader_kernel(kernel, state, &info.kernel_8);
+   init_shader_resource(kernel, state, &info.resource);
+
+   info.io.has_rt_write = true;
+   info.io.posoffset = GEN6_POSOFFSET_NONE;
+   info.io.attr_count = kernel->in.count;
+   info.io.use_z = kernel->in.has_pos;
+   info.io.use_w = kernel->in.has_pos;
+   info.io.use_coverage_mask = false;
+   info.io.pscdepth = (kernel->out.has_pos) ?
+      GEN7_PSCDEPTH_ON : GEN7_PSCDEPTH_OFF;
+   info.io.write_pixel_mask = kernel->has_kill;
+   info.io.write_omask = false;
+
+   info.params.sample_mask = 0x1;
+   info.params.earlyz_control_psexec = false;
+   info.params.alpha_may_kill = false;
+   info.params.dual_source_blending = false;
+   info.params.has_writeable_rt = true;
+
+   info.valid_kernels = GEN6_PS_DISPATCH_8;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 284:
+    *
+    *     "(MSDISPMODE_PERSAMPLE) This is the high-quality multisample mode
+    *      where (over and above PERPIXEL mode) the PS is run for each covered
+    *      sample. This mode is also used for "normal" non-multisample
+    *      rendering (aka 1X), given Number of Multisamples is programmed to
+    *      NUMSAMPLES_1."
+    */
+   info.per_sample_dispatch = true;
+
+   info.rt_clear_enable = false;
+   info.rt_resolve_enable = false;
+   info.cv_per_sample_interp = false;
+   info.cv_has_earlyz_op = false;
+   info.sample_count_one = true;
+   info.cv_has_depth_buffer = true;
+
+   ilo_state_ps_init(&kernel->cso.ps, state->info.dev, &info);
+
+   /* remember current parameters */
+   kernel->ps_params = info.params;
+}
+
+static void
+init_sol(struct ilo_shader *kernel,
+         const struct ilo_dev *dev,
+         const struct pipe_stream_output_info *so_info,
+         bool rasterizer_discard)
+{
+   struct ilo_state_sol_decl_info decls[4][PIPE_MAX_SO_OUTPUTS];
+   unsigned buf_offsets[PIPE_MAX_SO_BUFFERS];
+   struct ilo_state_sol_info info;
+   unsigned i;
+
+   if (!so_info->num_outputs) {
+      ilo_state_sol_init_disabled(&kernel->sol, dev, rasterizer_discard);
       return;
+   }
+
+   memset(&info, 0, sizeof(info));
+   info.data = kernel->sol_data;
+   info.data_size = sizeof(kernel->sol_data);
+   info.sol_enable = true;
+   info.stats_enable = true;
+   info.tristrip_reorder = GEN7_REORDER_TRAILING;
+   info.render_disable = rasterizer_discard;
+   info.render_stream = 0;
+
+   for (i = 0; i < 4; i++) {
+      info.buffer_strides[i] = so_info->stride[i] * 4;
 
-   sh->so_info = *so_info;
+      info.streams[i].cv_vue_attr_count = kernel->out.count;
+      info.streams[i].decls = decls[i];
+   }
 
+   memset(decls, 0, sizeof(decls));
+   memset(buf_offsets, 0, sizeof(buf_offsets));
    for (i = 0; i < so_info->num_outputs; i++) {
+      const unsigned stream = so_info->output[i].stream;
+      const unsigned buffer = so_info->output[i].output_buffer;
+      struct ilo_state_sol_decl_info *decl;
+      unsigned attr;
+
       /* figure out which attribute is sourced */
-      for (attr = 0; attr < sh->out.count; attr++) {
-         const int reg_idx = sh->out.register_indices[attr];
+      for (attr = 0; attr < kernel->out.count; attr++) {
+         const int reg_idx = kernel->out.register_indices[attr];
          if (reg_idx == so_info->output[i].register_index)
             break;
       }
-
-      if (attr < sh->out.count) {
-         sh->so_info.output[i].register_index = attr;
-      }
-      else {
+      if (attr >= kernel->out.count) {
          assert(!"stream output an undefined register");
-         sh->so_info.output[i].register_index = 0;
+         attr = 0;
       }
 
+      if (info.streams[stream].vue_read_count < attr + 1)
+         info.streams[stream].vue_read_count = attr + 1;
+
+      /* pad with holes first */
+      while (buf_offsets[buffer] < so_info->output[i].dst_offset) {
+         int num_dwords;
+
+         num_dwords = so_info->output[i].dst_offset - buf_offsets[buffer];
+         if (num_dwords > 4)
+            num_dwords = 4;
+
+         assert(info.streams[stream].decl_count < ARRAY_SIZE(decls[stream]));
+         decl = &decls[stream][info.streams[stream].decl_count];
+
+         decl->attr = 0;
+         decl->is_hole = true;
+         decl->component_base = 0;
+         decl->component_count = num_dwords;
+         decl->buffer = buffer;
+
+         info.streams[stream].decl_count++;
+         buf_offsets[buffer] += num_dwords;
+      }
+      assert(buf_offsets[buffer] == so_info->output[i].dst_offset);
+
+      assert(info.streams[stream].decl_count < ARRAY_SIZE(decls[stream]));
+      decl = &decls[stream][info.streams[stream].decl_count];
+
+      decl->attr = attr;
+      decl->is_hole = false;
       /* PSIZE is at W channel */
-      if (sh->out.semantic_names[attr] == TGSI_SEMANTIC_PSIZE) {
+      if (kernel->out.semantic_names[attr] == TGSI_SEMANTIC_PSIZE) {
          assert(so_info->output[i].start_component == 0);
          assert(so_info->output[i].num_components == 1);
-         sh->so_info.output[i].start_component = 3;
+         decl->component_base = 3;
+         decl->component_count = 1;
+      } else {
+         decl->component_base = so_info->output[i].start_component;
+         decl->component_count = so_info->output[i].num_components;
       }
+      decl->buffer = buffer;
+
+      info.streams[stream].decl_count++;
+      buf_offsets[buffer] += so_info->output[i].num_components;
    }
+
+   ilo_state_sol_init(&kernel->sol, dev, &info);
 }
 
 /**
@@ -599,17 +814,20 @@ static struct ilo_shader *
 ilo_shader_state_add_variant(struct ilo_shader_state *state,
                              const struct ilo_shader_variant *variant)
 {
+   bool rasterizer_discard = false;
    struct ilo_shader *sh;
 
    switch (state->info.type) {
    case PIPE_SHADER_VERTEX:
       sh = ilo_shader_compile_vs(state, variant);
+      rasterizer_discard = variant->u.vs.rasterizer_discard;
       break;
    case PIPE_SHADER_FRAGMENT:
       sh = ilo_shader_compile_fs(state, variant);
       break;
    case PIPE_SHADER_GEOMETRY:
       sh = ilo_shader_compile_gs(state, variant);
+      rasterizer_discard = variant->u.gs.rasterizer_discard;
       break;
    case PIPE_SHADER_COMPUTE:
       sh = ilo_shader_compile_cs(state, variant);
@@ -625,7 +843,8 @@ ilo_shader_state_add_variant(struct ilo_shader_state *state,
 
    sh->variant = *variant;
 
-   copy_so_info(sh, &state->info.stream_output);
+   init_sol(sh, state->info.dev, &state->info.stream_output,
+         rasterizer_discard);
 
    ilo_shader_state_add_shader(state, sh);
 
@@ -665,13 +884,13 @@ ilo_shader_state_use_variant(struct ilo_shader_state *state,
    if (construct_cso) {
       switch (state->info.type) {
       case PIPE_SHADER_VERTEX:
-         ilo_gpe_init_vs_cso(state->info.dev, state, &sh->cso);
+         init_vs(sh, state);
          break;
       case PIPE_SHADER_GEOMETRY:
-         ilo_gpe_init_gs_cso(state->info.dev, state, &sh->cso);
+         init_gs(sh, state);
          break;
       case PIPE_SHADER_FRAGMENT:
-         ilo_gpe_init_fs_cso(state->info.dev, state, &sh->cso);
+         init_ps(sh, state);
          break;
       default:
          break;
@@ -789,16 +1008,33 @@ ilo_shader_select_kernel(struct ilo_shader_state *shader,
                          const struct ilo_state_vector *vec,
                          uint32_t dirty)
 {
-   const struct ilo_shader * const cur = shader->shader;
    struct ilo_shader_variant variant;
+   bool changed = false;
 
-   if (!(shader->info.non_orthogonal_states & dirty))
-      return false;
+   if (shader->info.non_orthogonal_states & dirty) {
+      const struct ilo_shader * const old = shader->shader;
+
+      ilo_shader_variant_init(&variant, &shader->info, vec);
+      ilo_shader_state_use_variant(shader, &variant);
+      changed = (shader->shader != old);
+   }
 
-   ilo_shader_variant_init(&variant, &shader->info, vec);
-   ilo_shader_state_use_variant(shader, &variant);
+   if (shader->info.type == PIPE_SHADER_FRAGMENT) {
+      struct ilo_shader *kernel = shader->shader;
 
-   return (shader->shader != cur);
+      if (kernel->ps_params.sample_mask != vec->sample_mask ||
+          kernel->ps_params.alpha_may_kill != vec->blend->alpha_may_kill) {
+         kernel->ps_params.sample_mask = vec->sample_mask;
+         kernel->ps_params.alpha_may_kill = vec->blend->alpha_may_kill;
+
+         ilo_state_ps_set_params(&kernel->cso.ps, shader->info.dev,
+               &kernel->ps_params);
+
+         changed = true;
+      }
+   }
+
+   return changed;
 }
 
 static int
@@ -829,82 +1065,104 @@ route_attr(const int *semantics, const int *indices, int len,
  * \return true if a different routing is selected
  */
 bool
-ilo_shader_select_kernel_routing(struct ilo_shader_state *shader,
-                                 const struct ilo_shader_state *source,
-                                 const struct ilo_rasterizer_state *rasterizer)
+ilo_shader_select_kernel_sbe(struct ilo_shader_state *shader,
+                             const struct ilo_shader_state *source,
+                             const struct ilo_rasterizer_state *rasterizer)
 {
-   const uint32_t sprite_coord_enable = rasterizer->state.sprite_coord_enable;
+   const bool is_point = true;
    const bool light_twoside = rasterizer->state.light_twoside;
+   const uint32_t sprite_coord_enable = rasterizer->state.sprite_coord_enable;
+   const int sprite_coord_mode = rasterizer->state.sprite_coord_mode;
    struct ilo_shader *kernel = shader->shader;
    struct ilo_kernel_routing *routing = &kernel->routing;
+   struct ilo_state_sbe_swizzle_info swizzles[ILO_STATE_SBE_MAX_SWIZZLE_COUNT];
+   struct ilo_state_sbe_info info;
    const int *src_semantics, *src_indices;
-   int src_len, max_src_slot;
+   int src_skip, src_len, src_slot;
    int dst_len, dst_slot;
 
-   /* we are constructing 3DSTATE_SBE here */
-   ILO_DEV_ASSERT(shader->info.dev, 6, 8);
-
    assert(kernel);
 
    if (source) {
       assert(source->shader);
+
       src_semantics = source->shader->out.semantic_names;
       src_indices = source->shader->out.semantic_indices;
       src_len = source->shader->out.count;
-   }
-   else {
+      src_skip = 0;
+
+      assert(src_len >= 2 &&
+             src_semantics[0] == TGSI_SEMANTIC_PSIZE &&
+             src_semantics[1] == TGSI_SEMANTIC_POSITION);
+
+      /*
+       * skip PSIZE and POSITION (how about the optional CLIPDISTs?), unless
+       * they are all the source shader has and FS needs to read some
+       * attributes.
+       */
+      if (src_len > 2 || !kernel->in.count) {
+         src_semantics += 2;
+         src_indices += 2;
+         src_len -= 2;
+         src_skip = 2;
+      }
+   } else {
       src_semantics = kernel->in.semantic_names;
       src_indices = kernel->in.semantic_indices;
       src_len = kernel->in.count;
+      src_skip = 0;
    }
 
    /* no change */
-   if (kernel->routing_initialized &&
-       routing->source_skip + routing->source_len <= src_len &&
-       kernel->routing_sprite_coord_enable == sprite_coord_enable &&
-       !memcmp(kernel->routing_src_semantics,
-          &src_semantics[routing->source_skip],
-          sizeof(kernel->routing_src_semantics[0]) * routing->source_len) &&
-       !memcmp(kernel->routing_src_indices,
-          &src_indices[routing->source_skip],
-          sizeof(kernel->routing_src_indices[0]) * routing->source_len))
+   if (routing->initialized &&
+       routing->is_point == is_point &&
+       routing->light_twoside == light_twoside &&
+       routing->sprite_coord_enable == sprite_coord_enable &&
+       routing->sprite_coord_mode == sprite_coord_mode &&
+       routing->src_len <= src_len &&
+       !memcmp(routing->src_semantics, src_semantics,
+          sizeof(src_semantics[0]) * routing->src_len) &&
+       !memcmp(routing->src_indices, src_indices,
+          sizeof(src_indices[0]) * routing->src_len))
       return false;
 
-   if (source) {
-      /* skip PSIZE and POSITION (how about the optional CLIPDISTs?) */
-      assert(src_semantics[0] == TGSI_SEMANTIC_PSIZE);
-      assert(src_semantics[1] == TGSI_SEMANTIC_POSITION);
-      routing->source_skip = 2;
-
-      routing->source_len = src_len - routing->source_skip;
-      src_semantics += routing->source_skip;
-      src_indices += routing->source_skip;
-   }
-   else {
-      routing->source_skip = 0;
-      routing->source_len = src_len;
-   }
-
-   routing->const_interp_enable = kernel->in.const_interp_enable;
-   routing->point_sprite_enable = 0;
-   routing->swizzle_enable = false;
-
-   assert(kernel->in.count <= Elements(routing->swizzles));
-   dst_len = MIN2(kernel->in.count, Elements(routing->swizzles));
-   max_src_slot = -1;
+   routing->is_point = is_point;
+   routing->light_twoside = light_twoside;
+   routing->sprite_coord_enable = sprite_coord_enable;
+   routing->sprite_coord_mode = sprite_coord_mode;
+
+   assert(kernel->in.count <= Elements(swizzles));
+   dst_len = MIN2(kernel->in.count, Elements(swizzles));
+
+   memset(&swizzles, 0, sizeof(swizzles));
+   memset(&info, 0, sizeof(info));
+
+   info.attr_count = dst_len;
+   info.cv_vue_attr_count = src_skip + src_len;
+   info.vue_read_base = src_skip;
+   info.vue_read_count = 0;
+   info.has_min_read_count = true;
+   info.swizzle_enable = false;
+   info.swizzle_16_31 = false;
+   info.swizzle_count = 0;
+   info.swizzles = swizzles;
+   info.const_interp_enables = kernel->in.const_interp_enable;
+   info.point_sprite_enables = 0x0;
+   info.point_sprite_origin_lower_left =
+      (sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT);
+   info.cv_is_point = is_point;
 
    for (dst_slot = 0; dst_slot < dst_len; dst_slot++) {
       const int semantic = kernel->in.semantic_names[dst_slot];
       const int index = kernel->in.semantic_indices[dst_slot];
-      int src_slot;
 
       if (semantic == TGSI_SEMANTIC_GENERIC &&
           (sprite_coord_enable & (1 << index)))
-         routing->point_sprite_enable |= 1 << dst_slot;
+         info.point_sprite_enables |= 1 << dst_slot;
 
       if (source) {
-         src_slot = route_attr(src_semantics, src_indices,
-               routing->source_len, semantic, index);
+         src_slot = route_attr(src_semantics, src_indices, src_len,
+               semantic, index);
 
          /*
           * The source shader stage does not output this attribute.  The value
@@ -918,58 +1176,47 @@ ilo_shader_select_kernel_routing(struct ilo_shader_state *shader,
           */
          if (src_slot < 0)
             src_slot = 0;
-      }
-      else {
+      } else {
          src_slot = dst_slot;
       }
 
-      routing->swizzles[dst_slot] = src_slot;
-
       /* use the following slot for two-sided lighting */
       if (semantic == TGSI_SEMANTIC_COLOR && light_twoside &&
-          src_slot + 1 < routing->source_len &&
+          src_slot + 1 < src_len &&
           src_semantics[src_slot + 1] == TGSI_SEMANTIC_BCOLOR &&
           src_indices[src_slot + 1] == index) {
-         routing->swizzles[dst_slot] |= GEN8_SBE_SWIZ_INPUTATTR_FACING;
+         swizzles[dst_slot].attr_select = GEN6_INPUTATTR_FACING;
+         swizzles[dst_slot].attr = src_slot;
+         info.swizzle_enable = true;
          src_slot++;
+      } else {
+         swizzles[dst_slot].attr_select = GEN6_INPUTATTR_NORMAL;
+         swizzles[dst_slot].attr = src_slot;
+         if (src_slot != dst_slot)
+            info.swizzle_enable = true;
       }
 
-      if (routing->swizzles[dst_slot] != dst_slot)
-         routing->swizzle_enable = true;
+      swizzles[dst_slot].force_zeros = false;
 
-      if (max_src_slot < src_slot)
-         max_src_slot = src_slot;
+      if (info.vue_read_count < src_slot + 1)
+         info.vue_read_count = src_slot + 1;
    }
 
-   memset(&routing->swizzles[dst_slot], 0, sizeof(routing->swizzles) -
-         sizeof(routing->swizzles[0]) * dst_slot);
+   if (info.swizzle_enable)
+      info.swizzle_count = dst_len;
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 248:
-    *
-    *     "It is UNDEFINED to set this field (Vertex URB Entry Read Length) to
-    *      0 indicating no Vertex URB data to be read.
-    *
-    *      This field should be set to the minimum length required to read the
-    *      maximum source attribute. The maximum source attribute is indicated
-    *      by the maximum value of the enabled Attribute # Source Attribute if
-    *      Attribute Swizzle Enable is set, Number of Output Attributes-1 if
-    *      enable is not set.
-    *
-    *        read_length = ceiling((max_source_attr+1)/2)
-    *
-    *      [errata] Corruption/Hang possible if length programmed larger than
-    *      recommended"
-    */
-   routing->source_len = max_src_slot + 1;
+   if (routing->initialized)
+      ilo_state_sbe_set_info(&routing->sbe, shader->info.dev, &info);
+   else
+      ilo_state_sbe_init(&routing->sbe, shader->info.dev, &info);
+
+   routing->src_len = info.vue_read_count;
+   memcpy(routing->src_semantics, src_semantics,
+         sizeof(src_semantics[0]) * routing->src_len);
+   memcpy(routing->src_indices, src_indices,
+         sizeof(src_indices[0]) * routing->src_len);
 
-   /* remember the states of the source */
-   kernel->routing_initialized = true;
-   kernel->routing_sprite_coord_enable = sprite_coord_enable;
-   memcpy(kernel->routing_src_semantics, src_semantics,
-         sizeof(kernel->routing_src_semantics[0]) * routing->source_len);
-   memcpy(kernel->routing_src_indices, src_indices,
-         sizeof(kernel->routing_src_indices[0]) * routing->source_len);
+   routing->initialized = true;
 
    return true;
 }
@@ -1147,7 +1394,7 @@ ilo_shader_get_kernel_param(const struct ilo_shader_state *shader,
 /**
  * Return the CSO of the selected kernel.
  */
-const struct ilo_shader_cso *
+const union ilo_shader_cso *
 ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader)
 {
    const struct ilo_shader *kernel = shader->shader;
@@ -1162,23 +1409,29 @@ ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader)
  */
 const struct pipe_stream_output_info *
 ilo_shader_get_kernel_so_info(const struct ilo_shader_state *shader)
+{
+   return &shader->info.stream_output;
+}
+
+const struct ilo_state_sol *
+ilo_shader_get_kernel_sol(const struct ilo_shader_state *shader)
 {
    const struct ilo_shader *kernel = shader->shader;
 
    assert(kernel);
 
-   return &kernel->so_info;
+   return &kernel->sol;
 }
 
 /**
  * Return the routing info of the selected kernel.
  */
-const struct ilo_kernel_routing *
-ilo_shader_get_kernel_routing(const struct ilo_shader_state *shader)
+const struct ilo_state_sbe *
+ilo_shader_get_kernel_sbe(const struct ilo_shader_state *shader)
 {
    const struct ilo_shader *kernel = shader->shader;
 
    assert(kernel);
 
-   return &kernel->routing;
+   return &kernel->routing.sbe;
 }
index 8a359001bb821c9d8aa5857e1d663152a42c44ab..d9f02a4746a7bbc9774973a11bc5b0d36126d69c 100644 (file)
@@ -28,6 +28,8 @@
 #ifndef ILO_SHADER_H
 #define ILO_SHADER_H
 
+#include "core/ilo_state_shader.h"
+
 #include "ilo_common.h"
 
 enum ilo_kernel_param {
@@ -81,23 +83,28 @@ enum ilo_kernel_param {
    ILO_KERNEL_PARAM_COUNT,
 };
 
-struct ilo_kernel_routing {
-   uint32_t const_interp_enable;
-   uint32_t point_sprite_enable;
-   unsigned source_skip, source_len;
-
-   bool swizzle_enable;
-   uint16_t swizzles[16];
-};
-
 struct intel_bo;
 struct ilo_builder;
 struct ilo_rasterizer_state;
 struct ilo_shader_cache;
 struct ilo_shader_state;
-struct ilo_shader_cso;
+struct ilo_state_sbe;
+struct ilo_state_sol;
 struct ilo_state_vector;
 
+union ilo_shader_cso {
+   struct ilo_state_vs vs;
+   struct ilo_state_hs hs;
+   struct ilo_state_ds ds;
+   struct ilo_state_gs gs;
+   struct ilo_state_ps ps;
+
+   struct {
+      struct ilo_state_vs vs;
+      struct ilo_state_gs sol;
+   } vs_sol;
+};
+
 struct ilo_shader_cache *
 ilo_shader_cache_create(void);
 
@@ -151,9 +158,9 @@ ilo_shader_select_kernel(struct ilo_shader_state *shader,
                          uint32_t dirty);
 
 bool
-ilo_shader_select_kernel_routing(struct ilo_shader_state *shader,
-                                 const struct ilo_shader_state *source,
-                                 const struct ilo_rasterizer_state *rasterizer);
+ilo_shader_select_kernel_sbe(struct ilo_shader_state *shader,
+                             const struct ilo_shader_state *source,
+                             const struct ilo_rasterizer_state *rasterizer);
 
 uint32_t
 ilo_shader_get_kernel_offset(const struct ilo_shader_state *shader);
@@ -162,13 +169,16 @@ int
 ilo_shader_get_kernel_param(const struct ilo_shader_state *shader,
                             enum ilo_kernel_param param);
 
-const struct ilo_shader_cso *
+const union ilo_shader_cso *
 ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader);
 
 const struct pipe_stream_output_info *
 ilo_shader_get_kernel_so_info(const struct ilo_shader_state *shader);
 
-const struct ilo_kernel_routing *
-ilo_shader_get_kernel_routing(const struct ilo_shader_state *shader);
+const struct ilo_state_sol *
+ilo_shader_get_kernel_sol(const struct ilo_shader_state *shader);
+
+const struct ilo_state_sbe *
+ilo_shader_get_kernel_sbe(const struct ilo_shader_state *shader);
 
 #endif /* ILO_SHADER_H */
index b1bd49a0b6c5e66dc4aef649c1842429bbe10d56..63534f33fa76b1545706d974427cdc832c251a0f 100644 (file)
  *    Chia-I Wu <olv@lunarg.com>
  */
 
-#include "core/ilo_state_3d.h"
+#include "util/u_dual_blend.h"
 #include "util/u_dynarray.h"
+#include "util/u_framebuffer.h"
 #include "util/u_helpers.h"
+#include "util/u_resource.h"
 #include "util/u_upload_mgr.h"
 
 #include "ilo_context.h"
+#include "ilo_format.h"
 #include "ilo_resource.h"
 #include "ilo_shader.h"
 #include "ilo_state.h"
 
+/**
+ * Translate a pipe primitive type to the matching hardware primitive type.
+ */
+static enum gen_3dprim_type
+ilo_translate_draw_mode(unsigned mode)
+{
+   static const enum gen_3dprim_type prim_mapping[PIPE_PRIM_MAX] = {
+      [PIPE_PRIM_POINTS]                     = GEN6_3DPRIM_POINTLIST,
+      [PIPE_PRIM_LINES]                      = GEN6_3DPRIM_LINELIST,
+      [PIPE_PRIM_LINE_LOOP]                  = GEN6_3DPRIM_LINELOOP,
+      [PIPE_PRIM_LINE_STRIP]                 = GEN6_3DPRIM_LINESTRIP,
+      [PIPE_PRIM_TRIANGLES]                  = GEN6_3DPRIM_TRILIST,
+      [PIPE_PRIM_TRIANGLE_STRIP]             = GEN6_3DPRIM_TRISTRIP,
+      [PIPE_PRIM_TRIANGLE_FAN]               = GEN6_3DPRIM_TRIFAN,
+      [PIPE_PRIM_QUADS]                      = GEN6_3DPRIM_QUADLIST,
+      [PIPE_PRIM_QUAD_STRIP]                 = GEN6_3DPRIM_QUADSTRIP,
+      [PIPE_PRIM_POLYGON]                    = GEN6_3DPRIM_POLYGON,
+      [PIPE_PRIM_LINES_ADJACENCY]            = GEN6_3DPRIM_LINELIST_ADJ,
+      [PIPE_PRIM_LINE_STRIP_ADJACENCY]       = GEN6_3DPRIM_LINESTRIP_ADJ,
+      [PIPE_PRIM_TRIANGLES_ADJACENCY]        = GEN6_3DPRIM_TRILIST_ADJ,
+      [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]   = GEN6_3DPRIM_TRISTRIP_ADJ,
+   };
+
+   assert(prim_mapping[mode]);
+
+   return prim_mapping[mode];
+}
+
+static enum gen_index_format
+ilo_translate_index_size(unsigned index_size)
+{
+   switch (index_size) {
+   case 1:                             return GEN6_INDEX_BYTE;
+   case 2:                             return GEN6_INDEX_WORD;
+   case 4:                             return GEN6_INDEX_DWORD;
+   default:
+      assert(!"unknown index size");
+      return GEN6_INDEX_BYTE;
+   }
+}
+
+static enum gen_mip_filter
+ilo_translate_mip_filter(unsigned filter)
+{
+   switch (filter) {
+   case PIPE_TEX_MIPFILTER_NEAREST:    return GEN6_MIPFILTER_NEAREST;
+   case PIPE_TEX_MIPFILTER_LINEAR:     return GEN6_MIPFILTER_LINEAR;
+   case PIPE_TEX_MIPFILTER_NONE:       return GEN6_MIPFILTER_NONE;
+   default:
+      assert(!"unknown mipfilter");
+      return GEN6_MIPFILTER_NONE;
+   }
+}
+
+static int
+ilo_translate_img_filter(unsigned filter)
+{
+   switch (filter) {
+   case PIPE_TEX_FILTER_NEAREST:       return GEN6_MAPFILTER_NEAREST;
+   case PIPE_TEX_FILTER_LINEAR:        return GEN6_MAPFILTER_LINEAR;
+   default:
+      assert(!"unknown sampler filter");
+      return GEN6_MAPFILTER_NEAREST;
+   }
+}
+
+static enum gen_texcoord_mode
+ilo_translate_address_wrap(unsigned wrap)
+{
+   switch (wrap) {
+   case PIPE_TEX_WRAP_CLAMP:           return GEN8_TEXCOORDMODE_HALF_BORDER;
+   case PIPE_TEX_WRAP_REPEAT:          return GEN6_TEXCOORDMODE_WRAP;
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:   return GEN6_TEXCOORDMODE_CLAMP;
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return GEN6_TEXCOORDMODE_CLAMP_BORDER;
+   case PIPE_TEX_WRAP_MIRROR_REPEAT:   return GEN6_TEXCOORDMODE_MIRROR;
+   case PIPE_TEX_WRAP_MIRROR_CLAMP:
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+   default:
+      assert(!"unknown sampler wrap mode");
+      return GEN6_TEXCOORDMODE_WRAP;
+   }
+}
+
+static enum gen_aniso_ratio
+ilo_translate_max_anisotropy(unsigned max_anisotropy)
+{
+   switch (max_anisotropy) {
+   case 0: case 1: case 2:             return GEN6_ANISORATIO_2;
+   case 3: case 4:                     return GEN6_ANISORATIO_4;
+   case 5: case 6:                     return GEN6_ANISORATIO_6;
+   case 7: case 8:                     return GEN6_ANISORATIO_8;
+   case 9: case 10:                    return GEN6_ANISORATIO_10;
+   case 11: case 12:                   return GEN6_ANISORATIO_12;
+   case 13: case 14:                   return GEN6_ANISORATIO_14;
+   default:                            return GEN6_ANISORATIO_16;
+   }
+}
+
+static enum gen_prefilter_op
+ilo_translate_shadow_func(unsigned func)
+{
+   /*
+    * For PIPE_FUNC_x, the reference value is on the left-hand side of the
+    * comparison, and 1.0 is returned when the comparison is true.
+    *
+    * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
+    * the comparison, and 0.0 is returned when the comparison is true.
+    */
+   switch (func) {
+   case PIPE_FUNC_NEVER:               return GEN6_PREFILTEROP_ALWAYS;
+   case PIPE_FUNC_LESS:                return GEN6_PREFILTEROP_LEQUAL;
+   case PIPE_FUNC_EQUAL:               return GEN6_PREFILTEROP_NOTEQUAL;
+   case PIPE_FUNC_LEQUAL:              return GEN6_PREFILTEROP_LESS;
+   case PIPE_FUNC_GREATER:             return GEN6_PREFILTEROP_GEQUAL;
+   case PIPE_FUNC_NOTEQUAL:            return GEN6_PREFILTEROP_EQUAL;
+   case PIPE_FUNC_GEQUAL:              return GEN6_PREFILTEROP_GREATER;
+   case PIPE_FUNC_ALWAYS:              return GEN6_PREFILTEROP_NEVER;
+   default:
+      assert(!"unknown shadow compare function");
+      return GEN6_PREFILTEROP_NEVER;
+   }
+}
+
+static enum gen_front_winding
+ilo_translate_front_ccw(unsigned front_ccw)
+{
+   return (front_ccw) ? GEN6_FRONTWINDING_CCW : GEN6_FRONTWINDING_CW;
+}
+
+static enum gen_cull_mode
+ilo_translate_cull_face(unsigned cull_face)
+{
+   switch (cull_face) {
+   case PIPE_FACE_NONE:                return GEN6_CULLMODE_NONE;
+   case PIPE_FACE_FRONT:               return GEN6_CULLMODE_FRONT;
+   case PIPE_FACE_BACK:                return GEN6_CULLMODE_BACK;
+   case PIPE_FACE_FRONT_AND_BACK:      return GEN6_CULLMODE_BOTH;
+   default:
+      assert(!"unknown face culling");
+      return GEN6_CULLMODE_NONE;
+   }
+}
+
+static enum gen_fill_mode
+ilo_translate_poly_mode(unsigned poly_mode)
+{
+   switch (poly_mode) {
+   case PIPE_POLYGON_MODE_FILL:        return GEN6_FILLMODE_SOLID;
+   case PIPE_POLYGON_MODE_LINE:        return GEN6_FILLMODE_WIREFRAME;
+   case PIPE_POLYGON_MODE_POINT:       return GEN6_FILLMODE_POINT;
+   default:
+      assert(!"unknown polygon mode");
+      return GEN6_FILLMODE_SOLID;
+   }
+}
+
+static enum gen_pixel_location
+ilo_translate_half_pixel_center(bool half_pixel_center)
+{
+   return (half_pixel_center) ? GEN6_PIXLOC_CENTER : GEN6_PIXLOC_UL_CORNER;
+}
+
+static enum gen_compare_function
+ilo_translate_compare_func(unsigned func)
+{
+   switch (func) {
+   case PIPE_FUNC_NEVER:               return GEN6_COMPAREFUNCTION_NEVER;
+   case PIPE_FUNC_LESS:                return GEN6_COMPAREFUNCTION_LESS;
+   case PIPE_FUNC_EQUAL:               return GEN6_COMPAREFUNCTION_EQUAL;
+   case PIPE_FUNC_LEQUAL:              return GEN6_COMPAREFUNCTION_LEQUAL;
+   case PIPE_FUNC_GREATER:             return GEN6_COMPAREFUNCTION_GREATER;
+   case PIPE_FUNC_NOTEQUAL:            return GEN6_COMPAREFUNCTION_NOTEQUAL;
+   case PIPE_FUNC_GEQUAL:              return GEN6_COMPAREFUNCTION_GEQUAL;
+   case PIPE_FUNC_ALWAYS:              return GEN6_COMPAREFUNCTION_ALWAYS;
+   default:
+      assert(!"unknown compare function");
+      return GEN6_COMPAREFUNCTION_NEVER;
+   }
+}
+
+static enum gen_stencil_op
+ilo_translate_stencil_op(unsigned stencil_op)
+{
+   switch (stencil_op) {
+   case PIPE_STENCIL_OP_KEEP:          return GEN6_STENCILOP_KEEP;
+   case PIPE_STENCIL_OP_ZERO:          return GEN6_STENCILOP_ZERO;
+   case PIPE_STENCIL_OP_REPLACE:       return GEN6_STENCILOP_REPLACE;
+   case PIPE_STENCIL_OP_INCR:          return GEN6_STENCILOP_INCRSAT;
+   case PIPE_STENCIL_OP_DECR:          return GEN6_STENCILOP_DECRSAT;
+   case PIPE_STENCIL_OP_INCR_WRAP:     return GEN6_STENCILOP_INCR;
+   case PIPE_STENCIL_OP_DECR_WRAP:     return GEN6_STENCILOP_DECR;
+   case PIPE_STENCIL_OP_INVERT:        return GEN6_STENCILOP_INVERT;
+   default:
+      assert(!"unknown stencil op");
+      return GEN6_STENCILOP_KEEP;
+   }
+}
+
+static enum gen_logic_op
+ilo_translate_logicop(unsigned logicop)
+{
+   switch (logicop) {
+   case PIPE_LOGICOP_CLEAR:            return GEN6_LOGICOP_CLEAR;
+   case PIPE_LOGICOP_NOR:              return GEN6_LOGICOP_NOR;
+   case PIPE_LOGICOP_AND_INVERTED:     return GEN6_LOGICOP_AND_INVERTED;
+   case PIPE_LOGICOP_COPY_INVERTED:    return GEN6_LOGICOP_COPY_INVERTED;
+   case PIPE_LOGICOP_AND_REVERSE:      return GEN6_LOGICOP_AND_REVERSE;
+   case PIPE_LOGICOP_INVERT:           return GEN6_LOGICOP_INVERT;
+   case PIPE_LOGICOP_XOR:              return GEN6_LOGICOP_XOR;
+   case PIPE_LOGICOP_NAND:             return GEN6_LOGICOP_NAND;
+   case PIPE_LOGICOP_AND:              return GEN6_LOGICOP_AND;
+   case PIPE_LOGICOP_EQUIV:            return GEN6_LOGICOP_EQUIV;
+   case PIPE_LOGICOP_NOOP:             return GEN6_LOGICOP_NOOP;
+   case PIPE_LOGICOP_OR_INVERTED:      return GEN6_LOGICOP_OR_INVERTED;
+   case PIPE_LOGICOP_COPY:             return GEN6_LOGICOP_COPY;
+   case PIPE_LOGICOP_OR_REVERSE:       return GEN6_LOGICOP_OR_REVERSE;
+   case PIPE_LOGICOP_OR:               return GEN6_LOGICOP_OR;
+   case PIPE_LOGICOP_SET:              return GEN6_LOGICOP_SET;
+   default:
+      assert(!"unknown logicop function");
+      return GEN6_LOGICOP_CLEAR;
+   }
+}
+
+static int
+ilo_translate_blend_func(unsigned blend)
+{
+   switch (blend) {
+   case PIPE_BLEND_ADD:                return GEN6_BLENDFUNCTION_ADD;
+   case PIPE_BLEND_SUBTRACT:           return GEN6_BLENDFUNCTION_SUBTRACT;
+   case PIPE_BLEND_REVERSE_SUBTRACT:   return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
+   case PIPE_BLEND_MIN:                return GEN6_BLENDFUNCTION_MIN;
+   case PIPE_BLEND_MAX:                return GEN6_BLENDFUNCTION_MAX;
+   default:
+      assert(!"unknown blend function");
+      return GEN6_BLENDFUNCTION_ADD;
+   }
+}
+
+static int
+ilo_translate_blend_factor(unsigned factor)
+{
+   switch (factor) {
+   case PIPE_BLENDFACTOR_ONE:                return GEN6_BLENDFACTOR_ONE;
+   case PIPE_BLENDFACTOR_SRC_COLOR:          return GEN6_BLENDFACTOR_SRC_COLOR;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:          return GEN6_BLENDFACTOR_SRC_ALPHA;
+   case PIPE_BLENDFACTOR_DST_ALPHA:          return GEN6_BLENDFACTOR_DST_ALPHA;
+   case PIPE_BLENDFACTOR_DST_COLOR:          return GEN6_BLENDFACTOR_DST_COLOR;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
+   case PIPE_BLENDFACTOR_CONST_COLOR:        return GEN6_BLENDFACTOR_CONST_COLOR;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:        return GEN6_BLENDFACTOR_CONST_ALPHA;
+   case PIPE_BLENDFACTOR_SRC1_COLOR:         return GEN6_BLENDFACTOR_SRC1_COLOR;
+   case PIPE_BLENDFACTOR_SRC1_ALPHA:         return GEN6_BLENDFACTOR_SRC1_ALPHA;
+   case PIPE_BLENDFACTOR_ZERO:               return GEN6_BLENDFACTOR_ZERO;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:      return GEN6_BLENDFACTOR_INV_SRC_COLOR;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:      return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:      return GEN6_BLENDFACTOR_INV_DST_ALPHA;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:      return GEN6_BLENDFACTOR_INV_DST_COLOR;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:    return GEN6_BLENDFACTOR_INV_CONST_COLOR;
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:    return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
+   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:     return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
+   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:     return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
+   default:
+      assert(!"unknown blend factor");
+      return GEN6_BLENDFACTOR_ONE;
+   }
+}
+
 static void
 finalize_shader_states(struct ilo_state_vector *vec)
 {
@@ -78,7 +350,7 @@ finalize_shader_states(struct ilo_state_vector *vec)
       /* need to setup SBE for FS */
       if (type == PIPE_SHADER_FRAGMENT && vec->dirty &
             (state | ILO_DIRTY_GS | ILO_DIRTY_VS | ILO_DIRTY_RASTERIZER)) {
-         if (ilo_shader_select_kernel_routing(shader,
+         if (ilo_shader_select_kernel_sbe(shader,
                (vec->gs) ? vec->gs : vec->vs, vec->rasterizer))
             vec->dirty |= state;
       }
@@ -97,7 +369,6 @@ finalize_cbuf_state(struct ilo_context *ilo,
       ~ilo_shader_get_kernel_param(sh, ILO_KERNEL_SKIP_CBUF0_UPLOAD);
 
    while (upload_mask) {
-      const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
       unsigned offset, i;
 
       i = u_bit_scan(&upload_mask);
@@ -105,14 +376,16 @@ finalize_cbuf_state(struct ilo_context *ilo,
       if (cbuf->cso[i].resource)
          continue;
 
-      u_upload_data(ilo->uploader, 0, cbuf->cso[i].user_buffer_size,
+      u_upload_data(ilo->uploader, 0, cbuf->cso[i].info.size,
             cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource);
 
-      ilo_gpe_init_view_surface_for_buffer(ilo->dev,
-            ilo_buffer(cbuf->cso[i].resource),
-            offset, cbuf->cso[i].user_buffer_size,
-            util_format_get_blocksize(elem_format), elem_format,
-            false, false, &cbuf->cso[i].surface);
+      cbuf->cso[i].info.buf = ilo_buffer(cbuf->cso[i].resource);
+      cbuf->cso[i].info.offset = offset;
+
+      memset(&cbuf->cso[i].surface, 0, sizeof(cbuf->cso[i].surface));
+      ilo_state_surface_init_for_buffer(&cbuf->cso[i].surface,
+            ilo->dev, &cbuf->cso[i].info);
+      cbuf->cso[i].surface.bo = cbuf->cso[i].info.buf->bo;
 
       ilo->state_vector.dirty |= ILO_DIRTY_CBUF;
    }
@@ -133,114 +406,380 @@ finalize_constant_buffers(struct ilo_context *ilo)
 static void
 finalize_index_buffer(struct ilo_context *ilo)
 {
+   const struct ilo_dev *dev = ilo->dev;
    struct ilo_state_vector *vec = &ilo->state_vector;
    const bool need_upload = (vec->draw->indexed &&
-         (vec->ib.user_buffer || vec->ib.offset % vec->ib.index_size));
+         (vec->ib.state.user_buffer ||
+          vec->ib.state.offset % vec->ib.state.index_size));
    struct pipe_resource *current_hw_res = NULL;
+   struct ilo_state_index_buffer_info info;
+   int64_t vertex_start_bias = 0;
 
    if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload)
       return;
 
+   /* make sure vec->ib.hw_resource changes when reallocated */
    pipe_resource_reference(&current_hw_res, vec->ib.hw_resource);
 
    if (need_upload) {
-      const unsigned offset = vec->ib.index_size * vec->draw->start;
-      const unsigned size = vec->ib.index_size * vec->draw->count;
+      const unsigned offset = vec->ib.state.index_size * vec->draw->start;
+      const unsigned size = vec->ib.state.index_size * vec->draw->count;
       unsigned hw_offset;
 
-      if (vec->ib.user_buffer) {
+      if (vec->ib.state.user_buffer) {
          u_upload_data(ilo->uploader, 0, size,
-               vec->ib.user_buffer + offset, &hw_offset, &vec->ib.hw_resource);
-      }
-      else {
-         u_upload_buffer(ilo->uploader, 0, vec->ib.offset + offset, size,
-               vec->ib.buffer, &hw_offset, &vec->ib.hw_resource);
+               vec->ib.state.user_buffer + offset,
+               &hw_offset, &vec->ib.hw_resource);
+      } else {
+         u_upload_buffer(ilo->uploader, 0,
+               vec->ib.state.offset + offset, size, vec->ib.state.buffer,
+               &hw_offset, &vec->ib.hw_resource);
       }
 
       /* the HW offset should be aligned */
-      assert(hw_offset % vec->ib.index_size == 0);
-      vec->ib.draw_start_offset = hw_offset / vec->ib.index_size;
+      assert(hw_offset % vec->ib.state.index_size == 0);
+      vertex_start_bias = hw_offset / vec->ib.state.index_size;
 
       /*
        * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
        * resource
        */
-      vec->ib.draw_start_offset -= vec->draw->start;
-   }
-   else {
-      pipe_resource_reference(&vec->ib.hw_resource, vec->ib.buffer);
+      vertex_start_bias -= vec->draw->start;
+   } else {
+      pipe_resource_reference(&vec->ib.hw_resource, vec->ib.state.buffer);
 
       /* note that index size may be zero when the draw is not indexed */
       if (vec->draw->indexed)
-         vec->ib.draw_start_offset = vec->ib.offset / vec->ib.index_size;
-      else
-         vec->ib.draw_start_offset = 0;
+         vertex_start_bias = vec->ib.state.offset / vec->ib.state.index_size;
    }
 
+   vec->draw_info.vertex_start += vertex_start_bias;
+
    /* treat the IB as clean if the HW states do not change */
    if (vec->ib.hw_resource == current_hw_res &&
-       vec->ib.hw_index_size == vec->ib.index_size)
+       vec->ib.hw_index_size == vec->ib.state.index_size)
       vec->dirty &= ~ILO_DIRTY_IB;
    else
-      vec->ib.hw_index_size = vec->ib.index_size;
+      vec->ib.hw_index_size = vec->ib.state.index_size;
 
    pipe_resource_reference(&current_hw_res, NULL);
+
+   memset(&info, 0, sizeof(info));
+   if (vec->ib.hw_resource) {
+      info.buf = ilo_buffer(vec->ib.hw_resource);
+      info.size = info.buf->bo_size;
+      info.format = ilo_translate_index_size(vec->ib.hw_index_size);
+
+      vec->ib.ib.bo = info.buf->bo;
+   }
+
+   ilo_state_index_buffer_set_info(&vec->ib.ib, dev, &info);
 }
 
 static void
 finalize_vertex_elements(struct ilo_context *ilo)
 {
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_ve_state *ve = vec->ve;
+   const bool last_element_edge_flag = (vec->vs &&
+         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG));
+   const bool prepend_vertexid = (vec->vs &&
+         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_VERTEXID));
+   const bool prepend_instanceid = (vec->vs &&
+         ilo_shader_get_kernel_param(vec->vs,
+            ILO_KERNEL_VS_INPUT_INSTANCEID));
+   const enum gen_index_format index_format = (vec->draw->indexed) ?
+      ilo_translate_index_size(vec->ib.state.index_size) : GEN6_INDEX_DWORD;
+
+   /* check for non-orthogonal states */
+   if (ve->vf_params.cv_topology != vec->draw_info.topology ||
+       ve->vf_params.prepend_vertexid != prepend_vertexid ||
+       ve->vf_params.prepend_instanceid != prepend_instanceid ||
+       ve->vf_params.last_element_edge_flag != last_element_edge_flag ||
+       ve->vf_params.cv_index_format != index_format ||
+       ve->vf_params.cut_index_enable != vec->draw->primitive_restart ||
+       ve->vf_params.cut_index != vec->draw->restart_index) {
+      ve->vf_params.cv_topology = vec->draw_info.topology;
+      ve->vf_params.prepend_vertexid = prepend_vertexid;
+      ve->vf_params.prepend_instanceid = prepend_instanceid;
+      ve->vf_params.last_element_edge_flag = last_element_edge_flag;
+      ve->vf_params.cv_index_format = index_format;
+      ve->vf_params.cut_index_enable = vec->draw->primitive_restart;
+      ve->vf_params.cut_index = vec->draw->restart_index;
+
+      ilo_state_vf_set_params(&ve->vf, dev, &ve->vf_params);
+
+      vec->dirty |= ILO_DIRTY_VE;
+   }
+}
+
+static void
+finalize_vertex_buffers(struct ilo_context *ilo)
+{
+   const struct ilo_dev *dev = ilo->dev;
    struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_state_vertex_buffer_info info;
+   unsigned i;
 
-   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS)))
+   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VB)))
       return;
 
-   vec->dirty |= ILO_DIRTY_VE;
+   memset(&info, 0, sizeof(info));
+
+   for (i = 0; i < vec->ve->vb_count; i++) {
+      const unsigned pipe_idx = vec->ve->vb_mapping[i];
+      const struct pipe_vertex_buffer *cso = &vec->vb.states[pipe_idx];
+
+      if (cso->buffer) {
+         info.buf = ilo_buffer(cso->buffer);
+         info.offset = cso->buffer_offset;
+         info.size = info.buf->bo_size;
+
+         info.stride = cso->stride;
+
+         vec->vb.vb[i].bo = info.buf->bo;
+      } else {
+         memset(&info, 0, sizeof(info));
+      }
+
+      ilo_state_vertex_buffer_set_info(&vec->vb.vb[i], dev, &info);
+   }
+}
+
+static void
+finalize_urb(struct ilo_context *ilo)
+{
+   const uint16_t attr_size = sizeof(uint32_t) * 4;
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_state_urb_info info;
+
+   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS |
+                       ILO_DIRTY_GS | ILO_DIRTY_FS)))
+      return;
+
+   memset(&info, 0, sizeof(info));
+
+   info.ve_entry_size = attr_size * ilo_state_vf_get_attr_count(&vec->ve->vf);
+
+   if (vec->vs) {
+      info.vs_const_data = (bool)
+         (ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_PCB_CBUF0_SIZE) +
+          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_PCB_UCP_SIZE));
+      info.vs_entry_size = attr_size *
+         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_OUTPUT_COUNT);
+   }
+
+   if (vec->gs) {
+      info.gs_const_data = (bool)
+         ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_PCB_CBUF0_SIZE);
 
-   vec->ve->last_cso_edgeflag = false;
-   if (vec->ve->count && vec->vs &&
-         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)) {
-      vec->ve->edgeflag_cso = vec->ve->cso[vec->ve->count - 1];
-      ilo_gpe_set_ve_edgeflag(ilo->dev, &vec->ve->edgeflag_cso);
-      vec->ve->last_cso_edgeflag = true;
-   }
-
-   vec->ve->prepend_nosrc_cso = false;
-   if (vec->vs &&
-       (ilo_shader_get_kernel_param(vec->vs,
-                                    ILO_KERNEL_VS_INPUT_INSTANCEID) ||
-        ilo_shader_get_kernel_param(vec->vs,
-                                    ILO_KERNEL_VS_INPUT_VERTEXID))) {
-      ilo_gpe_init_ve_nosrc(ilo->dev,
-            GEN6_VFCOMP_STORE_VID,
-            GEN6_VFCOMP_STORE_IID,
-            GEN6_VFCOMP_NOSTORE,
-            GEN6_VFCOMP_NOSTORE,
-            &vec->ve->nosrc_cso);
-      vec->ve->prepend_nosrc_cso = true;
-   } else if (!vec->vs) {
-      /* generate VUE header */
-      ilo_gpe_init_ve_nosrc(ilo->dev,
-            GEN6_VFCOMP_STORE_0, /* Reserved */
-            GEN6_VFCOMP_STORE_0, /* Render Target Array Index */
-            GEN6_VFCOMP_STORE_0, /* Viewport Index */
-            GEN6_VFCOMP_STORE_0, /* Point Width */
-            &vec->ve->nosrc_cso);
-      vec->ve->prepend_nosrc_cso = true;
-   } else if (!vec->ve->count) {
       /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 92:
+       * From the Ivy Bridge PRM, volume 2 part 1, page 189:
+       *
+       *     "All outputs of a GS thread will be stored in the single GS
+       *      thread output URB entry."
        *
-       *    "SW must ensure that at least one vertex element is defined prior
-       *     to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
+       * TODO
        */
-      ilo_gpe_init_ve_nosrc(ilo->dev,
-            GEN6_VFCOMP_STORE_0,
-            GEN6_VFCOMP_STORE_0,
-            GEN6_VFCOMP_STORE_0,
-            GEN6_VFCOMP_STORE_1_FP,
-            &vec->ve->nosrc_cso);
-      vec->ve->prepend_nosrc_cso = true;
+      info.gs_entry_size = attr_size *
+         ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_OUTPUT_COUNT);
+   }
+
+   if (vec->fs) {
+      info.ps_const_data = (bool)
+         ilo_shader_get_kernel_param(vec->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
+   }
+
+   ilo_state_urb_set_info(&vec->urb, dev, &info);
+}
+
+static void
+finalize_viewport(struct ilo_context *ilo)
+{
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+
+   if (vec->dirty & ILO_DIRTY_VIEWPORT) {
+      ilo_state_viewport_set_params(&vec->viewport.vp,
+            dev, &vec->viewport.params, false);
+   } else if (vec->dirty & ILO_DIRTY_SCISSOR) {
+      ilo_state_viewport_set_params(&vec->viewport.vp,
+            dev, &vec->viewport.params, true);
+      vec->dirty |= ILO_DIRTY_VIEWPORT;
+   }
+}
+
+static bool
+can_enable_gb_test(const struct ilo_rasterizer_state *rasterizer,
+                   const struct ilo_viewport_state *viewport,
+                   const struct ilo_fb_state *fb)
+{
+   unsigned i;
+
+   /*
+    * There are several reasons that guard band test should be disabled
+    *
+    *  - GL wide points (to avoid partially visibie object)
+    *  - GL wide or AA lines (to avoid partially visibie object)
+    *  - missing 2D clipping
+    */
+   if (rasterizer->state.point_size_per_vertex ||
+       rasterizer->state.point_size > 1.0f ||
+       rasterizer->state.line_width > 1.0f ||
+       rasterizer->state.line_smooth)
+      return false;
+
+   for (i = 0; i < viewport->params.count; i++) {
+      const struct ilo_state_viewport_matrix_info *mat =
+         &viewport->matrices[i];
+      float min_x, max_x, min_y, max_y;
+
+      min_x = -1.0f * fabsf(mat->scale[0]) + mat->translate[0];
+      max_x =  1.0f * fabsf(mat->scale[0]) + mat->translate[0];
+      min_y = -1.0f * fabsf(mat->scale[1]) + mat->translate[1];
+      max_y =  1.0f * fabsf(mat->scale[1]) + mat->translate[1];
+
+      if (min_x > 0.0f || max_x < fb->state.width ||
+          min_y > 0.0f || max_y < fb->state.height)
+         return false;
+   }
+
+   return true;
+}
+
+static void
+finalize_rasterizer(struct ilo_context *ilo)
+{
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_rasterizer_state *rasterizer = vec->rasterizer;
+   struct ilo_state_raster_info *info = &vec->rasterizer->info;
+   const bool gb_test_enable =
+      can_enable_gb_test(rasterizer, &vec->viewport, &vec->fb);
+   const bool multisample =
+      (rasterizer->state.multisample && vec->fb.num_samples > 1);
+   const uint8_t barycentric_interps = ilo_shader_get_kernel_param(vec->fs,
+         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
+
+   /* check for non-orthogonal states */
+   if (info->clip.viewport_count != vec->viewport.params.count ||
+       info->clip.gb_test_enable != gb_test_enable ||
+       info->setup.msaa_enable != multisample ||
+       info->setup.line_msaa_enable != multisample ||
+       info->tri.depth_offset_format != vec->fb.depth_offset_format ||
+       info->scan.sample_count != vec->fb.num_samples ||
+       info->scan.sample_mask != vec->sample_mask ||
+       info->scan.barycentric_interps != barycentric_interps ||
+       info->params.any_integer_rt != vec->fb.has_integer_rt ||
+       info->params.hiz_enable != vec->fb.has_hiz) {
+      info->clip.viewport_count = vec->viewport.params.count;
+      info->clip.gb_test_enable = gb_test_enable;
+      info->setup.msaa_enable = multisample;
+      info->setup.line_msaa_enable = multisample;
+      info->tri.depth_offset_format = vec->fb.depth_offset_format;
+      info->scan.sample_count = vec->fb.num_samples;
+      info->scan.sample_mask = vec->sample_mask;
+      info->scan.barycentric_interps = barycentric_interps;
+      info->params.any_integer_rt = vec->fb.has_integer_rt;
+      info->params.hiz_enable = vec->fb.has_hiz;
+
+      ilo_state_raster_set_info(&rasterizer->rs, dev, &rasterizer->info);
+
+      vec->dirty |= ILO_DIRTY_RASTERIZER;
+   }
+}
+
+static bool
+finalize_blend_rt(struct ilo_context *ilo)
+{
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   const struct ilo_fb_state *fb = &vec->fb;
+   struct ilo_blend_state *blend = vec->blend;
+   struct ilo_state_cc_blend_info *info = &vec->blend->info.blend;
+   bool changed = false;
+   unsigned i;
+
+   if (!(vec->dirty & (ILO_DIRTY_FB | ILO_DIRTY_BLEND)))
+      return false;
+
+   /* set up one for dummy RT writes */
+   if (!fb->state.nr_cbufs) {
+      if (info->rt != &blend->dummy_rt) {
+         info->rt = &blend->dummy_rt;
+         info->rt_count = 1;
+         changed = true;
+      }
+
+      return changed;
+   }
+
+   if (info->rt != blend->effective_rt ||
+       info->rt_count != fb->state.nr_cbufs) {
+      info->rt = blend->effective_rt;
+      info->rt_count = fb->state.nr_cbufs;
+      changed = true;
+   }
+
+   for (i = 0; i < fb->state.nr_cbufs; i++) {
+      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
+      struct ilo_state_cc_blend_rt_info *rt = &blend->effective_rt[i];
+      /* ignore logicop when not UNORM */
+      const bool logicop_enable =
+         (blend->rt[i].logicop_enable && caps->is_unorm);
+
+      if (rt->cv_is_unorm != caps->is_unorm ||
+          rt->cv_is_integer != caps->is_integer ||
+          rt->logicop_enable != logicop_enable ||
+          rt->force_dst_alpha_one != caps->force_dst_alpha_one) {
+         rt->cv_is_unorm = caps->is_unorm;
+         rt->cv_is_integer = caps->is_integer;
+         rt->logicop_enable = logicop_enable;
+         rt->force_dst_alpha_one = caps->force_dst_alpha_one;
+
+         changed = true;
+      }
+   }
+
+   return changed;
+}
+
+static void
+finalize_blend(struct ilo_context *ilo)
+{
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_blend_state *blend = vec->blend;
+   struct ilo_state_cc_info *info = &blend->info;
+   const bool sample_count_one = (vec->fb.num_samples <= 1);
+   const bool float_source0_alpha =
+      (!vec->fb.state.nr_cbufs || !vec->fb.state.cbufs[0] ||
+       !util_format_is_pure_integer(vec->fb.state.cbufs[0]->format));
+
+   /* check for non-orthogonal states */
+   if (finalize_blend_rt(ilo) ||
+       info->alpha.cv_sample_count_one != sample_count_one ||
+       info->alpha.cv_float_source0_alpha != float_source0_alpha ||
+       info->alpha.test_enable != vec->dsa->alpha_test ||
+       info->alpha.test_func != vec->dsa->alpha_func ||
+       memcmp(&info->stencil, &vec->dsa->stencil, sizeof(info->stencil)) ||
+       memcmp(&info->depth, &vec->dsa->depth, sizeof(info->depth)) ||
+       memcmp(&info->params, &vec->cc_params, sizeof(info->params))) {
+      info->alpha.cv_sample_count_one = sample_count_one;
+      info->alpha.cv_float_source0_alpha = float_source0_alpha;
+      info->alpha.test_enable = vec->dsa->alpha_test;
+      info->alpha.test_func = vec->dsa->alpha_func;
+      info->stencil = vec->dsa->stencil;
+      info->depth = vec->dsa->depth;
+      info->params = vec->cc_params;
+
+      ilo_state_cc_set_info(&blend->cc, dev, info);
+
+      blend->alpha_may_kill = (info->alpha.alpha_to_coverage ||
+                               info->alpha.test_enable);
+
+      vec->dirty |= ILO_DIRTY_BLEND;
    }
 }
 
@@ -254,10 +793,24 @@ ilo_finalize_3d_states(struct ilo_context *ilo,
 {
    ilo->state_vector.draw = draw;
 
+   ilo->state_vector.draw_info.topology = ilo_translate_draw_mode(draw->mode);
+   ilo->state_vector.draw_info.indexed = draw->indexed;
+   ilo->state_vector.draw_info.vertex_count = draw->count;
+   ilo->state_vector.draw_info.vertex_start = draw->start;
+   ilo->state_vector.draw_info.instance_count = draw->instance_count;
+   ilo->state_vector.draw_info.instance_start = draw->start_instance;
+   ilo->state_vector.draw_info.vertex_base = draw->index_bias;
+
+   finalize_blend(ilo);
    finalize_shader_states(&ilo->state_vector);
    finalize_constant_buffers(ilo);
    finalize_index_buffer(ilo);
    finalize_vertex_elements(ilo);
+   finalize_vertex_buffers(ilo);
+
+   finalize_urb(ilo);
+   finalize_rasterizer(ilo);
+   finalize_viewport(ilo);
 
    u_upload_unmap(ilo->uploader);
 }
@@ -301,12 +854,79 @@ ilo_create_blend_state(struct pipe_context *pipe,
                        const struct pipe_blend_state *state)
 {
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
+   struct ilo_state_cc_info *info;
    struct ilo_blend_state *blend;
+   int i;
 
-   blend = MALLOC_STRUCT(ilo_blend_state);
+   blend = CALLOC_STRUCT(ilo_blend_state);
    assert(blend);
 
-   ilo_gpe_init_blend(dev, state, blend);
+   info = &blend->info;
+
+   info->alpha.cv_float_source0_alpha = true;
+   info->alpha.cv_sample_count_one = true;
+   info->alpha.alpha_to_one = state->alpha_to_one;
+   info->alpha.alpha_to_coverage = state->alpha_to_coverage;
+   info->alpha.test_enable = false;
+   info->alpha.test_func = GEN6_COMPAREFUNCTION_ALWAYS;
+
+   info->stencil.cv_has_buffer = true;
+   info->depth.cv_has_buffer= true;
+
+   info->blend.rt = blend->effective_rt;
+   info->blend.rt_count = 1;
+   info->blend.dither_enable = state->dither;
+
+   for (i = 0; i < ARRAY_SIZE(blend->rt); i++) {
+      const struct pipe_rt_blend_state *rt = &state->rt[i];
+      struct ilo_state_cc_blend_rt_info *rt_info = &blend->rt[i];
+
+      rt_info->cv_has_buffer = true;
+      rt_info->cv_is_unorm = true;
+      rt_info->cv_is_integer = false;
+
+      /* logic op takes precedence over blending */
+      if (state->logicop_enable) {
+         rt_info->logicop_enable = true;
+         rt_info->logicop_func = ilo_translate_logicop(state->logicop_func);
+      } else if (rt->blend_enable) {
+         rt_info->blend_enable = true;
+
+         rt_info->rgb_src = ilo_translate_blend_factor(rt->rgb_src_factor);
+         rt_info->rgb_dst = ilo_translate_blend_factor(rt->rgb_dst_factor);
+         rt_info->rgb_func = ilo_translate_blend_func(rt->rgb_func);
+
+         rt_info->a_src = ilo_translate_blend_factor(rt->alpha_src_factor);
+         rt_info->a_dst = ilo_translate_blend_factor(rt->alpha_dst_factor);
+         rt_info->a_func = ilo_translate_blend_func(rt->alpha_func);
+      }
+
+      if (!(rt->colormask & PIPE_MASK_A))
+         rt_info->argb_write_disables |= (1 << 3);
+      if (!(rt->colormask & PIPE_MASK_R))
+         rt_info->argb_write_disables |= (1 << 2);
+      if (!(rt->colormask & PIPE_MASK_G))
+         rt_info->argb_write_disables |= (1 << 1);
+      if (!(rt->colormask & PIPE_MASK_B))
+         rt_info->argb_write_disables |= (1 << 0);
+
+      if (!state->independent_blend_enable) {
+         for (i = 1; i < ARRAY_SIZE(blend->rt); i++)
+            blend->rt[i] = *rt_info;
+         break;
+      }
+   }
+
+   memcpy(blend->effective_rt, blend->rt, sizeof(blend->rt));
+
+   blend->dummy_rt.argb_write_disables = 0xf;
+
+   if (!ilo_state_cc_init(&blend->cc, dev, &blend->info)) {
+      FREE(blend);
+      return NULL;
+   }
+
+   blend->dual_blend = util_blend_state_is_dual(state, 0);
 
    return blend;
 }
@@ -333,11 +953,105 @@ ilo_create_sampler_state(struct pipe_context *pipe,
 {
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_sampler_cso *sampler;
+   struct ilo_state_sampler_info info;
+   struct ilo_state_sampler_border_info border;
 
-   sampler = MALLOC_STRUCT(ilo_sampler_cso);
+   sampler = CALLOC_STRUCT(ilo_sampler_cso);
    assert(sampler);
 
-   ilo_gpe_init_sampler_cso(dev, state, sampler);
+   memset(&info, 0, sizeof(info));
+
+   info.non_normalized = !state->normalized_coords;
+   if (state->normalized_coords) {
+      info.lod_bias = state->lod_bias;
+      info.min_lod = state->min_lod;
+      info.max_lod = state->max_lod;
+
+      info.mip_filter = ilo_translate_mip_filter(state->min_mip_filter);
+   } else {
+      /* work around a bug in util_blitter */
+      info.mip_filter = GEN6_MIPFILTER_NONE;
+   }
+
+   if (state->max_anisotropy) {
+      info.min_filter = GEN6_MAPFILTER_ANISOTROPIC;
+      info.mag_filter = GEN6_MAPFILTER_ANISOTROPIC;
+   } else {
+      info.min_filter = ilo_translate_img_filter(state->min_img_filter);
+      info.mag_filter = ilo_translate_img_filter(state->mag_img_filter);
+   }
+
+   info.max_anisotropy = ilo_translate_max_anisotropy(state->max_anisotropy);
+
+   /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
+   if (info.mip_filter == GEN6_MIPFILTER_NONE && info.min_lod > 0.0f) {
+      info.min_lod = 0.0f;
+      info.mag_filter = info.min_filter;
+   }
+
+   if (state->seamless_cube_map) {
+      if (state->min_img_filter == PIPE_TEX_FILTER_NEAREST ||
+          state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) {
+         info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+         info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+         info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+      } else {
+         info.tcx_ctrl = GEN6_TEXCOORDMODE_CUBE;
+         info.tcy_ctrl = GEN6_TEXCOORDMODE_CUBE;
+         info.tcz_ctrl = GEN6_TEXCOORDMODE_CUBE;
+      }
+   } else {
+      info.tcx_ctrl = ilo_translate_address_wrap(state->wrap_s);
+      info.tcy_ctrl = ilo_translate_address_wrap(state->wrap_t);
+      info.tcz_ctrl = ilo_translate_address_wrap(state->wrap_r);
+
+      if (ilo_dev_gen(dev) < ILO_GEN(8)) {
+         /*
+          * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
+          * PIPE_TEX_WRAP_CLAMP_TO_EDGE;  for linear filtering,
+          * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
+          * additionally clamping the texture coordinates to [0.0, 1.0].
+          *
+          * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8.  The
+          * clamping has to be taken care of in the shaders.  There are two
+          * filters here, but let the minification one has a say.
+          */
+         const bool clamp_is_to_edge =
+            (state->min_img_filter == PIPE_TEX_FILTER_NEAREST);
+
+         if (clamp_is_to_edge) {
+            if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
+               info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+            if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
+               info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+            if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
+               info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
+         } else {
+            if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
+               info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
+               sampler->saturate_s = true;
+            }
+            if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
+               info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
+               sampler->saturate_t = true;
+            }
+            if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
+               info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
+               sampler->saturate_r = true;
+            }
+         }
+      }
+   }
+
+   if (state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
+      info.shadow_func = ilo_translate_shadow_func(state->compare_func);
+
+   ilo_state_sampler_init(&sampler->sampler, dev, &info);
+
+   memset(&border, 0, sizeof(border));
+   memcpy(border.rgba.f, state->border_color.f, sizeof(border.rgba.f));
+
+   ilo_state_sampler_border_init(&sampler->border, dev, &border);
 
    return sampler;
 }
@@ -403,12 +1117,74 @@ ilo_create_rasterizer_state(struct pipe_context *pipe,
 {
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_rasterizer_state *rast;
+   struct ilo_state_raster_info *info;
 
-   rast = MALLOC_STRUCT(ilo_rasterizer_state);
+   rast = CALLOC_STRUCT(ilo_rasterizer_state);
    assert(rast);
 
    rast->state = *state;
-   ilo_gpe_init_rasterizer(dev, state, rast);
+
+   info = &rast->info;
+
+   info->clip.clip_enable = true;
+   info->clip.stats_enable = true;
+   info->clip.viewport_count = 1;
+   info->clip.force_rtaindex_zero = true;
+   info->clip.user_clip_enables = state->clip_plane_enable;
+   info->clip.gb_test_enable = true;
+   info->clip.xy_test_enable = true;
+   info->clip.z_far_enable = state->depth_clip;
+   info->clip.z_near_enable = state->depth_clip;
+   info->clip.z_near_zero = state->clip_halfz;
+
+   info->setup.first_vertex_provoking = state->flatshade_first;
+   info->setup.viewport_transform = true;
+   info->setup.scissor_enable = state->scissor;
+   info->setup.msaa_enable = false;
+   info->setup.line_msaa_enable = false;
+   info->point.aa_enable = state->point_smooth;
+   info->point.programmable_width = state->point_size_per_vertex;
+   info->line.aa_enable = state->line_smooth;
+   info->line.stipple_enable = state->line_stipple_enable;
+   info->line.giq_enable = true;
+   info->line.giq_last_pixel = state->line_last_pixel;
+   info->tri.front_winding = ilo_translate_front_ccw(state->front_ccw);
+   info->tri.cull_mode = ilo_translate_cull_face(state->cull_face);
+   info->tri.fill_mode_front = ilo_translate_poly_mode(state->fill_front);
+   info->tri.fill_mode_back = ilo_translate_poly_mode(state->fill_back);
+   info->tri.depth_offset_format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
+   info->tri.depth_offset_solid = state->offset_tri;
+   info->tri.depth_offset_wireframe = state->offset_line;
+   info->tri.depth_offset_point = state->offset_point;
+   info->tri.poly_stipple_enable = state->poly_stipple_enable;
+
+   info->scan.stats_enable = true;
+   info->scan.sample_count = 1;
+   info->scan.pixloc =
+      ilo_translate_half_pixel_center(state->half_pixel_center);
+   info->scan.sample_mask = ~0u;
+   info->scan.zw_interp = GEN6_ZW_INTERP_PIXEL;
+   info->scan.barycentric_interps = GEN6_INTERP_PERSPECTIVE_PIXEL;
+   info->scan.earlyz_control = GEN7_EDSC_NORMAL;
+   info->scan.earlyz_op = ILO_STATE_RASTER_EARLYZ_NORMAL;
+   info->scan.earlyz_stencil_clear = false;
+
+   info->params.any_integer_rt = false;
+   info->params.hiz_enable = true;
+   info->params.point_width =
+      (state->point_size == 0.0f) ? 1.0f : state->point_size;
+   info->params.line_width =
+      (state->line_width == 0.0f) ? 1.0f : state->line_width;
+
+   info->params.depth_offset_scale = state->offset_scale;
+   /*
+    * Scale the constant term.  The minimum representable value used by the HW
+    * is not large enouch to be the minimum resolvable difference.
+    */
+   info->params.depth_offset_const = state->offset_units * 2.0f;
+   info->params.depth_offset_clamp = state->offset_clamp;
+
+   ilo_state_raster_init(&rast->rs, dev, info);
 
    return rast;
 }
@@ -416,10 +1192,20 @@ ilo_create_rasterizer_state(struct pipe_context *pipe,
 static void
 ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
 {
+   const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
    vec->rasterizer = state;
 
+   if (vec->rasterizer) {
+      struct ilo_state_line_stipple_info info;
+
+      info.pattern = vec->rasterizer->state.line_stipple_pattern;
+      info.repeat_count = vec->rasterizer->state.line_stipple_factor + 1;
+
+      ilo_state_line_stipple_set_info(&vec->line_stipple, dev, &info);
+   }
+
    vec->dirty |= ILO_DIRTY_RASTERIZER;
 }
 
@@ -433,13 +1219,48 @@ static void *
 ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
                                      const struct pipe_depth_stencil_alpha_state *state)
 {
-   const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_dsa_state *dsa;
+   int i;
 
-   dsa = MALLOC_STRUCT(ilo_dsa_state);
+   dsa = CALLOC_STRUCT(ilo_dsa_state);
    assert(dsa);
 
-   ilo_gpe_init_dsa(dev, state, dsa);
+   dsa->depth.cv_has_buffer = true;
+   dsa->depth.test_enable = state->depth.enabled;
+   dsa->depth.write_enable = state->depth.writemask;
+   dsa->depth.test_func = ilo_translate_compare_func(state->depth.func);
+
+   dsa->stencil.cv_has_buffer = true;
+   for (i = 0; i < ARRAY_SIZE(state->stencil); i++) {
+      const struct pipe_stencil_state *stencil = &state->stencil[i];
+      struct ilo_state_cc_stencil_op_info *op;
+
+      if (!stencil->enabled)
+         break;
+
+      if (i == 0) {
+         dsa->stencil.test_enable = true;
+         dsa->stencil_front.test_mask = stencil->valuemask;
+         dsa->stencil_front.write_mask = stencil->writemask;
+
+         op = &dsa->stencil.front;
+      } else {
+         dsa->stencil.twosided_enable = true;
+         dsa->stencil_back.test_mask = stencil->valuemask;
+         dsa->stencil_back.write_mask = stencil->writemask;
+
+         op = &dsa->stencil.back;
+      }
+
+      op->test_func = ilo_translate_compare_func(stencil->func);
+      op->fail_op = ilo_translate_stencil_op(stencil->fail_op);
+      op->zfail_op = ilo_translate_stencil_op(stencil->zfail_op);
+      op->zpass_op = ilo_translate_stencil_op(stencil->zpass_op);
+   }
+
+   dsa->alpha_test = state->alpha.enabled;
+   dsa->alpha_ref = state->alpha.ref_value;
+   dsa->alpha_func = ilo_translate_compare_func(state->alpha.func);
 
    return dsa;
 }
@@ -450,6 +1271,17 @@ ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
    vec->dsa = state;
+   if (vec->dsa) {
+      vec->cc_params.alpha_ref = vec->dsa->alpha_ref;
+      vec->cc_params.stencil_front.test_mask =
+         vec->dsa->stencil_front.test_mask;
+      vec->cc_params.stencil_front.write_mask =
+         vec->dsa->stencil_front.write_mask;
+      vec->cc_params.stencil_back.test_mask =
+         vec->dsa->stencil_back.test_mask;
+      vec->cc_params.stencil_back.write_mask =
+         vec->dsa->stencil_back.write_mask;
+   }
 
    vec->dirty |= ILO_DIRTY_DSA;
 }
@@ -575,12 +1407,60 @@ ilo_create_vertex_elements_state(struct pipe_context *pipe,
                                  const struct pipe_vertex_element *elements)
 {
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
+   struct ilo_state_vf_element_info vf_elements[PIPE_MAX_ATTRIBS];
+   unsigned instance_divisors[PIPE_MAX_ATTRIBS];
+   struct ilo_state_vf_info vf_info;
    struct ilo_ve_state *ve;
+   unsigned i;
 
-   ve = MALLOC_STRUCT(ilo_ve_state);
+   ve = CALLOC_STRUCT(ilo_ve_state);
    assert(ve);
 
-   ilo_gpe_init_ve(dev, num_elements, elements, ve);
+   for (i = 0; i < num_elements; i++) {
+      const struct pipe_vertex_element *elem = &elements[i];
+      struct ilo_state_vf_element_info *attr = &vf_elements[i];
+      unsigned hw_idx;
+
+      /*
+       * map the pipe vb to the hardware vb, which has a fixed instance
+       * divisor
+       */
+      for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
+         if (ve->vb_mapping[hw_idx] == elem->vertex_buffer_index &&
+             instance_divisors[hw_idx] == elem->instance_divisor)
+            break;
+      }
+
+      /* create one if there is no matching hardware vb */
+      if (hw_idx >= ve->vb_count) {
+         hw_idx = ve->vb_count++;
+
+         ve->vb_mapping[hw_idx] = elem->vertex_buffer_index;
+         instance_divisors[hw_idx] = elem->instance_divisor;
+      }
+
+      attr->buffer = hw_idx;
+      attr->vertex_offset = elem->src_offset;
+      attr->format = ilo_format_translate_vertex(dev, elem->src_format);
+      attr->format_size = util_format_get_blocksize(elem->src_format);
+      attr->component_count = util_format_get_nr_components(elem->src_format);
+      attr->is_integer = util_format_is_pure_integer(elem->src_format);
+
+      attr->instancing_enable = (elem->instance_divisor != 0);
+      attr->instancing_step_rate = elem->instance_divisor;
+   }
+
+   memset(&vf_info, 0, sizeof(vf_info));
+   vf_info.data = ve->vf_data;
+   vf_info.data_size = sizeof(ve->vf_data);
+   vf_info.elements = vf_elements;
+   vf_info.element_count = num_elements;
+   /* vf_info.params and ve->vf_params are both zeroed */
+
+   if (!ilo_state_vf_init(&ve->vf, dev, &vf_info)) {
+      FREE(ve);
+      return NULL;
+   }
 
    return ve;
 }
@@ -609,7 +1489,7 @@ ilo_set_blend_color(struct pipe_context *pipe,
 {
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
-   vec->blend_color = *state;
+   memcpy(vec->cc_params.blend_rgba, state->color, sizeof(state->color));
 
    vec->dirty |= ILO_DIRTY_BLEND_COLOR;
 }
@@ -626,6 +1506,9 @@ ilo_set_stencil_ref(struct pipe_context *pipe,
 
    vec->stencil_ref = *state;
 
+   vec->cc_params.stencil_front.test_ref = state->ref_value[0];
+   vec->cc_params.stencil_back.test_ref = state->ref_value[1];
+
    vec->dirty |= ILO_DIRTY_STENCIL_REF;
 }
 
@@ -675,47 +1558,47 @@ ilo_set_constant_buffer(struct pipe_context *pipe,
 
          pipe_resource_reference(&cso->resource, buf[i].buffer);
 
+         cso->info.access = ILO_STATE_SURFACE_ACCESS_DP_DATA;
+         cso->info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
+         cso->info.format_size = 16;
+         cso->info.struct_size = 16;
+         cso->info.readonly = true;
+         cso->info.size = buf[i].buffer_size;
+
          if (buf[i].buffer) {
-            const enum pipe_format elem_format =
-               PIPE_FORMAT_R32G32B32A32_FLOAT;
+            cso->info.buf = ilo_buffer(buf[i].buffer);
+            cso->info.offset = buf[i].buffer_offset;
 
-            ilo_gpe_init_view_surface_for_buffer(dev,
-                  ilo_buffer(buf[i].buffer),
-                  buf[i].buffer_offset, buf[i].buffer_size,
-                  util_format_get_blocksize(elem_format), elem_format,
-                  false, false, &cso->surface);
+            memset(&cso->surface, 0, sizeof(cso->surface));
+            ilo_state_surface_init_for_buffer(&cso->surface, dev, &cso->info);
+            cso->surface.bo = cso->info.buf->bo;
 
             cso->user_buffer = NULL;
-            cso->user_buffer_size = 0;
 
             cbuf->enabled_mask |= 1 << (index + i);
-         }
-         else if (buf[i].user_buffer) {
-            cso->surface.bo = NULL;
-
+         } else if (buf[i].user_buffer) {
+            cso->info.buf = NULL;
             /* buffer_offset does not apply for user buffer */
             cso->user_buffer = buf[i].user_buffer;
-            cso->user_buffer_size = buf[i].buffer_size;
 
             cbuf->enabled_mask |= 1 << (index + i);
-         }
-         else {
-            cso->surface.bo = NULL;
+         } else {
+            cso->info.buf = NULL;
+            cso->info.size = 0;
             cso->user_buffer = NULL;
-            cso->user_buffer_size = 0;
 
             cbuf->enabled_mask &= ~(1 << (index + i));
          }
       }
-   }
-   else {
+   } else {
       for (i = 0; i < count; i++) {
          struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
 
          pipe_resource_reference(&cso->resource, NULL);
-         cso->surface.bo = NULL;
+
+         cso->info.buf = NULL;
+         cso->info.size = 0;
          cso->user_buffer = NULL;
-         cso->user_buffer_size = 0;
 
          cbuf->enabled_mask &= ~(1 << (index + i));
       }
@@ -724,14 +1607,117 @@ ilo_set_constant_buffer(struct pipe_context *pipe,
    vec->dirty |= ILO_DIRTY_CBUF;
 }
 
+static void
+fb_set_blend_caps(const struct ilo_dev *dev,
+                  enum pipe_format format,
+                  struct ilo_fb_blend_caps *caps)
+{
+   const struct util_format_description *desc =
+      util_format_description(format);
+   const int ch = util_format_get_first_non_void_channel(format);
+
+   memset(caps, 0, sizeof(*caps));
+
+   if (format == PIPE_FORMAT_NONE || desc->is_mixed)
+      return;
+
+   caps->is_unorm = (ch >= 0 && desc->channel[ch].normalized &&
+         desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED &&
+         desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB);
+   caps->is_integer = util_format_is_pure_integer(format);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 365:
+    *
+    *     "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
+    *      variants), otherwise Logic Ops must be DISABLED."
+    *
+    * According to the classic driver, this is lifted on Gen8+.
+    */
+   caps->can_logicop = (ilo_dev_gen(dev) >= ILO_GEN(8) || caps->is_unorm);
+
+   /* no blending for pure integer formats */
+   caps->can_blend = !caps->is_integer;
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 382:
+    *
+    *     "Alpha Test can only be enabled if Pixel Shader outputs a float
+    *      alpha value."
+    */
+   caps->can_alpha_test = !caps->is_integer;
+
+   caps->force_dst_alpha_one =
+      (ilo_format_translate_render(dev, format) !=
+       ilo_format_translate_color(dev, format));
+
+   /* sanity check */
+   if (caps->force_dst_alpha_one) {
+      enum pipe_format render_format;
+
+      switch (format) {
+      case PIPE_FORMAT_B8G8R8X8_UNORM:
+         render_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+         break;
+      default:
+         render_format = PIPE_FORMAT_NONE;
+         break;
+      }
+
+      assert(ilo_format_translate_render(dev, format) ==
+             ilo_format_translate_color(dev, render_format));
+   }
+}
+
 static void
 ilo_set_framebuffer_state(struct pipe_context *pipe,
                           const struct pipe_framebuffer_state *state)
 {
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
+   struct ilo_fb_state *fb = &vec->fb;
+   const struct pipe_surface *first_surf = NULL;
+   int i;
+
+   util_copy_framebuffer_state(&fb->state, state);
+
+   fb->has_integer_rt = false;
+   for (i = 0; i < state->nr_cbufs; i++) {
+      if (state->cbufs[i]) {
+         fb_set_blend_caps(dev, state->cbufs[i]->format, &fb->blend_caps[i]);
 
-   ilo_gpe_set_fb(dev, state, &vec->fb);
+         fb->has_integer_rt |= fb->blend_caps[i].is_integer;
+
+         if (!first_surf)
+            first_surf = state->cbufs[i];
+      } else {
+         fb_set_blend_caps(dev, PIPE_FORMAT_NONE, &fb->blend_caps[i]);
+      }
+   }
+
+   if (!first_surf && state->zsbuf)
+      first_surf = state->zsbuf;
+
+   fb->num_samples = (first_surf) ? first_surf->texture->nr_samples : 1;
+   if (!fb->num_samples)
+      fb->num_samples = 1;
+
+   if (state->zsbuf) {
+      const struct ilo_surface_cso *cso =
+         (const struct ilo_surface_cso *) state->zsbuf;
+
+      fb->has_hiz = cso->u.zs.hiz_bo;
+      fb->depth_offset_format =
+         ilo_state_zs_get_depth_format(&cso->u.zs, dev);
+   } else {
+      fb->has_hiz = false;
+      fb->depth_offset_format = GEN6_ZFORMAT_D32_FLOAT;
+   }
+
+   /*
+    * The PRMs list several restrictions when the framebuffer has more than
+    * one surface.  It seems they are actually lifted on GEN6+.
+    */
 
    vec->dirty |= ILO_DIRTY_FB;
 }
@@ -740,9 +1726,15 @@ static void
 ilo_set_polygon_stipple(struct pipe_context *pipe,
                         const struct pipe_poly_stipple *state)
 {
+   const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
+   struct ilo_state_poly_stipple_info info;
+   int i;
+
+   for (i = 0; i < 32; i++)
+      info.pattern[i] = state->stipple[i];
 
-   vec->poly_stipple = *state;
+   ilo_state_poly_stipple_set_info(&vec->poly_stipple, dev, &info);
 
    vec->dirty |= ILO_DIRTY_POLY_STIPPLE;
 }
@@ -753,11 +1745,26 @@ ilo_set_scissor_states(struct pipe_context *pipe,
                        unsigned num_scissors,
                        const struct pipe_scissor_state *scissors)
 {
-   const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
+   unsigned i;
+
+   for (i = 0; i < num_scissors; i++) {
+      struct ilo_state_viewport_scissor_info *info =
+         &vec->viewport.scissors[start_slot + i];
 
-   ilo_gpe_set_scissor(dev, start_slot, num_scissors,
-         scissors, &vec->scissor);
+      if (scissors[i].minx < scissors[i].maxx &&
+          scissors[i].miny < scissors[i].maxy) {
+         info->min_x = scissors[i].minx;
+         info->min_y = scissors[i].miny;
+         info->max_x = scissors[i].maxx - 1;
+         info->max_y = scissors[i].maxy - 1;
+      } else {
+         info->min_x = 1;
+         info->min_y = 1;
+         info->max_x = 0;
+         info->max_y = 0;
+      }
+   }
 
    vec->dirty |= ILO_DIRTY_SCISSOR;
 }
@@ -768,28 +1775,31 @@ ilo_set_viewport_states(struct pipe_context *pipe,
                         unsigned num_viewports,
                         const struct pipe_viewport_state *viewports)
 {
-   const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
    if (viewports) {
       unsigned i;
 
       for (i = 0; i < num_viewports; i++) {
-         ilo_gpe_set_viewport_cso(dev, &viewports[i],
-               &vec->viewport.cso[start_slot + i]);
+         struct ilo_state_viewport_matrix_info *info =
+            &vec->viewport.matrices[start_slot + i];
+
+         memcpy(info->scale, viewports[i].scale, sizeof(info->scale));
+         memcpy(info->translate, viewports[i].translate,
+               sizeof(info->translate));
       }
 
-      if (vec->viewport.count < start_slot + num_viewports)
-         vec->viewport.count = start_slot + num_viewports;
+      if (vec->viewport.params.count < start_slot + num_viewports)
+         vec->viewport.params.count = start_slot + num_viewports;
 
       /* need to save viewport 0 for util_blitter */
       if (!start_slot && num_viewports)
          vec->viewport.viewport0 = viewports[0];
    }
    else {
-      if (vec->viewport.count <= start_slot + num_viewports &&
-          vec->viewport.count > start_slot)
-         vec->viewport.count = start_slot;
+      if (vec->viewport.params.count <= start_slot + num_viewports &&
+          vec->viewport.params.count > start_slot)
+         vec->viewport.params.count = start_slot;
    }
 
    vec->dirty |= ILO_DIRTY_VIEWPORT;
@@ -905,16 +1915,11 @@ ilo_set_index_buffer(struct pipe_context *pipe,
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
    if (state) {
-      pipe_resource_reference(&vec->ib.buffer, state->buffer);
-      vec->ib.user_buffer = state->user_buffer;
-      vec->ib.offset = state->offset;
-      vec->ib.index_size = state->index_size;
-   }
-   else {
-      pipe_resource_reference(&vec->ib.buffer, NULL);
-      vec->ib.user_buffer = NULL;
-      vec->ib.offset = 0;
-      vec->ib.index_size = 0;
+      pipe_resource_reference(&vec->ib.state.buffer, state->buffer);
+      vec->ib.state = *state;
+   } else {
+      pipe_resource_reference(&vec->ib.state.buffer, NULL);
+      memset(&vec->ib.state, 0, sizeof(vec->ib.state));
    }
 
    vec->dirty |= ILO_DIRTY_IB;
@@ -926,19 +1931,28 @@ ilo_create_stream_output_target(struct pipe_context *pipe,
                                 unsigned buffer_offset,
                                 unsigned buffer_size)
 {
-   struct pipe_stream_output_target *target;
+   const struct ilo_dev *dev = ilo_context(pipe)->dev;
+   struct ilo_stream_output_target *target;
+   struct ilo_state_sol_buffer_info info;
 
-   target = MALLOC_STRUCT(pipe_stream_output_target);
+   target = CALLOC_STRUCT(ilo_stream_output_target);
    assert(target);
 
-   pipe_reference_init(&target->reference, 1);
-   target->buffer = NULL;
-   pipe_resource_reference(&target->buffer, res);
-   target->context = pipe;
-   target->buffer_offset = buffer_offset;
-   target->buffer_size = buffer_size;
+   pipe_reference_init(&target->base.reference, 1);
+   pipe_resource_reference(&target->base.buffer, res);
+   target->base.context = pipe;
+   target->base.buffer_offset = buffer_offset;
+   target->base.buffer_size = buffer_size;
+
+   memset(&info, 0, sizeof(info));
+   info.buf = ilo_buffer(res);
+   info.offset = buffer_offset;
+   info.size = buffer_size;
 
-   return target;
+   ilo_state_sol_buffer_init(&target->sb, dev, &info);
+   target->sb.bo = info.buf->bo;
+
+   return &target->base;
 }
 
 static void
@@ -991,7 +2005,7 @@ ilo_create_sampler_view(struct pipe_context *pipe,
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_view_cso *view;
 
-   view = MALLOC_STRUCT(ilo_view_cso);
+   view = CALLOC_STRUCT(ilo_view_cso);
    assert(view);
 
    view->base = *templ;
@@ -1001,16 +2015,24 @@ ilo_create_sampler_view(struct pipe_context *pipe,
    view->base.context = pipe;
 
    if (res->target == PIPE_BUFFER) {
-      const unsigned elem_size = util_format_get_blocksize(templ->format);
-      const unsigned first_elem = templ->u.buf.first_element;
-      const unsigned num_elems = templ->u.buf.last_element - first_elem + 1;
-
-      ilo_gpe_init_view_surface_for_buffer(dev, ilo_buffer(res),
-            first_elem * elem_size, num_elems * elem_size,
-            elem_size, templ->format, false, false, &view->surface);
-   }
-   else {
+      struct ilo_state_surface_buffer_info info;
+
+      memset(&info, 0, sizeof(info));
+      info.buf = ilo_buffer(res);
+      info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
+      info.format = ilo_format_translate_color(dev, templ->format);
+      info.format_size = util_format_get_blocksize(templ->format);
+      info.struct_size = info.format_size;
+      info.readonly = true;
+      info.offset = templ->u.buf.first_element * info.struct_size;
+      info.size = (templ->u.buf.last_element -
+            templ->u.buf.first_element + 1) * info.struct_size;
+
+      ilo_state_surface_init_for_buffer(&view->surface, dev, &info);
+      view->surface.bo = info.buf->bo;
+   } else {
       struct ilo_texture *tex = ilo_texture(res);
+      struct ilo_state_surface_image_info info;
 
       /* warn about degraded performance because of a missing binding flag */
       if (tex->image.tiling == GEN6_TILING_NONE &&
@@ -1019,13 +2041,33 @@ ilo_create_sampler_view(struct pipe_context *pipe,
                   "not created for sampling\n");
       }
 
-      ilo_gpe_init_view_surface_for_image(dev, &tex->image,
-            tex->base.target, templ->format,
-            templ->u.tex.first_level,
-            templ->u.tex.last_level - templ->u.tex.first_level + 1,
-            templ->u.tex.first_layer,
-            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
-            false, &view->surface);
+      memset(&info, 0, sizeof(info));
+      info.img = &tex->image;
+
+      info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
+
+      if (templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
+          tex->image.separate_stencil) {
+         info.format = ilo_format_translate_texture(dev,
+               PIPE_FORMAT_Z32_FLOAT);
+      } else {
+         info.format = ilo_format_translate_texture(dev, templ->format);
+      }
+
+      info.is_cube_map = (tex->image.target == PIPE_TEXTURE_CUBE ||
+                          tex->image.target == PIPE_TEXTURE_CUBE_ARRAY);
+      info.is_array = util_resource_is_array_texture(&tex->base);
+      info.readonly = true;
+
+      info.level_base = templ->u.tex.first_level;
+      info.level_count = templ->u.tex.last_level -
+         templ->u.tex.first_level + 1;
+      info.slice_base = templ->u.tex.first_layer;
+      info.slice_count = templ->u.tex.last_layer -
+         templ->u.tex.first_layer + 1;
+
+      ilo_state_surface_init_for_image(&view->surface, dev, &info);
+      view->surface.bo = info.img->bo;
    }
 
    return &view->base;
@@ -1048,7 +2090,7 @@ ilo_create_surface(struct pipe_context *pipe,
    struct ilo_texture *tex = ilo_texture(res);
    struct ilo_surface_cso *surf;
 
-   surf = MALLOC_STRUCT(ilo_surface_cso);
+   surf = CALLOC_STRUCT(ilo_surface_cso);
    assert(surf);
 
    surf->base = *templ;
@@ -1063,28 +2105,56 @@ ilo_create_surface(struct pipe_context *pipe,
    surf->is_rt = !util_format_is_depth_or_stencil(templ->format);
 
    if (surf->is_rt) {
+      struct ilo_state_surface_image_info info;
+
       /* relax this? */
       assert(tex->base.target != PIPE_BUFFER);
 
-      /*
-       * classic i965 sets render_cache_rw for constant buffers and sol
-       * surfaces but not render buffers.  Why?
-       */
-      ilo_gpe_init_view_surface_for_image(dev,
-            &tex->image, tex->base.target,
-            templ->format, templ->u.tex.level, 1,
-            templ->u.tex.first_layer,
-            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
-            true, &surf->u.rt);
+      memset(&info, 0, sizeof(info));
+      info.img = &tex->image;
+      info.access = ILO_STATE_SURFACE_ACCESS_DP_RENDER;
+      info.format = ilo_format_translate_render(dev, templ->format);
+      info.is_array = util_resource_is_array_texture(&tex->base);
+      info.level_base = templ->u.tex.level;
+      info.level_count = 1;
+      info.slice_base = templ->u.tex.first_layer;
+      info.slice_count = templ->u.tex.last_layer -
+         templ->u.tex.first_layer + 1;
+
+      ilo_state_surface_init_for_image(&surf->u.rt, dev, &info);
+      surf->u.rt.bo = info.img->bo;
    } else {
+      struct ilo_state_zs_info info;
+
       assert(res->target != PIPE_BUFFER);
 
-      ilo_gpe_init_zs_surface(dev, &tex->image,
-            (tex->separate_s8) ? &tex->separate_s8->image : NULL,
-            tex->base.target, templ->format,
-            templ->u.tex.level, templ->u.tex.first_layer,
-            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
-            &surf->u.zs);
+      memset(&info, 0, sizeof(info));
+
+      if (templ->format == PIPE_FORMAT_S8_UINT) {
+         info.s_img = &tex->image;
+      } else {
+         info.z_img = &tex->image;
+         info.s_img = (tex->separate_s8) ? &tex->separate_s8->image : NULL;
+
+         info.hiz_enable =
+            ilo_image_can_enable_aux(&tex->image, templ->u.tex.level);
+      }
+
+      info.level = templ->u.tex.level;
+      info.slice_base = templ->u.tex.first_layer;
+      info.slice_count = templ->u.tex.last_layer -
+         templ->u.tex.first_layer + 1;
+
+      ilo_state_zs_init(&surf->u.zs, dev, &info);
+
+      if (info.z_img) {
+         surf->u.zs.depth_bo = info.z_img->bo;
+         if (info.hiz_enable)
+            surf->u.zs.hiz_bo = info.z_img->aux.bo;
+      }
+
+      if (info.s_img)
+         surf->u.zs.stencil_bo = info.s_img->bo;
    }
 
    return &surf->base;
@@ -1294,10 +2364,30 @@ void
 ilo_state_vector_init(const struct ilo_dev *dev,
                       struct ilo_state_vector *vec)
 {
-   ilo_gpe_set_scissor_null(dev, &vec->scissor);
+   struct ilo_state_urb_info urb_info;
 
-   ilo_gpe_init_zs_surface(dev, NULL, NULL, PIPE_TEXTURE_2D,
-         PIPE_FORMAT_NONE, 0, 0, 1, &vec->fb.null_zs);
+   vec->sample_mask = ~0u;
+
+   ilo_state_viewport_init_data_only(&vec->viewport.vp, dev,
+         vec->viewport.vp_data, sizeof(vec->viewport.vp_data));
+   assert(vec->viewport.vp.array_size >= ILO_MAX_VIEWPORTS);
+
+   vec->viewport.params.matrices = vec->viewport.matrices;
+   vec->viewport.params.scissors = vec->viewport.scissors;
+
+   ilo_state_hs_init_disabled(&vec->disabled_hs, dev);
+   ilo_state_ds_init_disabled(&vec->disabled_ds, dev);
+   ilo_state_gs_init_disabled(&vec->disabled_gs, dev);
+
+   ilo_state_sol_buffer_init_disabled(&vec->so.dummy_sb, dev);
+
+   ilo_state_surface_init_for_null(&vec->fb.null_rt, dev);
+   ilo_state_zs_init_for_null(&vec->fb.null_zs, dev);
+
+   ilo_state_sampler_init_disabled(&vec->disabled_sampler, dev);
+
+   memset(&urb_info, 0, sizeof(urb_info));
+   ilo_state_urb_init(&vec->urb, dev, &urb_info);
 
    util_dynarray_init(&vec->global_binding.bindings);
 
@@ -1314,7 +2404,7 @@ ilo_state_vector_cleanup(struct ilo_state_vector *vec)
          pipe_resource_reference(&vec->vb.states[i].buffer, NULL);
    }
 
-   pipe_resource_reference(&vec->ib.buffer, NULL);
+   pipe_resource_reference(&vec->ib.state.buffer, NULL);
    pipe_resource_reference(&vec->ib.hw_resource, NULL);
 
    for (i = 0; i < vec->so.count; i++)
@@ -1377,7 +2467,7 @@ ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
          }
       }
 
-      if (vec->ib.buffer == res) {
+      if (vec->ib.state.buffer == res) {
          states |= ILO_DIRTY_IB;
 
          /*
@@ -1392,6 +2482,10 @@ ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
 
       for (i = 0; i < vec->so.count; i++) {
          if (vec->so.states[i]->buffer == res) {
+            struct ilo_stream_output_target *target =
+               (struct ilo_stream_output_target *) vec->so.states[i];
+
+            target->sb.bo = ilo_buffer(res)->bo;
             states |= ILO_DIRTY_SO;
             break;
          }
@@ -1456,7 +2550,8 @@ ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
          struct ilo_surface_cso *cso =
             (struct ilo_surface_cso *) vec->fb.state.zsbuf;
 
-         cso->u.rt.bo = bo;
+         cso->u.zs.depth_bo = bo;
+
          states |= ILO_DIRTY_FB;
       }
    }
index fd0a3156ebc68f1333f31f27e5c3187e11f8c595..3e6fd8a2554408859eb5301463c36199cc55e38a 100644 (file)
 #ifndef ILO_STATE_H
 #define ILO_STATE_H
 
-#include "core/ilo_state_3d.h"
+#include "core/ilo_builder_3d.h" /* for gen6_3dprimitive_info */
+#include "core/ilo_state_cc.h"
+#include "core/ilo_state_compute.h"
+#include "core/ilo_state_raster.h"
+#include "core/ilo_state_sampler.h"
+#include "core/ilo_state_sbe.h"
+#include "core/ilo_state_shader.h"
+#include "core/ilo_state_sol.h"
+#include "core/ilo_state_surface.h"
+#include "core/ilo_state_urb.h"
+#include "core/ilo_state_vf.h"
+#include "core/ilo_state_viewport.h"
+#include "core/ilo_state_zs.h"
 #include "pipe/p_state.h"
 #include "util/u_dynarray.h"
 
 #include "ilo_common.h"
 
+/**
+ * \see brw_context.h
+ */
+#define ILO_MAX_DRAW_BUFFERS    8
+#define ILO_MAX_CONST_BUFFERS   (1 + 12)
+#define ILO_MAX_SAMPLER_VIEWS   16
+#define ILO_MAX_SAMPLERS        16
+#define ILO_MAX_SO_BINDINGS     64
+#define ILO_MAX_SO_BUFFERS      4
+#define ILO_MAX_VIEWPORTS       1
+
+#define ILO_MAX_SURFACES        256
+
 /**
  * States that we track.
  *
@@ -120,6 +145,172 @@ enum ilo_dirty_flags {
 };
 
 struct ilo_context;
+struct ilo_shader_state;
+
+struct ilo_ve_state {
+   unsigned vb_mapping[PIPE_MAX_ATTRIBS];
+   unsigned vb_count;
+
+   /* these are not valid until the state is finalized */
+   uint32_t vf_data[PIPE_MAX_ATTRIBS][4];
+   struct ilo_state_vf_params_info vf_params;
+   struct ilo_state_vf vf;
+};
+
+struct ilo_vb_state {
+   struct pipe_vertex_buffer states[PIPE_MAX_ATTRIBS];
+   struct ilo_state_vertex_buffer vb[PIPE_MAX_ATTRIBS];
+   uint32_t enabled_mask;
+};
+
+struct ilo_ib_state {
+   struct pipe_index_buffer state;
+
+   /* these are not valid until the state is finalized */
+   struct pipe_resource *hw_resource;
+   unsigned hw_index_size;
+   struct ilo_state_index_buffer ib;
+};
+
+struct ilo_cbuf_cso {
+   struct pipe_resource *resource;
+   struct ilo_state_surface_buffer_info info;
+   struct ilo_state_surface surface;
+
+   /*
+    * this CSO is not so constant because user buffer needs to be uploaded in
+    * finalize_constant_buffers()
+    */
+   const void *user_buffer;
+};
+
+struct ilo_sampler_cso {
+   struct ilo_state_sampler sampler;
+   struct ilo_state_sampler_border border;
+   bool saturate_s;
+   bool saturate_t;
+   bool saturate_r;
+};
+
+struct ilo_sampler_state {
+   const struct ilo_sampler_cso *cso[ILO_MAX_SAMPLERS];
+};
+
+struct ilo_cbuf_state {
+   struct ilo_cbuf_cso cso[ILO_MAX_CONST_BUFFERS];
+   uint32_t enabled_mask;
+};
+
+struct ilo_resource_state {
+   struct pipe_surface *states[PIPE_MAX_SHADER_RESOURCES];
+   unsigned count;
+};
+
+struct ilo_view_cso {
+   struct pipe_sampler_view base;
+
+   struct ilo_state_surface surface;
+};
+
+struct ilo_view_state {
+   struct pipe_sampler_view *states[ILO_MAX_SAMPLER_VIEWS];
+   unsigned count;
+};
+
+struct ilo_stream_output_target {
+   struct pipe_stream_output_target base;
+
+   struct ilo_state_sol_buffer sb;
+};
+
+struct ilo_so_state {
+   struct pipe_stream_output_target *states[ILO_MAX_SO_BUFFERS];
+   unsigned count;
+   unsigned append_bitmask;
+
+   struct ilo_state_sol_buffer dummy_sb;
+
+   bool enabled;
+};
+
+struct ilo_rasterizer_state {
+   struct pipe_rasterizer_state state;
+
+   /* these are invalid until finalize_rasterizer() */
+   struct ilo_state_raster_info info;
+   struct ilo_state_raster rs;
+};
+
+struct ilo_viewport_state {
+   struct ilo_state_viewport_matrix_info matrices[ILO_MAX_VIEWPORTS];
+   struct ilo_state_viewport_scissor_info scissors[ILO_MAX_VIEWPORTS];
+   struct ilo_state_viewport_params_info params;
+
+   struct pipe_viewport_state viewport0;
+   struct pipe_scissor_state scissor0;
+
+   struct ilo_state_viewport vp;
+   uint32_t vp_data[20 * ILO_MAX_VIEWPORTS];
+};
+
+struct ilo_surface_cso {
+   struct pipe_surface base;
+
+   bool is_rt;
+   union {
+      struct ilo_state_surface rt;
+      struct ilo_state_zs zs;
+   } u;
+};
+
+struct ilo_fb_state {
+   struct pipe_framebuffer_state state;
+
+   struct ilo_state_surface null_rt;
+   struct ilo_state_zs null_zs;
+
+   struct ilo_fb_blend_caps {
+      bool is_unorm;
+      bool is_integer;
+      bool force_dst_alpha_one;
+
+      bool can_logicop;
+      bool can_blend;
+      bool can_alpha_test;
+   } blend_caps[PIPE_MAX_COLOR_BUFS];
+
+   unsigned num_samples;
+
+   bool has_integer_rt;
+   bool has_hiz;
+   enum gen_depth_format depth_offset_format;
+};
+
+struct ilo_dsa_state {
+   struct ilo_state_cc_depth_info depth;
+
+   struct ilo_state_cc_stencil_info stencil;
+   struct {
+      uint8_t test_mask;
+      uint8_t write_mask;
+   } stencil_front, stencil_back;
+
+   bool alpha_test;
+   float alpha_ref;
+   enum gen_compare_function alpha_func;
+};
+
+struct ilo_blend_state {
+   struct ilo_state_cc_blend_rt_info rt[PIPE_MAX_COLOR_BUFS];
+   struct ilo_state_cc_blend_rt_info dummy_rt;
+   bool dual_blend;
+
+   /* these are invalid until finalize_blend() */
+   struct ilo_state_cc_blend_rt_info effective_rt[PIPE_MAX_COLOR_BUFS];
+   struct ilo_state_cc_info info;
+   struct ilo_state_cc cc;
+   bool alpha_may_kill;
+};
 
 struct ilo_global_binding_cso {
    struct pipe_resource *resource;
@@ -147,6 +338,7 @@ struct ilo_global_binding {
 
 struct ilo_state_vector {
    const struct pipe_draw_info *draw;
+   struct gen6_3dprimitive_info draw_info;
 
    uint32_t dirty;
 
@@ -157,30 +349,41 @@ struct ilo_state_vector {
    struct ilo_shader_state *vs;
    struct ilo_shader_state *gs;
 
+   struct ilo_state_hs disabled_hs;
+   struct ilo_state_ds disabled_ds;
+   struct ilo_state_gs disabled_gs;
+
    struct ilo_so_state so;
 
    struct pipe_clip_state clip;
+
    struct ilo_viewport_state viewport;
-   struct ilo_scissor_state scissor;
 
-   const struct ilo_rasterizer_state *rasterizer;
-   struct pipe_poly_stipple poly_stipple;
+   struct ilo_rasterizer_state *rasterizer;
+
+   struct ilo_state_line_stipple line_stipple;
+   struct ilo_state_poly_stipple poly_stipple;
    unsigned sample_mask;
 
    struct ilo_shader_state *fs;
 
-   const struct ilo_dsa_state *dsa;
+   struct ilo_state_cc_params_info cc_params;
    struct pipe_stencil_ref stencil_ref;
-   const struct ilo_blend_state *blend;
-   struct pipe_blend_color blend_color;
+   const struct ilo_dsa_state *dsa;
+   struct ilo_blend_state *blend;
+
    struct ilo_fb_state fb;
 
+   struct ilo_state_urb urb;
+
    /* shader resources */
    struct ilo_sampler_state sampler[PIPE_SHADER_TYPES];
    struct ilo_view_state view[PIPE_SHADER_TYPES];
    struct ilo_cbuf_state cbuf[PIPE_SHADER_TYPES];
    struct ilo_resource_state resource;
 
+   struct ilo_state_sampler disabled_sampler;
+
    /* GPGPU */
    struct ilo_shader_state *cs;
    struct ilo_resource_state cs_resource;
index d2dc2f5b5b436519268f2126654150669787a408..01c86675202da082187cff34338fc70452f09be5 100644 (file)
@@ -28,6 +28,9 @@
 #ifndef ILO_SHADER_INTERNAL_H
 #define ILO_SHADER_INTERNAL_H
 
+#include "core/ilo_state_sbe.h"
+#include "core/ilo_state_sol.h"
+
 #include "ilo_common.h"
 #include "ilo_state.h"
 #include "ilo_shader.h"
@@ -72,13 +75,27 @@ struct ilo_shader_variant {
    uint32_t saturate_tex_coords[3];
 };
 
+struct ilo_kernel_routing {
+   bool initialized;
+
+   bool is_point;
+   bool light_twoside;
+   uint32_t sprite_coord_enable;
+   int sprite_coord_mode;
+   int src_len;
+   int src_semantics[PIPE_MAX_SHADER_OUTPUTS];
+   int src_indices[PIPE_MAX_SHADER_OUTPUTS];
+
+   struct ilo_state_sbe sbe;
+};
+
 /**
  * A compiled shader.
  */
 struct ilo_shader {
    struct ilo_shader_variant variant;
 
-   struct ilo_shader_cso cso;
+   union ilo_shader_cso cso;
 
    struct {
       int semantic_names[PIPE_MAX_SHADER_INPUTS];
@@ -111,7 +128,9 @@ struct ilo_shader {
 
    bool stream_output;
    int svbi_post_inc;
-   struct pipe_stream_output_info so_info;
+
+   uint32_t sol_data[PIPE_MAX_SO_OUTPUTS][2];
+   struct ilo_state_sol sol;
 
    /* for VS stream output / rasterizer discard */
    int gs_offsets[3];
@@ -121,11 +140,8 @@ struct ilo_shader {
    void *kernel;
    int kernel_size;
 
-   bool routing_initialized;
-   int routing_src_semantics[PIPE_MAX_SHADER_OUTPUTS];
-   int routing_src_indices[PIPE_MAX_SHADER_OUTPUTS];
-   uint32_t routing_sprite_coord_enable;
    struct ilo_kernel_routing routing;
+   struct ilo_state_ps_params_info ps_params;
 
    /* what does the push constant buffer consist of? */
    struct {
index 65e47bf3a4ab15c50e22d9cdbab83bfe69bc3d2b..d38585f147512a12b5f4b7e98e4ec6a04ad8f8ba 100644 (file)
@@ -2036,9 +2036,6 @@ parse_instruction(struct toy_tgsi *tgsi,
       if (!dst_is_scratch[i])
          continue;
 
-      if (tgsi_inst->Instruction.Saturate == TGSI_SAT_MINUS_PLUS_ONE)
-         tc_fail(tgsi->tc, "TGSI_SAT_MINUS_PLUS_ONE unhandled");
-
       tgsi->tc->templ.saturate = tgsi_inst->Instruction.Saturate;
 
       /* emit indirect store */
index b6c32ffb979b0f216b7823f06c149e9bbc4d300e..b25e041375070a4bdc2209b2c2a722a723775bb1 100644 (file)
@@ -975,10 +975,6 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
                                          s_bld.int_vec_type, "");
       }
 
-      /* convert scalar stencil refs into vectors */
-      stencil_refs[0] = lp_build_broadcast_scalar(&s_bld, stencil_refs[0]);
-      stencil_refs[1] = lp_build_broadcast_scalar(&s_bld, stencil_refs[1]);
-
       s_pass_mask = lp_build_stencil_test(&s_bld, stencil,
                                           stencil_refs, stencil_vals,
                                           front_facing);
index ec6b660b48ebed86e81db92be9fbe9441254ba14..27ab1baefbbb5691babdedb270b22b4f7be529d0 100644 (file)
@@ -1,10 +1,18 @@
 #ifndef LP_PUBLIC_H
 #define LP_PUBLIC_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct pipe_screen;
 struct sw_winsys;
 
 struct pipe_screen *
 llvmpipe_create_screen(struct sw_winsys *winsys);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index 4f8bab62e7b4f64e9947be78db0f8e4b05d10fe4..fc5936706712f745f3ca25c3f193f6e878557822 100644 (file)
@@ -315,7 +315,7 @@ llvmpipe_check_render_cond(struct llvmpipe_context *lp)
 
    b = pipe->get_query_result(pipe, lp->render_cond_query, wait, (void*)&result);
    if (b)
-      return (!result == lp->render_cond_cond);
+      return ((!result) == lp->render_cond_cond);
    else
       return TRUE;
 }
index f4ba596f35823c0eea3a456737f58e1fb9721b04..47f1897c7324570457f933449e342c15f8b9b5cd 100644 (file)
@@ -165,7 +165,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_DEPTH_CLIP_DISABLE:
       return 1;
    case PIPE_CAP_SHADER_STENCIL_EXPORT:
-      return 0;
+      return 1;
    case PIPE_CAP_TGSI_INSTANCEID:
    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
    case PIPE_CAP_START_INSTANCE:
@@ -258,8 +258,9 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
       return 1;
    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
-   case PIPE_CAP_SAMPLER_VIEW_TARGET:
       return 0;
+   case PIPE_CAP_SAMPLER_VIEW_TARGET:
+      return 1;
    case PIPE_CAP_FAKE_SW_MSAA:
       return 1;
    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
@@ -290,6 +291,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
    }
    /* should only get here on unhandled cases */
index 96cc77c250ceb45357c94d685492fd5c15857edc..4c8167a9e7dbcf8f382c43279d47342cafcd747a 100644 (file)
@@ -854,9 +854,10 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                      jit_tex->img_stride[j] = lp_tex->img_stride[j];
                   }
 
-                  if (res->target == PIPE_TEXTURE_1D_ARRAY ||
-                      res->target == PIPE_TEXTURE_2D_ARRAY ||
-                      res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+                  if (view->target == PIPE_TEXTURE_1D_ARRAY ||
+                      view->target == PIPE_TEXTURE_2D_ARRAY ||
+                      view->target == PIPE_TEXTURE_CUBE ||
+                      view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                      /*
                       * For array textures, we don't have first_layer, instead
                       * adjust last_layer (stored as depth) plus the mip level offsets
@@ -868,7 +869,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                         jit_tex->mip_offsets[j] += view->u.tex.first_layer *
                                                    lp_tex->img_stride[j];
                      }
-                     if (res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+                     if (view->target == PIPE_TEXTURE_CUBE ||
+                         view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                         assert(jit_tex->depth % 6 == 0);
                      }
                      assert(view->u.tex.first_layer <= view->u.tex.last_layer);
@@ -1067,10 +1069,13 @@ try_update_scene_state( struct lp_setup_context *setup )
    if (setup->dirty & LP_SETUP_NEW_CONSTANTS) {
       for (i = 0; i < Elements(setup->constants); ++i) {
          struct pipe_resource *buffer = setup->constants[i].current.buffer;
-         const unsigned current_size = setup->constants[i].current.buffer_size;
+         const unsigned current_size = MIN2(setup->constants[i].current.buffer_size,
+                                            LP_MAX_TGSI_CONST_BUFFER_SIZE);
          const ubyte *current_data = NULL;
          int num_constants;
 
+         STATIC_ASSERT(DATA_BLOCK_SIZE >= LP_MAX_TGSI_CONST_BUFFER_SIZE);
+
          if (buffer) {
             /* resource buffer */
             current_data = (ubyte *) llvmpipe_resource_data(buffer);
index 35fe7b201810b07e37b8d9bf56ec389853bf62da..b5ce8683f1a50ccb58bf030015179eb498c1dc28 100644 (file)
@@ -260,7 +260,8 @@ generate_fs_loop(struct gallivm_state *gallivm,
 {
    const struct util_format_description *zs_format_desc = NULL;
    const struct tgsi_token *tokens = shader->base.tokens;
-   LLVMTypeRef vec_type;
+   struct lp_type int_type = lp_int_type(type);
+   LLVMTypeRef vec_type, int_vec_type;
    LLVMValueRef mask_ptr, mask_val;
    LLVMValueRef consts_ptr, num_consts_ptr;
    LLVMValueRef z;
@@ -295,7 +296,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
       zs_format_desc = util_format_description(key->zsbuf_format);
       assert(zs_format_desc);
 
-      if (!shader->info.base.writes_z) {
+      if (!shader->info.base.writes_z && !shader->info.base.writes_stencil) {
          if (key->alpha.enabled ||
              key->blend.alpha_to_coverage ||
              shader->info.base.uses_kill) {
@@ -329,11 +330,14 @@ generate_fs_loop(struct gallivm_state *gallivm,
       depth_mode = 0;
    }
 
+   vec_type = lp_build_vec_type(gallivm, type);
+   int_vec_type = lp_build_vec_type(gallivm, int_type);
 
    stencil_refs[0] = lp_jit_context_stencil_ref_front_value(gallivm, context_ptr);
    stencil_refs[1] = lp_jit_context_stencil_ref_back_value(gallivm, context_ptr);
-
-   vec_type = lp_build_vec_type(gallivm, type);
+   /* convert scalar stencil refs into vectors */
+   stencil_refs[0] = lp_build_broadcast(gallivm, int_vec_type, stencil_refs[0]);
+   stencil_refs[1] = lp_build_broadcast(gallivm, int_vec_type, stencil_refs[1]);
 
    consts_ptr = lp_jit_context_constants(gallivm, context_ptr);
    num_consts_ptr = lp_jit_context_num_constants(gallivm, context_ptr);
@@ -462,7 +466,9 @@ generate_fs_loop(struct gallivm_state *gallivm,
       int pos0 = find_output_by_semantic(&shader->info.base,
                                          TGSI_SEMANTIC_POSITION,
                                          0);
-
+      int s_out = find_output_by_semantic(&shader->info.base,
+                                          TGSI_SEMANTIC_STENCIL,
+                                          0);
       if (pos0 != -1 && outputs[pos0][2]) {
          z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
 
@@ -512,6 +518,15 @@ generate_fs_loop(struct gallivm_state *gallivm,
          }
       }
 
+      if (s_out != -1 && outputs[s_out][1]) {
+         /* there's only one value, and spec says to discard additional bits */
+         LLVMValueRef s_max_mask = lp_build_const_int_vec(gallivm, int_type, 255);
+         stencil_refs[0] = LLVMBuildLoad(builder, outputs[s_out][1], "output.s");
+         stencil_refs[0] = LLVMBuildBitCast(builder, stencil_refs[0], int_vec_type, "");
+         stencil_refs[0] = LLVMBuildAnd(builder, stencil_refs[0], s_max_mask, "");
+         stencil_refs[1] = stencil_refs[0];
+      }
+
       lp_build_depth_stencil_load_swizzled(gallivm, type,
                                            zs_format_desc, key->resource_1d,
                                            depth_ptr, depth_stride,
index 21da62905749a3c5691f3e615df3a8962b5e1f82..b205f02fdba67fb84d3f1388c61cd18d5d0a9210 100644 (file)
@@ -170,6 +170,36 @@ llvmpipe_create_sampler_view(struct pipe_context *pipe,
       view->texture = NULL;
       pipe_resource_reference(&view->texture, texture);
       view->context = pipe;
+
+#ifdef DEBUG
+     /*
+      * This is possibly too lenient, but the primary reason is just
+      * to catch state trackers which forget to initialize this, so
+      * it only catches clearly impossible view targets.
+      */
+      if (view->target != texture->target) {
+         if (view->target == PIPE_TEXTURE_1D)
+            assert(texture->target == PIPE_TEXTURE_1D_ARRAY);
+         else if (view->target == PIPE_TEXTURE_1D_ARRAY)
+            assert(texture->target == PIPE_TEXTURE_1D);
+         else if (view->target == PIPE_TEXTURE_2D)
+            assert(texture->target == PIPE_TEXTURE_2D_ARRAY ||
+                   texture->target == PIPE_TEXTURE_CUBE ||
+                   texture->target == PIPE_TEXTURE_CUBE_ARRAY);
+         else if (view->target == PIPE_TEXTURE_2D_ARRAY)
+            assert(texture->target == PIPE_TEXTURE_2D ||
+                   texture->target == PIPE_TEXTURE_CUBE ||
+                   texture->target == PIPE_TEXTURE_CUBE_ARRAY);
+         else if (view->target == PIPE_TEXTURE_CUBE)
+            assert(texture->target == PIPE_TEXTURE_CUBE_ARRAY ||
+                   texture->target == PIPE_TEXTURE_2D_ARRAY);
+         else if (view->target == PIPE_TEXTURE_CUBE_ARRAY)
+            assert(texture->target == PIPE_TEXTURE_CUBE ||
+                   texture->target == PIPE_TEXTURE_2D_ARRAY);
+         else
+            assert(0);
+      }
+#endif
    }
 
    return view;
@@ -245,15 +275,17 @@ prepare_shader_sampling(
                   row_stride[j] = lp_tex->row_stride[j];
                   img_stride[j] = lp_tex->img_stride[j];
                }
-               if (res->target == PIPE_TEXTURE_1D_ARRAY ||
-                   res->target == PIPE_TEXTURE_2D_ARRAY ||
-                   res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+               if (view->target == PIPE_TEXTURE_1D_ARRAY ||
+                   view->target == PIPE_TEXTURE_2D_ARRAY ||
+                   view->target == PIPE_TEXTURE_CUBE ||
+                   view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                   num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
                   for (j = first_level; j <= last_level; j++) {
                      mip_offsets[j] += view->u.tex.first_layer *
                                        lp_tex->img_stride[j];
                   }
-                  if (res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+                  if (view->target == PIPE_TEXTURE_CUBE ||
+                      view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                      assert(num_layers % 6 == 0);
                   }
                   assert(view->u.tex.first_layer <= view->u.tex.last_layer);
index 08f968f7f0a4d86c36dfe501c009b7c62f949211..96f8ed82cd86b726c1a89c766064e275cc9e7008 100644 (file)
@@ -42,13 +42,6 @@ lp_resource_copy(struct pipe_context *pipe,
                  struct pipe_resource *src, unsigned src_level,
                  const struct pipe_box *src_box)
 {
-   struct llvmpipe_resource *src_tex = llvmpipe_resource(src);
-   struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst);
-   const enum pipe_format format = src_tex->base.format;
-   unsigned width = src_box->width;
-   unsigned height = src_box->height;
-   unsigned depth = src_box->depth;
-
    llvmpipe_flush_resource(pipe,
                            dst, dst_level,
                            FALSE, /* read_only */
@@ -63,58 +56,8 @@ lp_resource_copy(struct pipe_context *pipe,
                            FALSE, /* do_not_block */
                            "blit src");
 
-   /* Fallback for buffers. */
-   if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
-      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
-                                src, src_level, src_box);
-      return;
-   }
-
-   /*
-   printf("surface copy from %u lvl %u to %u lvl %u: %u,%u,%u to %u,%u,%u %u x %u x %u\n",
-          src_tex->id, src_level, dst_tex->id, dst_level,
-          src_box->x, src_box->y, src_box->z, dstx, dsty, dstz,
-          src_box->width, src_box->height, src_box->depth);
-   */
-
-   /* make sure display target resources (which cannot have levels/layers) are mapped */
-   if (src_tex->dt)
-      (void) llvmpipe_resource_map(src, src_level, 0, LP_TEX_USAGE_READ);
-   if (dst_tex->dt)
-      /*
-       * Could set this to WRITE_ALL if complete dst is covered but it gets
-       * ignored anyway.
-       */
-      (void) llvmpipe_resource_map(dst, dst_level, 0, LP_TEX_USAGE_READ_WRITE);
-
-
-   /* copy */
-   {
-      const ubyte *src_linear_ptr
-         = llvmpipe_get_texture_image_address(src_tex, src_box->z,
-                                              src_level);
-      ubyte *dst_linear_ptr
-         = llvmpipe_get_texture_image_address(dst_tex, dstz,
-                                              dst_level);
-
-      if (dst_linear_ptr && src_linear_ptr) {
-         util_copy_box(dst_linear_ptr, format,
-                       llvmpipe_resource_stride(&dst_tex->base, dst_level),
-                       dst_tex->img_stride[dst_level],
-                       dstx, dsty, 0,
-                       width, height, depth,
-                       src_linear_ptr,
-                       llvmpipe_resource_stride(&src_tex->base, src_level),
-                       src_tex->img_stride[src_level],
-                       src_box->x, src_box->y, 0);
-      }
-   }
-
-   if (src_tex->dt)
-      llvmpipe_resource_unmap(src, 0, 0);
-   if (dst_tex->dt)
-      llvmpipe_resource_unmap(dst, 0, 0);
-
+   util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
+                             src, src_level, src_box);
 }
 
 
@@ -139,11 +82,6 @@ static void lp_blit(struct pipe_context *pipe,
       return; /* done */
    }
 
-   if (info.mask & PIPE_MASK_S) {
-      debug_printf("llvmpipe: cannot blit stencil, skipping\n");
-      info.mask &= ~PIPE_MASK_S;
-   }
-
    if (!util_blitter_is_blit_supported(lp->blitter, &info)) {
       debug_printf("llvmpipe: blit unsupported %s -> %s\n",
                    util_format_short_name(info.src.resource->format),
index 420c8e5734c9456740b3c09c54b7008cf26b91cb..daf3abd1bb3dac7ba5e452610748309f0274f16d 100644 (file)
@@ -39,6 +39,10 @@ LOCAL_SRC_FILES := \
 LOCAL_SHARED_LIBRARIES := libdrm libdrm_nouveau
 LOCAL_MODULE := libmesa_pipe_nouveau
 
+ifeq ($(MESA_LOLLIPOP_BUILD),true)
+LOCAL_C_INCLUDES := external/libcxx/include
+else
 include external/stlport/libstlport.mk
+endif
 include $(GALLIUM_COMMON_MK)
 include $(BUILD_STATIC_LIBRARY)
index 0aefc031210d8f33b15d05336fd2ca312ec36062..d05f0a17ab4e7e9a03e546b6b3f489430e68c2d3 100644 (file)
@@ -48,7 +48,7 @@ nouveau_compiler_SOURCES = \
 
 nouveau_compiler_LDADD = \
        libnouveau.la \
-       ../../auxiliary/libgallium.la \
+       $(top_builddir)/src/gallium/auxiliary/libgallium.la \
        $(top_builddir)/src/util/libmesautil.la \
        $(GALLIUM_COMMON_LIB_DEPS)
 
index be17871edd468fd378c049bda50becf54442956d..b9c05a04b9a81fec1401b86589eca6373f72cba8 100644 (file)
@@ -11,7 +11,7 @@
 // SIZE:    22 / 14 * 8 bytes
 //
 gk110_div_u32:
-   sched 0x28282804280428
+   sched 0x28 0x04 0x28 0x04 0x28 0x28 0x28
    bfind u32 $r2 $r1
    xor b32 $r2 $r2 0x1f
    mov b32 $r3 0x1
@@ -19,7 +19,7 @@ gk110_div_u32:
    cvt u32 $r1 neg u32 $r1
    mul $r3 u32 $r1 u32 $r2
    add $r2 (mul high u32 $r2 u32 $r3) $r2
-   sched 0x28282828282828
+   sched 0x28 0x28 0x28 0x28 0x28 0x28 0x28
    mul $r3 u32 $r1 u32 $r2
    add $r2 (mul high u32 $r2 u32 $r3) $r2
    mul $r3 u32 $r1 u32 $r2
@@ -27,7 +27,7 @@ gk110_div_u32:
    mul $r3 u32 $r1 u32 $r2
    add $r2 (mul high u32 $r2 u32 $r3) $r2
    mul $r3 u32 $r1 u32 $r2
-   sched 0x042c2828042804
+   sched 0x04 0x28 0x04 0x28 0x28 0x2c 0x04
    add $r2 (mul high u32 $r2 u32 $r3) $r2
    mov b32 $r3 $r0
    mul high $r0 u32 $r0 u32 $r2
@@ -35,7 +35,7 @@ gk110_div_u32:
    add $r1 (mul u32 $r1 u32 $r0) $r3
    set $p0 0x1 ge u32 $r1 $r2
    $p0 sub b32 $r1 $r1 $r2
-   sched 0x20282e20042c28
+   sched 0x28 0x2c 0x04 0x20 0x2e 0x28 0x20
    $p0 add b32 $r0 $r0 0x1
    $p0 set $p0 0x1 ge u32 $r1 $r2
    $p0 sub b32 $r1 $r1 $r2
@@ -51,7 +51,7 @@ gk110_div_u32:
 gk110_div_s32:
    set $p2 0x1 lt s32 $r0 0x0
    set $p3 0x1 lt s32 $r1 0x0 xor $p2
-   sched 0x28042804282820
+   sched 0x20 0x28 0x28 0x04 0x28 0x04 0x28
    cvt s32 $r0 abs s32 $r0
    cvt s32 $r1 abs s32 $r1
    bfind u32 $r2 $r1
@@ -59,7 +59,7 @@ gk110_div_s32:
    mov b32 $r3 0x1
    shl b32 $r2 $r3 clamp $r2
    cvt u32 $r1 neg u32 $r1
-   sched 0x28282828282828
+   sched 0x28 0x28 0x28 0x28 0x28 0x28 0x28
    mul $r3 u32 $r1 u32 $r2
    add $r2 (mul high u32 $r2 u32 $r3) $r2
    mul $r3 u32 $r1 u32 $r2
@@ -67,7 +67,7 @@ gk110_div_s32:
    mul $r3 u32 $r1 u32 $r2
    add $r2 (mul high u32 $r2 u32 $r3) $r2
    mul $r3 u32 $r1 u32 $r2
-   sched 0x28280428042828
+   sched 0x28 0x28 0x04 0x28 0x04 0x28 0x28
    add $r2 (mul high u32 $r2 u32 $r3) $r2
    mul $r3 u32 $r1 u32 $r2
    add $r2 (mul high u32 $r2 u32 $r3) $r2
@@ -75,7 +75,7 @@ gk110_div_s32:
    mul high $r0 u32 $r0 u32 $r2
    cvt u32 $r2 neg u32 $r1
    add $r1 (mul u32 $r1 u32 $r0) $r3
-   sched 0x2028042c28042c
+   sched 0x2c 0x04 0x28 0x2c 0x04 0x28 0x20
    set $p0 0x1 ge u32 $r1 $r2
    $p0 sub b32 $r1 $r1 $r2
    $p0 add b32 $r0 $r0 0x1
@@ -83,7 +83,7 @@ gk110_div_s32:
    $p0 sub b32 $r1 $r1 $r2
    $p0 add b32 $r0 $r0 0x1
    $p3 cvt s32 $r0 neg s32 $r0
-   sched 0x2c200428042e04
+   sched 0x04 0x2e 0x04 0x28 0x04 0x20 0x2c
    $p2 cvt s32 $r1 neg s32 $r1
    ret
 
index 6bb9620d5f728cb9475f0cf3e9d8f120305de017..ab8bf2e55042e88d46338a46a58ca21f4bf5c872 100644 (file)
@@ -967,8 +967,8 @@ CodeEmitterGK110::emitSET(const CmpInstruction *i)
       code[0] = (code[0] & ~0xfc) | ((code[0] << 3) & 0xe0);
       if (i->defExists(1))
          defId(i->def(1), 2);
-   else
-      code[0] |= 0x1c;
+      else
+         code[0] |= 0x1c;
    } else {
       switch (i->sType) {
       case TYPE_F32: op2 = 0x000; op1 = 0x800; break;
@@ -990,8 +990,12 @@ CodeEmitterGK110::emitSET(const CmpInstruction *i)
       }
       FTZ_(3a);
 
-      if (i->dType == TYPE_F32)
-         code[1] |= 1 << 23;
+      if (i->dType == TYPE_F32) {
+         if (isFloatType(i->sType))
+            code[1] |= 1 << 23;
+         else
+            code[1] |= 1 << 15;
+      }
    }
    if (i->sType == TYPE_S32)
       code[1] |= 1 << 19;
@@ -1316,6 +1320,8 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
    } else
    if (mask & 2) {
       int32_t pcRel = f->target.bb->binPos - (codeSize + 8);
+      if (writeIssueDelays && !(f->target.bb->binPos & 0x3f))
+         pcRel += 8;
       // currently we don't want absolute branches
       assert(!f->absolute);
       code[0] |= (pcRel & 0x1ff) << 23;
index 22db368b3712325a984f573eb14dfa8a82a39977..399a6f1db13496d77715c4345f9773192c74e05b 100644 (file)
@@ -509,10 +509,13 @@ CodeEmitterGM107::emitBRA()
    emitCond5(0x00, CC_TR);
 
    if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
+      int32_t pos = insn->target.bb->binPos;
+      if (writeIssueDelays && !(pos & 0x1f))
+         pos += 8;
       if (!insn->absolute)
-         emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
+         emitField(0x14, 24, pos - (codeSize + 8));
       else
-         emitField(0x14, 32, insn->target.bb->binPos);
+         emitField(0x14, 32, pos);
    } else {
       emitCBUF (0x24, gpr, 20, 16, 0, insn->src(0));
       emitField(0x05, 1, 1);
@@ -1827,6 +1830,7 @@ CodeEmitterGM107::emitISET()
    emitCond3(0x31, insn->setCond);
    emitField(0x30, 1, isSignedType(insn->sType));
    emitCC   (0x2f);
+   emitField(0x2c, 1, insn->dType == TYPE_F32);
    emitX    (0x2b);
    emitGPR  (0x08, insn->src(0));
    emitGPR  (0x00, insn->def(0));
index d9aed34a0cecf27c91d5708212f091bb0b8a389e..472e3a841195aee87c37ec1796a4ddfe802d4ae5 100644 (file)
@@ -1078,8 +1078,14 @@ CodeEmitterNVC0::emitSET(const CmpInstruction *i)
    if (!isFloatType(i->sType))
       lo = 0x3;
 
-   if (isFloatType(i->dType) || isSignedIntType(i->sType))
+   if (isSignedIntType(i->sType))
       lo |= 0x20;
+   if (isFloatType(i->dType)) {
+      if (isFloatType(i->sType))
+         lo |= 0x20;
+      else
+         lo |= 0x80;
+   }
 
    switch (i->op) {
    case OP_SET_AND: hi = 0x10000000; break;
@@ -1406,6 +1412,8 @@ CodeEmitterNVC0::emitFlow(const Instruction *i)
    } else
    if (mask & 2) {
       int32_t pcRel = f->target.bb->binPos - (codeSize + 8);
+      if (writeIssueDelays && !(f->target.bb->binPos & 0x3f))
+         pcRel += 8;
       // currently we don't want absolute branches
       assert(!f->absolute);
       code[0] |= (pcRel & 0x3f) << 26;
@@ -2712,7 +2720,6 @@ private:
 
    RegScores *score; // for current BB
    std::vector<RegScores> scoreBoards;
-   int cycle;
    int prevData;
    operation prevOp;
 
index 254629f907a34f7cbfd4bac57447bcd1e14b824b..ecd115f980732eb93af17d738af22c10b43cd411 100644 (file)
@@ -1316,7 +1316,7 @@ private:
    };
 
 private:
-   const struct tgsi::Source *code;
+   const tgsi::Source *code;
    const struct nv50_ir_prog_info *info;
 
    struct {
@@ -1356,18 +1356,20 @@ Converter::srcToSym(tgsi::Instruction::SrcRegister src, int c)
 {
    const int swz = src.getSwizzle(c);
 
+   /* TODO: Use Array ID when it's available for the index */
    return makeSym(src.getFile(),
                   src.is2D() ? src.getIndex(1) : 0,
-                  src.isIndirect(0) ? -1 : src.getIndex(0), swz,
+                  src.getIndex(0), swz,
                   src.getIndex(0) * 16 + swz * 4);
 }
 
 Symbol *
 Converter::dstToSym(tgsi::Instruction::DstRegister dst, int c)
 {
+   /* TODO: Use Array ID when it's available for the index */
    return makeSym(dst.getFile(),
                   dst.is2D() ? dst.getIndex(1) : 0,
-                  dst.isIndirect(0) ? -1 : dst.getIndex(0), c,
+                  dst.getIndex(0), c,
                   dst.getIndex(0) * 16 + c * 4);
 }
 
@@ -1604,19 +1606,8 @@ Converter::storeDst(int d, int c, Value *val)
 {
    const tgsi::Instruction::DstRegister dst = tgsi.getDst(d);
 
-   switch (tgsi.getSaturate()) {
-   case TGSI_SAT_NONE:
-      break;
-   case TGSI_SAT_ZERO_ONE:
+   if (tgsi.getSaturate()) {
       mkOp1(OP_SAT, dstTy, val, val);
-      break;
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      mkOp2(OP_MAX, dstTy, val, val, mkImm(-1.0f));
-      mkOp2(OP_MIN, dstTy, val, val, mkImm(+1.0f));
-      break;
-   default:
-      assert(!"invalid saturation mode");
-      break;
    }
 
    Value *ptr = NULL;
@@ -1955,13 +1946,13 @@ isResourceSpecial(const int r)
 }
 
 static inline bool
-isResourceRaw(const struct tgsi::Source *code, const int r)
+isResourceRaw(const tgsi::Source *code, const int r)
 {
    return isResourceSpecial(r) || code->resources[r].raw;
 }
 
 static inline nv50_ir::TexTarget
-getResourceTarget(const struct tgsi::Source *code, int r)
+getResourceTarget(const tgsi::Source *code, int r)
 {
    if (isResourceSpecial(r))
       return nv50_ir::TEX_TARGET_BUFFER;
index 64989ac88460fead95a9036af4433a158b2a2920..596ac95d48982f2f82b032662c0841e34f81b0ca 100644 (file)
@@ -240,6 +240,7 @@ GM107LoweringPass::visit(Instruction *i)
             Value *ptr = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
                                     i->getIndirect(0, 0), bld.mkImm(4));
             i->setIndirect(0, 0, ptr);
+            i->op = OP_VFETCH;
          } else {
             i->op = OP_VFETCH;
             assert(prog->getType() != Program::TYPE_FRAGMENT); // INTERP
index 1ad086094dc0ab181edef5aeb317518fd3007adf..2c7f7e326b27575a58eec17770398f2ab646b231 100644 (file)
@@ -887,7 +887,7 @@ NV50LoweringPreSSA::handleTXL(TexInstruction *i)
       }
    }
    bld.setPosition(joinBB, false);
-   bld.mkOp(OP_JOIN, TYPE_NONE, NULL);
+   bld.mkFlow(OP_JOIN, NULL, CC_ALWAYS, NULL)->fixed = 1;
    return true;
 }
 
index b61f3c49bb90056ed968b5cf6dde9fdd199abb8b..7a5d1ce0299d2bc3c0d06f91bb66b212e8f1bfb8 100644 (file)
@@ -100,8 +100,7 @@ void
 NVC0LegalizeSSA::handleFTZ(Instruction *i)
 {
    // Only want to flush float inputs
-   if (i->sType != TYPE_F32)
-      return;
+   assert(i->sType == TYPE_F32);
 
    // If we're already flushing denorms (and NaN's) to zero, no need for this.
    if (i->dnz)
@@ -129,7 +128,7 @@ NVC0LegalizeSSA::visit(BasicBlock *bb)
    Instruction *next;
    for (Instruction *i = bb->getEntry(); i; i = next) {
       next = i->next;
-      if (i->dType == TYPE_F32) {
+      if (i->sType == TYPE_F32) {
          if (prog->getType() != Program::TYPE_COMPUTE)
             handleFTZ(i);
          continue;
@@ -169,7 +168,7 @@ NVC0LegalizePostRA::insnDominatedBy(const Instruction *later,
 
 void
 NVC0LegalizePostRA::addTexUse(std::list<TexUse> &uses,
-                              Instruction *usei, const Instruction *insn)
+                              Instruction *usei, const Instruction *texi)
 {
    bool add = true;
    for (std::list<TexUse>::iterator it = uses.begin();
@@ -184,7 +183,7 @@ NVC0LegalizePostRA::addTexUse(std::list<TexUse> &uses,
          ++it;
    }
    if (add)
-      uses.push_back(TexUse(usei, insn));
+      uses.push_back(TexUse(usei, texi));
 }
 
 void
@@ -196,7 +195,8 @@ NVC0LegalizePostRA::findOverwritingDefs(const Instruction *texi,
    while (insn->op == OP_MOV && insn->getDef(0)->equals(insn->getSrc(0)))
       insn = insn->getSrc(0)->getUniqueInsn();
 
-   if (!insn->bb->reachableBy(texi->bb, term))
+   // NOTE: the tex itself is, of course, not an overwriting definition
+   if (insn == texi || !insn->bb->reachableBy(texi->bb, term))
       return;
 
    switch (insn->op) {
@@ -244,7 +244,12 @@ NVC0LegalizePostRA::findFirstUses(
          visited.insert(usei);
 
          if (usei->op == OP_PHI || usei->op == OP_UNION) {
-            // need a barrier before WAW cases
+            // need a barrier before WAW cases, like:
+            //   %r0 = tex
+            //   if ...
+            //     texbar <- is required or tex might replace x again
+            //     %r1 = x <- overwriting def
+            //   %r2 = phi %r0, %r1
             for (int s = 0; usei->srcExists(s); ++s) {
                Instruction *defi = usei->getSrc(s)->getUniqueInsn();
                if (defi && &usei->src(s) != *u)
@@ -263,7 +268,7 @@ NVC0LegalizePostRA::findFirstUses(
              usei->subOp != NV50_IR_SUBOP_MOV_FINAL) {
             findFirstUses(texi, usei, uses, visited);
          } else {
-            addTexUse(uses, usei, insn);
+            addTexUse(uses, usei, texi);
          }
       }
    }
@@ -1751,6 +1756,7 @@ NVC0LoweringPass::visit(Instruction *i)
             Value *ptr = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
                                     i->getIndirect(0, 0), bld.mkImm(4));
             i->setIndirect(0, 0, ptr);
+            i->op = OP_VFETCH;
          } else {
             i->op = OP_VFETCH;
             assert(prog->getType() != Program::TYPE_FRAGMENT); // INTERP
index 14446b6b53f7f4fc41f13c3c2ec079a7dc9e0e84..ae739eeda83c63b460759de2cdf398f2270b40e5 100644 (file)
@@ -236,6 +236,9 @@ LoadPropagation::visit(BasicBlock *bb)
       if (i->op == OP_CALL) // calls have args as sources, they must be in regs
          continue;
 
+      if (i->op == OP_PFETCH) // pfetch expects arg1 to be a reg
+         continue;
+
       if (i->srcExists(1))
          checkSwapSrc01(i);
 
@@ -278,7 +281,6 @@ private:
 
    void tryCollapseChainedMULs(Instruction *, const int s, ImmediateValue&);
 
-   // TGSI 'true' is converted to -1 by F2I(NEG(SET)), track back to SET
    CmpInstruction *findOriginForTestWithZero(Value *);
 
    unsigned int foldCount;
@@ -337,25 +339,33 @@ ConstantFolding::findOriginForTestWithZero(Value *value)
       return NULL;
    Instruction *insn = value->getInsn();
 
-   while (insn && insn->op != OP_SET) {
-      Instruction *next = NULL;
-      switch (insn->op) {
-      case OP_NEG:
-      case OP_ABS:
-      case OP_CVT:
-         next = insn->getSrc(0)->getInsn();
-         if (insn->sType != next->dType)
+   if (insn->asCmp() && insn->op != OP_SLCT)
+      return insn->asCmp();
+
+   /* Sometimes mov's will sneak in as a result of other folding. This gets
+    * cleaned up later.
+    */
+   if (insn->op == OP_MOV)
+      return findOriginForTestWithZero(insn->getSrc(0));
+
+   /* Deal with AND 1.0 here since nv50 can't fold into boolean float */
+   if (insn->op == OP_AND) {
+      int s = 0;
+      ImmediateValue imm;
+      if (!insn->src(s).getImmediate(imm)) {
+         s = 1;
+         if (!insn->src(s).getImmediate(imm))
             return NULL;
-         break;
-      case OP_MOV:
-         next = insn->getSrc(0)->getInsn();
-         break;
-      default:
-         return NULL;
       }
-      insn = next;
+      if (imm.reg.data.f32 != 1.0f)
+         return NULL;
+      /* TODO: Come up with a way to handle the condition being inverted */
+      if (insn->src(!s).mod != Modifier(0))
+         return NULL;
+      return findOriginForTestWithZero(insn->getSrc(!s));
    }
-   return insn ? insn->asCmp() : NULL;
+
+   return NULL;
 }
 
 void
@@ -574,6 +584,11 @@ ConstantFolding::expr(Instruction *i,
    case OP_POPCNT:
       res.data.u32 = util_bitcount(a->data.u32 & b->data.u32);
       break;
+   case OP_PFETCH:
+      // The two arguments to pfetch are logically added together. Normally
+      // the second argument will not be constant, but that can happen.
+      res.data.u32 = a->data.u32 + b->data.u32;
+      break;
    default:
       return;
    }
@@ -588,7 +603,9 @@ ConstantFolding::expr(Instruction *i,
 
    i->getSrc(0)->reg.data = res.data;
 
-   if (i->op == OP_MAD || i->op == OP_FMA) {
+   switch (i->op) {
+   case OP_MAD:
+   case OP_FMA: {
       i->op = OP_ADD;
 
       i->setSrc(1, i->getSrc(0));
@@ -603,8 +620,14 @@ ConstantFolding::expr(Instruction *i,
          bld.setPosition(i, false);
          i->setSrc(1, bld.loadImm(NULL, res.data.u32));
       }
-   } else {
+      break;
+   }
+   case OP_PFETCH:
+      // Leave PFETCH alone... we just folded its 2 args into 1.
+      break;
+   default:
       i->op = i->saturate ? OP_SAT : OP_MOV; /* SAT handled by unary() */
+      break;
    }
    i->subOp = 0;
 }
@@ -946,33 +969,82 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
 
    case OP_SET: // TODO: SET_AND,OR,XOR
    {
+      /* This optimizes the case where the output of a set is being compared
+       * to zero. Since the set can only produce 0/-1 (int) or 0/1 (float), we
+       * can be a lot cleverer in our comparison.
+       */
       CmpInstruction *si = findOriginForTestWithZero(i->getSrc(t));
       CondCode cc, ccZ;
-      if (i->src(t).mod != Modifier(0))
-         return;
-      if (imm0.reg.data.u32 != 0 || !si || si->op != OP_SET)
+      if (imm0.reg.data.u32 != 0 || !si)
          return;
       cc = si->setCond;
       ccZ = (CondCode)((unsigned int)i->asCmp()->setCond & ~CC_U);
+      // We do everything assuming var (cmp) 0, reverse the condition if 0 is
+      // first.
       if (s == 0)
          ccZ = reverseCondCode(ccZ);
+      // If there is a negative modifier, we need to undo that, by flipping
+      // the comparison to zero.
+      if (i->src(t).mod.neg())
+         ccZ = reverseCondCode(ccZ);
+      // If this is a signed comparison, we expect the input to be a regular
+      // boolean, i.e. 0/-1. However the rest of the logic assumes that true
+      // is positive, so just flip the sign.
+      if (i->sType == TYPE_S32) {
+         assert(!isFloatType(si->dType));
+         ccZ = reverseCondCode(ccZ);
+      }
       switch (ccZ) {
-      case CC_LT: cc = CC_FL; break;
-      case CC_GE: cc = CC_TR; break;
-      case CC_EQ: cc = inverseCondCode(cc); break;
-      case CC_LE: cc = inverseCondCode(cc); break;
-      case CC_GT: break;
-      case CC_NE: break;
+      case CC_LT: cc = CC_FL; break; // bool < 0 -- this is never true
+      case CC_GE: cc = CC_TR; break; // bool >= 0 -- this is always true
+      case CC_EQ: cc = inverseCondCode(cc); break; // bool == 0 -- !bool
+      case CC_LE: cc = inverseCondCode(cc); break; // bool <= 0 -- !bool
+      case CC_GT: break; // bool > 0 -- bool
+      case CC_NE: break; // bool != 0 -- bool
       default:
          return;
       }
+
+      // Update the condition of this SET to be identical to the origin set,
+      // but with the updated condition code. The original SET should get
+      // DCE'd, ideally.
+      i->op = si->op;
       i->asCmp()->setCond = cc;
       i->setSrc(0, si->src(0));
       i->setSrc(1, si->src(1));
+      if (si->srcExists(2))
+         i->setSrc(2, si->src(2));
       i->sType = si->sType;
    }
       break;
 
+   case OP_AND:
+   {
+      CmpInstruction *cmp = i->getSrc(t)->getInsn()->asCmp();
+      if (!cmp || cmp->op == OP_SLCT || cmp->getDef(0)->refCount() > 1)
+         return;
+      if (!prog->getTarget()->isOpSupported(cmp->op, TYPE_F32))
+         return;
+      if (imm0.reg.data.f32 != 1.0)
+         return;
+      if (i->getSrc(t)->getInsn()->dType != TYPE_U32)
+         return;
+
+      i->getSrc(t)->getInsn()->dType = TYPE_F32;
+      if (i->src(t).mod != Modifier(0)) {
+         assert(i->src(t).mod == Modifier(NV50_IR_MOD_NOT));
+         i->src(t).mod = Modifier(0);
+         cmp->setCond = inverseCondCode(cmp->setCond);
+      }
+      i->op = OP_MOV;
+      i->setSrc(s, NULL);
+      if (t) {
+         i->setSrc(0, i->getSrc(t));
+         i->setSrc(t, NULL);
+      }
+   }
+      break;
+
    case OP_SHL:
    {
       if (s != 1 || i->src(0).mod != Modifier(0))
@@ -2216,7 +2288,7 @@ FlatteningPass::visit(BasicBlock *bb)
              insn->op != OP_LINTERP && // probably just nve4
              insn->op != OP_PINTERP && // probably just nve4
              ((insn->op != OP_LOAD && insn->op != OP_STORE) ||
-              typeSizeof(insn->dType) <= 4) &&
+              (typeSizeof(insn->dType) <= 4 && !insn->src(0).isIndirect(0))) &&
              !insn->isNop()) {
             insn->join = 1;
             bb->remove(bb->getExit());
index 178a1671c3f35213c2d5187391029059b3321c87..ca545a6024a1bd30c27822ee594f118e6e546124 100644 (file)
@@ -84,7 +84,7 @@ static const struct opProperties _initProps[] =
    //           neg  abs  not  sat  c[]  s[], a[], imm
    { OP_ADD,    0x3, 0x0, 0x0, 0x8, 0x2, 0x1, 0x1, 0x2 },
    { OP_SUB,    0x3, 0x0, 0x0, 0x8, 0x2, 0x1, 0x1, 0x2 },
-   { OP_MUL,    0x3, 0x0, 0x0, 0x8, 0x2, 0x1, 0x1, 0x2 },
+   { OP_MUL,    0x3, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x2 },
    { OP_MAX,    0x3, 0x3, 0x0, 0x0, 0x2, 0x1, 0x1, 0x0 },
    { OP_MIN,    0x3, 0x3, 0x0, 0x0, 0x2, 0x1, 0x1, 0x0 },
    { OP_MAD,    0x7, 0x0, 0x0, 0x8, 0x6, 0x1, 0x1, 0x0 }, // special constraint
@@ -188,6 +188,9 @@ void TargetNV50::initOpInfo()
       if (prop->mSat & 8)
          opInfo[prop->op].dstMods = NV50_IR_MOD_SAT;
    }
+
+   if (chipset >= 0xa0)
+      opInfo[OP_MUL].dstMods = NV50_IR_MOD_SAT;
 }
 
 unsigned int
@@ -413,6 +416,8 @@ TargetNV50::isOpSupported(operation op, DataType ty) const
       return false;
    case OP_SAD:
       return ty == TYPE_S32;
+   case OP_SET:
+      return !isFloatType(ty);
    default:
       return true;
    }
index 32fa65c8a51c577a8fbb6a48bb21ebe271eda459..09cdbb53ecb7cea4ac16da65c1e69807d45ec3a1 100644 (file)
@@ -658,13 +658,13 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
       switch (buffer->base.usage) {
       case PIPE_USAGE_DEFAULT:
       case PIPE_USAGE_IMMUTABLE:
-         buffer->domain = NOUVEAU_BO_VRAM;
+         buffer->domain = NV_VRAM_DOMAIN(screen);
          break;
       case PIPE_USAGE_DYNAMIC:
          /* For most apps, we'd have to do staging transfers to avoid sync
           * with this usage, and GART -> GART copies would be suboptimal.
           */
-         buffer->domain = NOUVEAU_BO_VRAM;
+         buffer->domain = NV_VRAM_DOMAIN(screen);
          break;
       case PIPE_USAGE_STAGING:
       case PIPE_USAGE_STREAM:
@@ -676,7 +676,7 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
       }
    } else {
       if (buffer->base.bind & screen->vidmem_bindings)
-         buffer->domain = NOUVEAU_BO_VRAM;
+         buffer->domain = NV_VRAM_DOMAIN(screen);
       else
       if (buffer->base.bind & screen->sysmem_bindings)
          buffer->domain = NOUVEAU_BO_GART;
index d0b22844ad0140dad21e851b719ac77b18a9699f..a3d64a65623938b3da1a8438f7c58350aab475a1 100644 (file)
 #ifndef __NOUVEAU_HEAP_H__
 #define __NOUVEAU_HEAP_H__
 
+/* This datastructure represents a memory allocation heap. Fundamentally, this
+ * is a doubly-linked list with a few properties, and a usage convention.
+ *
+ * On initial allocation, there is a single node with the full size that's
+ * marked as not in-use. As allocations are made, blocks are taken off the end
+ * of that first node, and inserted right after it. If the first node doesn't
+ * have enough free space, we look for free space down in the rest of the
+ * list. This can happen if an allocation is made and then freed.
+ *
+ * The first node will remain with in_use == 0 even if the whole heap is
+ * exhausted. Another invariant is that there will never be two sequential
+ * in_use == 0 nodes. If a node is freed and it has one (or both) adjacent
+ * free nodes, they are merged into one, and the relevant heap entries are
+ * freed.
+ *
+ * The pattern to free the whole heap is to start with the first node and then
+ * just free the "next" node, until there is no next node. This should assure
+ * that at the end the first (and only) node is not in use and contains the
+ * full size of the heap.
+ */
 struct nouveau_heap {
        struct nouveau_heap *prev;
        struct nouveau_heap *next;
index b4f1413fd8badb6ccdc08adc61a8a4c18962040b..c6e5074db1954afdb058ee914b896723388a3a6c 100644 (file)
@@ -164,6 +164,16 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
                size = sizeof(nvc0_data);
        }
 
+       /*
+        * Set default VRAM domain if not overridden
+        */
+       if (!screen->vram_domain) {
+               if (dev->vram_size > 0)
+                       screen->vram_domain = NOUVEAU_BO_VRAM;
+               else
+                       screen->vram_domain = NOUVEAU_BO_GART;
+       }
+
        ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
                                 data, size, &screen->channel);
        if (ret)
index cf06f7e88aa0b848355d79b820b77b648c62a52c..30041b271c94c1723bb55be9d3c70c2add05ee31 100644 (file)
@@ -51,6 +51,8 @@ struct nouveau_screen {
 
        boolean hint_buf_keep_sysmem_copy;
 
+       unsigned vram_domain;
+
        struct {
                unsigned profiles_checked;
                unsigned profiles_present;
@@ -94,6 +96,8 @@ struct nouveau_screen {
 #endif
 };
 
+#define NV_VRAM_DOMAIN(screen) ((screen)->vram_domain)
+
 #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
 # define NOUVEAU_DRV_STAT(s, n, v) do {         \
       (s)->stats.named.n += (v);               \
index 1ab8929cc384d587f93b3728fd4f4a190be6b0bf..83fd1fa38dde39a59502bf02534a08e40138ad44 100644 (file)
@@ -58,7 +58,7 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers,
    struct pipe_framebuffer_state *fb = &nv30->framebuffer;
    uint32_t colr = 0, zeta = 0, mode = 0;
 
-   if (!nv30_state_validate(nv30, TRUE))
+   if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, TRUE))
       return;
 
    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
index 7b32aaee936441e8d57d4f2fc2009782bbbd9c5b..592cdbe24f97de42d3f0ce64ff2f3ad8e9590d39 100644 (file)
@@ -204,7 +204,7 @@ void
 nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info);
 
 boolean
-nv30_state_validate(struct nv30_context *nv30, boolean hwtnl);
+nv30_state_validate(struct nv30_context *nv30, uint32_t mask, boolean hwtnl);
 
 void
 nv30_state_release(struct nv30_context *nv30);
index 3575c3d29fa8e0457abe767a5694b59f508155cc..c1665b7ad2f7cad3f004d7381ecc11a745267594 100644 (file)
@@ -71,12 +71,12 @@ nv30_render_allocate_vertices(struct vbuf_render *render,
    struct nv30_render *r = nv30_render(render);
    struct nv30_context *nv30 = r->nv30;
 
-   r->length = vertex_size * nr_vertices;
+   r->length = (uint32_t)vertex_size * (uint32_t)nr_vertices;
 
    if (r->offset + r->length >= render->max_vertex_buffer_bytes) {
       pipe_resource_reference(&r->buffer, NULL);
       r->buffer = pipe_buffer_create(&nv30->screen->base.base,
-                                     PIPE_BIND_VERTEX_BUFFER, 0,
+                                     PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_STREAM,
                                      render->max_vertex_buffer_bytes);
       if (!r->buffer)
          return FALSE;
@@ -91,10 +91,14 @@ static void *
 nv30_render_map_vertices(struct vbuf_render *render)
 {
    struct nv30_render *r = nv30_render(render);
-   char *map = pipe_buffer_map(&r->nv30->base.pipe, r->buffer,
-                               PIPE_TRANSFER_WRITE |
-                               PIPE_TRANSFER_UNSYNCHRONIZED, &r->transfer);
-   return map + r->offset;
+   char *map = pipe_buffer_map_range(
+         &r->nv30->base.pipe, r->buffer,
+         r->offset, r->length,
+         PIPE_TRANSFER_WRITE |
+         PIPE_TRANSFER_DISCARD_RANGE,
+         &r->transfer);
+   assert(map);
+   return map;
 }
 
 static void
@@ -103,6 +107,7 @@ nv30_render_unmap_vertices(struct vbuf_render *render,
 {
    struct nv30_render *r = nv30_render(render);
    pipe_buffer_unmap(&r->nv30->base.pipe, r->transfer);
+   r->transfer = NULL;
 }
 
 static void
@@ -126,10 +131,10 @@ nv30_render_draw_elements(struct vbuf_render *render,
    for (i = 0; i < r->vertex_info.num_attribs; i++) {
       PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                        nv04_resource(r->buffer), r->offset + r->vtxptr[i],
-                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
    }
 
-   if (!nv30_state_validate(nv30, FALSE))
+   if (!nv30_state_validate(nv30, ~0, FALSE))
       return;
 
    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
@@ -171,10 +176,10 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
    for (i = 0; i < r->vertex_info.num_attribs; i++) {
       PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                        nv04_resource(r->buffer), r->offset + r->vtxptr[i],
-                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
    }
 
-   if (!nv30_state_validate(nv30, FALSE))
+   if (!nv30_state_validate(nv30, ~0, FALSE))
       return;
 
    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
@@ -213,22 +218,24 @@ static const struct {
    [TGSI_SEMANTIC_BCOLOR  ] = { EMIT_4F, INTERP_LINEAR     , 1, 3, 0x00000004 },
    [TGSI_SEMANTIC_FOG     ] = { EMIT_4F, INTERP_PERSPECTIVE, 5, 5, 0x00000010 },
    [TGSI_SEMANTIC_PSIZE   ] = { EMIT_1F_PSIZE, INTERP_POS  , 6, 6, 0x00000020 },
-   [TGSI_SEMANTIC_GENERIC ] = { EMIT_4F, INTERP_PERSPECTIVE, 8, 7, 0x00004000 }
+   [TGSI_SEMANTIC_TEXCOORD] = { EMIT_4F, INTERP_PERSPECTIVE, 8, 7, 0x00004000 },
 };
 
 static boolean
 vroute_add(struct nv30_render *r, uint attrib, uint sem, uint *idx)
 {
-   struct pipe_screen *pscreen = &r->nv30->screen->base.base;
+   struct nv30_screen *screen = r->nv30->screen;
    struct nv30_fragprog *fp = r->nv30->fragprog.program;
    struct vertex_info *vinfo = &r->vertex_info;
    enum pipe_format format;
    uint emit = EMIT_OMIT;
    uint result = *idx;
 
-   if (sem == TGSI_SEMANTIC_GENERIC && result >= 8) {
-      for (result = 0; result < 8; result++) {
-         if (fp->texcoord[result] == *idx) {
+   if (sem == TGSI_SEMANTIC_GENERIC) {
+      uint num_texcoords = (screen->eng3d->oclass < NV40_3D_CLASS) ? 8 : 10;
+      for (result = 0; result < num_texcoords; result++) {
+         if (fp->texcoord[result] == *idx + 8) {
+            sem = TGSI_SEMANTIC_TEXCOORD;
             emit = vroute[sem].emit;
             break;
          }
@@ -243,11 +250,11 @@ vroute_add(struct nv30_render *r, uint attrib, uint sem, uint *idx)
    draw_emit_vertex_attr(vinfo, emit, vroute[sem].interp, attrib);
    format = draw_translate_vinfo_format(emit);
 
-   r->vtxfmt[attrib] = nv30_vtxfmt(pscreen, format)->hw;
-   r->vtxptr[attrib] = vinfo->size | NV30_3D_VTXBUF_DMA1;
+   r->vtxfmt[attrib] = nv30_vtxfmt(&screen->base.base, format)->hw;
+   r->vtxptr[attrib] = vinfo->size;
    vinfo->size += draw_translate_vinfo_size(emit);
 
-   if (nv30_screen(pscreen)->eng3d->oclass < NV40_3D_CLASS) {
+   if (screen->eng3d->oclass < NV40_3D_CLASS) {
       r->vtxprog[attrib][0] = 0x001f38d8;
       r->vtxprog[attrib][1] = 0x0080001b | (attrib << 9);
       r->vtxprog[attrib][2] = 0x0836106c;
@@ -259,7 +266,12 @@ vroute_add(struct nv30_render *r, uint attrib, uint sem, uint *idx)
       r->vtxprog[attrib][3] = 0x6041ff80 | (result + vroute[sem].vp40) << 2;
    }
 
-   *idx = vroute[sem].ow40 << result;
+   if (result < 8)
+      *idx = vroute[sem].ow40 << result;
+   else {
+      assert(sem == TGSI_SEMANTIC_TEXCOORD);
+      *idx = 0x00001000 << (result - 8);
+   }
    return TRUE;
 }
 
@@ -313,7 +325,7 @@ nv30_render_validate(struct nv30_context *nv30)
 
    while (pntc && attrib < 16) {
       uint index = ffs(pntc) - 1; pntc &= ~(1 << index);
-      if (vroute_add(r, attrib, TGSI_SEMANTIC_GENERIC, &index)) {
+      if (vroute_add(r, attrib, TGSI_SEMANTIC_TEXCOORD, &index)) {
          vp_attribs |= (1 << attrib++);
          vp_results |= index;
       }
@@ -398,17 +410,17 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
       if (nv30->vertprog.constbuf) {
          void *map = nv04_resource(nv30->vertprog.constbuf)->data;
          draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
-                                         map, nv30->vertprog.constbuf_nr);
+                                         map, nv30->vertprog.constbuf_nr * 16);
+      } else {
+         draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
       }
    }
 
    for (i = 0; i < nv30->num_vtxbufs; i++) {
       const void *map = nv30->vtxbuf[i].user_buffer;
       if (!map) {
-         if (!nv30->vtxbuf[i].buffer) {
-            continue;
-         }
-         map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
+         if (nv30->vtxbuf[i].buffer)
+            map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
                                   PIPE_TRANSFER_UNSYNCHRONIZED |
                                   PIPE_TRANSFER_READ, &transfer[i]);
       }
@@ -418,9 +430,9 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    if (info->indexed) {
       const void *map = nv30->idxbuf.user_buffer;
       if (!map)
-         pipe_buffer_map(pipe, nv30->idxbuf.buffer,
-                                  PIPE_TRANSFER_UNSYNCHRONIZED |
-                                  PIPE_TRANSFER_READ, &transferi);
+         map = pipe_buffer_map(pipe, nv30->idxbuf.buffer,
+                               PIPE_TRANSFER_UNSYNCHRONIZED |
+                               PIPE_TRANSFER_READ, &transferi);
       draw_set_indexes(draw,
                        (ubyte *) map + nv30->idxbuf.offset,
                        nv30->idxbuf.index_size, ~0);
@@ -444,6 +456,12 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 static void
 nv30_render_destroy(struct vbuf_render *render)
 {
+   struct nv30_render *r = nv30_render(render);
+
+   if (r->transfer)
+      pipe_buffer_unmap(&r->nv30->base.pipe, r->transfer);
+   pipe_resource_reference(&r->buffer, NULL);
+   nouveau_heap_free(&r->vertprog);
    FREE(render);
 }
 
index a05bfe10ee9ab9b1e1be45a826481fee43442c93..7f227868f737ef2c9c68c2e5c1697905a2a4cae0 100644 (file)
@@ -23,6 +23,7 @@
  *
  */
 
+#include "draw/draw_context.h"
 #include "tgsi/tgsi_parse.h"
 
 #include "nv_object.xml.h"
@@ -147,8 +148,12 @@ nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso)
 
    pipe_resource_reference(&fp->buffer, NULL);
 
+   if (fp->draw)
+      draw_delete_fragment_shader(nv30_context(pipe)->draw, fp->draw);
+
    FREE((void *)fp->pipe.tokens);
    FREE(fp->insn);
+   FREE(fp->consts);
    FREE(fp);
 }
 
index eeb714864e2a8f5a262998932cb68e6624d1a7d4..2e38a1978ae256730067a8a3293bdabd5eb11e02 100644 (file)
@@ -161,6 +161,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
@@ -251,6 +252,7 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
          return 0;
       default:
          debug_printf("unknown vertex shader param %d\n", param);
@@ -291,6 +293,7 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
          return 0;
       default:
          debug_printf("unknown fragment shader param %d\n", param);
@@ -523,7 +526,7 @@ nv30_screen_create(struct nouveau_device *dev)
 
    ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify);
    if (ret == 0)
-      nouveau_bo_map(screen->notify, 0, screen->base.client);
+      ret = nouveau_bo_map(screen->notify, 0, screen->base.client);
    if (ret)
       FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);
 
index 0f9d19dd68efec00d89210299c02186a779155e4..a954dcce5626fe8e5de7378e955add2ed0f8af80 100644 (file)
@@ -272,15 +272,13 @@ nv30_validate_clip(struct nv30_context *nv30)
    uint32_t clpd_enable = 0;
 
    for (i = 0; i < 6; i++) {
-      if (nv30->rast->pipe.clip_plane_enable & (1 << i)) {
-         if (nv30->dirty & NV30_NEW_CLIP) {
-            BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
-            PUSH_DATA (push, i);
-            PUSH_DATAp(push, nv30->clip.ucp[i], 4);
-         }
-
-         clpd_enable |= 1 << (1 + 4*i);
+      if (nv30->dirty & NV30_NEW_CLIP) {
+         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
+         PUSH_DATA (push, i);
+         PUSH_DATAp(push, nv30->clip.ucp[i], 4);
       }
+      if (nv30->rast->pipe.clip_plane_enable & (1 << i))
+         clpd_enable |= 2 << (4*i);
    }
 
    BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
@@ -389,7 +387,7 @@ static struct state_validate hwtnl_validate_list[] = {
     { nv30_validate_stipple,       NV30_NEW_STIPPLE },
     { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
     { nv30_validate_viewport,      NV30_NEW_VIEWPORT },
-    { nv30_validate_clip,          NV30_NEW_CLIP },
+    { nv30_validate_clip,          NV30_NEW_CLIP | NV30_NEW_RASTERIZER },
     { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
     { nv30_vertprog_validate,      NV30_NEW_VERTPROG | NV30_NEW_VERTCONST |
                                    NV30_NEW_FRAGPROG | NV30_NEW_RASTERIZER },
@@ -456,7 +454,7 @@ nv30_state_context_switch(struct nv30_context *nv30)
 }
 
 boolean
-nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
+nv30_state_validate(struct nv30_context *nv30, uint32_t mask, boolean hwtnl)
 {
    struct nouveau_screen *screen = &nv30->screen->base;
    struct nouveau_pushbuf *push = nv30->base.pushbuf;
@@ -481,14 +479,16 @@ nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
    else
       validate = swtnl_validate_list;
 
-   if (nv30->dirty) {
+   mask &= nv30->dirty;
+
+   if (mask) {
       while (validate->func) {
-         if (nv30->dirty & validate->mask)
+         if (mask & validate->mask)
             validate->func(nv30);
          validate++;
       }
 
-      nv30->dirty = 0;
+      nv30->dirty &= ~mask;
    }
 
    nouveau_pushbuf_bufctx(push, bctx);
index 67ab8295218bef999d4483c41c751894a1e8b49f..d4e384b21d2f749794176f511fcc03c579a57794 100644 (file)
@@ -564,7 +564,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS)))
       nv30_update_user_vbufs(nv30);
 
-   nv30_state_validate(nv30, TRUE);
+   nv30_state_validate(nv30, ~0, TRUE);
    if (nv30->draw_flags) {
       nv30_render_vbo(pipe, info);
       return;
index 3c1b7e714ea24e70ca847447a7a64f715bfa1767..4d4145d10b5dc73fd5b201aeb27c561cdf57c5a9 100644 (file)
@@ -23,6 +23,7 @@
  *
  */
 
+#include "draw/draw_context.h"
 #include "util/u_dynarray.h"
 #include "tgsi/tgsi_parse.h"
 
@@ -237,6 +238,10 @@ nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso)
 
    if (vp->translated)
       nv30_vertprog_destroy(vp);
+
+   if (vp->draw)
+      draw_delete_vertex_shader(nv30_context(pipe)->draw, vp->draw);
+
    FREE((void *)vp->pipe.tokens);
    FREE(vp);
 }
index bbdca8102f0c391ad488f9a93f4b8bd2f6279861..9ef16965f3960adfc8753870bb6cc4dc0331862d 100644 (file)
@@ -327,6 +327,8 @@ nv40_fp_rep(struct nvfx_fpc *fpc, unsigned count, unsigned target)
         //util_dynarray_append(&fpc->loop_stack, unsigned, target);
 }
 
+#if 0
+/* documentation only */
 /* warning: this only works forward, and probably only if not inside any IF */
 static void
 nv40_fp_bra(struct nvfx_fpc *fpc, unsigned target)
@@ -352,6 +354,7 @@ nv40_fp_bra(struct nvfx_fpc *fpc, unsigned target)
         reloc.location = fpc->inst_offset + 3;
         util_dynarray_append(&fpc->label_relocs, struct nvfx_relocation, reloc);
 }
+#endif
 
 static void
 nv40_fp_brk(struct nvfx_fpc *fpc)
@@ -528,7 +531,7 @@ nvfx_fragprog_parse_instruction(struct nvfx_fpc *fpc,
 
    dst  = tgsi_dst(fpc, &finst->Dst[0]);
    mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
-   sat  = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
+   sat  = finst->Instruction.Saturate;
 
    switch (finst->Instruction.Opcode) {
    case TGSI_OPCODE_ABS:
@@ -1201,17 +1204,3 @@ out_err:
    tgsi_dump(fp->pipe.tokens, 0);
    goto out;
 }
-
-static inline void
-nvfx_fp_memcpy(void* dst, const void* src, size_t len)
-{
-#ifndef PIPE_ARCH_BIG_ENDIAN
-   memcpy(dst, src, len);
-#else
-   size_t i;
-   for(i = 0; i < len; i += 4) {
-      uint32_t v = *(uint32_t*)((char*)src + i);
-      *(uint32_t*)((char*)dst + i) = (v >> 16) | (v << 16);
-   }
-#endif
-}
index 29d506b6e9bf4ed8967260502fd961227800227e..1ce0589be713e28999656c95e61eeaee33c68106 100644 (file)
@@ -539,7 +539,7 @@ nvfx_vertprog_parse_instruction(struct nvfx_vpc *vpc,
 
    final_dst = dst  = tgsi_dst(vpc, &finst->Dst[0]);
    mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
-   if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) {
+   if(finst->Instruction.Saturate) {
       assert(finst->Instruction.Opcode != TGSI_OPCODE_ARL);
       if (vpc->is_nv4x)
          sat = TRUE;
@@ -796,7 +796,7 @@ nvfx_vertprog_parse_instruction(struct nvfx_vpc *vpc,
       return FALSE;
    }
 
-   if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE && !vpc->is_nv4x) {
+   if(finst->Instruction.Saturate && !vpc->is_nv4x) {
       if (!vpc->r_0_1.type)
          vpc->r_0_1 = constant(vpc, -1, 0, 1, 0, 0);
       nvfx_vp_emit(vpc, arith(0, VEC, MAX, dst, mask, nvfx_src(dst), swz(nvfx_src(vpc->r_0_1), X, X, X, X), none));
@@ -872,9 +872,8 @@ nvfx_vertprog_parse_decl_output(struct nvfx_vpc *vpc,
       }
       break;
    case TGSI_SEMANTIC_EDGEFLAG:
-      /* not really an error just a fallback */
-      NOUVEAU_ERR("cannot handle edgeflag output\n");
-      return FALSE;
+      vpc->r_result[idx] = nvfx_reg(NVFXSR_NONE, 0);
+      return TRUE;
    default:
       NOUVEAU_ERR("bad output semantic\n");
       return FALSE;
index 2cfd5db5ea030fdd3d1d0e8b228ecd26ddbb7e5c..5b5d3912c20caa75b47a426fe8c41cb870380b37 100644 (file)
@@ -138,8 +138,11 @@ nv50_destroy(struct pipe_context *pipe)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
-   if (nv50_context_screen(nv50)->cur_ctx == nv50)
-      nv50_context_screen(nv50)->cur_ctx = NULL;
+   if (nv50->screen->cur_ctx == nv50) {
+      nv50->screen->cur_ctx = NULL;
+      /* Save off the state in case another context gets created */
+      nv50->screen->save_state = nv50->state;
+   }
    nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
    nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);
 
@@ -290,6 +293,10 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
    pipe->get_sample_position = nv50_context_get_sample_position;
 
    if (!screen->cur_ctx) {
+      /* Restore the last context's state here, normally handled during
+       * context switch
+       */
+      nv50->state = screen->save_state;
       screen->cur_ctx = nv50;
       nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
    }
index 45eb554eb4f76147ab79c04e8f286c24af466783..1f123ef7e92f5d3a4eedb6a2ae26af9dc4858b91 100644 (file)
@@ -104,28 +104,7 @@ struct nv50_context {
    uint32_t dirty;
    boolean cb_dirty;
 
-   struct {
-      uint32_t instance_elts; /* bitmask of per-instance elements */
-      uint32_t instance_base;
-      uint32_t interpolant_ctrl;
-      uint32_t semantic_color;
-      uint32_t semantic_psize;
-      int32_t index_bias;
-      boolean uniform_buffer_bound[3];
-      boolean prim_restart;
-      boolean point_sprite;
-      boolean rt_serialize;
-      boolean flushed;
-      boolean rasterizer_discard;
-      uint8_t tls_required;
-      boolean new_tls_space;
-      uint8_t num_vtxbufs;
-      uint8_t num_vtxelts;
-      uint8_t num_textures[3];
-      uint8_t num_samplers[3];
-      uint8_t prim_size;
-      uint16_t scissor;
-   } state;
+   struct nv50_graph_state state;
 
    struct nv50_blend_stateobj *blend;
    struct nv50_rasterizer_stateobj *rast;
@@ -191,12 +170,6 @@ nv50_context(struct pipe_context *pipe)
    return (struct nv50_context *)pipe;
 }
 
-static INLINE struct nv50_screen *
-nv50_context_screen(struct nv50_context *nv50)
-{
-   return nv50_screen(&nv50->base.screen->base);
-}
-
 /* return index used in nv50_context arrays for a specific shader type */
 static INLINE unsigned
 nv50_context_shader_stage(unsigned pipe)
index 744a3a5bf8bfe916953ac91f1a4dc4463e9cbe60..f15d8f3ecb69ff40929b7a5372aef1fd4bb52aef 100644 (file)
@@ -377,7 +377,7 @@ nv50_miptree_create(struct pipe_screen *pscreen,
    if (!bo_config.nv50.memtype && (pt->bind & PIPE_BIND_SHARED))
       mt->base.domain = NOUVEAU_BO_GART;
    else
-      mt->base.domain = NOUVEAU_BO_VRAM;
+      mt->base.domain = NV_VRAM_DOMAIN(nouveau_screen(pscreen));
 
    bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP;
    if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
@@ -419,7 +419,7 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
       FREE(mt);
       return NULL;
    }
-   mt->base.domain = NOUVEAU_BO_VRAM;
+   mt->base.domain = mt->base.bo->flags & NOUVEAU_BO_APER;
    mt->base.address = mt->base.bo->offset;
 
    mt->base.base = *templ;
index 6690aa282eb2846c2e1b341d279ee79e49bb9b97..81f7474e36b4d2b01452eab14e5b537d88bd8630 100644 (file)
 #include "nv50/nv50_context.h"
 #include "nv_object.xml.h"
 
+#define NV50_QUERY_STATE_READY   0
+#define NV50_QUERY_STATE_ACTIVE  1
+#define NV50_QUERY_STATE_ENDED   2
+#define NV50_QUERY_STATE_FLUSHED 3
+
 /* XXX: Nested queries, and simultaneous queries on multiple gallium contexts
  * (since we use only a single GPU channel per screen) will not work properly.
  *
@@ -42,10 +47,10 @@ struct nv50_query {
    struct nouveau_bo *bo;
    uint32_t base;
    uint32_t offset; /* base + i * 32 */
-   boolean ready;
-   boolean flushed;
+   uint8_t state;
    boolean is64bit;
    struct nouveau_mm_allocation *mm;
+   struct nouveau_fence *fence;
 };
 
 #define NV50_QUERY_ALLOC_SPACE 256
@@ -65,7 +70,7 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
    if (q->bo) {
       nouveau_bo_ref(NULL, &q->bo);
       if (q->mm) {
-         if (q->ready)
+         if (q->state == NV50_QUERY_STATE_READY)
             nouveau_mm_free(q->mm);
          else
             nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work,
@@ -92,6 +97,7 @@ static void
 nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
 {
    nv50_query_allocate(nv50_context(pipe), nv50_query(pq), 0);
+   nouveau_fence_ref(NULL, &nv50_query(pq)->fence);
    FREE(nv50_query(pq));
 }
 
@@ -112,7 +118,8 @@ nv50_query_create(struct pipe_context *pipe, unsigned type, unsigned index)
 
    q->is64bit = (type == PIPE_QUERY_PRIMITIVES_GENERATED ||
                  type == PIPE_QUERY_PRIMITIVES_EMITTED ||
-                 type == PIPE_QUERY_SO_STATISTICS);
+                 type == PIPE_QUERY_SO_STATISTICS ||
+                 type == PIPE_QUERY_PIPELINE_STATISTICS);
    q->type = type;
 
    if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) {
@@ -200,7 +207,7 @@ nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
    default:
       break;
    }
-   q->ready = FALSE;
+   q->state = NV50_QUERY_STATE_ACTIVE;
    return true;
 }
 
@@ -211,6 +218,8 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_query *q = nv50_query(pq);
 
+   q->state = NV50_QUERY_STATE_ENDED;
+
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
       nv50_query_get(push, q, 0, 0x0100f002);
@@ -253,19 +262,27 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
       break;
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
       /* This query is not issued on GPU because disjoint is forced to FALSE */
-      q->ready = TRUE;
+      q->state = NV50_QUERY_STATE_READY;
       break;
    default:
       assert(0);
       break;
    }
-   q->ready = q->flushed = FALSE;
+
+   if (q->is64bit)
+      nouveau_fence_ref(nv50->screen->base.fence.current, &q->fence);
 }
 
-static INLINE boolean
-nv50_query_ready(struct nv50_query *q)
+static INLINE void
+nv50_query_update(struct nv50_query *q)
 {
-   return q->ready || (!q->is64bit && (q->data[0] == q->sequence));
+   if (q->is64bit) {
+      if (nouveau_fence_signalled(q->fence))
+         q->state = NV50_QUERY_STATE_READY;
+   } else {
+      if (q->data[0] == q->sequence)
+         q->state = NV50_QUERY_STATE_READY;
+   }
 }
 
 static boolean
@@ -280,13 +297,14 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
    uint64_t *data64 = (uint64_t *)q->data;
    int i;
 
-   if (!q->ready) /* update ? */
-      q->ready = nv50_query_ready(q);
-   if (!q->ready) {
+   if (q->state != NV50_QUERY_STATE_READY)
+      nv50_query_update(q);
+
+   if (q->state != NV50_QUERY_STATE_READY) {
       if (!wait) {
          /* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
-         if (!q->flushed) {
-            q->flushed = TRUE;
+         if (q->state != NV50_QUERY_STATE_FLUSHED) {
+            q->state = NV50_QUERY_STATE_FLUSHED;
             PUSH_KICK(nv50->base.pushbuf);
          }
          return FALSE;
@@ -294,7 +312,7 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
       if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
          return FALSE;
    }
-   q->ready = TRUE;
+   q->state = NV50_QUERY_STATE_READY;
 
    switch (q->type) {
    case PIPE_QUERY_GPU_FINISHED:
@@ -434,6 +452,7 @@ nv50_query_pushbuf_submit(struct nouveau_pushbuf *push,
    /* XXX: does this exist ? */
 #define NV50_IB_ENTRY_1_NO_PREFETCH (0 << (31 - 8))
 
+   PUSH_REFN(push, q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_GART);
    nouveau_pushbuf_space(push, 0, 0, 1);
    nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 |
                         NV50_IB_ENTRY_1_NO_PREFETCH);
index 829dfbc13fa28589a6424e5f247392f9334538bc..6583a35357833e36e66863c0aa84eb07bc0e2808 100644 (file)
@@ -209,6 +209,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_VERTEXID_NOBASE:
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: /* potentially supported on some hw */
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
@@ -290,6 +291,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
    case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
    case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
    case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
       return 0;
    default:
       NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
index f8ce365135a33c701b6e62b654d07efedd9dd6c8..881051b1862590e7df8e8d976c9b74bb5e8846e7 100644 (file)
@@ -25,10 +25,34 @@ struct nv50_context;
 
 struct nv50_blitter;
 
+struct nv50_graph_state {
+   uint32_t instance_elts; /* bitmask of per-instance elements */
+   uint32_t instance_base;
+   uint32_t interpolant_ctrl;
+   uint32_t semantic_color;
+   uint32_t semantic_psize;
+   int32_t index_bias;
+   boolean uniform_buffer_bound[3];
+   boolean prim_restart;
+   boolean point_sprite;
+   boolean rt_serialize;
+   boolean flushed;
+   boolean rasterizer_discard;
+   uint8_t tls_required;
+   boolean new_tls_space;
+   uint8_t num_vtxbufs;
+   uint8_t num_vtxelts;
+   uint8_t num_textures[3];
+   uint8_t num_samplers[3];
+   uint8_t prim_size;
+   uint16_t scissor;
+};
+
 struct nv50_screen {
    struct nouveau_screen base;
 
    struct nv50_context *cur_ctx;
+   struct nv50_graph_state save_state;
 
    struct nouveau_bo *code;
    struct nouveau_bo *uniforms;
index 290750459cff88dcbcd2f5775da67a258d4e218d..d4d41af3c614aecd8c23ae5c55a06810dc64599b 100644 (file)
@@ -811,12 +811,12 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
    if (nv50->constbuf[s][i].user) {
       nv50->constbuf[s][i].u.data = cb->user_buffer;
-      nv50->constbuf[s][i].size = cb->buffer_size;
+      nv50->constbuf[s][i].size = MIN2(cb->buffer_size, 0x10000);
       nv50->constbuf_valid[s] |= 1 << i;
    } else
    if (res) {
       nv50->constbuf[s][i].offset = cb->buffer_offset;
-      nv50->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+      nv50->constbuf[s][i].size = MIN2(align(cb->buffer_size, 0x100), 0x10000);
       nv50->constbuf_valid[s] |= 1 << i;
    } else {
       nv50->constbuf_valid[s] &= ~(1 << i);
index 85e19b4c623e8be59be419983f5c0c91c7fbdd3d..116bf4bba7cb0bc08943e0a7221e6b4c9e20f656 100644 (file)
@@ -394,6 +394,8 @@ nv50_switch_pipe_context(struct nv50_context *ctx_to)
 
    if (ctx_from)
       ctx_to->state = ctx_from->state;
+   else
+      ctx_to->state = ctx_to->screen->save_state;
 
    ctx_to->dirty = ~0;
    ctx_to->viewports_dirty = ~0;
index c1590eefe9f01dbefe0f4a9c45d1cea04d3c8b2a..1fd33b8aa5934ea8a0f82053732e5723012bca12 100644 (file)
@@ -628,6 +628,7 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
          BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
          PUSH_DATA (push, prim);
 
+         PUSH_REFN(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
          nouveau_pushbuf_space(push, 8, 0, 1);
 
          switch (index_size) {
index ad287a2af6b694405108d5df1fe349671f1b4e31..56fc83d3679f46bab5885fb1fed5979f8a13b930 100644 (file)
@@ -57,7 +57,7 @@ nvc0_screen_compute_setup(struct nvc0_screen *screen,
       return ret;
    }
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 1 << 12, NULL,
+   ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 0, 1 << 12, NULL,
                         &screen->parm);
    if (ret)
       return ret;
index 7662fb50f615baf14fa35e4bec1672ae7ba3c447..a35c3f661423f13cc6f98b5428fb2c10b9e3eeaa 100644 (file)
@@ -139,8 +139,12 @@ nvc0_destroy(struct pipe_context *pipe)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
 
-   if (nvc0->screen->cur_ctx == nvc0)
+   if (nvc0->screen->cur_ctx == nvc0) {
       nvc0->screen->cur_ctx = NULL;
+      nvc0->screen->save_state = nvc0->state;
+      nvc0->screen->save_state.tfb = NULL;
+   }
+
    /* Unset bufctx, we don't want to revalidate any resources after the flush.
     * Other contexts will always set their bufctx again on action calls.
     */
@@ -303,6 +307,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
    pipe->get_sample_position = nvc0_context_get_sample_position;
 
    if (!screen->cur_ctx) {
+      nvc0->state = screen->save_state;
       screen->cur_ctx = nvc0;
       nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
    }
@@ -324,7 +329,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
 
    /* add permanently resident buffers to bufctxts */
 
-   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
+   flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD;
 
    BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
    BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo);
@@ -335,7 +340,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
       BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->parm);
    }
 
-   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
+   flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR;
 
    if (screen->poly_cache)
       BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->poly_cache);
index ef251f35a1bc63eb5b029028cce55fcbfa700c43..a8d7593b3989674248d9e49866e6e457841a7625 100644 (file)
@@ -113,29 +113,7 @@ struct nvc0_context {
    uint32_t dirty;
    uint32_t dirty_cp; /* dirty flags for compute state */
 
-   struct {
-      boolean flushed;
-      boolean rasterizer_discard;
-      boolean early_z_forced;
-      boolean prim_restart;
-      uint32_t instance_elts; /* bitmask of per-instance elements */
-      uint32_t instance_base;
-      uint32_t constant_vbos;
-      uint32_t constant_elts;
-      int32_t index_bias;
-      uint16_t scissor;
-      uint8_t vbo_mode; /* 0 = normal, 1 = translate, 3 = translate, forced */
-      uint8_t num_vtxbufs;
-      uint8_t num_vtxelts;
-      uint8_t num_textures[6];
-      uint8_t num_samplers[6];
-      uint8_t tls_required; /* bitmask of shader types using l[] */
-      uint8_t c14_bound; /* whether immediate array constbuf is bound */
-      uint8_t clip_enable;
-      uint32_t clip_mode;
-      uint32_t uniform_buffer_bound[5];
-      struct nvc0_transform_feedback_state *tfb;
-   } state;
+   struct nvc0_graph_state state;
 
    struct nvc0_blend_stateobj *blend;
    struct nvc0_rasterizer_stateobj *rast;
index fc75fc6a4a17d46a7d7c5569535800160d725dce..3875bbf4ca4d8b478779dfc369a8584d6ce975e7 100644 (file)
@@ -302,7 +302,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    if (!bo_config.nvc0.memtype && (pt->usage == PIPE_USAGE_STAGING || pt->bind & PIPE_BIND_SHARED))
       mt->base.domain = NOUVEAU_BO_GART;
    else
-      mt->base.domain = NOUVEAU_BO_VRAM;
+      mt->base.domain = NV_VRAM_DOMAIN(nouveau_screen(pscreen));
 
    bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP;
 
index c156e918dc56916fee57858d5e14af22ba440fb4..e1f5a8c4416bd6771f1ad34179355ad03c29261a 100644 (file)
@@ -392,7 +392,7 @@ nvc0_gp_gen_header(struct nvc0_program *gp, struct nv50_ir_prog_info *info)
       break;
    }
 
-   gp->hdr[4] = info->prop.gp.maxVertices & 0x1ff;
+   gp->hdr[4] = MIN2(info->prop.gp.maxVertices, 1024);
 
    return nvc0_vtgp_gen_header(gp, info);
 }
@@ -683,11 +683,12 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
    ret = nouveau_heap_alloc(screen->text_heap, size, prog, &prog->mem);
    if (ret) {
       struct nouveau_heap *heap = screen->text_heap;
-      struct nouveau_heap *iter;
-      for (iter = heap; iter && iter->next != heap; iter = iter->next) {
-         struct nvc0_program *evict = iter->priv;
-         if (evict)
-            nouveau_heap_free(&evict->mem);
+      /* Note that the code library, which is allocated before anything else,
+       * does not have a priv pointer. We can stop once we hit it.
+       */
+      while (heap->next && heap->next->priv) {
+         struct nvc0_program *evict = heap->next->priv;
+         nouveau_heap_free(&evict->mem);
       }
       debug_printf("WARNING: out of code space, evicting all shaders.\n");
       ret = nouveau_heap_alloc(heap, size, prog, &prog->mem);
@@ -734,12 +735,12 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
 
    if (!is_cp)
       nvc0->base.push_data(&nvc0->base, screen->text, prog->code_base,
-                           NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr);
+                           NV_VRAM_DOMAIN(&screen->base), NVC0_SHADER_HEADER_SIZE, prog->hdr);
    nvc0->base.push_data(&nvc0->base, screen->text, code_pos,
-                        NOUVEAU_BO_VRAM, prog->code_size, prog->code);
+                        NV_VRAM_DOMAIN(&screen->base), prog->code_size, prog->code);
    if (prog->immd_size)
       nvc0->base.push_data(&nvc0->base,
-                           screen->text, prog->immd_base, NOUVEAU_BO_VRAM,
+                           screen->text, prog->immd_base, NV_VRAM_DOMAIN(&screen->base),
                            prog->immd_size, prog->immd_data);
 
    BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(MEM_BARRIER), 1);
@@ -770,7 +771,7 @@ nvc0_program_library_upload(struct nvc0_context *nvc0)
       return;
 
    nvc0->base.push_data(&nvc0->base,
-                        screen->text, screen->lib_code->start, NOUVEAU_BO_VRAM,
+                        screen->text, screen->lib_code->start, NV_VRAM_DOMAIN(&screen->base),
                         size, code);
    /* no need for a memory barrier, will be emitted with first program */
 }
index 52032eb6f83471a75c4debbd8f7985091c3417c0..aea6cbda02d383723e63a98f7bef723801b7f94b 100644 (file)
@@ -617,6 +617,7 @@ nvc0_query_pushbuf_submit(struct nouveau_pushbuf *push,
 
 #define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8))
 
+   PUSH_REFN(push, q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_GART);
    nouveau_pushbuf_space(push, 0, 0, 1);
    nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 |
                         NVC0_IB_ENTRY_1_NO_PREFETCH);
@@ -1407,11 +1408,14 @@ nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen,
    count += NVC0_QUERY_DRV_STAT_COUNT;
 
    if (screen->base.device->drm_version >= 0x01000101) {
-      if (screen->base.class_3d >= NVE4_3D_CLASS) {
-         count += NVE4_PM_QUERY_COUNT;
-      } else
       if (screen->compute) {
-         count += NVC0_PM_QUERY_COUNT; /* NVC0_COMPUTE is not always enabled */
+         if (screen->base.class_3d == NVE4_3D_CLASS) {
+            count += NVE4_PM_QUERY_COUNT;
+         } else
+         if (screen->base.class_3d < NVE4_3D_CLASS) {
+            /* NVC0_COMPUTE is not always enabled */
+            count += NVC0_PM_QUERY_COUNT;
+         }
       }
    }
 
@@ -1437,19 +1441,21 @@ nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen,
    } else
 #endif
    if (id < count) {
-      if (screen->base.class_3d >= NVE4_3D_CLASS) {
-         info->name = nve4_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
-         info->query_type = NVE4_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
-         info->max_value.u64 =
-            (id < NVE4_PM_QUERY_METRIC_MP_OCCUPANCY) ? 0 : 100;
-         info->group_id = NVC0_QUERY_MP_COUNTER_GROUP;
-         return 1;
-      } else
       if (screen->compute) {
-         info->name = nvc0_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
-         info->query_type = NVC0_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
-         info->group_id = NVC0_QUERY_MP_COUNTER_GROUP;
-         return 1;
+         if (screen->base.class_3d == NVE4_3D_CLASS) {
+            info->name = nve4_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
+            info->query_type = NVE4_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
+            info->max_value.u64 =
+               (id < NVE4_PM_QUERY_METRIC_MP_OCCUPANCY) ? 0 : 100;
+            info->group_id = NVC0_QUERY_MP_COUNTER_GROUP;
+            return 1;
+         } else
+         if (screen->base.class_3d < NVE4_3D_CLASS) {
+            info->name = nvc0_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
+            info->query_type = NVC0_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
+            info->group_id = NVC0_QUERY_MP_COUNTER_GROUP;
+            return 1;
+         }
       }
    }
    /* user asked for info about non-existing query */
@@ -1469,10 +1475,13 @@ nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
 #endif
 
    if (screen->base.device->drm_version >= 0x01000101) {
-      if (screen->base.class_3d >= NVE4_3D_CLASS) {
-         count++;
-      } else if (screen->compute) {
-         count++; /* NVC0_COMPUTE is not always enabled */
+      if (screen->compute) {
+         if (screen->base.class_3d == NVE4_3D_CLASS) {
+            count++;
+         } else
+         if (screen->base.class_3d < NVE4_3D_CLASS) {
+            count++; /* NVC0_COMPUTE is not always enabled */
+         }
       }
    }
 
@@ -1480,25 +1489,28 @@ nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
       return count;
 
    if (id == NVC0_QUERY_MP_COUNTER_GROUP) {
-      info->name = "MP counters";
-      info->type = PIPE_DRIVER_QUERY_GROUP_TYPE_GPU;
-
-      if (screen->base.class_3d >= NVE4_3D_CLASS) {
-         info->num_queries = NVE4_PM_QUERY_COUNT;
-
-          /* On NVE4+, each multiprocessor have 8 hardware counters separated
-           * in two distinct domains, but we allow only one active query
-           * simultaneously because some of them use more than one hardware
-           * counter and this will result in an undefined behaviour. */
-          info->max_active_queries = 1; /* TODO: handle multiple hw counters */
-          return 1;
-      } else if (screen->compute) {
-         info->num_queries = NVC0_PM_QUERY_COUNT;
-
-         /* On NVC0:NVE4, each multiprocessor have 8 hardware counters
-          * in a single domain. */
-         info->max_active_queries = 8;
-         return 1;
+      if (screen->compute) {
+         info->name = "MP counters";
+         info->type = PIPE_DRIVER_QUERY_GROUP_TYPE_GPU;
+
+         if (screen->base.class_3d == NVE4_3D_CLASS) {
+            info->num_queries = NVE4_PM_QUERY_COUNT;
+
+             /* On NVE4+, each multiprocessor have 8 hardware counters separated
+              * in two distinct domains, but we allow only one active query
+              * simultaneously because some of them use more than one hardware
+              * counter and this will result in an undefined behaviour. */
+             info->max_active_queries = 1; /* TODO: handle multiple hw counters */
+             return 1;
+         } else
+         if (screen->base.class_3d < NVE4_3D_CLASS) {
+            info->num_queries = NVC0_PM_QUERY_COUNT;
+
+            /* On NVC0:NVE4, each multiprocessor have 8 hardware counters
+             * in a single domain. */
+            info->max_active_queries = 8;
+            return 1;
+         }
       }
    }
 #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
index 748c9e7c8b903aa248db6a927d64f6e0dc70dd5c..56c230e42fc2b2cc50a0d7c31cb84e9536f55113 100644 (file)
@@ -193,6 +193,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
    case PIPE_CAP_VERTEXID_NOBASE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
@@ -296,6 +297,7 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
       return 1;
    case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
    case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
       return 0;
    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
       return 16; /* would be 32 in linked (OpenGL-style) mode */
@@ -581,7 +583,7 @@ nvc0_screen_resize_tls_area(struct nvc0_screen *screen,
 
    size = align(size, 1 << 17);
 
-   ret = nouveau_bo_new(screen->base.device, NOUVEAU_BO_VRAM, 1 << 17, size,
+   ret = nouveau_bo_new(screen->base.device, NV_VRAM_DOMAIN(&screen->base), 1 << 17, size,
                         NULL, &bo);
    if (ret) {
       NOUVEAU_ERR("failed to allocate TLS area, size: 0x%"PRIx64"\n", size);
@@ -644,6 +646,11 @@ nvc0_screen_create(struct nouveau_device *dev)
    screen->base.sysmem_bindings |=
       PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
 
+   if (screen->base.vram_domain & NOUVEAU_BO_GART) {
+      screen->base.sysmem_bindings |= screen->base.vidmem_bindings;
+      screen->base.vidmem_bindings = 0;
+   }
+
    pscreen->destroy = nvc0_screen_destroy;
    pscreen->context_create = nvc0_create;
    pscreen->is_format_supported = nvc0_screen_is_format_supported;
@@ -822,7 +829,7 @@ nvc0_screen_create(struct nouveau_device *dev)
 
    nvc0_magic_3d_init(push, screen->eng3d->oclass);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
+   ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 20, NULL,
                         &screen->text);
    if (ret)
       goto fail;
@@ -832,12 +839,12 @@ nvc0_screen_create(struct nouveau_device *dev)
     */
    nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL,
+   ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 12, 6 << 16, NULL,
                         &screen->uniform_bo);
    if (ret)
       goto fail;
 
-   PUSH_REFN (push, screen->uniform_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+   PUSH_REFN (push, screen->uniform_bo, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_WR);
 
    for (i = 0; i < 5; ++i) {
       /* TIC and TSC entries for each unit (nve4+ only) */
@@ -908,7 +915,7 @@ nvc0_screen_create(struct nouveau_device *dev)
    PUSH_DATA (push, 0);
 
    if (screen->eng3d->oclass < GM107_3D_CLASS) {
-      ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
+      ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 20, NULL,
                            &screen->poly_cache);
       if (ret)
          goto fail;
@@ -919,7 +926,7 @@ nvc0_screen_create(struct nouveau_device *dev)
       PUSH_DATA (push, 3);
    }
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL,
+   ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 17, NULL,
                         &screen->txc);
    if (ret)
       goto fail;
index 1a7d5027a7c028cffbe46447dfabb15910cd55e8..ef2bd43f006c6bc0785ed04887f7eb16163e5633 100644 (file)
@@ -27,10 +27,35 @@ struct nvc0_context;
 
 struct nvc0_blitter;
 
+struct nvc0_graph_state {
+   boolean flushed;
+   boolean rasterizer_discard;
+   boolean early_z_forced;
+   boolean prim_restart;
+   uint32_t instance_elts; /* bitmask of per-instance elements */
+   uint32_t instance_base;
+   uint32_t constant_vbos;
+   uint32_t constant_elts;
+   int32_t index_bias;
+   uint16_t scissor;
+   uint8_t vbo_mode; /* 0 = normal, 1 = translate, 3 = translate, forced */
+   uint8_t num_vtxbufs;
+   uint8_t num_vtxelts;
+   uint8_t num_textures[6];
+   uint8_t num_samplers[6];
+   uint8_t tls_required; /* bitmask of shader types using l[] */
+   uint8_t c14_bound; /* whether immediate array constbuf is bound */
+   uint8_t clip_enable;
+   uint32_t clip_mode;
+   uint32_t uniform_buffer_bound[5];
+   struct nvc0_transform_feedback_state *tfb;
+};
+
 struct nvc0_screen {
    struct nouveau_screen base;
 
    struct nvc0_context *cur_ctx;
+   struct nvc0_graph_state save_state;
 
    int num_occlusion_queries_active;
 
index 516b33b76d556504b3e55de05c2f7f1566794fc0..e0842784a8867ba77dcedfc6302fe9db4e699326 100644 (file)
@@ -34,7 +34,7 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0,
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
    if (prog && prog->need_tls) {
-      const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
+      const uint32_t flags = NV_VRAM_DOMAIN(&nvc0->screen->base) | NOUVEAU_BO_RDWR;
       if (!nvc0->state.tls_required)
          BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls);
       nvc0->state.tls_required |= 1 << stage;
@@ -262,11 +262,13 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
       if (tfb)
          targ->stride = tfb->stride[b];
 
+      buf = nv04_resource(targ->pipe.buffer);
+
+      BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR);
+
       if (!(nvc0->tfbbuf_dirty & (1 << b)))
          continue;
 
-      buf = nv04_resource(targ->pipe.buffer);
-
       if (!targ->clean)
          nvc0_query_fifo_wait(push, targ->pq);
       BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
@@ -280,7 +282,6 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
          PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */
          targ->clean = FALSE;
       }
-      BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR);
    }
    for (; b < 4; ++b)
       IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
index dca06f4cddb1dbb92fe3263e96705698b0ebd886..6b7a211e71bd0ac7c5b9210fcc512ed672f88680 100644 (file)
@@ -413,24 +413,6 @@ nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
 #define NV50_TSC_WRAP_CASE(n) \
     case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
 
-static INLINE unsigned
-nv50_tsc_wrap_mode(unsigned wrap)
-{
-   switch (wrap) {
-   NV50_TSC_WRAP_CASE(REPEAT);
-   NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
-   NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
-   NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
-   NV50_TSC_WRAP_CASE(CLAMP);
-   NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
-   NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
-   NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
-   default:
-       NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
-       return NV50_TSC_WRAP_REPEAT;
-   }
-}
-
 static void
 nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
 {
@@ -811,12 +793,12 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
    if (nvc0->constbuf[s][i].user) {
       nvc0->constbuf[s][i].u.data = cb->user_buffer;
-      nvc0->constbuf[s][i].size = cb->buffer_size;
+      nvc0->constbuf[s][i].size = MIN2(cb->buffer_size, 0x10000);
       nvc0->constbuf_valid[s] |= 1 << i;
    } else
    if (cb) {
       nvc0->constbuf[s][i].offset = cb->buffer_offset;
-      nvc0->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+      nvc0->constbuf[s][i].size = MIN2(align(cb->buffer_size, 0x100), 0x10000);
       nvc0->constbuf_valid[s] |= 1 << i;
    }
    else {
index 6051f128f66cc57f1c3fdea6f01fc47bb34906ac..c52399ab312e00556e22bd1d0394cda47a7f6b0b 100644 (file)
@@ -439,7 +439,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
                BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
                PUSH_DATA (push, (0 << 4) | 1);
             }
-            nvc0_cb_push(&nvc0->base, bo, NOUVEAU_BO_VRAM,
+            nvc0_cb_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
                          base, nvc0->state.uniform_buffer_bound[s],
                          0, (size + 3) / 4,
                          nvc0->constbuf[s][0].u.data);
@@ -543,6 +543,8 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
 
    if (ctx_from)
       ctx_to->state = ctx_from->state;
+   else
+      ctx_to->state = ctx_to->screen->save_state;
 
    ctx_to->dirty = ~0;
    ctx_to->viewports_dirty = ~0;
index 4404d8c1a745aa34a835866f6dabce18bf9a240d..a820de7259a40f6933be041510ffe78ad0c8b59a 100644 (file)
@@ -1152,6 +1152,12 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
                       NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32 |
                       NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
    }
+   if (nvc0->state.instance_elts) {
+      nvc0->state.instance_elts = 0;
+      BEGIN_NVC0(push, NVC0_3D(MACRO_VERTEX_ARRAY_PER_INSTANCE), 2);
+      PUSH_DATA (push, n);
+      PUSH_DATA (push, 0);
+   }
    nvc0->state.num_vtxelts = 2;
 
    for (i = 0; i < info->dst.box.depth; ++i, z += dz) {
index 457f27c8311f505ab8139847bf8c99da65147a71..ddc0409ca86d0ddd99a4203d54763add7d333c23 100644 (file)
@@ -396,7 +396,7 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
          tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
 
          nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc,
-                               65536 + tsc->id * 32, NOUVEAU_BO_VRAM,
+                               65536 + tsc->id * 32, NV_VRAM_DOMAIN(&nvc0->screen->base),
                                32, tsc->tsc);
          need_flush = TRUE;
       }
index 657b8c0fe827d43be3ebccfc535656b5762361e2..8cf2584b0ce5f3da2f1f57e562c01556da622947 100644 (file)
@@ -829,6 +829,7 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
    }
    PUSH_DATA(push, nvc0_prim_gl(info->mode));
 #define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8))
+   PUSH_REFN(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
    nouveau_pushbuf_space(push, 0, 0, 1);
    nouveau_pushbuf_data(push,
                         buf->bo, offset, NVC0_IB_ENTRY_1_NO_PREFETCH | size);
index f243316b899c76366b1d0af9bd9db48e4c9e5b17..fce02a7cc576a4ce68097e79620c269fe5f6928b 100644 (file)
@@ -63,7 +63,7 @@ nve4_screen_compute_setup(struct nvc0_screen *screen,
       return ret;
    }
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, NVE4_CP_PARAM_SIZE, NULL,
+   ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 0, NVE4_CP_PARAM_SIZE, NULL,
                         &screen->parm);
    if (ret)
       return ret;
index a7b59d8bfbbafe8462b62a2f3a0ec09e0cebf665..a7bca915f573eb017bffd2f9c77f360a404464ad 100644 (file)
@@ -190,6 +190,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_POLYGON_OFFSET_CLAMP:
         case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
         case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+        case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
             return 0;
 
         /* SWTCL-only features. */
@@ -273,6 +274,7 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
         case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
             return (is_r500 ? 256 : 32) * sizeof(float[4]);
         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
             return 1;
         case PIPE_SHADER_CAP_MAX_TEMPS:
             return is_r500 ? 128 : is_r400 ? 64 : 32;
@@ -332,6 +334,7 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
         case PIPE_SHADER_CAP_MAX_PREDS:
             return 0; /* unused */
         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
             return 1;
         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
index 69afb4caeaaed8ba58b2b68f4041607cbda9bf60..23ed2cf2532c0c19333a6ac9ca28cc74b25ba9cb 100644 (file)
@@ -133,13 +133,7 @@ static unsigned translate_opcode(unsigned opcode)
 
 static unsigned translate_saturate(unsigned saturate)
 {
-    switch(saturate) {
-        default:
-            fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
-            /* fall-through */
-        case TGSI_SAT_NONE: return RC_SATURATE_NONE;
-        case TGSI_SAT_ZERO_ONE: return RC_SATURATE_ZERO_ONE;
-    }
+    return saturate ? RC_SATURATE_ZERO_ONE : RC_SATURATE_NONE;
 }
 
 static unsigned translate_register_file(unsigned file)
index e9357597a9bf5d0e25aba7ed19dd8be6aa2bcc5d..bfe3987308959cea3010c22e66fd2a7c51f0ff62 100644 (file)
@@ -33,6 +33,10 @@ LOCAL_SRC_FILES := $(C_SOURCES) $(CXX_SOURCES)
 LOCAL_SHARED_LIBRARIES := libdrm libdrm_radeon
 LOCAL_MODULE := libmesa_pipe_r600
 
+ifeq ($(MESA_LOLLIPOP_BUILD),true)
+LOCAL_C_INCLUDES := external/libcxx/include
+else
 include external/stlport/libstlport.mk
+endif
 include $(GALLIUM_COMMON_MK)
 include $(BUILD_STATIC_LIBRARY)
index 21e5d42adc315718d4b9f7e978cf11969dd294c0..e122b607b863170c6111fa3db771e2d79d54586e 100644 (file)
@@ -332,6 +332,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
        case PIPE_CAP_VERTEXID_NOBASE:
+       case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
                return 0;
 
        /* Stream output. */
@@ -475,6 +476,7 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
        case PIPE_SHADER_CAP_SUBROUTINES:
                return 0;
        case PIPE_SHADER_CAP_INTEGERS:
+       case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
                return 1;
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
index 87b6e6e06ecc85d878963637fc2e02013ae4152d..af7622e9b3417249c2cf16d7ebb757216a92050c 100644 (file)
@@ -617,98 +617,100 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
 
        switch (d->Declaration.File) {
        case TGSI_FILE_INPUT:
-               i = ctx->shader->ninput;
-                assert(i < Elements(ctx->shader->input));
-               ctx->shader->ninput += count;
-               ctx->shader->input[i].name = d->Semantic.Name;
-               ctx->shader->input[i].sid = d->Semantic.Index;
-               ctx->shader->input[i].interpolate = d->Interp.Interpolate;
-               ctx->shader->input[i].interpolate_location = d->Interp.Location;
-               ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + d->Range.First;
-               if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
-                       ctx->shader->input[i].spi_sid = r600_spi_sid(&ctx->shader->input[i]);
-                       switch (ctx->shader->input[i].name) {
-                       case TGSI_SEMANTIC_FACE:
-                               if (ctx->face_gpr != -1)
-                                       ctx->shader->input[i].gpr = ctx->face_gpr; /* already allocated by allocate_system_value_inputs */
-                               else
-                                       ctx->face_gpr = ctx->shader->input[i].gpr;
-                               break;
-                       case TGSI_SEMANTIC_COLOR:
-                               ctx->colors_used++;
-                               break;
-                       case TGSI_SEMANTIC_POSITION:
-                               ctx->fragcoord_input = i;
-                               break;
-                       case TGSI_SEMANTIC_PRIMID:
-                               /* set this for now */
-                               ctx->shader->gs_prim_id_input = true;
-                               ctx->shader->ps_prim_id_input = i;
-                               break;
-                       }
-                       if (ctx->bc->chip_class >= EVERGREEN) {
-                               if ((r = evergreen_interp_input(ctx, i)))
-                                       return r;
+               for (j = 0; j < count; j++) {
+                       i = ctx->shader->ninput + j;
+                       assert(i < Elements(ctx->shader->input));
+                       ctx->shader->input[i].name = d->Semantic.Name;
+                       ctx->shader->input[i].sid = d->Semantic.Index + j;
+                       ctx->shader->input[i].interpolate = d->Interp.Interpolate;
+                       ctx->shader->input[i].interpolate_location = d->Interp.Location;
+                       ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + d->Range.First + j;
+                       if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
+                               ctx->shader->input[i].spi_sid = r600_spi_sid(&ctx->shader->input[i]);
+                               switch (ctx->shader->input[i].name) {
+                               case TGSI_SEMANTIC_FACE:
+                                       if (ctx->face_gpr != -1)
+                                               ctx->shader->input[i].gpr = ctx->face_gpr; /* already allocated by allocate_system_value_inputs */
+                                       else
+                                               ctx->face_gpr = ctx->shader->input[i].gpr;
+                                       break;
+                               case TGSI_SEMANTIC_COLOR:
+                                       ctx->colors_used++;
+                                       break;
+                               case TGSI_SEMANTIC_POSITION:
+                                       ctx->fragcoord_input = i;
+                                       break;
+                               case TGSI_SEMANTIC_PRIMID:
+                                       /* set this for now */
+                                       ctx->shader->gs_prim_id_input = true;
+                                       ctx->shader->ps_prim_id_input = i;
+                                       break;
+                               }
+                               if (ctx->bc->chip_class >= EVERGREEN) {
+                                       if ((r = evergreen_interp_input(ctx, i)))
+                                               return r;
+                               }
+                       } else if (ctx->type == TGSI_PROCESSOR_GEOMETRY) {
+                               /* FIXME probably skip inputs if they aren't passed in the ring */
+                               ctx->shader->input[i].ring_offset = ctx->next_ring_offset;
+                               ctx->next_ring_offset += 16;
+                               if (ctx->shader->input[i].name == TGSI_SEMANTIC_PRIMID)
+                                       ctx->shader->gs_prim_id_input = true;
                        }
-               } else if (ctx->type == TGSI_PROCESSOR_GEOMETRY) {
-                       /* FIXME probably skip inputs if they aren't passed in the ring */
-                       ctx->shader->input[i].ring_offset = ctx->next_ring_offset;
-                       ctx->next_ring_offset += 16;
-                       if (ctx->shader->input[i].name == TGSI_SEMANTIC_PRIMID)
-                               ctx->shader->gs_prim_id_input = true;
-               }
-               for (j = 1; j < count; ++j) {
-                       ctx->shader->input[i + j] = ctx->shader->input[i];
-                       ctx->shader->input[i + j].gpr += j;
                }
+               ctx->shader->ninput += count;
                break;
        case TGSI_FILE_OUTPUT:
-               i = ctx->shader->noutput++;
-                assert(i < Elements(ctx->shader->output));
-               ctx->shader->output[i].name = d->Semantic.Name;
-               ctx->shader->output[i].sid = d->Semantic.Index;
-               ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + d->Range.First;
-               ctx->shader->output[i].interpolate = d->Interp.Interpolate;
-               ctx->shader->output[i].write_mask = d->Declaration.UsageMask;
-               if (ctx->type == TGSI_PROCESSOR_VERTEX ||
-                               ctx->type == TGSI_PROCESSOR_GEOMETRY) {
-                       ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);
-                       switch (d->Semantic.Name) {
-                       case TGSI_SEMANTIC_CLIPDIST:
-                               ctx->shader->clip_dist_write |= d->Declaration.UsageMask << (d->Semantic.Index << 2);
-                               break;
-                       case TGSI_SEMANTIC_PSIZE:
-                               ctx->shader->vs_out_misc_write = 1;
-                               ctx->shader->vs_out_point_size = 1;
-                               break;
-                       case TGSI_SEMANTIC_EDGEFLAG:
-                               ctx->shader->vs_out_misc_write = 1;
-                               ctx->shader->vs_out_edgeflag = 1;
-                               ctx->edgeflag_output = i;
-                               break;
-                       case TGSI_SEMANTIC_VIEWPORT_INDEX:
-                               ctx->shader->vs_out_misc_write = 1;
-                               ctx->shader->vs_out_viewport = 1;
-                               break;
-                       case TGSI_SEMANTIC_LAYER:
-                               ctx->shader->vs_out_misc_write = 1;
-                               ctx->shader->vs_out_layer = 1;
-                               break;
-                       case TGSI_SEMANTIC_CLIPVERTEX:
-                               ctx->clip_vertex_write = TRUE;
-                               ctx->cv_output = i;
-                               break;
-                       }
-                       if (ctx->type == TGSI_PROCESSOR_GEOMETRY) {
-                               ctx->gs_out_ring_offset += 16;
-                       }
-               } else if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
-                       switch (d->Semantic.Name) {
-                       case TGSI_SEMANTIC_COLOR:
-                               ctx->shader->nr_ps_max_color_exports++;
-                               break;
+               for (j = 0; j < count; j++) {
+                       i = ctx->shader->noutput + j;
+                       assert(i < Elements(ctx->shader->output));
+                       ctx->shader->output[i].name = d->Semantic.Name;
+                       ctx->shader->output[i].sid = d->Semantic.Index + j;
+                       ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + d->Range.First + j;
+                       ctx->shader->output[i].interpolate = d->Interp.Interpolate;
+                       ctx->shader->output[i].write_mask = d->Declaration.UsageMask;
+                       if (ctx->type == TGSI_PROCESSOR_VERTEX ||
+                           ctx->type == TGSI_PROCESSOR_GEOMETRY) {
+                               ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);
+                               switch (d->Semantic.Name) {
+                               case TGSI_SEMANTIC_CLIPDIST:
+                                       ctx->shader->clip_dist_write |= d->Declaration.UsageMask <<
+                                                                       ((d->Semantic.Index + j) << 2);
+                                       break;
+                               case TGSI_SEMANTIC_PSIZE:
+                                       ctx->shader->vs_out_misc_write = 1;
+                                       ctx->shader->vs_out_point_size = 1;
+                                       break;
+                               case TGSI_SEMANTIC_EDGEFLAG:
+                                       ctx->shader->vs_out_misc_write = 1;
+                                       ctx->shader->vs_out_edgeflag = 1;
+                                       ctx->edgeflag_output = i;
+                                       break;
+                               case TGSI_SEMANTIC_VIEWPORT_INDEX:
+                                       ctx->shader->vs_out_misc_write = 1;
+                                       ctx->shader->vs_out_viewport = 1;
+                                       break;
+                               case TGSI_SEMANTIC_LAYER:
+                                       ctx->shader->vs_out_misc_write = 1;
+                                       ctx->shader->vs_out_layer = 1;
+                                       break;
+                               case TGSI_SEMANTIC_CLIPVERTEX:
+                                       ctx->clip_vertex_write = TRUE;
+                                       ctx->cv_output = i;
+                                       break;
+                               }
+                               if (ctx->type == TGSI_PROCESSOR_GEOMETRY) {
+                                       ctx->gs_out_ring_offset += 16;
+                               }
+                       } else if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
+                               switch (d->Semantic.Name) {
+                               case TGSI_SEMANTIC_COLOR:
+                                       ctx->shader->nr_ps_max_color_exports++;
+                                       break;
+                               }
                        }
                }
+               ctx->shader->noutput += count;
                break;
        case TGSI_FILE_TEMPORARY:
                if (ctx->info.indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
@@ -723,6 +725,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
 
        case TGSI_FILE_CONSTANT:
        case TGSI_FILE_SAMPLER:
+       case TGSI_FILE_SAMPLER_VIEW:
        case TGSI_FILE_ADDRESS:
                break;
 
@@ -1337,7 +1340,7 @@ static int emit_streamout(struct r600_shader_ctx *ctx, struct pipe_stream_output
        int i, j, r;
 
        /* Sanity checking. */
-       if (so->num_outputs > PIPE_MAX_SHADER_OUTPUTS) {
+       if (so->num_outputs > PIPE_MAX_SO_OUTPUTS) {
                R600_ERR("Too many stream outputs: %d\n", so->num_outputs);
                r = -EINVAL;
                goto out_err;
index c50c7055851dbd7ce683725575b44b23f919de3a..13dc9ee8c10086c78eaec12a852c6afcfe192983 100644 (file)
@@ -95,22 +95,23 @@ static void r600_texture_barrier(struct pipe_context *ctx)
 static unsigned r600_conv_pipe_prim(unsigned prim)
 {
        static const unsigned prim_conv[] = {
-               V_008958_DI_PT_POINTLIST,
-               V_008958_DI_PT_LINELIST,
-               V_008958_DI_PT_LINELOOP,
-               V_008958_DI_PT_LINESTRIP,
-               V_008958_DI_PT_TRILIST,
-               V_008958_DI_PT_TRISTRIP,
-               V_008958_DI_PT_TRIFAN,
-               V_008958_DI_PT_QUADLIST,
-               V_008958_DI_PT_QUADSTRIP,
-               V_008958_DI_PT_POLYGON,
-               V_008958_DI_PT_LINELIST_ADJ,
-               V_008958_DI_PT_LINESTRIP_ADJ,
-               V_008958_DI_PT_TRILIST_ADJ,
-               V_008958_DI_PT_TRISTRIP_ADJ,
-               V_008958_DI_PT_RECTLIST
+               [PIPE_PRIM_POINTS]                      = V_008958_DI_PT_POINTLIST,
+               [PIPE_PRIM_LINES]                       = V_008958_DI_PT_LINELIST,
+               [PIPE_PRIM_LINE_LOOP]                   = V_008958_DI_PT_LINELOOP,
+               [PIPE_PRIM_LINE_STRIP]                  = V_008958_DI_PT_LINESTRIP,
+               [PIPE_PRIM_TRIANGLES]                   = V_008958_DI_PT_TRILIST,
+               [PIPE_PRIM_TRIANGLE_STRIP]              = V_008958_DI_PT_TRISTRIP,
+               [PIPE_PRIM_TRIANGLE_FAN]                = V_008958_DI_PT_TRIFAN,
+               [PIPE_PRIM_QUADS]                       = V_008958_DI_PT_QUADLIST,
+               [PIPE_PRIM_QUAD_STRIP]                  = V_008958_DI_PT_QUADSTRIP,
+               [PIPE_PRIM_POLYGON]                     = V_008958_DI_PT_POLYGON,
+               [PIPE_PRIM_LINES_ADJACENCY]             = V_008958_DI_PT_LINELIST_ADJ,
+               [PIPE_PRIM_LINE_STRIP_ADJACENCY]        = V_008958_DI_PT_LINESTRIP_ADJ,
+               [PIPE_PRIM_TRIANGLES_ADJACENCY]         = V_008958_DI_PT_TRILIST_ADJ,
+               [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]    = V_008958_DI_PT_TRISTRIP_ADJ,
+               [R600_PRIM_RECTANGLE_LIST]              = V_008958_DI_PT_RECTLIST
        };
+       assert(prim < Elements(prim_conv));
        return prim_conv[prim];
 }
 
index d61579280eadad00cfd56efa1aadd96838f9b6d5..6997a6d3ec36cc3b3892e45e10dd0cdb215f2c25 100644 (file)
@@ -30,6 +30,10 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(C_SOURCES)
 
+ifeq ($(MESA_ENABLE_LLVM),true)
+LOCAL_SRC_FILES += $(LLVM_C_FILES)
+endif
+
 LOCAL_SHARED_LIBRARIES := libdrm libdrm_radeon
 LOCAL_MODULE := libmesa_pipe_radeon
 
index c655fe5787b476d3764577bead9ce59cdaeb6b90..f63790c329e86535d424089e8d0916ab10da5a18 100644 (file)
@@ -12,6 +12,7 @@ C_SOURCES := \
        radeon_uvd.c \
        radeon_uvd.h \
        radeon_vce_40_2_2.c \
+       radeon_vce_50.c \
        radeon_vce.c \
        radeon_vce.h \
        radeon_video.c \
index 42e681dc7d218ec9b11fd463ccc72ee530b5413c..3def44468823557cea70140ec50c9e7da037fe2a 100644 (file)
@@ -107,11 +107,10 @@ void r600_draw_rectangle(struct blitter_context *blitter,
 
 void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw)
 {
-       /* The number of dwords we already used in the DMA so far. */
-       num_dw += ctx->rings.dma.cs->cdw;
        /* Flush if there's not enough space. */
-       if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
+       if ((num_dw + ctx->rings.dma.cs->cdw) > RADEON_MAX_CMDBUF_DWORDS) {
                ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
+               assert((num_dw + ctx->rings.dma.cs->cdw) <= RADEON_MAX_CMDBUF_DWORDS);
        }
 }
 
index 8612ef8daf75bc92e8ac5e483e6d2f34ae68c71e..6a9557b0b734e4a95b7730cc0bd16d4acfda465f 100644 (file)
@@ -33,7 +33,6 @@
 
 #define RADEON_LLVM_MAX_INPUTS 32 * 4
 #define RADEON_LLVM_MAX_OUTPUTS 32 * 4
-#define RADEON_LLVM_MAX_ARRAYS 16
 
 #define RADEON_LLVM_INITIAL_CF_DEPTH 4
 
@@ -130,8 +129,7 @@ struct radeon_llvm_context {
        unsigned loop_depth;
        unsigned loop_depth_max;
 
-       struct tgsi_declaration_range arrays[RADEON_LLVM_MAX_ARRAYS];
-       unsigned num_arrays;
+       struct tgsi_declaration_range *arrays;
 
        LLVMValueRef main_fn;
 
index 624077c74650c491cb5db56d532cc44d04162d59..25580b6bd4cac0c88f5339d5c1289947934035d8 100644 (file)
@@ -86,10 +86,18 @@ static void init_r600_target()
 {
        static unsigned initialized = 0;
        if (!initialized) {
+#if HAVE_LLVM < 0x0307
                LLVMInitializeR600TargetInfo();
                LLVMInitializeR600Target();
                LLVMInitializeR600TargetMC();
                LLVMInitializeR600AsmPrinter();
+#else
+               LLVMInitializeAMDGPUTargetInfo();
+               LLVMInitializeAMDGPUTarget();
+               LLVMInitializeAMDGPUTargetMC();
+               LLVMInitializeAMDGPUAsmPrinter();
+
+#endif
                initialized = 1;
        }
 }
index 20e506b7c5e433058c34cc69a3a637e76a70a2d8..c8c980d9d329053d7e8ae8cb7b3ccf91d2357a1e 100644 (file)
@@ -85,8 +85,9 @@ get_array_range(struct lp_build_tgsi_context *bld_base,
                unsigned File, const struct tgsi_ind_register *reg)
 {
        struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
+
        if (File != TGSI_FILE_TEMPORARY || reg->ArrayID == 0 ||
-            reg->ArrayID > RADEON_LLVM_MAX_ARRAYS) {
+           reg->ArrayID > bld_base->info->array_max[TGSI_FILE_TEMPORARY]) {
                struct tgsi_declaration_range range;
                range.First = 0;
                range.Last = bld_base->info->file_max[File];
@@ -252,8 +253,14 @@ static void emit_declaration(
        }
 
        case TGSI_FILE_TEMPORARY:
-               if (decl->Declaration.Array && decl->Array.ArrayID <= RADEON_LLVM_MAX_ARRAYS)
+               if (decl->Declaration.Array) {
+                       if (!ctx->arrays) {
+                               int size = bld_base->info->array_max[TGSI_FILE_TEMPORARY];
+                               ctx->arrays = MALLOC(sizeof(ctx->arrays[0]) * size);
+                       }
+
                        ctx->arrays[decl->Array.ArrayID - 1] = decl->Range;
+               }
                if (uses_temp_indirect_addressing(bld_base)) {
                        lp_emit_declaration_soa(bld_base, decl);
                        break;
@@ -314,6 +321,21 @@ static void emit_declaration(
        }
 }
 
+static LLVMValueRef radeon_llvm_saturate(struct lp_build_tgsi_context *bld_base,
+                                         LLVMValueRef value)
+{
+       struct lp_build_emit_data clamp_emit_data;
+
+       memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
+       clamp_emit_data.arg_count = 3;
+       clamp_emit_data.args[0] = value;
+       clamp_emit_data.args[2] = bld_base->base.one;
+       clamp_emit_data.args[1] = bld_base->base.zero;
+
+       return lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
+                                 &clamp_emit_data);
+}
+
 static void
 emit_store(
        struct lp_build_tgsi_context * bld_base,
@@ -324,7 +346,6 @@ emit_store(
        struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
        struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
        struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
-       struct lp_build_context base = bld->bld_base.base;
        const struct tgsi_full_dst_register *reg = &inst->Dst[0];
        LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
        LLVMValueRef temp_ptr;
@@ -350,28 +371,8 @@ emit_store(
        TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
                LLVMValueRef value = dst[chan_index];
 
-               if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
-                       struct lp_build_emit_data clamp_emit_data;
-
-                       memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
-                       clamp_emit_data.arg_count = 3;
-                       clamp_emit_data.args[0] = value;
-                       clamp_emit_data.args[2] = base.one;
-
-                       switch(inst->Instruction.Saturate) {
-                       case TGSI_SAT_ZERO_ONE:
-                               clamp_emit_data.args[1] = base.zero;
-                               break;
-                       case TGSI_SAT_MINUS_PLUS_ONE:
-                               clamp_emit_data.args[1] = LLVMConstReal(
-                                               base.elem_type, -1.0f);
-                               break;
-                       default:
-                               assert(0);
-                       }
-                       value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
-                                               &clamp_emit_data);
-               }
+               if (inst->Instruction.Saturate)
+                       value = radeon_llvm_saturate(bld_base, value);
 
                if (reg->Register.File == TGSI_FILE_ADDRESS) {
                        temp_ptr = bld->addr[reg->Register.Index][chan_index];
@@ -1438,8 +1439,6 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
        /* Allocate outputs */
        ctx->soa.outputs = ctx->outputs;
 
-       ctx->num_arrays = 0;
-
        /* XXX: Is there a better way to initialize all this ? */
 
        lp_set_default_actions(bld_base);
@@ -1628,8 +1627,11 @@ void radeon_llvm_dispose(struct radeon_llvm_context * ctx)
 {
        LLVMDisposeModule(ctx->soa.bld_base.base.gallivm->module);
        LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context);
+       FREE(ctx->arrays);
+       ctx->arrays = NULL;
        FREE(ctx->temps);
        ctx->temps = NULL;
+       ctx->temps_count = 0;
        FREE(ctx->loop);
        ctx->loop = NULL;
        ctx->loop_depth_max = 0;
index e220f40165b3849cfb386012d5288c02e9845653..a6567379fe3501632c5a16b656e6ba46f318fe05 100644 (file)
 #include "radeon_video.h"
 #include "radeon_vce.h"
 
+#define FW_40_2_2 ((40 << 24) | (2 << 16) | (2 << 8))
+#define FW_50_0_1 ((50 << 24) | (0 << 16) | (1 << 8))
+#define FW_50_1_2 ((50 << 24) | (1 << 16) | (2 << 8))
+
 /**
  * flush commands to the hardware
  */
@@ -182,6 +186,44 @@ static unsigned get_cpb_num(struct rvce_encoder *enc)
        return MIN2(dpb / (w * h), 16);
 }
 
+/**
+ * Get the slot for the currently encoded frame
+ */
+struct rvce_cpb_slot *current_slot(struct rvce_encoder *enc)
+{
+       return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.prev, list);
+}
+
+/**
+ * Get the slot for L0
+ */
+struct rvce_cpb_slot *l0_slot(struct rvce_encoder *enc)
+{
+       return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next, list);
+}
+
+/**
+ * Get the slot for L1
+ */
+struct rvce_cpb_slot *l1_slot(struct rvce_encoder *enc)
+{
+       return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next->next, list);
+}
+
+/**
+ * Calculate the offsets into the CPB
+ */
+void rvce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot,
+                      unsigned *luma_offset, unsigned *chroma_offset)
+{
+       unsigned pitch = align(enc->luma->level[0].pitch_bytes, 128);
+       unsigned vpitch = align(enc->luma->npix_y, 16);
+       unsigned fsize = pitch * (vpitch + vpitch / 2);
+
+       *luma_offset = slot->index * fsize;
+       *chroma_offset = *luma_offset + pitch * vpitch;
+}
+
 /**
  * destroy this video encoder
  */
@@ -406,7 +448,19 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context,
 
        reset_cpb(enc);
 
-       radeon_vce_40_2_2_init(enc);
+       switch (rscreen->info.vce_fw_version) {
+       case FW_40_2_2:
+               radeon_vce_40_2_2_init(enc);
+               break;
+
+       case FW_50_0_1:
+       case FW_50_1_2:
+               radeon_vce_50_init(enc);
+               break;
+
+       default:
+               goto error;
+       }
 
        return &enc->base;
 
@@ -426,5 +480,7 @@ error:
  */
 bool rvce_is_fw_version_supported(struct r600_common_screen *rscreen)
 {
-       return rscreen->info.vce_fw_version == ((40 << 24) | (2 << 16) | (2 << 8));
+       return rscreen->info.vce_fw_version == FW_40_2_2 ||
+               rscreen->info.vce_fw_version == FW_50_0_1 ||
+               rscreen->info.vce_fw_version == FW_50_1_2;
 }
index 1cf018006a887cd013f26488c519d5df59502fda..8319ef48cd56438308aa9bd071108a2187c5f360 100644 (file)
@@ -104,6 +104,13 @@ struct rvce_encoder {
        bool use_vui;
 };
 
+/* CPB handling functions */
+struct rvce_cpb_slot *current_slot(struct rvce_encoder *enc);
+struct rvce_cpb_slot *l0_slot(struct rvce_encoder *enc);
+struct rvce_cpb_slot *l1_slot(struct rvce_encoder *enc);
+void rvce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot,
+                      unsigned *luma_offset, unsigned *chroma_offset);
+
 struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context,
                                             const struct pipe_video_codec *templat,
                                             struct radeon_winsys* ws,
@@ -114,4 +121,7 @@ bool rvce_is_fw_version_supported(struct r600_common_screen *rscreen);
 /* init vce fw 40.2.2 specific callbacks */
 void radeon_vce_40_2_2_init(struct rvce_encoder *enc);
 
+/* init vce fw 50 specific callbacks */
+void radeon_vce_50_init(struct rvce_encoder *enc);
+
 #endif
index 09029575547ac7b1cfd12014bf5770eb04c16abb..51b17b5f6a8dd6058388799b103a1273388e72dc 100644 (file)
 
 static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 };
 
-static struct rvce_cpb_slot *current_slot(struct rvce_encoder *enc)
-{
-       return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.prev, list);
-}
-
-static struct rvce_cpb_slot *l0_slot(struct rvce_encoder *enc)
-{
-       return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next, list);
-}
-
-static struct rvce_cpb_slot *l1_slot(struct rvce_encoder *enc)
-{
-       return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next->next, list);
-}
-
-static void frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot,
-                        unsigned *luma_offset, unsigned *chroma_offset)
-{
-       unsigned pitch = align(enc->luma->level[0].pitch_bytes, 128);
-       unsigned vpitch = align(enc->luma->npix_y, 16);
-       unsigned fsize = pitch * (vpitch + vpitch / 2);
-
-       *luma_offset = slot->index * fsize;
-       *chroma_offset = *luma_offset + pitch * vpitch;
-}
-
 static void session(struct rvce_encoder *enc)
 {
        RVCE_BEGIN(0x00000001); // session cmd
@@ -369,7 +343,7 @@ static void encode(struct rvce_encoder *enc)
        if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
           enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
                struct rvce_cpb_slot *l0 = l0_slot(enc);
-               frame_offset(enc, l0, &luma_offset, &chroma_offset);
+               rvce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
                RVCE_CS(l0->picture_type); // encPicType
                RVCE_CS(l0->frame_num); // frameNumber
                RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
@@ -395,7 +369,7 @@ static void encode(struct rvce_encoder *enc)
        RVCE_CS(0x00000000); // pictureStructure
        if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
                struct rvce_cpb_slot *l1 = l1_slot(enc);
-               frame_offset(enc, l1, &luma_offset, &chroma_offset);
+               rvce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
                RVCE_CS(l1->picture_type); // encPicType
                RVCE_CS(l1->frame_num); // frameNumber
                RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
@@ -409,7 +383,7 @@ static void encode(struct rvce_encoder *enc)
                RVCE_CS(0xffffffff); // chromaOffset
        }
 
-       frame_offset(enc, current_slot(enc), &luma_offset, &chroma_offset);
+       rvce_frame_offset(enc, current_slot(enc), &luma_offset, &chroma_offset);
        RVCE_CS(luma_offset); // encReconstructedLumaOffset
        RVCE_CS(chroma_offset); // encReconstructedChromaOffset
        RVCE_CS(0x00000000); // encColocBufferOffset
diff --git a/src/gallium/drivers/radeon/radeon_vce_50.c b/src/gallium/drivers/radeon/radeon_vce_50.c
new file mode 100644 (file)
index 0000000..84a2bfb
--- /dev/null
@@ -0,0 +1,228 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Advanced Micro Devices, 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ *      Christian König <christian.koenig@amd.com>
+ *
+ */
+
+#include <stdio.h>
+
+#include "pipe/p_video_codec.h"
+
+#include "util/u_video.h"
+#include "util/u_memory.h"
+
+#include "vl/vl_video_buffer.h"
+
+#include "r600_pipe_common.h"
+#include "radeon_video.h"
+#include "radeon_vce.h"
+
+static void task_info(struct rvce_encoder *enc, uint32_t taskOperation)
+{
+       RVCE_BEGIN(0x00000002); // task info
+       RVCE_CS(0xffffffff); // offsetOfNextTaskInfo
+       RVCE_CS(taskOperation); // taskOperation
+       RVCE_CS(0x00000000); // referencePictureDependency
+       RVCE_CS(0x00000000); // collocateFlagDependency
+       RVCE_CS(0x00000000); // feedbackIndex
+       RVCE_CS(0x00000000); // videoBitstreamRingIndex
+       RVCE_END();
+}
+
+static void rate_control(struct rvce_encoder *enc)
+{
+       RVCE_BEGIN(0x04000005); // rate control
+       RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod
+       RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate
+       RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate
+       RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum
+       RVCE_CS(0x00000000); // encGOPSize
+       RVCE_CS(enc->pic.quant_i_frames); // encQP_I
+       RVCE_CS(enc->pic.quant_p_frames); // encQP_P
+       RVCE_CS(enc->pic.quant_b_frames); // encQP_B
+       RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize
+       RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen
+       RVCE_CS(0x00000000); // encVBVBufferLevel
+       RVCE_CS(0x00000000); // encMaxAUSize
+       RVCE_CS(0x00000000); // encQPInitialMode
+       RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture
+       RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger
+       RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
+       RVCE_CS(0x00000000); // encMinQP
+       RVCE_CS(0x00000033); // encMaxQP
+       RVCE_CS(0x00000000); // encSkipFrameEnable
+       RVCE_CS(0x00000000); // encFillerDataEnable
+       RVCE_CS(0x00000000); // encEnforceHRD
+       RVCE_CS(0x00000000); // encBPicsDeltaQP
+       RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP
+       RVCE_CS(0x00000000); // encRateControlReInitDisable
+       RVCE_CS(0x00000000); // encLCVBRInitQPFlag
+       RVCE_CS(0x00000000); // encLCVBRSATDBasedNonlinearBitBudgetFlag
+       RVCE_END();
+}
+
+static void encode(struct rvce_encoder *enc)
+{
+       int i;
+       unsigned luma_offset, chroma_offset;
+
+       task_info(enc, 0x00000003);
+
+       RVCE_BEGIN(0x05000001); // context buffer
+       RVCE_READWRITE(enc->cpb.res->cs_buf, enc->cpb.res->domains); // encodeContextAddressHi
+       RVCE_CS(0x00000000); // encodeContextAddressLo
+       RVCE_END();
+
+       RVCE_BEGIN(0x05000004); // video bitstream buffer
+       RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT); // videoBitstreamRingAddressHi
+       RVCE_CS(0x00000000); // videoBitstreamRingAddressLo
+       RVCE_CS(enc->bs_size); // videoBitstreamRingSize
+       RVCE_END();
+
+       RVCE_BEGIN(0x03000001); // encode
+       RVCE_CS(enc->pic.frame_num ? 0x0 : 0x11); // insertHeaders
+       RVCE_CS(0x00000000); // pictureStructure
+       RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize
+       RVCE_CS(0x00000000); // forceRefreshMap
+       RVCE_CS(0x00000000); // insertAUD
+       RVCE_CS(0x00000000); // endOfSequence
+       RVCE_CS(0x00000000); // endOfStream
+       RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM); // inputPictureLumaAddressHi
+       RVCE_CS(enc->luma->level[0].offset); // inputPictureLumaAddressLo
+       RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM); // inputPictureChromaAddressHi
+       RVCE_CS(enc->chroma->level[0].offset); // inputPictureChromaAddressLo
+       RVCE_CS(align(enc->luma->npix_y, 16)); // encInputFrameYPitch
+       RVCE_CS(enc->luma->level[0].pitch_bytes); // encInputPicLumaPitch
+       RVCE_CS(enc->chroma->level[0].pitch_bytes); // encInputPicChromaPitch
+       RVCE_CS(0x00010000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
+       RVCE_CS(0x00000000); // encInputPicTileConfig
+       RVCE_CS(enc->pic.picture_type); // encPicType
+       RVCE_CS(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); // encIdrFlag
+       RVCE_CS(0x00000000); // encIdrPicId
+       RVCE_CS(0x00000000); // encMGSKeyPic
+       RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag
+       RVCE_CS(0x00000000); // encTemporalLayerIndex
+       RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
+       RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
+       RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
+
+       i = enc->pic.frame_num - enc->pic.ref_idx_l0;
+       if (i > 1 && enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P) {
+               RVCE_CS(0x00000001); // encRefListModificationOp
+               RVCE_CS(i - 1);      // encRefListModificationNum
+       } else {
+               RVCE_CS(0x00000000); // encRefListModificationOp
+               RVCE_CS(0x00000000); // encRefListModificationNum
+       }
+
+       for (i = 0; i < 3; ++i) {
+               RVCE_CS(0x00000000); // encRefListModificationOp
+               RVCE_CS(0x00000000); // encRefListModificationNum
+       }
+       for (i = 0; i < 4; ++i) {
+               RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
+               RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
+               RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
+               RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
+               RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
+       }
+
+       // encReferencePictureL0[0]
+       RVCE_CS(0x00000000); // pictureStructure
+       if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
+          enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
+               struct rvce_cpb_slot *l0 = l0_slot(enc);
+               rvce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
+               RVCE_CS(l0->picture_type); // encPicType
+               RVCE_CS(l0->frame_num); // frameNumber
+               RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
+               RVCE_CS(luma_offset); // lumaOffset
+               RVCE_CS(chroma_offset); // chromaOffset
+       } else {
+               RVCE_CS(0x00000000); // encPicType
+               RVCE_CS(0x00000000); // frameNumber
+               RVCE_CS(0x00000000); // pictureOrderCount
+               RVCE_CS(0xffffffff); // lumaOffset
+               RVCE_CS(0xffffffff); // chromaOffset
+       }
+
+       // encReferencePictureL0[1]
+       RVCE_CS(0x00000000); // pictureStructure
+       RVCE_CS(0x00000000); // encPicType
+       RVCE_CS(0x00000000); // frameNumber
+       RVCE_CS(0x00000000); // pictureOrderCount
+       RVCE_CS(0xffffffff); // lumaOffset
+       RVCE_CS(0xffffffff); // chromaOffset
+
+       // encReferencePictureL1[0]
+       RVCE_CS(0x00000000); // pictureStructure
+       if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
+               struct rvce_cpb_slot *l1 = l1_slot(enc);
+               rvce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
+               RVCE_CS(l1->picture_type); // encPicType
+               RVCE_CS(l1->frame_num); // frameNumber
+               RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
+               RVCE_CS(luma_offset); // lumaOffset
+               RVCE_CS(chroma_offset); // chromaOffset
+       } else {
+               RVCE_CS(0x00000000); // encPicType
+               RVCE_CS(0x00000000); // frameNumber
+               RVCE_CS(0x00000000); // pictureOrderCount
+               RVCE_CS(0xffffffff); // lumaOffset
+               RVCE_CS(0xffffffff); // chromaOffset
+       }
+
+       rvce_frame_offset(enc, current_slot(enc), &luma_offset, &chroma_offset);
+       RVCE_CS(luma_offset); // encReconstructedLumaOffset
+       RVCE_CS(chroma_offset); // encReconstructedChromaOffset
+       RVCE_CS(0x00000000); // encColocBufferOffset
+       RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset
+       RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset
+       RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset
+       RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset
+       RVCE_CS(0x00000000); // pictureCount
+       RVCE_CS(enc->pic.frame_num); // frameNumber
+       RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
+       RVCE_CS(0x00000000); // numIPicRemainInRCGOP
+       RVCE_CS(0x00000000); // numPPicRemainInRCGOP
+       RVCE_CS(0x00000000); // numBPicRemainInRCGOP
+       RVCE_CS(0x00000000); // numIRPicRemainInRCGOP
+       RVCE_CS(0x00000000); // enableIntraRefresh
+       RVCE_END();
+}
+
+void radeon_vce_50_init(struct rvce_encoder *enc)
+{
+       radeon_vce_40_2_2_init(enc);
+
+       /* only the two below are different */
+       enc->rate_control = rate_control;
+       enc->encode = encode;
+}
index 774dc2285c01db18b7de4f8a9d9af9a95739c3c3..2876c0ae7359ccd1250bd5b240948ea751494b72 100644 (file)
@@ -1,4 +1,5 @@
 C_SOURCES := \
+       cik_sdma.c \
        si_blit.c \
        si_commands.c \
        si_compute.c \
diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c
new file mode 100644 (file)
index 0000000..86111cb
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ * Copyright 2014,2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *      Jerome Glisse
+ */
+
+#include "sid.h"
+#include "si_pipe.h"
+#include "../radeon/r600_cs.h"
+
+#include "util/u_format.h"
+
+static uint32_t cik_micro_tile_mode(struct si_screen *sscreen, unsigned tile_mode)
+{
+       if (sscreen->b.info.si_tile_mode_array_valid) {
+               uint32_t gb_tile_mode = sscreen->b.info.si_tile_mode_array[tile_mode];
+
+               return G_009910_MICRO_TILE_MODE_NEW(gb_tile_mode);
+       }
+
+       /* The kernel cannod return the tile mode array. Guess? */
+       return V_009910_ADDR_SURF_THIN_MICRO_TILING;
+}
+
+static void cik_sdma_do_copy_buffer(struct si_context *ctx,
+                                   struct pipe_resource *dst,
+                                   struct pipe_resource *src,
+                                   uint64_t dst_offset,
+                                   uint64_t src_offset,
+                                   uint64_t size)
+{
+       struct radeon_winsys_cs *cs = ctx->b.rings.dma.cs;
+       unsigned i, ncopy, csize;
+       struct r600_resource *rdst = (struct r600_resource*)dst;
+       struct r600_resource *rsrc = (struct r600_resource*)src;
+
+       dst_offset += r600_resource(dst)->gpu_address;
+       src_offset += r600_resource(src)->gpu_address;
+
+       ncopy = (size + CIK_SDMA_COPY_MAX_SIZE - 1) / CIK_SDMA_COPY_MAX_SIZE;
+       r600_need_dma_space(&ctx->b, ncopy * 7);
+
+       r600_context_bo_reloc(&ctx->b, &ctx->b.rings.dma, rsrc, RADEON_USAGE_READ,
+                             RADEON_PRIO_MIN);
+       r600_context_bo_reloc(&ctx->b, &ctx->b.rings.dma, rdst, RADEON_USAGE_WRITE,
+                             RADEON_PRIO_MIN);
+
+       for (i = 0; i < ncopy; i++) {
+               csize = size < CIK_SDMA_COPY_MAX_SIZE ? size : CIK_SDMA_COPY_MAX_SIZE;
+               cs->buf[cs->cdw++] = CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY,
+                                                    CIK_SDMA_COPY_SUB_OPCODE_LINEAR,
+                                                    0);
+               cs->buf[cs->cdw++] = csize;
+               cs->buf[cs->cdw++] = 0; /* src/dst endian swap */
+               cs->buf[cs->cdw++] = src_offset;
+               cs->buf[cs->cdw++] = src_offset >> 32;
+               cs->buf[cs->cdw++] = dst_offset;
+               cs->buf[cs->cdw++] = dst_offset >> 32;
+               dst_offset += csize;
+               src_offset += csize;
+               size -= csize;
+       }
+}
+
+static void cik_sdma_copy_buffer(struct si_context *ctx,
+                                struct pipe_resource *dst,
+                                struct pipe_resource *src,
+                                uint64_t dst_offset,
+                                uint64_t src_offset,
+                                uint64_t size)
+{
+       struct r600_resource *rdst = (struct r600_resource*)dst;
+
+       /* Mark the buffer range of destination as valid (initialized),
+        * so that transfer_map knows it should wait for the GPU when mapping
+        * that range. */
+       util_range_add(&rdst->valid_buffer_range, dst_offset,
+                      dst_offset + size);
+
+       cik_sdma_do_copy_buffer(ctx, dst, src, dst_offset, src_offset, size);
+}
+
+static void cik_sdma_copy_tile(struct si_context *ctx,
+                              struct pipe_resource *dst,
+                              unsigned dst_level,
+                              struct pipe_resource *src,
+                              unsigned src_level,
+                              unsigned y,
+                              unsigned copy_height,
+                              unsigned y_align,
+                              unsigned pitch,
+                              unsigned bpe)
+{
+       struct radeon_winsys_cs *cs = ctx->b.rings.dma.cs;
+       struct si_screen *sscreen = ctx->screen;
+       struct r600_texture *rsrc = (struct r600_texture*)src;
+       struct r600_texture *rdst = (struct r600_texture*)dst;
+       struct r600_texture *rlinear, *rtiled;
+       unsigned linear_lvl, tiled_lvl;
+       unsigned array_mode, lbpe, pitch_tile_max, slice_tile_max, size;
+       unsigned ncopy, height, cheight, detile, i, src_mode, dst_mode;
+       unsigned sub_op, bank_h, bank_w, mt_aspect, nbanks, tile_split, mt;
+       uint64_t base, addr;
+       unsigned pipe_config, tile_mode_index;
+
+       dst_mode = rdst->surface.level[dst_level].mode;
+       src_mode = rsrc->surface.level[src_level].mode;
+       /* downcast linear aligned to linear to simplify test */
+       src_mode = src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED ? RADEON_SURF_MODE_LINEAR : src_mode;
+       dst_mode = dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED ? RADEON_SURF_MODE_LINEAR : dst_mode;
+       assert(dst_mode != src_mode);
+       assert(src_mode == RADEON_SURF_MODE_LINEAR || dst_mode == RADEON_SURF_MODE_LINEAR);
+
+       sub_op = CIK_SDMA_COPY_SUB_OPCODE_TILED;
+       lbpe = util_logbase2(bpe);
+       pitch_tile_max = ((pitch / bpe) / 8) - 1;
+
+       detile = dst_mode == RADEON_SURF_MODE_LINEAR;
+       rlinear = detile ? rdst : rsrc;
+       rtiled = detile ? rsrc : rdst;
+       linear_lvl = detile ? dst_level : src_level;
+       tiled_lvl = detile ? src_level : dst_level;
+
+       assert(!util_format_is_depth_and_stencil(rtiled->resource.b.b.format));
+
+       array_mode = si_array_mode(rtiled->surface.level[tiled_lvl].mode);
+       slice_tile_max = (rtiled->surface.level[tiled_lvl].nblk_x *
+                         rtiled->surface.level[tiled_lvl].nblk_y) / (8*8) - 1;
+       height = rlinear->surface.level[linear_lvl].nblk_y;
+       base = rtiled->surface.level[tiled_lvl].offset;
+       addr = rlinear->surface.level[linear_lvl].offset;
+       bank_h = cik_bank_wh(rtiled->surface.bankh);
+       bank_w = cik_bank_wh(rtiled->surface.bankw);
+       mt_aspect = cik_macro_tile_aspect(rtiled->surface.mtilea);
+       tile_split = cik_tile_split(rtiled->surface.tile_split);
+       tile_mode_index = si_tile_mode_index(rtiled, tiled_lvl, false);
+       nbanks = si_num_banks(sscreen, rtiled);
+       base += rtiled->resource.gpu_address;
+       addr += rlinear->resource.gpu_address;
+
+       pipe_config = cik_db_pipe_config(sscreen, tile_mode_index);
+       mt = cik_micro_tile_mode(sscreen, tile_mode_index);
+
+       size = (copy_height * pitch) / 4;
+       cheight = copy_height;
+       if (((cheight * pitch) / 4) > CIK_SDMA_COPY_MAX_SIZE) {
+               cheight = (CIK_SDMA_COPY_MAX_SIZE * 4) / pitch;
+               cheight &= ~(y_align - 1);
+       }
+       ncopy = (copy_height + cheight - 1) / cheight;
+       r600_need_dma_space(&ctx->b, ncopy * 12);
+
+       r600_context_bo_reloc(&ctx->b, &ctx->b.rings.dma, &rsrc->resource,
+                             RADEON_USAGE_READ, RADEON_PRIO_MIN);
+       r600_context_bo_reloc(&ctx->b, &ctx->b.rings.dma, &rdst->resource,
+                             RADEON_USAGE_WRITE, RADEON_PRIO_MIN);
+
+       copy_height = size * 4 / pitch;
+       for (i = 0; i < ncopy; i++) {
+               cheight = copy_height;
+               if (((cheight * pitch) / 4) > CIK_SDMA_COPY_MAX_SIZE) {
+                       cheight = (CIK_SDMA_COPY_MAX_SIZE * 4) / pitch;
+                       cheight &= ~(y_align - 1);
+               }
+               size = (cheight * pitch) / 4;
+
+               cs->buf[cs->cdw++] = CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY,
+                                                    sub_op, detile << 15);
+               cs->buf[cs->cdw++] = base;
+               cs->buf[cs->cdw++] = base >> 32;
+               cs->buf[cs->cdw++] = ((height - 1) << 16) | pitch_tile_max;
+               cs->buf[cs->cdw++] = slice_tile_max;
+               cs->buf[cs->cdw++] = (pipe_config << 26) | (mt_aspect << 24) |
+                       (nbanks << 21) | (bank_h << 18) | (bank_w << 15) |
+                       (tile_split << 11) | (mt << 8) | (array_mode << 3) |
+                       lbpe;
+               cs->buf[cs->cdw++] = y << 16; /* | x */
+               cs->buf[cs->cdw++] = 0; /* z */;
+               cs->buf[cs->cdw++] = addr & 0xfffffffc;
+               cs->buf[cs->cdw++] = addr >> 32;
+               cs->buf[cs->cdw++] = (pitch / bpe) - 1;
+               cs->buf[cs->cdw++] = size;
+
+               copy_height -= cheight;
+               y += cheight;
+       }
+}
+
+void cik_sdma_copy(struct pipe_context *ctx,
+                  struct pipe_resource *dst,
+                  unsigned dst_level,
+                  unsigned dstx, unsigned dsty, unsigned dstz,
+                  struct pipe_resource *src,
+                  unsigned src_level,
+                  const struct pipe_box *src_box)
+{
+       struct si_context *sctx = (struct si_context *)ctx;
+       struct r600_texture *rsrc = (struct r600_texture*)src;
+       struct r600_texture *rdst = (struct r600_texture*)dst;
+       unsigned dst_pitch, src_pitch, bpe, dst_mode, src_mode;
+       unsigned src_w, dst_w;
+       unsigned src_x, src_y;
+       unsigned copy_height, y_align;
+       unsigned dst_x = dstx, dst_y = dsty, dst_z = dstz;
+
+       if (sctx->b.rings.dma.cs == NULL) {
+               goto fallback;
+       }
+
+       if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
+               cik_sdma_copy_buffer(sctx, dst, src, dst_x, src_box->x, src_box->width);
+               return;
+       }
+
+       /* Before re-enabling this, please make sure you can hit all newly
+        * enabled paths in your testing, preferably with both piglit (in
+        * particular the streaming-texture-leak test) and real world apps
+        * (e.g. the UE4 Elemental demo).
+        */
+       goto fallback;
+
+       if (src->format != dst->format ||
+           rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 ||
+           rdst->dirty_level_mask & (1 << dst_level)) {
+               goto fallback;
+       }
+
+       if (rsrc->dirty_level_mask & (1 << src_level)) {
+               if (rsrc->htile_buffer)
+                       goto fallback;
+
+               ctx->flush_resource(ctx, src);
+       }
+
+       src_x = util_format_get_nblocksx(src->format, src_box->x);
+       dst_x = util_format_get_nblocksx(src->format, dst_x);
+       src_y = util_format_get_nblocksy(src->format, src_box->y);
+       dst_y = util_format_get_nblocksy(src->format, dst_y);
+
+       dst_pitch = rdst->surface.level[dst_level].pitch_bytes;
+       src_pitch = rsrc->surface.level[src_level].pitch_bytes;
+       src_w = rsrc->surface.level[src_level].npix_x;
+       dst_w = rdst->surface.level[dst_level].npix_x;
+
+       if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w ||
+           src_box->width != src_w ||
+           rsrc->surface.level[src_level].nblk_y !=
+           rdst->surface.level[dst_level].nblk_y) {
+               /* FIXME CIK can do partial blit */
+               goto fallback;
+       }
+
+       bpe = rdst->surface.bpe;
+       copy_height = src_box->height / rsrc->surface.blk_h;
+       dst_mode = rdst->surface.level[dst_level].mode;
+       src_mode = rsrc->surface.level[src_level].mode;
+       /* downcast linear aligned to linear to simplify test */
+       src_mode = src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED ? RADEON_SURF_MODE_LINEAR : src_mode;
+       dst_mode = dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED ? RADEON_SURF_MODE_LINEAR : dst_mode;
+
+       /* Dimensions must be aligned to (macro)tiles */
+       switch (src_mode == RADEON_SURF_MODE_LINEAR ? dst_mode : src_mode) {
+       case RADEON_SURF_MODE_1D:
+               if ((src_x % 8) || (src_y % 8) || (dst_x % 8) || (dst_y % 8) ||
+                   (copy_height % 8))
+                       goto fallback;
+               y_align = 8;
+               break;
+       case RADEON_SURF_MODE_2D: {
+               unsigned mtilew, mtileh, num_banks;
+
+                       switch (si_num_banks(sctx->screen, rsrc)) {
+                       case V_02803C_ADDR_SURF_2_BANK:
+                       default:
+                               num_banks = 2;
+                               break;
+                       case V_02803C_ADDR_SURF_4_BANK:
+                               num_banks = 4;
+                               break;
+                       case V_02803C_ADDR_SURF_8_BANK:
+                               num_banks = 8;
+                               break;
+                       case V_02803C_ADDR_SURF_16_BANK:
+                               num_banks = 16;
+                               break;
+                       }
+
+                       mtilew = (8 * rsrc->surface.bankw *
+                                 sctx->screen->b.tiling_info.num_channels) *
+                               rsrc->surface.mtilea;
+                       assert(!(mtilew & (mtilew - 1)));
+                       mtileh = (8 * rsrc->surface.bankh * num_banks) /
+                               rsrc->surface.mtilea;
+                       assert(!(mtileh & (mtileh - 1)));
+
+                       if ((src_x & (mtilew - 1)) || (src_y & (mtileh - 1)) ||
+                           (dst_x & (mtilew - 1)) || (dst_y & (mtileh - 1)) ||
+                           (copy_height & (mtileh - 1)))
+                               goto fallback;
+
+                       y_align = mtileh;
+                       break;
+       }
+       default:
+               y_align = 1;
+       }
+
+       if (src_mode == dst_mode) {
+               uint64_t dst_offset, src_offset;
+               unsigned src_h, dst_h;
+
+               src_h = rsrc->surface.level[src_level].npix_y;
+               dst_h = rdst->surface.level[dst_level].npix_y;
+
+               if (src_box->depth > 1 &&
+                   (src_y || dst_y || src_h != dst_h || src_box->height != src_h))
+                       goto fallback;
+
+               /* simple dma blit would do NOTE code here assume :
+                *   dst_pitch == src_pitch
+                */
+               src_offset= rsrc->surface.level[src_level].offset;
+               src_offset += rsrc->surface.level[src_level].slice_size * src_box->z;
+               src_offset += src_y * src_pitch + src_x * bpe;
+               dst_offset = rdst->surface.level[dst_level].offset;
+               dst_offset += rdst->surface.level[dst_level].slice_size * dst_z;
+               dst_offset += dst_y * dst_pitch + dst_x * bpe;
+               cik_sdma_do_copy_buffer(sctx, dst, src, dst_offset, src_offset,
+                                       src_box->depth *
+                                       rsrc->surface.level[src_level].slice_size);
+       } else {
+               if (dst_y != src_y || src_box->depth > 1 || src_box->z || dst_z)
+                       goto fallback;
+
+               cik_sdma_copy_tile(sctx, dst, dst_level, src, src_level,
+                                  src_y, copy_height, y_align, dst_pitch, bpe);
+       }
+       return;
+
+fallback:
+       si_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
+                               src, src_level, src_box);
+}
index db523eef3185c5e22cd19f928e3c9acf36a488c4..7a0076e7aa919087de1dffa72ef1563e0a109641 100644 (file)
 
 #include "util/u_format.h"
 
-static unsigned si_array_mode(unsigned mode)
-{
-       switch (mode) {
-       case RADEON_SURF_MODE_LINEAR_ALIGNED:
-               return V_009910_ARRAY_LINEAR_ALIGNED;
-       case RADEON_SURF_MODE_1D:
-               return V_009910_ARRAY_1D_TILED_THIN1;
-       case RADEON_SURF_MODE_2D:
-               return V_009910_ARRAY_2D_TILED_THIN1;
-       default:
-       case RADEON_SURF_MODE_LINEAR:
-               return V_009910_ARRAY_LINEAR_GENERAL;
-       }
-}
-
 static uint32_t si_micro_tile_mode(struct si_screen *sscreen, unsigned tile_mode)
 {
        if (sscreen->b.info.si_tile_mode_array_valid) {
@@ -240,11 +225,6 @@ void si_dma_copy(struct pipe_context *ctx,
                goto fallback;
        }
 
-       /* TODO: Implement DMA copy for CIK */
-       if (sctx->b.chip_class >= CIK) {
-               goto fallback;
-       }
-
        if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
                si_dma_copy_buffer(sctx, dst, src, dst_x, src_box->x, src_box->width);
                return;
index e68c30e8c7c98046a18e780cebf04c496fb630d8..53ae71a8c926e8f1fae33d80bd6c9a90837757d1 100644 (file)
@@ -251,6 +251,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_POLYGON_OFFSET_CLAMP:
        case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
        case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+       case PIPE_CAP_TGSI_TEXCOORD:
                return 1;
 
        case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
@@ -286,13 +287,13 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
        case PIPE_CAP_VERTEX_COLOR_CLAMPED:
        case PIPE_CAP_USER_VERTEX_BUFFERS:
-       case PIPE_CAP_TGSI_TEXCOORD:
        case PIPE_CAP_FAKE_SW_MSAA:
        case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
        case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
        case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
        case PIPE_CAP_VERTEXID_NOBASE:
+       case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
                return 0;
 
        case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
@@ -451,6 +452,7 @@ static int si_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enu
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
                return 0;
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+       case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
                return 1;
        }
        return 0;
index f98c7a837448cdbae0696c3fa0db7f43a6940c00..2d67342f1608dc8aad026766afb5bbbaa3629f18 100644 (file)
@@ -237,6 +237,15 @@ struct si_context {
        unsigned                spi_tmpring_size;
 };
 
+/* cik_sdma.c */
+void cik_sdma_copy(struct pipe_context *ctx,
+                  struct pipe_resource *dst,
+                  unsigned dst_level,
+                  unsigned dstx, unsigned dsty, unsigned dstz,
+                  struct pipe_resource *src,
+                  unsigned src_level,
+                  const struct pipe_box *src_box);
+
 /* si_blit.c */
 void si_init_blit_functions(struct si_context *sctx);
 void si_flush_depth_textures(struct si_context *sctx,
index 89f02ab041097b9fb58693fd4d2792ee83fba619..47e5f96cbed43ddeae01049f96aab7bd7193bca7 100644 (file)
@@ -128,21 +128,10 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
        case TGSI_SEMANTIC_CLIPDIST:
                assert(index <= 1);
                return 2 + index;
-       case TGSI_SEMANTIC_CLIPVERTEX:
-               return 4;
-       case TGSI_SEMANTIC_COLOR:
-               assert(index <= 1);
-               return 5 + index;
-       case TGSI_SEMANTIC_BCOLOR:
-               assert(index <= 1);
-               return 7 + index;
-       case TGSI_SEMANTIC_FOG:
-               return 9;
-       case TGSI_SEMANTIC_EDGEFLAG:
-               return 10;
        case TGSI_SEMANTIC_GENERIC:
-               assert(index <= 63-11);
-               return 11 + index;
+               assert(index <= 63-4);
+               return 4 + index;
+
        default:
                assert(0);
                return 63;
@@ -1183,6 +1172,7 @@ handle_semantic:
                        continue;
                case TGSI_SEMANTIC_PRIMID:
                case TGSI_SEMANTIC_FOG:
+               case TGSI_SEMANTIC_TEXCOORD:
                case TGSI_SEMANTIC_GENERIC:
                        target = V_008DFC_SQ_EXP_PARAM + param_count;
                        shader->vs_output_param_offset[i] = param_count;
index 7f0fdd599dc81705be5450e52270c9db6a94d9d8..6c18836d1895d3c77f7e5bb05d1e8f537eb00965 100644 (file)
@@ -44,6 +44,21 @@ static void si_init_atom(struct r600_atom *atom, struct r600_atom **list_elem,
        *list_elem = atom;
 }
 
+unsigned si_array_mode(unsigned mode)
+{
+       switch (mode) {
+       case RADEON_SURF_MODE_LINEAR_ALIGNED:
+               return V_009910_ARRAY_LINEAR_ALIGNED;
+       case RADEON_SURF_MODE_1D:
+               return V_009910_ARRAY_1D_TILED_THIN1;
+       case RADEON_SURF_MODE_2D:
+               return V_009910_ARRAY_2D_TILED_THIN1;
+       default:
+       case RADEON_SURF_MODE_LINEAR:
+               return V_009910_ARRAY_LINEAR_GENERAL;
+       }
+}
+
 uint32_t si_num_banks(struct si_screen *sscreen, struct r600_texture *tex)
 {
        if (sscreen->b.chip_class == CIK &&
@@ -636,18 +651,14 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        rs->offset_units = state->offset_units;
        rs->offset_scale = state->offset_scale * 12.0f;
 
-       tmp = S_0286D4_FLAT_SHADE_ENA(1);
-       if (state->sprite_coord_enable) {
-               tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
-                       S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
-                       S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) |
-                       S_0286D4_PNT_SPRITE_OVRD_Z(V_0286D4_SPI_PNT_SPRITE_SEL_0) |
-                       S_0286D4_PNT_SPRITE_OVRD_W(V_0286D4_SPI_PNT_SPRITE_SEL_1);
-               if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
-                       tmp |= S_0286D4_PNT_SPRITE_TOP_1(1);
-               }
-       }
-       si_pm4_set_reg(pm4, R_0286D4_SPI_INTERP_CONTROL_0, tmp);
+       si_pm4_set_reg(pm4, R_0286D4_SPI_INTERP_CONTROL_0,
+               S_0286D4_FLAT_SHADE_ENA(1) |
+               S_0286D4_PNT_SPRITE_ENA(1) |
+               S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
+               S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) |
+               S_0286D4_PNT_SPRITE_OVRD_Z(V_0286D4_SPI_PNT_SPRITE_SEL_0) |
+               S_0286D4_PNT_SPRITE_OVRD_W(V_0286D4_SPI_PNT_SPRITE_SEL_1) |
+               S_0286D4_PNT_SPRITE_TOP_1(state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT));
 
        /* point size 12.4 fixed point */
        tmp = (unsigned)(state->point_size * 8.0);
@@ -2910,11 +2921,16 @@ void si_init_state_functions(struct si_context *sctx)
        sctx->b.b.set_polygon_stipple = si_set_polygon_stipple;
        sctx->b.b.set_min_samples = si_set_min_samples;
 
-       sctx->b.dma_copy = si_dma_copy;
        sctx->b.set_occlusion_query_state = si_set_occlusion_query_state;
        sctx->b.need_gfx_cs_space = si_need_gfx_cs_space;
 
        sctx->b.b.draw_vbo = si_draw_vbo;
+
+       if (sctx->b.chip_class >= CIK) {
+               sctx->b.dma_copy = cik_sdma_copy;
+       } else {
+               sctx->b.dma_copy = si_dma_copy;
+       }
 }
 
 static void
index 2f8a943846ad2a7dea8e90e072829bcdc6347f1c..5e68b16213753f2c6030a1a87cf05abbb1ef87be 100644 (file)
@@ -261,6 +261,7 @@ unsigned cik_bank_wh(unsigned bankwh);
 unsigned cik_db_pipe_config(struct si_screen *sscreen, unsigned tile_mode);
 unsigned cik_macro_tile_aspect(unsigned macro_tile_aspect);
 unsigned cik_tile_split(unsigned tile_split);
+unsigned si_array_mode(unsigned mode);
 uint32_t si_num_banks(struct si_screen *sscreen, struct r600_texture *tex);
 unsigned si_tile_mode_index(struct r600_texture *rtex, unsigned level, bool stencil);
 
index 1bbc6b3ca7aa7d7e4322dd54f0bf9aaf438d717d..208c8523ef107807c68364d70b850cdb5520e96f 100644 (file)
@@ -182,8 +182,13 @@ static void si_shader_vs(struct si_shader *shader)
        for (nparams = 0, i = 0 ; i < info->num_outputs; i++) {
                switch (info->output_semantic_name[i]) {
                case TGSI_SEMANTIC_CLIPVERTEX:
+               case TGSI_SEMANTIC_CLIPDIST:
+               case TGSI_SEMANTIC_CULLDIST:
                case TGSI_SEMANTIC_POSITION:
                case TGSI_SEMANTIC_PSIZE:
+               case TGSI_SEMANTIC_EDGEFLAG:
+               case TGSI_SEMANTIC_VIEWPORT_INDEX:
+               case TGSI_SEMANTIC_LAYER:
                        break;
                default:
                        nparams++;
@@ -351,21 +356,25 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
                                          union si_shader_key *key)
 {
        struct si_context *sctx = (struct si_context *)ctx;
-       memset(key, 0, sizeof(*key));
+       unsigned i;
 
-       if (sel->type == PIPE_SHADER_VERTEX) {
-               unsigned i;
-               if (!sctx->vertex_elements)
-                       return;
+       memset(key, 0, sizeof(*key));
 
-               for (i = 0; i < sctx->vertex_elements->count; ++i)
-                       key->vs.instance_divisors[i] = sctx->vertex_elements->elements[i].instance_divisor;
+       switch (sel->type) {
+       case PIPE_SHADER_VERTEX:
+               if (sctx->vertex_elements)
+                       for (i = 0; i < sctx->vertex_elements->count; ++i)
+                               key->vs.instance_divisors[i] =
+                                       sctx->vertex_elements->elements[i].instance_divisor;
 
                if (sctx->gs_shader) {
                        key->vs.as_es = 1;
                        key->vs.gs_used_inputs = sctx->gs_shader->gs_used_inputs;
                }
-       } else if (sel->type == PIPE_SHADER_FRAGMENT) {
+               break;
+       case PIPE_SHADER_GEOMETRY:
+               break;
+       case PIPE_SHADER_FRAGMENT: {
                struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
 
                if (sel->info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
@@ -393,11 +402,14 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
                }
 
                key->ps.alpha_func = PIPE_FUNC_ALWAYS;
-
                /* Alpha-test should be disabled if colorbuffer 0 is integer. */
                if (sctx->queued.named.dsa &&
                    !sctx->framebuffer.cb0_is_integer)
                        key->ps.alpha_func = sctx->queued.named.dsa->alpha_func;
+               break;
+       }
+       default:
+               assert(0);
        }
 }
 
@@ -580,15 +592,22 @@ static void si_delete_shader_selector(struct pipe_context *ctx,
 
        while (p) {
                c = p->next_variant;
-               if (sel->type == PIPE_SHADER_GEOMETRY) {
+               switch (sel->type) {
+               case PIPE_SHADER_VERTEX:
+                       if (p->key.vs.as_es)
+                               si_pm4_delete_state(sctx, es, p->pm4);
+                       else
+                               si_pm4_delete_state(sctx, vs, p->pm4);
+                       break;
+               case PIPE_SHADER_GEOMETRY:
                        si_pm4_delete_state(sctx, gs, p->pm4);
                        si_pm4_delete_state(sctx, vs, p->gs_copy_shader->pm4);
-               } else if (sel->type == PIPE_SHADER_FRAGMENT)
+                       break;
+               case PIPE_SHADER_FRAGMENT:
                        si_pm4_delete_state(sctx, ps, p->pm4);
-               else if (p->key.vs.as_es)
-                       si_pm4_delete_state(sctx, es, p->pm4);
-               else
-                       si_pm4_delete_state(sctx, vs, p->pm4);
+                       break;
+               }
+
                si_shader_destroy(ctx, p);
                free(p);
                p = c;
@@ -661,8 +680,9 @@ bcolor:
                    (interpolate == TGSI_INTERPOLATE_COLOR && sctx->flatshade))
                        tmp |= S_028644_FLAT_SHADE(1);
 
-               if (name == TGSI_SEMANTIC_GENERIC &&
-                   sctx->sprite_coord_enable & (1 << index)) {
+               if (name == TGSI_SEMANTIC_PCOORD ||
+                   (name == TGSI_SEMANTIC_TEXCOORD &&
+                    sctx->sprite_coord_enable & (1 << index))) {
                        tmp |= S_028644_PT_SPRITE_TEX(1);
                }
 
@@ -835,8 +855,15 @@ static void si_update_spi_tmpring_size(struct si_context *sctx)
                        si_pm4_bind_state(sctx, ps, sctx->ps_shader->current->pm4);
                if (si_update_scratch_buffer(sctx, sctx->gs_shader))
                        si_pm4_bind_state(sctx, gs, sctx->gs_shader->current->pm4);
-               if (si_update_scratch_buffer(sctx, sctx->vs_shader))
-                       si_pm4_bind_state(sctx, vs, sctx->vs_shader->current->pm4);
+
+               /* VS can be bound as ES or VS. */
+               if (sctx->gs_shader) {
+                       if (si_update_scratch_buffer(sctx, sctx->vs_shader))
+                               si_pm4_bind_state(sctx, es, sctx->vs_shader->current->pm4);
+               } else {
+                       if (si_update_scratch_buffer(sctx, sctx->vs_shader))
+                               si_pm4_bind_state(sctx, vs, sctx->vs_shader->current->pm4);
+               }
        }
 
        /* The LLVM shader backend should be reporting aligned scratch_sizes. */
index afe011b15c77387335691acddd41b987bdea3d04..35d5ee232a01e93d9d32149e6e528f4da2d9f3ad 100644 (file)
 #define     V_009910_ADDR_SURF_8_BANK                               0x02
 #define     V_009910_ADDR_SURF_16_BANK                              0x03
 /* CIK */
+#define   S_009910_MICRO_TILE_MODE_NEW(x)                             (((x) & 0x07) << 22)
+#define   G_009910_MICRO_TILE_MODE_NEW(x)                             (((x) >> 22) & 0x07)
+#define   C_009910_MICRO_TILE_MODE_NEW(x)                             0xFE3FFFFF
+#define     V_009910_ADDR_SURF_DISPLAY_MICRO_TILING                 0x00
+#define     V_009910_ADDR_SURF_THIN_MICRO_TILING                    0x01
+#define     V_009910_ADDR_SURF_DEPTH_MICRO_TILING                   0x02
+#define     V_009910_ADDR_SURF_ROTATED_MICRO_TILING                 0x03
 #define R_00B01C_SPI_SHADER_PGM_RSRC3_PS                                0x00B01C
 #define   S_00B01C_CU_EN(x)                                           (((x) & 0xFFFF) << 0)
 #define   G_00B01C_CU_EN(x)                                           (((x) >> 0) & 0xFFFF)
 #define    SI_DMA_PACKET_CONSTANT_FILL             0xd
 #define    SI_DMA_PACKET_NOP                       0xf
 
+/* CIK async DMA packets */
+#define CIK_SDMA_PACKET(op, sub_op, n)   ((((n) & 0xFFFF) << 16) |     \
+                                        (((sub_op) & 0xFF) << 8) |     \
+                                        (((op) & 0xFF) << 0))
+/* CIK async DMA packet types */
+#define    CIK_SDMA_OPCODE_NOP                     0x0
+#define    CIK_SDMA_OPCODE_COPY                    0x1
+#define        CIK_SDMA_COPY_SUB_OPCODE_LINEAR            0x0
+#define        CIK_SDMA_COPY_SUB_OPCODE_TILED             0x1
+#define        CIK_SDMA_COPY_SUB_OPCODE_SOA               0x3
+#define        CIK_SDMA_COPY_SUB_OPCODE_LINEAR_SUB_WINDOW 0x4
+#define        CIK_SDMA_COPY_SUB_OPCODE_TILED_SUB_WINDOW  0x5
+#define        CIK_SDMA_COPY_SUB_OPCODE_T2T_SUB_WINDOW    0x6
+#define    CIK_SDMA_OPCODE_WRITE                   0x2
+#define        SDMA_WRITE_SUB_OPCODE_LINEAR               0x0
+#define        SDMA_WRTIE_SUB_OPCODE_TILED                0x1
+#define    CIK_SDMA_OPCODE_INDIRECT_BUFFER         0x4
+#define    CIK_SDMA_PACKET_FENCE                   0x5
+#define    CIK_SDMA_PACKET_TRAP                    0x6
+#define    CIK_SDMA_PACKET_SEMAPHORE               0x7
+#define    CIK_SDMA_PACKET_CONSTANT_FILL           0xb
+#define    CIK_SDMA_PACKET_SRBM_WRITE              0xe
+#define    CIK_SDMA_COPY_MAX_SIZE                  0x1fffff
+
 #endif /* _SID_H */
 
index b66740b49cde652fe1bfe607f136dfabbb3e2ded..83f9c94e31ff8f2d55cf08438edfb11ae918e25e 100644 (file)
 #ifndef RBUG_PUBLIC_H
 #define RBUG_PUBLIC_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct pipe_screen;
 struct pipe_context;
 
@@ -37,4 +41,8 @@ rbug_screen_create(struct pipe_screen *screen);
 boolean
 rbug_enabled(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* RBUG_PUBLIC_H */
index 62d0903d87a3bdfcf604dc4df1eefde306ed0e78..88a9b5e6643295a781ce81be377b8c13720678d8 100644 (file)
@@ -1,10 +1,18 @@
 #ifndef SP_PUBLIC_H
 #define SP_PUBLIC_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct pipe_screen;
 struct sw_winsys;
 
 struct pipe_screen *
 softpipe_create_screen(struct sw_winsys *winsys);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index e77387082bc0d71690e9f9ad8d3d4398aaad0ac7..76105b4c0ec2f660cb3505cb18dbb30408a3f63c 100644 (file)
@@ -277,7 +277,7 @@ softpipe_check_render_cond(struct softpipe_context *sp)
    b = pipe->get_query_result(pipe, sp->render_cond_query, wait,
                               (void*)&result);
    if (b)
-      return (!result == sp->render_cond_cond);
+      return (!result) == sp->render_cond_cond;
    else
       return TRUE;
 }
index d289e28a6f8ff462f0c28afc66a92dc9acca3acb..a688d319bb8bed0c9213a2b2c042860a62d3cf02 100644 (file)
@@ -191,7 +191,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_ENDIANNESS:
       return PIPE_ENDIAN_NATIVE;
    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
+      return 4;
    case PIPE_CAP_TEXTURE_GATHER_SM5:
+      return 1;
    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
    case PIPE_CAP_TEXTURE_QUERY_LOD:
    case PIPE_CAP_SAMPLE_SHADING:
@@ -200,13 +202,15 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
       return 1;
    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
-   case PIPE_CAP_SAMPLER_VIEW_TARGET:
       return 0;
+   case PIPE_CAP_SAMPLER_VIEW_TARGET:
+      return 1;
    case PIPE_CAP_FAKE_SW_MSAA:
       return 1;
    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
+      return -32;
    case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
-      return 0;
+      return 31;
    case PIPE_CAP_DRAW_INDIRECT:
       return 1;
 
@@ -237,6 +241,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 0;
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
    }
    /* should only get here on unhandled cases */
index e56fb5b1485315528024b9a235f28121ad1b240d..d7a3360713fbf7f5fd31738de9c1cf2e057a92cc 100644 (file)
@@ -202,7 +202,7 @@ prepare_shader_sampling(
             struct pipe_resource *res = view->texture;
             int j;
 
-            if (res->target != PIPE_BUFFER) {
+            if (view->target != PIPE_BUFFER) {
                first_level = view->u.tex.first_level;
                last_level = view->u.tex.last_level;
                assert(first_level <= last_level);
@@ -214,15 +214,17 @@ prepare_shader_sampling(
                   row_stride[j] = sp_tex->stride[j];
                   img_stride[j] = sp_tex->img_stride[j];
                }
-               if (res->target == PIPE_TEXTURE_1D_ARRAY ||
-                   res->target == PIPE_TEXTURE_2D_ARRAY ||
-                   res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+               if (view->target == PIPE_TEXTURE_1D_ARRAY ||
+                   view->target == PIPE_TEXTURE_2D_ARRAY ||
+                   view->target == PIPE_TEXTURE_CUBE ||
+                   view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                   num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
                   for (j = first_level; j <= last_level; j++) {
                      mip_offsets[j] += view->u.tex.first_layer *
                                        sp_tex->img_stride[j];
                   }
-                  if (res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+                  if (view->target == PIPE_TEXTURE_CUBE ||
+                      view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                      assert(num_layers % 6 == 0);
                   }
                   assert(view->u.tex.first_layer <= view->u.tex.last_layer);
index 68dcf57240d32c5b42504e962068091d4628bf28..1010b63de2cb476759c23fc8d54153d4f120fd79 100644 (file)
@@ -131,68 +131,80 @@ repeat(int coord, unsigned size)
  * \param icoord  returns the integer texcoords
  */
 static void
-wrap_nearest_repeat(float s, unsigned size, int *icoord)
+wrap_nearest_repeat(float s, unsigned size, int offset, int *icoord)
 {
    /* s limited to [0,1) */
    /* i limited to [0,size-1] */
    int i = util_ifloor(s * size);
-   *icoord = repeat(i, size);
+   *icoord = repeat(i + offset, size);
 }
 
 
 static void
-wrap_nearest_clamp(float s, unsigned size, int *icoord)
+wrap_nearest_clamp(float s, unsigned size, int offset, int *icoord)
 {
    /* s limited to [0,1] */
    /* i limited to [0,size-1] */
+   s *= size;
+   s += offset;
    if (s <= 0.0F)
       *icoord = 0;
-   else if (s >= 1.0F)
+   else if (s >= size)
       *icoord = size - 1;
    else
-      *icoord = util_ifloor(s * size);
+      *icoord = util_ifloor(s);
 }
 
 
 static void
-wrap_nearest_clamp_to_edge(float s, unsigned size, int *icoord)
+wrap_nearest_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
 {
    /* s limited to [min,max] */
    /* i limited to [0, size-1] */
-   const float min = 1.0F / (2.0F * size);
-   const float max = 1.0F - min;
+   const float min = 0.5F;
+   const float max = (float)size - 0.5F;
+
+   s *= size;
+   s += offset;
+
    if (s < min)
       *icoord = 0;
    else if (s > max)
       *icoord = size - 1;
    else
-      *icoord = util_ifloor(s * size);
+      *icoord = util_ifloor(s);
 }
 
 
 static void
-wrap_nearest_clamp_to_border(float s, unsigned size, int *icoord)
+wrap_nearest_clamp_to_border(float s, unsigned size, int offset, int *icoord)
 {
    /* s limited to [min,max] */
    /* i limited to [-1, size] */
-   const float min = -1.0F / (2.0F * size);
-   const float max = 1.0F - min;
+   const float min = -0.5F;
+   const float max = size + 0.5F;
+
+   s *= size;
+   s += offset;
    if (s <= min)
       *icoord = -1;
    else if (s >= max)
       *icoord = size;
    else
-      *icoord = util_ifloor(s * size);
+      *icoord = util_ifloor(s);
 }
 
-
 static void
-wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord)
+wrap_nearest_mirror_repeat(float s, unsigned size, int offset, int *icoord)
 {
    const float min = 1.0F / (2.0F * size);
    const float max = 1.0F - min;
-   const int flr = util_ifloor(s);
-   float u = frac(s);
+   int flr;
+   float u;
+
+   s += (float)offset / size;
+   flr = util_ifloor(s);
+   u = frac(s);
    if (flr & 1)
       u = 1.0F - u;
    if (u < min)
@@ -205,51 +217,52 @@ wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord)
 
 
 static void
-wrap_nearest_mirror_clamp(float s, unsigned size, int *icoord)
+wrap_nearest_mirror_clamp(float s, unsigned size, int offset, int *icoord)
 {
    /* s limited to [0,1] */
    /* i limited to [0,size-1] */
-   const float u = fabsf(s);
+   const float u = fabsf(s * size + offset);
    if (u <= 0.0F)
       *icoord = 0;
-   else if (u >= 1.0F)
+   else if (u >= size)
       *icoord = size - 1;
    else
-      *icoord = util_ifloor(u * size);
+      *icoord = util_ifloor(u);
 }
 
 
 static void
-wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int *icoord)
+wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
 {
    /* s limited to [min,max] */
    /* i limited to [0, size-1] */
-   const float min = 1.0F / (2.0F * size);
-   const float max = 1.0F - min;
-   const float u = fabsf(s);
+   const float min = 0.5F;
+   const float max = (float)size - 0.5F;
+   const float u = fabsf(s * size + offset);
+
    if (u < min)
       *icoord = 0;
    else if (u > max)
       *icoord = size - 1;
    else
-      *icoord = util_ifloor(u * size);
+      *icoord = util_ifloor(u);
 }
 
 
 static void
-wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord)
+wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int offset, int *icoord)
 {
-   /* s limited to [min,max] */
-   /* i limited to [0, size-1] */
-   const float min = -1.0F / (2.0F * size);
-   const float max = 1.0F - min;
-   const float u = fabsf(s);
+   /* u limited to [-0.5, size-0.5] */
+   const float min = -0.5F;
+   const float max = (float)size + 0.5F;
+   const float u = fabsf(s * size + offset);
+
    if (u < min)
       *icoord = -1;
    else if (u > max)
       *icoord = size;
    else
-      *icoord = util_ifloor(u * size);
+      *icoord = util_ifloor(u);
 }
 
 
@@ -264,22 +277,23 @@ wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord)
  * \param icoord  returns the computed integer texture coord
  */
 static void
-wrap_linear_repeat(float s, unsigned size,
+wrap_linear_repeat(float s, unsigned size, int offset,
                    int *icoord0, int *icoord1, float *w)
 {
    float u = s * size - 0.5F;
-   *icoord0 = repeat(util_ifloor(u), size);
+   *icoord0 = repeat(util_ifloor(u) + offset, size);
    *icoord1 = repeat(*icoord0 + 1, size);
    *w = frac(u);
 }
 
 
 static void
-wrap_linear_clamp(float s, unsigned size,
+wrap_linear_clamp(float s, unsigned size, int offset,
                   int *icoord0, int *icoord1, float *w)
 {
-   float u = CLAMP(s, 0.0F, 1.0F);
-   u = u * size - 0.5f;
+   float u = CLAMP(s * size + offset, 0.0F, (float)size);
+
+   u = u - 0.5f;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
    *w = frac(u);
@@ -287,11 +301,11 @@ wrap_linear_clamp(float s, unsigned size,
 
 
 static void
-wrap_linear_clamp_to_edge(float s, unsigned size,
+wrap_linear_clamp_to_edge(float s, unsigned size, int offset,
                           int *icoord0, int *icoord1, float *w)
 {
-   float u = CLAMP(s, 0.0F, 1.0F);
-   u = u * size - 0.5f;
+   float u = CLAMP(s * size + offset, 0.0F, (float)size);
+   u = u - 0.5f;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
    if (*icoord0 < 0)
@@ -303,13 +317,13 @@ wrap_linear_clamp_to_edge(float s, unsigned size,
 
 
 static void
-wrap_linear_clamp_to_border(float s, unsigned size,
+wrap_linear_clamp_to_border(float s, unsigned size, int offset,
                             int *icoord0, int *icoord1, float *w)
 {
-   const float min = -1.0F / (2.0F * size);
-   const float max = 1.0F - min;
-   float u = CLAMP(s, min, max);
-   u = u * size - 0.5f;
+   const float min = -0.5F;
+   const float max = (float)size + 0.5F;
+   float u = CLAMP(s * size + offset, min, max);
+   u = u - 0.5f;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
    *w = frac(u);
@@ -317,11 +331,15 @@ wrap_linear_clamp_to_border(float s, unsigned size,
 
 
 static void
-wrap_linear_mirror_repeat(float s, unsigned size,
+wrap_linear_mirror_repeat(float s, unsigned size, int offset,
                           int *icoord0, int *icoord1, float *w)
 {
-   const int flr = util_ifloor(s);
-   float u = frac(s);
+   int flr;
+   float u;
+
+   s += (float)offset / size;
+   flr = util_ifloor(s);
+   u = frac(s);
    if (flr & 1)
       u = 1.0F - u;
    u = u * size - 0.5F;
@@ -336,14 +354,12 @@ wrap_linear_mirror_repeat(float s, unsigned size,
 
 
 static void
-wrap_linear_mirror_clamp(float s, unsigned size,
+wrap_linear_mirror_clamp(float s, unsigned size, int offset,
                          int *icoord0, int *icoord1, float *w)
 {
-   float u = fabsf(s);
-   if (u >= 1.0F)
+   float u = fabsf(s * size + offset);
+   if (u >= size)
       u = (float) size;
-   else
-      u *= size;
    u -= 0.5F;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
@@ -352,14 +368,12 @@ wrap_linear_mirror_clamp(float s, unsigned size,
 
 
 static void
-wrap_linear_mirror_clamp_to_edge(float s, unsigned size,
+wrap_linear_mirror_clamp_to_edge(float s, unsigned size, int offset,
                                  int *icoord0, int *icoord1, float *w)
 {
-   float u = fabsf(s);
-   if (u >= 1.0F)
+   float u = fabsf(s * size + offset);
+   if (u >= size)
       u = (float) size;
-   else
-      u *= size;
    u -= 0.5F;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
@@ -372,18 +386,16 @@ wrap_linear_mirror_clamp_to_edge(float s, unsigned size,
 
 
 static void
-wrap_linear_mirror_clamp_to_border(float s, unsigned size,
+wrap_linear_mirror_clamp_to_border(float s, unsigned size, int offset,
                                    int *icoord0, int *icoord1, float *w)
 {
-   const float min = -1.0F / (2.0F * size);
-   const float max = 1.0F - min;
-   float u = fabsf(s);
+   const float min = -0.5F;
+   const float max = size + 0.5F;
+   float u = fabsf(s * size + offset);
    if (u <= min)
-      u = min * size;
+      u = min;
    else if (u >= max)
-      u = max * size;
-   else
-      u *= size;
+      u = max;
    u -= 0.5F;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
@@ -395,10 +407,10 @@ wrap_linear_mirror_clamp_to_border(float s, unsigned size,
  * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords.
  */
 static void
-wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord)
+wrap_nearest_unorm_clamp(float s, unsigned size, int offset, int *icoord)
 {
    int i = util_ifloor(s);
-   *icoord = CLAMP(i, 0, (int) size-1);
+   *icoord = CLAMP(i + offset, 0, (int) size-1);
 }
 
 
@@ -406,9 +418,9 @@ wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord)
  * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords.
  */
 static void
-wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord)
+wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int offset, int *icoord)
 {
-   *icoord = util_ifloor( CLAMP(s, -0.5F, (float) size + 0.5F) );
+   *icoord = util_ifloor( CLAMP(s + offset, -0.5F, (float) size + 0.5F) );
 }
 
 
@@ -416,9 +428,9 @@ wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord)
  * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords.
  */
 static void
-wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord)
+wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
 {
-   *icoord = util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
+   *icoord = util_ifloor( CLAMP(s + offset, 0.5F, (float) size - 0.5F) );
 }
 
 
@@ -426,11 +438,11 @@ wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord)
  * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords.
  */
 static void
-wrap_linear_unorm_clamp(float s, unsigned size,
+wrap_linear_unorm_clamp(float s, unsigned size, int offset,
                         int *icoord0, int *icoord1, float *w)
 {
    /* Not exactly what the spec says, but it matches NVIDIA output */
-   float u = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f);
+   float u = CLAMP(s + offset - 0.5F, 0.0f, (float) size - 1.0f);
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
    *w = frac(u);
@@ -441,10 +453,10 @@ wrap_linear_unorm_clamp(float s, unsigned size,
  * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords.
  */
 static void
-wrap_linear_unorm_clamp_to_border(float s, unsigned size,
+wrap_linear_unorm_clamp_to_border(float s, unsigned size, int offset,
                                   int *icoord0, int *icoord1, float *w)
 {
-   float u = CLAMP(s, -0.5F, (float) size + 0.5F);
+   float u = CLAMP(s + offset, -0.5F, (float) size + 0.5F);
    u -= 0.5F;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
@@ -458,10 +470,10 @@ wrap_linear_unorm_clamp_to_border(float s, unsigned size,
  * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords.
  */
 static void
-wrap_linear_unorm_clamp_to_edge(float s, unsigned size,
+wrap_linear_unorm_clamp_to_edge(float s, unsigned size, int offset,
                                 int *icoord0, int *icoord1, float *w)
 {
-   float u = CLAMP(s, +0.5F, (float) size - 0.5F);
+   float u = CLAMP(s + offset, +0.5F, (float) size - 0.5F);
    u -= 0.5F;
    *icoord0 = util_ifloor(u);
    *icoord1 = *icoord0 + 1;
@@ -474,11 +486,11 @@ wrap_linear_unorm_clamp_to_edge(float s, unsigned size,
 /**
  * Do coordinate to array index conversion.  For array textures.
  */
-static INLINE void
-wrap_array_layer(float coord, unsigned size, int *layer)
+static INLINE int
+coord_to_layer(float coord, unsigned first_layer, unsigned last_layer)
 {
    int c = util_ifloor(coord + 0.5F);
-   *layer = CLAMP(c, 0, (int) size - 1);
+   return CLAMP(c, (int)first_layer, (int)last_layer);
 }
 
 
@@ -757,61 +769,6 @@ get_next_ycoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
 }
 
 
-static INLINE const float *
-get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
-                        union tex_tile_address addr, int x, int y,
-                        float *corner)
-{
-   const struct pipe_resource *texture = sp_sview->base.texture;
-   unsigned level = addr.bits.level;
-   unsigned face = addr.bits.face;
-   int new_x, new_y, max_x;
-
-   max_x = (int) u_minify(texture->width0, level);
-
-   assert(texture->width0 == texture->height0);
-   new_x = x;
-   new_y = y;
-
-   /* change the face */
-   if (x < 0) {
-      /*
-       * Cheat with corners. They are difficult and I believe because we don't get
-       * per-pixel faces we can actually have multiple corner texels per pixel,
-       * which screws things up majorly in any case (as the per spec behavior is
-       * to average the 3 remaining texels, which we might not have).
-       * Hence just make sure that the 2nd coord is clamped, will simply pick the
-       * sample which would have fallen off the x coord, but not y coord.
-       * So the filter weight of the samples will be wrong, but at least this
-       * ensures that only valid texels near the corner are used.
-       */
-      if (y < 0 || y >= max_x) {
-         y = CLAMP(y, 0, max_x - 1);
-      }
-      new_x = get_next_xcoord(face, 0, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 0, max_x -1, x, y);
-      face = get_next_face(face, 0);
-   } else if (x >= max_x) {
-      if (y < 0 || y >= max_x) {
-         y = CLAMP(y, 0, max_x - 1);
-      }
-      new_x = get_next_xcoord(face, 1, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 1, max_x -1, x, y);
-      face = get_next_face(face, 1);
-   } else if (y < 0) {
-      new_x = get_next_xcoord(face, 2, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 2, max_x -1, x, y);
-      face = get_next_face(face, 2);
-   } else if (y >= max_x) {
-      new_x = get_next_xcoord(face, 3, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 3, max_x -1, x, y);
-      face = get_next_face(face, 3);
-   }
-
-   addr.bits.face = face;
-   return get_texel_2d_no_border( sp_sview, addr, new_x, new_y );
-}
-
 /* Gather a quad of adjacent texels within a tile:
  */
 static INLINE void
@@ -948,6 +905,60 @@ get_texel_2d_array(const struct sp_sampler_view *sp_sview,
 }
 
 
+static INLINE const float *
+get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
+                        union tex_tile_address addr, int x, int y,
+                        float *corner, int layer, unsigned face)
+{
+   const struct pipe_resource *texture = sp_sview->base.texture;
+   unsigned level = addr.bits.level;
+   int new_x, new_y, max_x;
+
+   max_x = (int) u_minify(texture->width0, level);
+
+   assert(texture->width0 == texture->height0);
+   new_x = x;
+   new_y = y;
+
+   /* change the face */
+   if (x < 0) {
+      /*
+       * Cheat with corners. They are difficult and I believe because we don't get
+       * per-pixel faces we can actually have multiple corner texels per pixel,
+       * which screws things up majorly in any case (as the per spec behavior is
+       * to average the 3 remaining texels, which we might not have).
+       * Hence just make sure that the 2nd coord is clamped, will simply pick the
+       * sample which would have fallen off the x coord, but not y coord.
+       * So the filter weight of the samples will be wrong, but at least this
+       * ensures that only valid texels near the corner are used.
+       */
+      if (y < 0 || y >= max_x) {
+         y = CLAMP(y, 0, max_x - 1);
+      }
+      new_x = get_next_xcoord(face, 0, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 0, max_x -1, x, y);
+      face = get_next_face(face, 0);
+   } else if (x >= max_x) {
+      if (y < 0 || y >= max_x) {
+         y = CLAMP(y, 0, max_x - 1);
+      }
+      new_x = get_next_xcoord(face, 1, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 1, max_x -1, x, y);
+      face = get_next_face(face, 1);
+   } else if (y < 0) {
+      new_x = get_next_xcoord(face, 2, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 2, max_x -1, x, y);
+      face = get_next_face(face, 2);
+   } else if (y >= max_x) {
+      new_x = get_next_xcoord(face, 3, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 3, max_x -1, x, y);
+      face = get_next_face(face, 3);
+   }
+
+   return get_texel_3d_no_border(sp_sview, addr, new_x, new_y, layer + face);
+}
+
+
 /* Get texel pointer for cube array texture */
 static INLINE const float *
 get_texel_cube_array(const struct sp_sampler_view *sp_sview,
@@ -1008,22 +1019,18 @@ print_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZ
 static INLINE void
 img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview,
                                 struct sp_sampler *sp_samp,
-                                float s,
-                                float t,
-                                float p,
-                                unsigned level,
-                                unsigned face_id,
+                                const struct img_filter_args *args,
                                 float *rgba)
 {
-   unsigned xpot = pot_level_size(sp_sview->xpot, level);
-   unsigned ypot = pot_level_size(sp_sview->ypot, level);
+   unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
+   unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
    int xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
    int ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
    union tex_tile_address addr;
    int c;
 
-   float u = s * xpot - 0.5F;
-   float v = t * ypot - 0.5F;
+   float u = (args->s * xpot - 0.5F) + args->offset[0];
+   float v = (args->t * ypot - 0.5F) + args->offset[1];
 
    int uflr = util_ifloor(u);
    int vflr = util_ifloor(v);
@@ -1037,7 +1044,7 @@ img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview,
    const float *tx[4];
       
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    /* Can we fetch all four at once:
     */
@@ -1066,21 +1073,17 @@ img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview,
 static INLINE void
 img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview,
                                  struct sp_sampler *sp_samp,
-                                 float s,
-                                 float t,
-                                 float p,
-                                 unsigned level,
-                                 unsigned face_id,
+                                 const struct img_filter_args *args,
                                  float rgba[TGSI_QUAD_SIZE])
 {
-   unsigned xpot = pot_level_size(sp_sview->xpot, level);
-   unsigned ypot = pot_level_size(sp_sview->ypot, level);
+   unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
+   unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
    const float *out;
    union tex_tile_address addr;
    int c;
 
-   float u = s * xpot;
-   float v = t * ypot;
+   float u = args->s * xpot + args->offset[0];
+   float v = args->t * ypot + args->offset[1];
 
    int uflr = util_ifloor(u);
    int vflr = util_ifloor(v);
@@ -1089,7 +1092,7 @@ img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview,
    int y0 = vflr & (ypot - 1);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    out = get_texel_2d_no_border(sp_sview, addr, x0, y0);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1104,26 +1107,22 @@ img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview,
 static INLINE void
 img_filter_2d_nearest_clamp_POT(struct sp_sampler_view *sp_sview,
                                 struct sp_sampler *sp_samp,
-                                float s,
-                                float t,
-                                float p,
-                                unsigned level,
-                                unsigned face_id,
+                                const struct img_filter_args *args,
                                 float rgba[TGSI_QUAD_SIZE])
 {
-   unsigned xpot = pot_level_size(sp_sview->xpot, level);
-   unsigned ypot = pot_level_size(sp_sview->ypot, level);
+   unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
+   unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
    union tex_tile_address addr;
    int c;
 
-   float u = s * xpot;
-   float v = t * ypot;
+   float u = args->s * xpot + args->offset[0];
+   float v = args->t * ypot + args->offset[1];
 
    int x0, y0;
    const float *out;
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    x0 = util_ifloor(u);
    if (x0 < 0) 
@@ -1150,11 +1149,7 @@ img_filter_2d_nearest_clamp_POT(struct sp_sampler_view *sp_sview,
 static void
 img_filter_1d_nearest(struct sp_sampler_view *sp_sview,
                       struct sp_sampler *sp_samp,
-                      float s,
-                      float t,
-                      float p,
-                      unsigned level,
-                      unsigned face_id,
+                      const struct img_filter_args *args,
                       float rgba[TGSI_QUAD_SIZE])
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1164,14 +1159,14 @@ img_filter_1d_nearest(struct sp_sampler_view *sp_sview,
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
+   width = u_minify(texture->width0, args->level);
 
    assert(width > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->nearest_texcoord_s(s, width, &x);
+   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
 
    out = get_texel_2d(sp_sview, sp_samp, addr, x, 0);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1186,11 +1181,7 @@ img_filter_1d_nearest(struct sp_sampler_view *sp_sview,
 static void
 img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
                             struct sp_sampler *sp_samp,
-                            float s,
-                            float t,
-                            float p,
-                            unsigned level,
-                            unsigned face_id,
+                            const struct img_filter_args *args,
                             float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1200,15 +1191,16 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
+   width = u_minify(texture->width0, args->level);
 
    assert(width > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->nearest_texcoord_s(s, width, &x);
-   wrap_array_layer(t, texture->array_size, &layer);
+   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
+   layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    out = get_texel_1d_array(sp_sview, sp_samp, addr, x, layer);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1223,11 +1215,7 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
 static void
 img_filter_2d_nearest(struct sp_sampler_view *sp_sview,
                       struct sp_sampler *sp_samp,
-                      float s,
-                      float t,
-                      float p,
-                      unsigned level,
-                      unsigned face_id,
+                      const struct img_filter_args *args,
                       float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1237,17 +1225,17 @@ img_filter_2d_nearest(struct sp_sampler_view *sp_sview,
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
  
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->nearest_texcoord_s(s, width, &x);
-   sp_samp->nearest_texcoord_t(t, height, &y);
+   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
+   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
 
    out = get_texel_2d(sp_sview, sp_samp, addr, x, y);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1262,11 +1250,7 @@ img_filter_2d_nearest(struct sp_sampler_view *sp_sview,
 static void
 img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
                             struct sp_sampler *sp_samp,
-                            float s,
-                            float t,
-                            float p,
-                            unsigned level,
-                            unsigned face_id,
+                            const struct img_filter_args *args,
                             float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1276,18 +1260,19 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
  
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->nearest_texcoord_s(s, width, &x);
-   sp_samp->nearest_texcoord_t(t, height, &y);
-   wrap_array_layer(p, texture->array_size, &layer);
+   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
+   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
+   layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    out = get_texel_2d_array(sp_sview, sp_samp, addr, x, y, layer);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1299,54 +1284,43 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
 }
 
 
-static INLINE union tex_tile_address
-face(union tex_tile_address addr, unsigned face )
-{
-   addr.bits.face = face;
-   return addr;
-}
-
-
 static void
 img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
                         struct sp_sampler *sp_samp,
-                        float s,
-                        float t,
-                        float p,
-                        unsigned level,
-                        unsigned face_id,
+                        const struct img_filter_args *args,
                         float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
    int width, height;
-   int x, y;
+   int x, y, layerface;
    union tex_tile_address addr;
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
  
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    /*
     * If NEAREST filtering is done within a miplevel, always apply wrap
     * mode CLAMP_TO_EDGE.
     */
    if (sp_samp->base.seamless_cube_map) {
-      wrap_nearest_clamp_to_edge(s, width, &x);
-      wrap_nearest_clamp_to_edge(t, height, &y);
+      wrap_nearest_clamp_to_edge(args->s, width, args->offset[0], &x);
+      wrap_nearest_clamp_to_edge(args->t, height, args->offset[1], &y);
    } else {
       /* Would probably make sense to ignore mode and just do edge clamp */
-      sp_samp->nearest_texcoord_s(s, width, &x);
-      sp_samp->nearest_texcoord_t(t, height, &y);
+      sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
+      sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
    }
 
-   out = get_texel_2d(sp_sview, sp_samp, face(addr, face_id), x, y);
+   layerface = args->face_id + sp_sview->base.u.tex.first_layer;
+   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
       rgba[TGSI_NUM_CHANNELS*c] = out[c];
 
@@ -1358,34 +1332,32 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
 static void
 img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
                               struct sp_sampler *sp_samp,
-                              float s,
-                              float t,
-                              float p,
-                              unsigned level,
-                              unsigned face_id,
+                              const struct img_filter_args *args,
                               float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
    int width, height;
-   int x, y, layer;
+   int x, y, layerface;
    union tex_tile_address addr;
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
  
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->nearest_texcoord_s(s, width, &x);
-   sp_samp->nearest_texcoord_t(t, height, &y);
-   wrap_array_layer(p, texture->array_size, &layer);
+   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
+   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
+   layerface = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
+                              sp_sview->base.u.tex.first_layer,
+                              sp_sview->base.u.tex.last_layer - 5) + args->face_id;
 
-   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layer * 6 + face_id);
+   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
       rgba[TGSI_NUM_CHANNELS*c] = out[c];
 
@@ -1397,11 +1369,7 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
 static void
 img_filter_3d_nearest(struct sp_sampler_view *sp_sview,
                       struct sp_sampler *sp_samp,
-                      float s,
-                      float t,
-                      float p,
-                      unsigned level,
-                      unsigned face_id,
+                      const struct img_filter_args *args,
                       float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1411,20 +1379,20 @@ img_filter_3d_nearest(struct sp_sampler_view *sp_sview,
    const float *out;
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
-   depth = u_minify(texture->depth0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
+   depth = u_minify(texture->depth0, args->level);
 
    assert(width > 0);
    assert(height > 0);
    assert(depth > 0);
 
-   sp_samp->nearest_texcoord_s(s, width,  &x);
-   sp_samp->nearest_texcoord_t(t, height, &y);
-   sp_samp->nearest_texcoord_p(p, depth,  &z);
+   sp_samp->nearest_texcoord_s(args->s, width,  args->offset[0], &x);
+   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
+   sp_samp->nearest_texcoord_p(args->p, depth,  args->offset[2], &z);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    out = get_texel_3d(sp_sview, sp_samp, addr, x, y, z);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1435,11 +1403,7 @@ img_filter_3d_nearest(struct sp_sampler_view *sp_sview,
 static void
 img_filter_1d_linear(struct sp_sampler_view *sp_sview,
                      struct sp_sampler *sp_samp,
-                     float s,
-                     float t,
-                     float p,
-                     unsigned level,
-                     unsigned face_id,
+                     const struct img_filter_args *args,
                      float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1450,14 +1414,14 @@ img_filter_1d_linear(struct sp_sampler_view *sp_sview,
    const float *tx0, *tx1;
    int c;
 
-   width = u_minify(texture->width0, level);
+   width = u_minify(texture->width0, args->level);
 
    assert(width > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
+   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
 
    tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, 0);
    tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, 0);
@@ -1471,11 +1435,7 @@ img_filter_1d_linear(struct sp_sampler_view *sp_sview,
 static void
 img_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
                            struct sp_sampler *sp_samp,
-                           float s,
-                           float t,
-                           float p,
-                           unsigned level,
-                           unsigned face_id,
+                           const struct img_filter_args *args,
                            float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1486,15 +1446,16 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
    const float *tx0, *tx1;
    int c;
 
-   width = u_minify(texture->width0, level);
+   width = u_minify(texture->width0, args->level);
 
    assert(width > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
-   wrap_array_layer(t, texture->array_size, &layer);
+   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
+   layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    tx0 = get_texel_1d_array(sp_sview, sp_samp, addr, x0, layer);
    tx1 = get_texel_1d_array(sp_sview, sp_samp, addr, x1, layer);
@@ -1504,15 +1465,77 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
       rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
 }
 
+/*
+ * Retrieve the gathered value, need to convert to the
+ * TGSI expected interface, and take component select
+ * and swizzling into account.
+ */
+static float
+get_gather_value(const struct sp_sampler_view *sp_sview,
+                 int chan_in, int comp_sel,
+                 const float *tx[4])
+{
+   int chan;
+   unsigned swizzle;
+
+   /*
+    * softpipe samples in a different order
+    * to TGSI expects, so we need to swizzle,
+    * the samples into the correct slots.
+    */
+   switch (chan_in) {
+   case 0:
+      chan = 2;
+      break;
+   case 1:
+      chan = 3;
+      break;
+   case 2:
+      chan = 1;
+      break;
+   case 3:
+      chan = 0;
+      break;
+   default:
+      assert(0);
+      return 0.0;
+   }
+
+   /* pick which component to use for the swizzle */
+   switch (comp_sel) {
+   case 0:
+      swizzle = sp_sview->base.swizzle_r;
+      break;
+   case 1:
+      swizzle = sp_sview->base.swizzle_g;
+      break;
+   case 2:
+      swizzle = sp_sview->base.swizzle_b;
+      break;
+   case 3:
+      swizzle = sp_sview->base.swizzle_a;
+      break;
+   default:
+      assert(0);
+      return 0.0;
+   }
+
+   /* get correct result using the channel and swizzle */
+   switch (swizzle) {
+   case PIPE_SWIZZLE_ZERO:
+      return 0.0;
+   case PIPE_SWIZZLE_ONE:
+      return 1.0;
+   default:
+      return tx[chan][swizzle];
+   }
+}
+
 
 static void
 img_filter_2d_linear(struct sp_sampler_view *sp_sview,
                      struct sp_sampler *sp_samp,
-                     float s,
-                     float t,
-                     float p,
-                     unsigned level,
-                     unsigned face_id,
+                     const struct img_filter_args *args,
                      float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1520,42 +1543,45 @@ img_filter_2d_linear(struct sp_sampler_view *sp_sview,
    int x0, y0, x1, y1;
    float xw, yw; /* weights */
    union tex_tile_address addr;
-   const float *tx0, *tx1, *tx2, *tx3;
+   const float *tx[4];
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
-   sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
+   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
+   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
 
-   tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, y0);
-   tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, y0);
-   tx2 = get_texel_2d(sp_sview, sp_samp, addr, x0, y1);
-   tx3 = get_texel_2d(sp_sview, sp_samp, addr, x1, y1);
+   tx[0] = get_texel_2d(sp_sview, sp_samp, addr, x0, y0);
+   tx[1] = get_texel_2d(sp_sview, sp_samp, addr, x1, y0);
+   tx[2] = get_texel_2d(sp_sview, sp_samp, addr, x0, y1);
+   tx[3] = get_texel_2d(sp_sview, sp_samp, addr, x1, y1);
 
-   /* interpolate R, G, B, A */
-   for (c = 0; c < TGSI_QUAD_SIZE; c++)
-      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
-                                          tx0[c], tx1[c],
-                                          tx2[c], tx3[c]);
+   if (args->gather_only) {
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
+                                                      args->gather_comp,
+                                                      tx);
+   } else {
+      /* interpolate R, G, B, A */
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
+                                             tx[0][c], tx[1][c],
+                                             tx[2][c], tx[3][c]);
+   }
 }
 
 
 static void
 img_filter_2d_array_linear(struct sp_sampler_view *sp_sview,
                            struct sp_sampler *sp_samp,
-                           float s,
-                           float t,
-                           float p,
-                           unsigned level,
-                           unsigned face_id,
+                           const struct img_filter_args *args,
                            float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1563,63 +1589,67 @@ img_filter_2d_array_linear(struct sp_sampler_view *sp_sview,
    int x0, y0, x1, y1, layer;
    float xw, yw; /* weights */
    union tex_tile_address addr;
-   const float *tx0, *tx1, *tx2, *tx3;
+   const float *tx[4];
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
-
-   sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
-   sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
-   wrap_array_layer(p, texture->array_size, &layer);
-
-   tx0 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer);
-   tx1 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer);
-   tx2 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y1, layer);
-   tx3 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y1, layer);
-
-   /* interpolate R, G, B, A */
-   for (c = 0; c < TGSI_QUAD_SIZE; c++)
-      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
-                                          tx0[c], tx1[c],
-                                          tx2[c], tx3[c]);
+   addr.bits.level = args->level;
+
+   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
+   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
+   layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
+
+   tx[0] = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer);
+   tx[1] = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer);
+   tx[2] = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y1, layer);
+   tx[3] = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y1, layer);
+
+   if (args->gather_only) {
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
+                                                      args->gather_comp,
+                                                      tx);
+   } else {
+      /* interpolate R, G, B, A */
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
+                                             tx[0][c], tx[1][c],
+                                             tx[2][c], tx[3][c]);
+   }
 }
 
 
 static void
 img_filter_cube_linear(struct sp_sampler_view *sp_sview,
                        struct sp_sampler *sp_samp,
-                       float s,
-                       float t,
-                       float p,
-                       unsigned level,
-                       unsigned face_id,
+                       const struct img_filter_args *args,
                        float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
    int width, height;
-   int x0, y0, x1, y1;
+   int x0, y0, x1, y1, layer;
    float xw, yw; /* weights */
-   union tex_tile_address addr, addrj;
-   const float *tx0, *tx1, *tx2, *tx3;
+   union tex_tile_address addr;
+   const float *tx[4];
    float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
          corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    /*
     * For seamless if LINEAR filtering is done within a miplevel,
@@ -1627,43 +1657,47 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview,
     */
    if (sp_samp->base.seamless_cube_map) {
       /* Note this is a bit overkill, actual clamping is not required */
-      wrap_linear_clamp_to_border(s, width, &x0, &x1, &xw);
-      wrap_linear_clamp_to_border(t, height, &y0, &y1, &yw);
+      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
+      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
    } else {
       /* Would probably make sense to ignore mode and just do edge clamp */
-      sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
-      sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
+      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
+      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
    }
 
-   addrj = face(addr, face_id);
+   layer = sp_sview->base.u.tex.first_layer;
 
    if (sp_samp->base.seamless_cube_map) {
-      tx0 = get_texel_cube_seamless(sp_sview, addrj, x0, y0, corner0);
-      tx1 = get_texel_cube_seamless(sp_sview, addrj, x1, y0, corner1);
-      tx2 = get_texel_cube_seamless(sp_sview, addrj, x0, y1, corner2);
-      tx3 = get_texel_cube_seamless(sp_sview, addrj, x1, y1, corner3);
+      tx[0] = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id);
+      tx[1] = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id);
+      tx[2] = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id);
+      tx[3] = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id);
    } else {
-      tx0 = get_texel_2d(sp_sview, sp_samp, addrj, x0, y0);
-      tx1 = get_texel_2d(sp_sview, sp_samp, addrj, x1, y0);
-      tx2 = get_texel_2d(sp_sview, sp_samp, addrj, x0, y1);
-      tx3 = get_texel_2d(sp_sview, sp_samp, addrj, x1, y1);
+      tx[0] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id);
+      tx[1] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id);
+      tx[2] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id);
+      tx[3] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id);
+   }
+
+   if (args->gather_only) {
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
+                                                      args->gather_comp,
+                                                      tx);
+   } else {
+      /* interpolate R, G, B, A */
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
+                                             tx[0][c], tx[1][c],
+                                             tx[2][c], tx[3][c]);
    }
-   /* interpolate R, G, B, A */
-   for (c = 0; c < TGSI_QUAD_SIZE; c++)
-      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
-                                          tx0[c], tx1[c],
-                                          tx2[c], tx3[c]);
 }
 
 
 static void
 img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
                              struct sp_sampler *sp_samp,
-                             float s,
-                             float t,
-                             float p,
-                             unsigned level,
-                             unsigned face_id,
+                             const struct img_filter_args *args,
                              float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1671,42 +1705,68 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
    int x0, y0, x1, y1, layer;
    float xw, yw; /* weights */
    union tex_tile_address addr;
-   const float *tx0, *tx1, *tx2, *tx3;
+   const float *tx[4];
+   float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
+         corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
 
    assert(width > 0);
    assert(height > 0);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
-   sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
-   sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
-   wrap_array_layer(p, texture->array_size, &layer);
+   /*
+    * For seamless if LINEAR filtering is done within a miplevel,
+    * always apply wrap mode CLAMP_TO_BORDER.
+    */
+   if (sp_samp->base.seamless_cube_map) {
+      /* Note this is a bit overkill, actual clamping is not required */
+      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
+      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
+   } else {
+      /* Would probably make sense to ignore mode and just do edge clamp */
+      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
+      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
+   }
 
-   tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer * 6 + face_id);
-   tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer * 6 + face_id);
-   tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer * 6 + face_id);
-   tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer * 6 + face_id);
+   layer = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer - 5);
 
-   /* interpolate R, G, B, A */
-   for (c = 0; c < TGSI_QUAD_SIZE; c++)
-      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
-                                          tx0[c], tx1[c],
-                                          tx2[c], tx3[c]);
+   if (sp_samp->base.seamless_cube_map) {
+      tx[0] = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id);
+      tx[1] = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id);
+      tx[2] = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id);
+      tx[3] = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id);
+   } else {
+      tx[0] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id);
+      tx[1] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id);
+      tx[2] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id);
+      tx[3] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id);
+   }
+
+   if (args->gather_only) {
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
+                                                      args->gather_comp,
+                                                      tx);
+   } else {
+      /* interpolate R, G, B, A */
+      for (c = 0; c < TGSI_QUAD_SIZE; c++)
+         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
+                                             tx[0][c], tx[1][c],
+                                             tx[2][c], tx[3][c]);
+   }
 }
 
 static void
 img_filter_3d_linear(struct sp_sampler_view *sp_sview,
                      struct sp_sampler *sp_samp,
-                     float s,
-                     float t,
-                     float p,
-                     unsigned level,
-                     unsigned face_id,
+                     const struct img_filter_args *args,
                      float *rgba)
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -1717,21 +1777,20 @@ img_filter_3d_linear(struct sp_sampler_view *sp_sview,
    const float *tx00, *tx01, *tx02, *tx03, *tx10, *tx11, *tx12, *tx13;
    int c;
 
-   width = u_minify(texture->width0, level);
-   height = u_minify(texture->height0, level);
-   depth = u_minify(texture->depth0, level);
+   width = u_minify(texture->width0, args->level);
+   height = u_minify(texture->height0, args->level);
+   depth = u_minify(texture->depth0, args->level);
 
    addr.value = 0;
-   addr.bits.level = level;
+   addr.bits.level = args->level;
 
    assert(width > 0);
    assert(height > 0);
    assert(depth > 0);
 
-   sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
-   sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
-   sp_samp->linear_texcoord_p(p, depth,  &z0, &z1, &zw);
-
+   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
+   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
+   sp_samp->linear_texcoord_p(args->p, depth,  args->offset[2], &z0, &z1, &zw);
 
    tx00 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z0);
    tx01 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z0);
@@ -1837,6 +1896,7 @@ compute_lambda_lod(struct sp_sampler_view *sp_sview,
       }
       break;
    case tgsi_sampler_lod_zero:
+   case tgsi_sampler_gather:
       /* this is all static state in the sampler really need clamp here? */
       lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lod_bias, min_lod, max_lod);
       break;
@@ -1846,6 +1906,12 @@ compute_lambda_lod(struct sp_sampler_view *sp_sview,
    }
 }
 
+static INLINE unsigned
+get_gather_component(const float lod_in[TGSI_QUAD_SIZE])
+{
+   /* gather component is stored in lod_in slot as unsigned */
+   return (*(unsigned int *)lod_in) & 0x3;
+}
 
 static void
 mip_filter_linear(struct sp_sampler_view *sp_sview,
@@ -1857,36 +1923,45 @@ mip_filter_linear(struct sp_sampler_view *sp_sview,
                   const float p[TGSI_QUAD_SIZE],
                   const float c0[TGSI_QUAD_SIZE],
                   const float lod_in[TGSI_QUAD_SIZE],
-                  enum tgsi_sampler_control control,
+                  const struct filter_args *filt_args,
                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    const struct pipe_sampler_view *psview = &sp_sview->base;
    int j;
    float lod[TGSI_QUAD_SIZE];
+   struct img_filter_args args;
 
-   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod);
+   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
+
+   args.offset = filt_args->offset;
+   args.gather_only = filt_args->control == tgsi_sampler_gather;
+   args.gather_comp = get_gather_component(lod_in);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       int level0 = psview->u.tex.first_level + (int)lod[j];
 
-      if (lod[j] < 0.0)
-         mag_filter(sp_sview, sp_samp, s[j], t[j], p[j],
-                    psview->u.tex.first_level,
-                    sp_sview->faces[j], &rgba[0][j]);
-
-      else if (level0 >= (int) psview->u.tex.last_level)
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j], psview->u.tex.last_level,
-                    sp_sview->faces[j], &rgba[0][j]);
+      args.s = s[j];
+      args.t = t[j];
+      args.p = p[j];
+      args.face_id = sp_sview->faces[j];
 
+      if (lod[j] < 0.0) {
+         args.level = psview->u.tex.first_level;
+         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
+      }
+      else if (level0 >= (int) psview->u.tex.last_level) {
+         args.level = psview->u.tex.last_level;
+         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
+      }
       else {
          float levelBlend = frac(lod[j]);
          float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
          int c;
 
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j], level0,
-                    sp_sview->faces[j], &rgbax[0][0]);
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j], level0+1,
-                    sp_sview->faces[j], &rgbax[0][1]);
+         args.level = level0;
+         min_filter(sp_sview, sp_samp, &args, &rgbax[0][0]);
+         args.level = level0+1;
+         min_filter(sp_sview, sp_samp, &args, &rgbax[0][1]);
 
          for (c = 0; c < 4; c++) {
             rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
@@ -1915,25 +1990,33 @@ mip_filter_nearest(struct sp_sampler_view *sp_sview,
                    const float p[TGSI_QUAD_SIZE],
                    const float c0[TGSI_QUAD_SIZE],
                    const float lod_in[TGSI_QUAD_SIZE],
-                   enum tgsi_sampler_control control,
+                   const struct filter_args *filt_args,
                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    const struct pipe_sampler_view *psview = &sp_sview->base;
    float lod[TGSI_QUAD_SIZE];
    int j;
+   struct img_filter_args args;
+
+   args.offset = filt_args->offset;
+   args.gather_only = filt_args->control == tgsi_sampler_gather;
+   args.gather_comp = get_gather_component(lod_in);
 
-   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod);
+   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
-      if (lod[j] < 0.0)
-         mag_filter(sp_sview, sp_samp, s[j], t[j], p[j],
-                    psview->u.tex.first_level,
-                    sp_sview->faces[j], &rgba[0][j]);
-      else {
+      args.s = s[j];
+      args.t = t[j];
+      args.p = p[j];
+      args.face_id = sp_sview->faces[j];
+
+      if (lod[j] < 0.0) {
+         args.level = psview->u.tex.first_level;
+         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
+      } else {
          int level = psview->u.tex.first_level + (int)(lod[j] + 0.5F);
-         level = MIN2(level, (int)psview->u.tex.last_level);
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j],
-                    level, sp_sview->faces[j], &rgba[0][j]);
+         args.level = MIN2(level, (int)psview->u.tex.last_level);
+         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
       }
    }
 
@@ -1953,24 +2036,29 @@ mip_filter_none(struct sp_sampler_view *sp_sview,
                 const float p[TGSI_QUAD_SIZE],
                 const float c0[TGSI_QUAD_SIZE],
                 const float lod_in[TGSI_QUAD_SIZE],
-                enum tgsi_sampler_control control,
+                const struct filter_args *filt_args,
                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    float lod[TGSI_QUAD_SIZE];
    int j;
+   struct img_filter_args args;
+
+   args.level = sp_sview->base.u.tex.first_level;
+   args.offset = filt_args->offset;
+   args.gather_only = filt_args->control == tgsi_sampler_gather;
 
-   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod);
+   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
-      if (lod[j] < 0.0) { 
-         mag_filter(sp_sview, sp_samp, s[j], t[j], p[j],
-                    sp_sview->base.u.tex.first_level,
-                    sp_sview->faces[j], &rgba[0][j]);
+      args.s = s[j];
+      args.t = t[j];
+      args.p = p[j];
+      args.face_id = sp_sview->faces[j];
+      if (lod[j] < 0.0) {
+         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
       }
       else {
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j],
-                    sp_sview->base.u.tex.first_level,
-                    sp_sview->faces[j], &rgba[0][j]);
+         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
       }
    }
 }
@@ -1986,15 +2074,21 @@ mip_filter_none_no_filter_select(struct sp_sampler_view *sp_sview,
                                  const float p[TGSI_QUAD_SIZE],
                                  const float c0[TGSI_QUAD_SIZE],
                                  const float lod_in[TGSI_QUAD_SIZE],
-                                 enum tgsi_sampler_control control,
+                                 const struct filter_args *filt_args,
                                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    int j;
-
-   for (j = 0; j < TGSI_QUAD_SIZE; j++)
-      mag_filter(sp_sview, sp_samp, s[j], t[j], p[j],
-                 sp_sview->base.u.tex.first_level,
-                 sp_sview->faces[j], &rgba[0][j]);
+   struct img_filter_args args;
+   args.level = sp_sview->base.u.tex.first_level;
+   args.offset = filt_args->offset;
+   args.gather_only = filt_args->control == tgsi_sampler_gather;
+   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+      args.s = s[j];
+      args.t = t[j];
+      args.p = p[j];
+      args.face_id = sp_sview->faces[j];
+      mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
+   }
 }
 
 
@@ -2050,7 +2144,7 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview,
    float scaling = 1.0f / (1 << level0);
    int width = u_minify(texture->width0, level0);
    int height = u_minify(texture->height0, level0);
-
+   struct img_filter_args args;
    float ux = dudx * scaling;
    float vx = dvdx * scaling;
    float uy = dudy * scaling;
@@ -2100,7 +2194,8 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview,
     * full, then the pixel values are read from the image.
     */
    ddq = 2 * A;
-   
+
+   args.level = level;
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
        * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
@@ -2117,6 +2212,8 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview,
       float num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
       buffer_next = 0;
       den = 0;
+      args.face_id = sp_sview->faces[j];
+
       U = u0 - tex_u;
       for (v = v0; v <= v1; ++v) {
          float V = v - tex_v;
@@ -2148,8 +2245,10 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview,
                    * accelerated img_filter_2d_nearest_XXX functions.
                    */
                   for (jj = 0; jj < buffer_next; jj++) {
-                     min_filter(sp_sview, sp_samp, s_buffer[jj], t_buffer[jj], p[jj],
-                                level, sp_sview->faces[j], &rgba_temp[0][jj]);
+                     args.s = s_buffer[jj];
+                     args.t = t_buffer[jj];
+                     args.p = p[jj];
+                     min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]);
                      num[0] += weight_buffer[jj] * rgba_temp[0][jj];
                      num[1] += weight_buffer[jj] * rgba_temp[1][jj];
                      num[2] += weight_buffer[jj] * rgba_temp[2][jj];
@@ -2176,8 +2275,10 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview,
           * accelerated img_filter_2d_nearest_XXX functions.
           */
          for (jj = 0; jj < buffer_next; jj++) {
-            min_filter(sp_sview, sp_samp, s_buffer[jj], t_buffer[jj], p[jj],
-                       level, sp_sview->faces[j], &rgba_temp[0][jj]);
+            args.s = s_buffer[jj];
+            args.t = t_buffer[jj];
+            args.p = p[jj];
+            min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]);
             num[0] += weight_buffer[jj] * rgba_temp[0][jj];
             num[1] += weight_buffer[jj] * rgba_temp[1][jj];
             num[2] += weight_buffer[jj] * rgba_temp[2][jj];
@@ -2196,8 +2297,10 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview,
          rgba[2]=0;
          rgba[3]=0;*/
          /* not enough pixels in resampling, resort to direct interpolation */
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j], level,
-                    sp_sview->faces[j], &rgba_temp[0][j]);
+         args.s = s[j];
+         args.t = t[j];
+         args.p = p[j];
+         min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][j]);
          den = 1;
          num[0] = rgba_temp[0][j];
          num[1] = rgba_temp[1][j];
@@ -2226,7 +2329,7 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview,
                         const float p[TGSI_QUAD_SIZE],
                         const float c0[TGSI_QUAD_SIZE],
                         const float lod_in[TGSI_QUAD_SIZE],
-                        enum tgsi_sampler_control control,
+                        const struct filter_args *filt_args,
                         float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
@@ -2241,11 +2344,12 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview,
    float dudy = (s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]) * s_to_u;
    float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
    float dvdy = (t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]) * t_to_v;
-   
-   if (control == tgsi_sampler_lod_bias ||
-       control == tgsi_sampler_lod_none ||
+   struct img_filter_args args;
+
+   if (filt_args->control == tgsi_sampler_lod_bias ||
+       filt_args->control == tgsi_sampler_lod_none ||
        /* XXX FIXME */
-       control == tgsi_sampler_derivs_explicit) {
+       filt_args->control == tgsi_sampler_derivs_explicit) {
       /* note: instead of working with Px and Py, we will use the 
        * squared length instead, to avoid sqrt.
        */
@@ -2282,12 +2386,12 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview,
        * this since 0.5*log(x) = log(sqrt(x))
        */
       lambda = 0.5F * util_fast_log2(Pmin2) + sp_samp->base.lod_bias;
-      compute_lod(&sp_samp->base, control, lambda, lod_in, lod);
+      compute_lod(&sp_samp->base, filt_args->control, lambda, lod_in, lod);
    }
    else {
-      assert(control == tgsi_sampler_lod_explicit ||
-             control == tgsi_sampler_lod_zero);
-      compute_lod(&sp_samp->base, control, sp_samp->base.lod_bias, lod_in, lod);
+      assert(filt_args->control == tgsi_sampler_lod_explicit ||
+             filt_args->control == tgsi_sampler_lod_zero);
+      compute_lod(&sp_samp->base, filt_args->control, sp_samp->base.lod_bias, lod_in, lod);
    }
    
    /* XXX: Take into account all lod values.
@@ -2300,9 +2404,14 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview,
     */
    if (level0 >= (int) psview->u.tex.last_level) {
       int j;
-      for (j = 0; j < TGSI_QUAD_SIZE; j++)
-         min_filter(sp_sview, sp_samp, s[j], t[j], p[j], psview->u.tex.last_level,
-                    sp_sview->faces[j], &rgba[0][j]);
+      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+         args.s = s[j];
+         args.t = t[j];
+         args.p = p[j];
+         args.level = psview->u.tex.last_level;
+         args.face_id = sp_sview->faces[j];
+         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
+      }
    }
    else {
       /* don't bother interpolating between multiple LODs; it doesn't
@@ -2334,29 +2443,33 @@ mip_filter_linear_2d_linear_repeat_POT(
    const float p[TGSI_QUAD_SIZE],
    const float c0[TGSI_QUAD_SIZE],
    const float lod_in[TGSI_QUAD_SIZE],
-   enum tgsi_sampler_control control,
+   const struct filter_args *filt_args,
    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    const struct pipe_sampler_view *psview = &sp_sview->base;
    int j;
    float lod[TGSI_QUAD_SIZE];
 
-   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod);
+   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       int level0 = psview->u.tex.first_level + (int)lod[j];
-
+      struct img_filter_args args;
       /* Catches both negative and large values of level0:
        */
+      args.s = s[j];
+      args.t = t[j];
+      args.p = p[j];
+      args.face_id = sp_sview->faces[j];
+      args.offset = filt_args->offset;
+      args.gather_only = filt_args->control == tgsi_sampler_gather;
       if ((unsigned)level0 >= psview->u.tex.last_level) {
          if (level0 < 0)
-            img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j],
-                                            psview->u.tex.first_level,
-                                            sp_sview->faces[j], &rgba[0][j]);
+            args.level = psview->u.tex.first_level;
          else
-            img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j],
-                                            psview->u.tex.last_level,
-                                            sp_sview->faces[j], &rgba[0][j]);
+            args.level = psview->u.tex.last_level;
+         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args,
+                                         &rgba[0][j]);
 
       }
       else {
@@ -2364,10 +2477,10 @@ mip_filter_linear_2d_linear_repeat_POT(
          float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
          int c;
 
-         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j], level0,
-                                         sp_sview->faces[j], &rgbax[0][0]);
-         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j], level0+1,
-                                         sp_sview->faces[j], &rgbax[0][1]);
+         args.level = level0;
+         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][0]);
+         args.level = level0+1;
+         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][1]);
 
          for (c = 0; c < TGSI_NUM_CHANNELS; c++)
             rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
@@ -2395,11 +2508,12 @@ sample_compare(struct sp_sampler_view *sp_sview,
                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    const struct pipe_sampler_state *sampler = &sp_samp->base;
-   int j;
-   int k[4];
+   int j, v;
+   int k[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
    float pc[4];
    const struct util_format_description *format_desc;
    unsigned chan_type;
+   bool is_gather = (control == tgsi_sampler_gather);
 
    /**
     * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
@@ -2408,13 +2522,13 @@ sample_compare(struct sp_sampler_view *sp_sview,
     * RGBA channels.  We look at the red channel here.
     */
 
-   if (sp_sview->base.texture->target == PIPE_TEXTURE_2D_ARRAY ||
-       sp_sview->base.texture->target == PIPE_TEXTURE_CUBE) {
+   if (sp_sview->base.target == PIPE_TEXTURE_2D_ARRAY ||
+       sp_sview->base.target == PIPE_TEXTURE_CUBE) {
       pc[0] = c0[0];
       pc[1] = c0[1];
       pc[2] = c0[2];
       pc[3] = c0[3];
-   } else if (sp_sview->base.texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
+   } else if (sp_sview->base.target == PIPE_TEXTURE_CUBE_ARRAY) {
       pc[0] = c1[0];
       pc[1] = c1[1];
       pc[2] = c1[2];
@@ -2443,65 +2557,74 @@ sample_compare(struct sp_sampler_view *sp_sview,
       pc[3] = CLAMP(pc[3], 0.0F, 1.0F);
    }
 
-   /* compare four texcoords vs. four texture samples */
-   switch (sampler->compare_func) {
-   case PIPE_FUNC_LESS:
-      k[0] = pc[0] < rgba[0][0];
-      k[1] = pc[1] < rgba[0][1];
-      k[2] = pc[2] < rgba[0][2];
-      k[3] = pc[3] < rgba[0][3];
-      break;
-   case PIPE_FUNC_LEQUAL:
-      k[0] = pc[0] <= rgba[0][0];
-      k[1] = pc[1] <= rgba[0][1];
-      k[2] = pc[2] <= rgba[0][2];
-      k[3] = pc[3] <= rgba[0][3];
-      break;
-   case PIPE_FUNC_GREATER:
-      k[0] = pc[0] > rgba[0][0];
-      k[1] = pc[1] > rgba[0][1];
-      k[2] = pc[2] > rgba[0][2];
-      k[3] = pc[3] > rgba[0][3];
-      break;
-   case PIPE_FUNC_GEQUAL:
-      k[0] = pc[0] >= rgba[0][0];
-      k[1] = pc[1] >= rgba[0][1];
-      k[2] = pc[2] >= rgba[0][2];
-      k[3] = pc[3] >= rgba[0][3];
-      break;
-   case PIPE_FUNC_EQUAL:
-      k[0] = pc[0] == rgba[0][0];
-      k[1] = pc[1] == rgba[0][1];
-      k[2] = pc[2] == rgba[0][2];
-      k[3] = pc[3] == rgba[0][3];
-      break;
-   case PIPE_FUNC_NOTEQUAL:
-      k[0] = pc[0] != rgba[0][0];
-      k[1] = pc[1] != rgba[0][1];
-      k[2] = pc[2] != rgba[0][2];
-      k[3] = pc[3] != rgba[0][3];
-      break;
-   case PIPE_FUNC_ALWAYS:
-      k[0] = k[1] = k[2] = k[3] = 1;
-      break;
-   case PIPE_FUNC_NEVER:
-      k[0] = k[1] = k[2] = k[3] = 0;
-      break;
-   default:
-      k[0] = k[1] = k[2] = k[3] = 0;
-      assert(0);
-      break;
+   for (v = 0; v < (is_gather ? TGSI_NUM_CHANNELS : 1); v++) {
+      /* compare four texcoords vs. four texture samples */
+      switch (sampler->compare_func) {
+      case PIPE_FUNC_LESS:
+         k[v][0] = pc[0] < rgba[v][0];
+         k[v][1] = pc[1] < rgba[v][1];
+         k[v][2] = pc[2] < rgba[v][2];
+         k[v][3] = pc[3] < rgba[v][3];
+         break;
+      case PIPE_FUNC_LEQUAL:
+         k[v][0] = pc[0] <= rgba[v][0];
+         k[v][1] = pc[1] <= rgba[v][1];
+         k[v][2] = pc[2] <= rgba[v][2];
+         k[v][3] = pc[3] <= rgba[v][3];
+         break;
+      case PIPE_FUNC_GREATER:
+         k[v][0] = pc[0] > rgba[v][0];
+         k[v][1] = pc[1] > rgba[v][1];
+         k[v][2] = pc[2] > rgba[v][2];
+         k[v][3] = pc[3] > rgba[v][3];
+         break;
+      case PIPE_FUNC_GEQUAL:
+         k[v][0] = pc[0] >= rgba[v][0];
+         k[v][1] = pc[1] >= rgba[v][1];
+         k[v][2] = pc[2] >= rgba[v][2];
+         k[v][3] = pc[3] >= rgba[v][3];
+         break;
+      case PIPE_FUNC_EQUAL:
+         k[v][0] = pc[0] == rgba[v][0];
+         k[v][1] = pc[1] == rgba[v][1];
+         k[v][2] = pc[2] == rgba[v][2];
+         k[v][3] = pc[3] == rgba[v][3];
+         break;
+      case PIPE_FUNC_NOTEQUAL:
+         k[v][0] = pc[0] != rgba[v][0];
+         k[v][1] = pc[1] != rgba[v][1];
+         k[v][2] = pc[2] != rgba[v][2];
+         k[v][3] = pc[3] != rgba[v][3];
+         break;
+      case PIPE_FUNC_ALWAYS:
+         k[v][0] = k[v][1] = k[v][2] = k[v][3] = 1;
+         break;
+      case PIPE_FUNC_NEVER:
+         k[v][0] = k[v][1] = k[v][2] = k[v][3] = 0;
+         break;
+      default:
+         k[v][0] = k[v][1] = k[v][2] = k[v][3] = 0;
+         assert(0);
+         break;
+      }
    }
 
-   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
-      rgba[0][j] = k[j];
-      rgba[1][j] = k[j];
-      rgba[2][j] = k[j];
-      rgba[3][j] = 1.0F;
+   if (is_gather) {
+      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+         for (v = 0; v < TGSI_NUM_CHANNELS; v++) {
+            rgba[v][j] = k[v][j];
+         }
+      }
+   } else {
+      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+         rgba[0][j] = k[0][j];
+         rgba[1][j] = k[0][j];
+         rgba[2][j] = k[0][j];
+         rgba[3][j] = 1.0F;
+      }
    }
 }
 
-
 static void
 do_swizzling(const struct pipe_sampler_view *sview,
              float in[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
@@ -2679,9 +2802,9 @@ any_swizzle(const struct pipe_sampler_view *view)
 static img_filter_func
 get_img_filter(const struct sp_sampler_view *sp_sview,
                const struct pipe_sampler_state *sampler,
-               unsigned filter)
+               unsigned filter, bool gather)
 {
-   switch (sp_sview->base.texture->target) {
+   switch (sp_sview->base.target) {
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
       if (filter == PIPE_TEX_FILTER_NEAREST) 
@@ -2699,7 +2822,7 @@ get_img_filter(const struct sp_sampler_view *sp_sview,
    case PIPE_TEXTURE_RECT:
       /* Try for fast path:
        */
-      if (sp_sview->pot2d &&
+      if (!gather && sp_sview->pot2d &&
           sampler->wrap_s == sampler->wrap_t &&
           sampler->normalized_coords) 
       {
@@ -2769,35 +2892,38 @@ sample_mip(struct sp_sampler_view *sp_sview,
            const float p[TGSI_QUAD_SIZE],
            const float c0[TGSI_QUAD_SIZE],
            const float lod[TGSI_QUAD_SIZE],
-           enum tgsi_sampler_control control,
+           const struct filter_args *filt_args,
            float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    mip_filter_func mip_filter;
    img_filter_func min_img_filter = NULL;
    img_filter_func mag_img_filter = NULL;
 
-   if (sp_sview->pot2d & sp_samp->min_mag_equal_repeat_linear) {
+   if (filt_args->control == tgsi_sampler_gather) {
+      mip_filter = mip_filter_nearest;
+      min_img_filter = get_img_filter(sp_sview, &sp_samp->base, PIPE_TEX_FILTER_LINEAR, true);
+   } else if (sp_sview->pot2d & sp_samp->min_mag_equal_repeat_linear) {
       mip_filter = mip_filter_linear_2d_linear_repeat_POT;
    }
    else {
       mip_filter = sp_samp->mip_filter;
-      min_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->min_img_filter);
+      min_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->min_img_filter, false);
       if (sp_samp->min_mag_equal) {
          mag_img_filter = min_img_filter;
       }
       else {
-         mag_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->base.mag_img_filter);
+         mag_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->base.mag_img_filter, false);
       }
    }
 
    mip_filter(sp_sview, sp_samp, min_img_filter, mag_img_filter,
-              s, t, p, c0, lod, control, rgba);
+              s, t, p, c0, lod, filt_args, rgba);
 
    if (sp_samp->base.compare_mode != PIPE_TEX_COMPARE_NONE) {
-      sample_compare(sp_sview, sp_samp, s, t, p, c0, lod, control, rgba);
+      sample_compare(sp_sview, sp_samp, s, t, p, c0, lod, filt_args->control, rgba);
    }
 
-   if (sp_sview->need_swizzle) {
+   if (sp_sview->need_swizzle && filt_args->control != tgsi_sampler_gather) {
       float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
       memcpy(rgba_temp, rgba, sizeof(rgba_temp));
       do_swizzling(&sp_sview->base, rgba_temp, rgba);
@@ -2818,7 +2944,7 @@ sample_cube(struct sp_sampler_view *sp_sview,
             const float p[TGSI_QUAD_SIZE],
             const float c0[TGSI_QUAD_SIZE],
             const float c1[TGSI_QUAD_SIZE],
-            enum tgsi_sampler_control control,
+            const struct filter_args *filt_args,
             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    unsigned j;
@@ -2896,7 +3022,7 @@ sample_cube(struct sp_sampler_view *sp_sview,
       }
    }
 
-   sample_mip(sp_sview, sp_samp, ssss, tttt, pppp, c0, c1, control, rgba);
+   sample_mip(sp_sview, sp_samp, ssss, tttt, pppp, c0, c1, filt_args, rgba);
 }
 
 
@@ -2907,7 +3033,7 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level,
    const struct pipe_sampler_view *view = &sp_sview->base;
    const struct pipe_resource *texture = view->texture;
 
-   if (texture->target == PIPE_BUFFER) {
+   if (view->target == PIPE_BUFFER) {
       dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1;
       /* the other values are undefined, but let's avoid potential valgrind
        * warnings.
@@ -2924,7 +3050,7 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level,
    dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1;
    dims[0] = u_minify(texture->width0, level);
 
-   switch(texture->target) {
+   switch (view->target) {
    case PIPE_TEXTURE_1D_ARRAY:
       dims[1] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
       /* fallthrough */
@@ -2975,13 +3101,16 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
 
    addr.value = 0;
    /* TODO write a better test for LOD */
-   addr.bits.level = lod[0];
+   addr.bits.level = sp_sview->base.target == PIPE_BUFFER ? 0 :
+                        CLAMP(lod[0] + sp_sview->base.u.tex.first_level, 
+                              sp_sview->base.u.tex.first_level,
+                              sp_sview->base.u.tex.last_level);
 
    width = u_minify(texture->width0, addr.bits.level);
    height = u_minify(texture->height0, addr.bits.level);
    depth = u_minify(texture->depth0, addr.bits.level);
 
-   switch(texture->target) {
+   switch (sp_sview->base.target) {
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
       for (j = 0; j < TGSI_QUAD_SIZE; j++) {
@@ -2995,7 +3124,8 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
    case PIPE_TEXTURE_1D_ARRAY:
       for (j = 0; j < TGSI_QUAD_SIZE; j++) {
          int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
-         int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer, sp_sview->base.u.tex.last_layer);
+         int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer,
+                       sp_sview->base.u.tex.last_layer);
          tx = get_texel_2d_no_border(sp_sview, addr, x, y);
          for (c = 0; c < 4; c++) {
             rgba[c][j] = tx[c];
@@ -3017,7 +3147,8 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
       for (j = 0; j < TGSI_QUAD_SIZE; j++) {
          int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
          int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
-         int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer, sp_sview->base.u.tex.last_layer);
+         int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer,
+                           sp_sview->base.u.tex.last_layer);
          tx = get_texel_3d_no_border(sp_sview, addr, x, y, layer);
          for (c = 0; c < 4; c++) {
             rgba[c][j] = tx[c];
@@ -3140,7 +3271,7 @@ softpipe_get_lambda_func(const struct pipe_sampler_view *view, unsigned shader)
    if (shader != PIPE_SHADER_FRAGMENT)
       return compute_lambda_vert;
 
-   switch (view->texture->target) {
+   switch (view->target) {
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
    case PIPE_TEXTURE_1D_ARRAY:
@@ -3176,19 +3307,49 @@ softpipe_create_sampler_view(struct pipe_context *pipe,
       pipe_resource_reference(&view->texture, resource);
       view->context = pipe;
 
+#ifdef DEBUG
+     /*
+      * This is possibly too lenient, but the primary reason is just
+      * to catch state trackers which forget to initialize this, so
+      * it only catches clearly impossible view targets.
+      */
+      if (view->target != resource->target) {
+         if (view->target == PIPE_TEXTURE_1D)
+            assert(resource->target == PIPE_TEXTURE_1D_ARRAY);
+         else if (view->target == PIPE_TEXTURE_1D_ARRAY)
+            assert(resource->target == PIPE_TEXTURE_1D);
+         else if (view->target == PIPE_TEXTURE_2D)
+            assert(resource->target == PIPE_TEXTURE_2D_ARRAY ||
+                   resource->target == PIPE_TEXTURE_CUBE ||
+                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
+         else if (view->target == PIPE_TEXTURE_2D_ARRAY)
+            assert(resource->target == PIPE_TEXTURE_2D ||
+                   resource->target == PIPE_TEXTURE_CUBE ||
+                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
+         else if (view->target == PIPE_TEXTURE_CUBE)
+            assert(resource->target == PIPE_TEXTURE_CUBE_ARRAY ||
+                   resource->target == PIPE_TEXTURE_2D_ARRAY);
+         else if (view->target == PIPE_TEXTURE_CUBE_ARRAY)
+            assert(resource->target == PIPE_TEXTURE_CUBE ||
+                   resource->target == PIPE_TEXTURE_2D_ARRAY);
+         else
+            assert(0);
+      }
+#endif
+
       if (any_swizzle(view)) {
          sview->need_swizzle = TRUE;
       }
 
-      if (resource->target == PIPE_TEXTURE_CUBE ||
-          resource->target == PIPE_TEXTURE_CUBE_ARRAY)
+      if (view->target == PIPE_TEXTURE_CUBE ||
+          view->target == PIPE_TEXTURE_CUBE_ARRAY)
          sview->get_samples = sample_cube;
       else {
          sview->get_samples = sample_mip;
       }
       sview->pot2d = spr->pot &&
-                     (resource->target == PIPE_TEXTURE_2D ||
-                      resource->target == PIPE_TEXTURE_RECT);
+                     (view->target == PIPE_TEXTURE_2D ||
+                      view->target == PIPE_TEXTURE_RECT);
 
       sview->xpot = util_logbase2( resource->width0 );
       sview->ypot = util_logbase2( resource->height0 );
@@ -3230,7 +3391,7 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
                     float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
-
+   struct filter_args filt_args;
    assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
    assert(sampler_index < PIPE_MAX_SAMPLERS);
    assert(sp_samp->sp_sampler[sampler_index]);
@@ -3244,9 +3405,12 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
       }
       return;
    }
+
+   filt_args.control = control;
+   filt_args.offset = offset;
    sp_samp->sp_sview[sview_index].get_samples(&sp_samp->sp_sview[sview_index],
                                               sp_samp->sp_sampler[sampler_index],
-                                              s, t, p, c0, lod, control, rgba);
+                                              s, t, p, c0, lod, &filt_args, rgba);
 }
 
 
index 00a97c5186b74faf706966210cf7643561ae75a9..7d1aafc4473e1294d909f1537d94943fdc66efa0 100644 (file)
@@ -38,10 +38,12 @@ struct sp_sampler;
 
 typedef void (*wrap_nearest_func)(float s,
                                   unsigned size,
+                                  int offset,
                                   int *icoord);
 
 typedef void (*wrap_linear_func)(float s, 
                                  unsigned size,
+                                 int offset,
                                  int *icoord0,
                                  int *icoord1,
                                  float *w);
@@ -51,15 +53,27 @@ typedef float (*compute_lambda_func)(const struct sp_sampler_view *sp_sview,
                                      const float t[TGSI_QUAD_SIZE],
                                      const float p[TGSI_QUAD_SIZE]);
 
+struct img_filter_args {
+   float s;
+   float t;
+   float p;
+   unsigned level;
+   unsigned face_id;
+   const int8_t *offset;
+   bool gather_only;
+   int gather_comp;
+};
+
 typedef void (*img_filter_func)(struct sp_sampler_view *sp_sview,
                                 struct sp_sampler *sp_samp,
-                                float s,
-                                float t,
-                                float p,
-                                unsigned level,
-                                unsigned face_id,
+                                const struct img_filter_args *args,
                                 float *rgba);
 
+struct filter_args {
+   enum tgsi_sampler_control control;
+   const int8_t *offset;
+};
+
 typedef void (*mip_filter_func)(struct sp_sampler_view *sp_sview,
                                 struct sp_sampler *sp_samp,
                                 img_filter_func min_filter,
@@ -69,7 +83,7 @@ typedef void (*mip_filter_func)(struct sp_sampler_view *sp_sview,
                                 const float p[TGSI_QUAD_SIZE],
                                 const float c0[TGSI_QUAD_SIZE],
                                 const float lod[TGSI_QUAD_SIZE],
-                                enum tgsi_sampler_control control,
+                                const struct filter_args *args,
                                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 
 
@@ -80,7 +94,7 @@ typedef void (*filter_func)(struct sp_sampler_view *sp_sview,
                             const float p[TGSI_QUAD_SIZE],
                             const float c0[TGSI_QUAD_SIZE],
                             const float lod[TGSI_QUAD_SIZE],
-                            enum tgsi_sampler_control control,
+                            const struct filter_args *args,
                             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 
 
index ab8ba60849a62089826a34840c8c1ac229a7e572..4a421a8f8827bfb489d34772b40c53444036511c 100644 (file)
@@ -151,7 +151,7 @@ sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
          tc->entries[i].addr.bits.invalid = 1;
       }
 
-      tc->tex_face = -1; /* any invalid value here */
+      tc->tex_z = -1; /* any invalid value here */
    }
 }
 
@@ -172,7 +172,7 @@ sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
       for (pos = 0; pos < Elements(tc->entries); pos++) {
          tc->entries[pos].addr.bits.invalid = 1;
       }
-      tc->tex_face = -1;
+      tc->tex_z = -1;
    }
 
 }
@@ -190,8 +190,7 @@ tex_cache_pos( union tex_tile_address addr )
 {
    uint entry = (addr.bits.x + 
                  addr.bits.y * 9 + 
-                 addr.bits.z * 3 + 
-                 addr.bits.face + 
+                 addr.bits.z +
                  addr.bits.level * 7);
 
    return entry % NUM_TEX_TILE_ENTRIES;
@@ -226,7 +225,6 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
 
       /* check if we need to get a new transfer */
       if (!tc->tex_trans ||
-          tc->tex_face != addr.bits.face ||
           tc->tex_level != addr.bits.level ||
           tc->tex_z != addr.bits.z) {
          /* get new transfer (view into texture) */
@@ -245,7 +243,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
          }
          else {
             height = u_minify(tc->texture->height0, addr.bits.level);
-            layer = addr.bits.face + addr.bits.z;
+            layer = addr.bits.z;
          }
 
          tc->tex_trans_map =
@@ -255,7 +253,6 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
                               PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
                               0, 0, width, height, &tc->tex_trans);
 
-         tc->tex_face = addr.bits.face;
          tc->tex_level = addr.bits.level;
          tc->tex_z = addr.bits.z;
       }
index 4eb42460552667899e155524b93ae3650630f353..2233effc439916567a099b6bf29efb0783b47520 100644 (file)
@@ -55,7 +55,6 @@ union tex_tile_address {
       unsigned x:TEX_ADDR_BITS;  /* 16K / TILE_SIZE */
       unsigned y:TEX_ADDR_BITS;  /* 16K / TILE_SIZE */
       unsigned z:TEX_Z_BITS;     /* 16K -- z not tiled */
-      unsigned face:3;
       unsigned level:4;
       unsigned invalid:1;
    } bits;
@@ -94,7 +93,7 @@ struct softpipe_tex_tile_cache
 
    struct pipe_transfer *tex_trans;
    void *tex_trans_map;
-   int tex_face, tex_level, tex_z;
+   int tex_level, tex_z;
 
    unsigned swizzle_r;
    unsigned swizzle_g;
@@ -141,7 +140,6 @@ tex_tile_address( unsigned x,
    addr.bits.x = x / TEX_TILE_SIZE;
    addr.bits.y = y / TEX_TILE_SIZE;
    addr.bits.z = z;
-   addr.bits.face = face;
    addr.bits.level = level;
 
    return addr;
index b75f0386449e5646fe1f1bc78e80a0ac7b30a7e0..56e486786df40c9b545e39a845af164e4e776849 100644 (file)
@@ -308,6 +308,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_UMA:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
       return 0;
    }
 
@@ -376,6 +377,7 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
          return 0;
       }
       /* If we get here, we failed to handle a cap above */
@@ -433,6 +435,7 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
          return 0;
       }
       /* If we get here, we failed to handle a cap above */
index 7a12b52e2dda0b62642f943b2f4c130e268df270..bac956066a555eb001af6ab1030aa125cda738c5 100644 (file)
@@ -1900,7 +1900,7 @@ emit_tex(struct svga_shader_emitter *emit,
                       emit->key.fkey.tex[unit].swizzle_b != PIPE_SWIZZLE_BLUE ||
                       emit->key.fkey.tex[unit].swizzle_a != PIPE_SWIZZLE_ALPHA);
 
-   boolean saturate = insn->Instruction.Saturate != TGSI_SAT_NONE;
+   boolean saturate = insn->Instruction.Saturate;
 
    /* If doing compare processing or tex swizzle or saturation, we need to put
     * the fetched color into a temporary so it can be used as a source later on.
index 0b56517e69677ce26e613b2ccc465dbc00b14df2..0013c963e7ac3826ce3bc6b6ddde7d7e6fa872ff 100644 (file)
@@ -553,6 +553,8 @@ trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
 TRACE_SHADER_STATE(fs)
 TRACE_SHADER_STATE(vs)
 TRACE_SHADER_STATE(gs)
+TRACE_SHADER_STATE(tcs)
+TRACE_SHADER_STATE(tes)
 
 #undef TRACE_SHADER_STATE
 
@@ -1508,6 +1510,23 @@ static void trace_context_memory_barrier(struct pipe_context *_context,
 }
 
 
+static void trace_context_set_tess_state(struct pipe_context *_context,
+                                         const float default_outer_level[4],
+                                         const float default_inner_level[2])
+{
+   struct trace_context *tr_context = trace_context(_context);
+   struct pipe_context *context = tr_context->pipe;
+
+   trace_dump_call_begin("pipe_context", "set_tess_state");
+   trace_dump_arg(ptr, context);
+   trace_dump_arg_array(float, default_outer_level, 4);
+   trace_dump_arg_array(float, default_inner_level, 2);
+   trace_dump_call_end();
+
+   context->set_tess_state(context, default_outer_level, default_inner_level);
+}
+
+
 static const struct debug_named_value rbug_blocker_flags[] = {
    {"before", 1, NULL},
    {"after", 2, NULL},
@@ -1566,6 +1585,12 @@ trace_context_create(struct trace_screen *tr_scr,
    TR_CTX_INIT(create_gs_state);
    TR_CTX_INIT(bind_gs_state);
    TR_CTX_INIT(delete_gs_state);
+   TR_CTX_INIT(create_tcs_state);
+   TR_CTX_INIT(bind_tcs_state);
+   TR_CTX_INIT(delete_tcs_state);
+   TR_CTX_INIT(create_tes_state);
+   TR_CTX_INIT(bind_tes_state);
+   TR_CTX_INIT(delete_tes_state);
    TR_CTX_INIT(create_vertex_elements_state);
    TR_CTX_INIT(bind_vertex_elements_state);
    TR_CTX_INIT(delete_vertex_elements_state);
@@ -1597,6 +1622,7 @@ trace_context_create(struct trace_screen *tr_scr,
    TR_CTX_INIT(flush);
    TR_CTX_INIT(texture_barrier);
    TR_CTX_INIT(memory_barrier);
+   TR_CTX_INIT(set_tess_state);
 
    TR_CTX_INIT(transfer_map);
    TR_CTX_INIT(transfer_unmap);
index 7127338043489d4aecb9a363985a8a38e555a6f0..9bf4a722d8010c7d1e8d2648ab0bb2c82bd9df64 100644 (file)
@@ -709,6 +709,8 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
    trace_dump_member(uint, state, start_instance);
    trace_dump_member(uint, state, instance_count);
 
+   trace_dump_member(uint, state, vertices_per_patch);
+
    trace_dump_member(int,  state, index_bias);
    trace_dump_member(uint, state, min_index);
    trace_dump_member(uint, state, max_index);
index aee4937dd4fe519d5656e55be983d91b575baa35..b03133f8d97f34b56c86a26d286275b637e5026e 100644 (file)
@@ -28,6 +28,8 @@
 #ifndef TR_PUBLIC_H
 #define TR_PUBLIC_H
 
+#include "pipe/p_compiler.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/gallium/drivers/vc4/Android.mk b/src/gallium/drivers/vc4/Android.mk
new file mode 100644 (file)
index 0000000..f42a152
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 2014 Emil Velikov <emil.l.velikov@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+# get C_SOURCES
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+       $(C_SOURCES)
+
+LOCAL_SHARED_LIBRARIES := libdrm
+# We need libmesa_glsl to get NIR's generated include directories.
+LOCAL_STATIC_LIBRARIES := libmesa_glsl
+LOCAL_MODULE := libmesa_pipe_vc4
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
index 3fc591f10c17ebf6807311f1b1017346909228db..3f62ce21a9fa23e716a1b8acc1b1b002b56fbbd7 100644 (file)
@@ -19,7 +19,7 @@
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 # IN THE SOFTWARE.
 
-SUBDIRS = kernel
+AUTOMAKE_OPTIONS = subdir-objects
 
 include Makefile.sources
 include $(top_srcdir)/src/gallium/Automake.inc
@@ -39,5 +39,5 @@ AM_CFLAGS = \
 noinst_LTLIBRARIES = libvc4.la
 
 libvc4_la_SOURCES = $(C_SOURCES)
-libvc4_la_LIBADD = $(SIM_LIB) kernel/libvc4_kernel.la
+libvc4_la_LIBADD = $(SIM_LIB)
 libvc4_la_LDFLAGS = $(SIM_LDFLAGS)
index 49474df354814b221e75968de528d284f4a51866..1eb029e67e76911f996680ac425c589a7c8418de 100644 (file)
@@ -1,4 +1,10 @@
 C_SOURCES := \
+       kernel/vc4_drv.h \
+       kernel/vc4_gem.c \
+       kernel/vc4_packet.h \
+       kernel/vc4_render_cl.c \
+       kernel/vc4_validate.c \
+       kernel/vc4_validate_shaders.c \
        vc4_blit.c \
        vc4_bufmgr.c \
        vc4_bufmgr.h \
@@ -20,7 +26,6 @@ C_SOURCES := \
        vc4_opt_dead_code.c \
        vc4_opt_small_immediates.c \
        vc4_opt_vpm_writes.c \
-       vc4_packet.h \
        vc4_program.c \
        vc4_qir.c \
        vc4_qir_lower_uniforms.c \
diff --git a/src/gallium/drivers/vc4/kernel/Makefile.am b/src/gallium/drivers/vc4/kernel/Makefile.am
deleted file mode 100644 (file)
index 1ae5f1c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright Â© 2014 Broadcom
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice (including the next
-# paragraph) shall be included in all copies or substantial portions of the
-# Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-include Makefile.sources
-include $(top_srcdir)/src/gallium/Automake.inc
-
-if USE_VC4_SIMULATOR
-SIM_CFLAGS = -DUSE_VC4_SIMULATOR=1
-endif
-
-AM_CFLAGS = \
-       $(LIBDRM_CFLAGS) \
-       $(GALLIUM_DRIVER_CFLAGS) \
-       $(SIM_CFLAGS) \
-       -I$(top_srcdir)/src/mesa/ \
-       -I$(srcdir)/../ \
-       $()
-
-noinst_LTLIBRARIES = libvc4_kernel.la
-
-libvc4_kernel_la_SOURCES = $(C_SOURCES)
-libvc4_kernel_la_LDFLAGS = $(SIM_LDFLAGS)
diff --git a/src/gallium/drivers/vc4/kernel/Makefile.sources b/src/gallium/drivers/vc4/kernel/Makefile.sources
deleted file mode 100644 (file)
index 7d17a89..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-C_SOURCES := \
-       vc4_drv.h \
-       vc4_gem.c \
-       vc4_validate.c \
-       vc4_validate_shaders.c \
-       $()
index 325f944bf25c88d8a698c44c2d40cbf517655552..1fd8aa9fb28d5ff9551233ddf91ca8ac3d059774 100644 (file)
@@ -28,8 +28,6 @@
 
 enum vc4_bo_mode {
        VC4_MODE_UNDECIDED,
-       VC4_MODE_TILE_ALLOC,
-       VC4_MODE_TSDA,
        VC4_MODE_RENDER,
        VC4_MODE_SHADER,
 };
@@ -52,6 +50,11 @@ struct vc4_exec_info {
        struct vc4_bo_exec_state *bo;
        uint32_t bo_count;
 
+       /* List of other BOs used in the job that need to be released
+        * once the job is complete.
+        */
+       struct list_head unref_list;
+
        /* Current unvalidated indices into @bo loaded by the non-hardware
         * VC4_PACKET_GEM_HANDLES.
         */
@@ -83,14 +86,11 @@ struct vc4_exec_info {
        uint32_t shader_state_count;
 
        bool found_tile_binning_mode_config_packet;
-       bool found_tile_rendering_mode_config_packet;
        bool found_start_tile_binning_packet;
        bool found_increment_semaphore_packet;
-       bool found_wait_on_semaphore_packet;
        uint8_t bin_tiles_x, bin_tiles_y;
-       uint32_t fb_width, fb_height;
-       uint32_t tile_alloc_init_block_size;
-       struct drm_gem_cma_object *tile_alloc_bo;
+       struct drm_gem_cma_object *tile_bo;
+       uint32_t tile_alloc_offset;
 
        /**
         * Computed addresses pointing into exec_bo where we start the
@@ -157,13 +157,10 @@ struct vc4_validated_shader_info
 
 /* vc4_validate.c */
 int
-vc4_validate_cl(struct drm_device *dev,
-                void *validated,
-                void *unvalidated,
-                uint32_t len,
-                bool is_bin,
-                bool has_bin,
-                struct vc4_exec_info *exec);
+vc4_validate_bin_cl(struct drm_device *dev,
+                   void *validated,
+                   void *unvalidated,
+                   struct vc4_exec_info *exec);
 
 int
 vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec);
@@ -171,4 +168,16 @@ vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec);
 struct vc4_validated_shader_info *
 vc4_validate_shader(struct drm_gem_cma_object *shader_obj);
 
+bool vc4_use_bo(struct vc4_exec_info *exec,
+               uint32_t hindex,
+               enum vc4_bo_mode mode,
+               struct drm_gem_cma_object **obj);
+
+int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec);
+
+bool vc4_check_tex_size(struct vc4_exec_info *exec,
+                       struct drm_gem_cma_object *fbo,
+                       uint32_t offset, uint8_t tiling_format,
+                       uint32_t width, uint32_t height, uint8_t cpp);
+
 #endif /* VC4_DRV_H */
index ac29ab35dbca12bd5e9902e708a4387fe28312f1..e4b7fea59684182fa5c562fc0f3ffef6a5be9e72 100644 (file)
 
 #include "vc4_drv.h"
 
-int
-vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
+/*
+ * Copies in the user's binning command list and generates the validated bin
+ * CL, along with associated data (shader records, uniforms).
+ */
+static int
+vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
 {
        struct drm_vc4_submit_cl *args = exec->args;
        void *temp = NULL;
-       void *bin, *render;
+       void *bin;
        int ret = 0;
        uint32_t bin_offset = 0;
-       uint32_t render_offset = bin_offset + args->bin_cl_size;
-       uint32_t shader_rec_offset = roundup(render_offset +
-                                            args->render_cl_size, 16);
+       uint32_t shader_rec_offset = roundup(bin_offset + args->bin_cl_size,
+                                            16);
        uint32_t uniforms_offset = shader_rec_offset + args->shader_rec_size;
        uint32_t exec_size = uniforms_offset + args->uniforms_size;
        uint32_t temp_size = exec_size + (sizeof(struct vc4_shader_state) *
                                          args->shader_rec_count);
 
-       if (shader_rec_offset < render_offset ||
-           uniforms_offset < shader_rec_offset ||
+       if (uniforms_offset < shader_rec_offset ||
            exec_size < uniforms_offset ||
            args->shader_rec_count >= (UINT_MAX /
                                          sizeof(struct vc4_shader_state)) ||
@@ -66,7 +68,6 @@ vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
                goto fail;
        }
        bin = temp + bin_offset;
-       render = temp + render_offset;
        exec->shader_rec_u = temp + shader_rec_offset;
        exec->uniforms_u = temp + uniforms_offset;
        exec->shader_state = temp + exec_size;
@@ -80,14 +81,6 @@ vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
                goto fail;
        }
 
-       ret = copy_from_user(render,
-                            (void __user *)(uintptr_t)args->render_cl,
-                            args->render_cl_size);
-       if (ret) {
-               DRM_ERROR("Failed to copy in render cl\n");
-               goto fail;
-       }
-
        ret = copy_from_user(exec->shader_rec_u,
                             (void __user *)(uintptr_t)args->shader_rec,
                             args->shader_rec_size);
@@ -114,8 +107,10 @@ vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
        }
 #endif
 
+       list_addtail(&to_vc4_bo(&exec->exec_bo->base)->unref_head,
+                    &exec->unref_list);
+
        exec->ct0ca = exec->exec_bo->paddr + bin_offset;
-       exec->ct1ca = exec->exec_bo->paddr + render_offset;
 
        exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset;
        exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset;
@@ -125,23 +120,10 @@ vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
        exec->uniforms_p = exec->exec_bo->paddr + uniforms_offset;
        exec->uniforms_size = args->uniforms_size;
 
-       ret = vc4_validate_cl(dev,
-                             exec->exec_bo->vaddr + bin_offset,
-                             bin,
-                             args->bin_cl_size,
-                             true,
-                             args->bin_cl_size != 0,
-                             exec);
-       if (ret)
-               goto fail;
-
-       ret = vc4_validate_cl(dev,
-                             exec->exec_bo->vaddr + render_offset,
-                             render,
-                             args->render_cl_size,
-                             false,
-                             args->bin_cl_size != 0,
-                             exec);
+       ret = vc4_validate_bin_cl(dev,
+                                 exec->exec_bo->vaddr + bin_offset,
+                                 bin,
+                                 exec);
        if (ret)
                goto fail;
 
@@ -152,4 +134,25 @@ fail:
        return ret;
 }
 
+int
+vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
+{
+       int ret = 0;
+
+       if (exec->args->bin_cl_size != 0) {
+               ret = vc4_get_bcl(dev, exec);
+               if (ret)
+                       goto fail;
+       } else {
+               exec->ct0ca = exec->ct0ea = 0;
+       }
+
+       ret = vc4_get_rcl(dev, exec);
+       if (ret)
+               goto fail;
+
+fail:
+       return ret;
+}
+
 #endif /* USE_VC4_SIMULATOR */
diff --git a/src/gallium/drivers/vc4/kernel/vc4_packet.h b/src/gallium/drivers/vc4/kernel/vc4_packet.h
new file mode 100644 (file)
index 0000000..88cfc0f
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * Copyright Â© 2014 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef VC4_PACKET_H
+#define VC4_PACKET_H
+
+enum vc4_packet {
+        VC4_PACKET_HALT = 0,
+        VC4_PACKET_NOP = 1,
+
+        VC4_PACKET_FLUSH = 4,
+        VC4_PACKET_FLUSH_ALL = 5,
+        VC4_PACKET_START_TILE_BINNING = 6,
+        VC4_PACKET_INCREMENT_SEMAPHORE = 7,
+        VC4_PACKET_WAIT_ON_SEMAPHORE = 8,
+
+        VC4_PACKET_BRANCH = 16,
+        VC4_PACKET_BRANCH_TO_SUB_LIST = 17,
+
+        VC4_PACKET_STORE_MS_TILE_BUFFER = 24,
+        VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25,
+        VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26,
+        VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27,
+        VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28,
+        VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29,
+
+        VC4_PACKET_GL_INDEXED_PRIMITIVE = 32,
+        VC4_PACKET_GL_ARRAY_PRIMITIVE = 33,
+
+        VC4_PACKET_COMPRESSED_PRIMITIVE = 48,
+        VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49,
+
+        VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56,
+
+        VC4_PACKET_GL_SHADER_STATE = 64,
+        VC4_PACKET_NV_SHADER_STATE = 65,
+        VC4_PACKET_VG_SHADER_STATE = 66,
+
+        VC4_PACKET_CONFIGURATION_BITS = 96,
+        VC4_PACKET_FLAT_SHADE_FLAGS = 97,
+        VC4_PACKET_POINT_SIZE = 98,
+        VC4_PACKET_LINE_WIDTH = 99,
+        VC4_PACKET_RHT_X_BOUNDARY = 100,
+        VC4_PACKET_DEPTH_OFFSET = 101,
+        VC4_PACKET_CLIP_WINDOW = 102,
+        VC4_PACKET_VIEWPORT_OFFSET = 103,
+        VC4_PACKET_Z_CLIPPING = 104,
+        VC4_PACKET_CLIPPER_XY_SCALING = 105,
+        VC4_PACKET_CLIPPER_Z_SCALING = 106,
+
+        VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112,
+        VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113,
+        VC4_PACKET_CLEAR_COLORS = 114,
+        VC4_PACKET_TILE_COORDINATES = 115,
+
+        /* Not an actual hardware packet -- this is what we use to put
+         * references to GEM bos in the command stream, since we need the u32
+         * int the actual address packet in order to store the offset from the
+         * start of the BO.
+         */
+        VC4_PACKET_GEM_HANDLES = 254,
+} __attribute__ ((__packed__));
+
+#define VC4_PACKET_HALT_SIZE                                           1
+#define VC4_PACKET_NOP_SIZE                                            1
+#define VC4_PACKET_FLUSH_SIZE                                          1
+#define VC4_PACKET_FLUSH_ALL_SIZE                                      1
+#define VC4_PACKET_START_TILE_BINNING_SIZE                             1
+#define VC4_PACKET_INCREMENT_SEMAPHORE_SIZE                            1
+#define VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE                              1
+#define VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE                             5
+#define VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE                           1
+#define VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF_SIZE                   1
+#define VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE                      7
+#define VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE                       7
+#define VC4_PACKET_GL_INDEXED_PRIMITIVE_SIZE                           14
+#define VC4_PACKET_GL_ARRAY_PRIMITIVE_SIZE                             10
+#define VC4_PACKET_PRIMITIVE_LIST_FORMAT_SIZE                          2
+#define VC4_PACKET_GL_SHADER_STATE_SIZE                                        5
+#define VC4_PACKET_NV_SHADER_STATE_SIZE                                        5
+#define VC4_PACKET_CONFIGURATION_BITS_SIZE                             4
+#define VC4_PACKET_FLAT_SHADE_FLAGS_SIZE                               5
+#define VC4_PACKET_POINT_SIZE_SIZE                                     5
+#define VC4_PACKET_LINE_WIDTH_SIZE                                     5
+#define VC4_PACKET_RHT_X_BOUNDARY_SIZE                                 3
+#define VC4_PACKET_DEPTH_OFFSET_SIZE                                   5
+#define VC4_PACKET_CLIP_WINDOW_SIZE                                    9
+#define VC4_PACKET_VIEWPORT_OFFSET_SIZE                                        5
+#define VC4_PACKET_CLIPPER_XY_SCALING_SIZE                             9
+#define VC4_PACKET_CLIPPER_Z_SCALING_SIZE                              9
+#define VC4_PACKET_TILE_BINNING_MODE_CONFIG_SIZE                       16
+#define VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE                     11
+#define VC4_PACKET_CLEAR_COLORS_SIZE                                   14
+#define VC4_PACKET_TILE_COORDINATES_SIZE                               3
+#define VC4_PACKET_GEM_HANDLES_SIZE                                    9
+
+#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
+/* Using the GNU statement expression extension */
+#define VC4_SET_FIELD(value, field)                                       \
+        ({                                                                \
+                uint32_t fieldval = (value) << field ## _SHIFT;                  \
+                assert((fieldval & ~ field ## _MASK) == 0);               \
+                fieldval & field ## _MASK;                                \
+         })
+
+#define VC4_GET_FIELD(word, field) (((word)  & field ## _MASK) >> field ## _SHIFT)
+
+/** @{
+ * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
+ * VC4_PACKET_TILE_RENDERING_MODE_CONFIG.
+*/
+#define VC4_TILING_FORMAT_LINEAR    0
+#define VC4_TILING_FORMAT_T         1
+#define VC4_TILING_FORMAT_LT        2
+/** @} */
+
+/** @{
+ *
+ * byte 2 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL (low bits of the address)
+ */
+
+#define VC4_LOADSTORE_TILE_BUFFER_EOF                  (1 << 3)
+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK (1 << 2)
+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS      (1 << 1)
+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR   (1 << 0)
+
+/** @} */
+
+/** @{
+ *
+ * byte 0-1 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL
+ */
+#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR (1 << 15)
+#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR     (1 << 14)
+#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR  (1 << 13)
+#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP         (1 << 12)
+
+#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK      VC4_MASK(9, 8)
+#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT     8
+#define VC4_LOADSTORE_TILE_BUFFER_RGBA8888         0
+#define VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER    1
+#define VC4_LOADSTORE_TILE_BUFFER_BGR565           2
+/** @} */
+
+/** @{
+ *
+ * byte 0 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL
+ */
+#define VC4_STORE_TILE_BUFFER_MODE_MASK            VC4_MASK(7, 6)
+#define VC4_STORE_TILE_BUFFER_MODE_SHIFT           6
+#define VC4_STORE_TILE_BUFFER_MODE_SAMPLE0         (0 << 6)
+#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X4     (1 << 6)
+#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X16    (2 << 6)
+
+/** The values of the field are VC4_TILING_FORMAT_* */
+#define VC4_LOADSTORE_TILE_BUFFER_TILING_MASK      VC4_MASK(5, 4)
+#define VC4_LOADSTORE_TILE_BUFFER_TILING_SHIFT     4
+
+#define VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK      VC4_MASK(2, 0)
+#define VC4_LOADSTORE_TILE_BUFFER_BUFFER_SHIFT     0
+#define VC4_LOADSTORE_TILE_BUFFER_NONE             0
+#define VC4_LOADSTORE_TILE_BUFFER_COLOR            1
+#define VC4_LOADSTORE_TILE_BUFFER_ZS               2
+#define VC4_LOADSTORE_TILE_BUFFER_Z                3
+#define VC4_LOADSTORE_TILE_BUFFER_VG_MASK          4
+#define VC4_LOADSTORE_TILE_BUFFER_FULL             5
+/** @} */
+
+#define VC4_INDEX_BUFFER_U8                        (0 << 4)
+#define VC4_INDEX_BUFFER_U16                       (1 << 4)
+
+/* This flag is only present in NV shader state. */
+#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS         (1 << 3)
+#define VC4_SHADER_FLAG_ENABLE_CLIPPING            (1 << 2)
+#define VC4_SHADER_FLAG_VS_POINT_SIZE              (1 << 1)
+#define VC4_SHADER_FLAG_FS_SINGLE_THREAD           (1 << 0)
+
+/** @{ byte 2 of config bits. */
+#define VC4_CONFIG_BITS_EARLY_Z_UPDATE             (1 << 1)
+#define VC4_CONFIG_BITS_EARLY_Z                    (1 << 0)
+/** @} */
+
+/** @{ byte 1 of config bits. */
+#define VC4_CONFIG_BITS_Z_UPDATE                   (1 << 7)
+/** same values in this 3-bit field as PIPE_FUNC_* */
+#define VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT           4
+#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE        (1 << 3)
+
+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_NONZERO    (0 << 1)
+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ODD        (1 << 1)
+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_OR         (2 << 1)
+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ZERO       (3 << 1)
+
+#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT       (1 << 0)
+/** @} */
+
+/** @{ byte 0 of config bits. */
+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_NONE (0 << 6)
+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X   (1 << 6)
+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_16X  (2 << 6)
+
+#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES        (1 << 4)
+#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET        (1 << 3)
+#define VC4_CONFIG_BITS_CW_PRIMITIVES              (1 << 2)
+#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK           (1 << 1)
+#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT          (1 << 0)
+/** @} */
+
+/** @{ bits in the last u8 of VC4_PACKET_TILE_BINNING_MODE_CONFIG */
+#define VC4_BIN_CONFIG_DB_NON_MS                   (1 << 7)
+
+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK       VC4_MASK(6, 5)
+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_SHIFT      5
+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_32         0
+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_64         1
+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128        2
+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_256        3
+
+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK  VC4_MASK(4, 3)
+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_SHIFT 3
+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32    0
+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_64    1
+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_128   2
+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_256   3
+
+#define VC4_BIN_CONFIG_AUTO_INIT_TSDA              (1 << 2)
+#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT           (1 << 1)
+#define VC4_BIN_CONFIG_MS_MODE_4X                  (1 << 0)
+/** @} */
+
+/** @{ bits in the last u16 of VC4_PACKET_TILE_RENDERING_MODE_CONFIG */
+#define VC4_RENDER_CONFIG_DB_NON_MS                (1 << 12)
+#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE (1 << 11)
+#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G      (1 << 10)
+#define VC4_RENDER_CONFIG_COVERAGE_MODE            (1 << 9)
+#define VC4_RENDER_CONFIG_ENABLE_VG_MASK           (1 << 8)
+
+/** The values of the field are VC4_TILING_FORMAT_* */
+#define VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK       VC4_MASK(7, 6)
+#define VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT      6
+
+#define VC4_RENDER_CONFIG_DECIMATE_MODE_1X         (0 << 4)
+#define VC4_RENDER_CONFIG_DECIMATE_MODE_4X         (1 << 4)
+#define VC4_RENDER_CONFIG_DECIMATE_MODE_16X        (2 << 4)
+
+#define VC4_RENDER_CONFIG_FORMAT_MASK              VC4_MASK(3, 2)
+#define VC4_RENDER_CONFIG_FORMAT_SHIFT             2
+#define VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED   0
+#define VC4_RENDER_CONFIG_FORMAT_RGBA8888          1
+#define VC4_RENDER_CONFIG_FORMAT_BGR565            2
+
+#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT        (1 << 1)
+#define VC4_RENDER_CONFIG_MS_MODE_4X               (1 << 0)
+
+#define VC4_PRIMITIVE_LIST_FORMAT_16_INDEX         (1 << 4)
+#define VC4_PRIMITIVE_LIST_FORMAT_32_XY            (3 << 4)
+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_POINTS      (0 << 0)
+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_LINES       (1 << 0)
+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_TRIANGLES   (2 << 0)
+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_RHT         (3 << 0)
+
+enum vc4_texture_data_type {
+        VC4_TEXTURE_TYPE_RGBA8888 = 0,
+        VC4_TEXTURE_TYPE_RGBX8888 = 1,
+        VC4_TEXTURE_TYPE_RGBA4444 = 2,
+        VC4_TEXTURE_TYPE_RGBA5551 = 3,
+        VC4_TEXTURE_TYPE_RGB565 = 4,
+        VC4_TEXTURE_TYPE_LUMINANCE = 5,
+        VC4_TEXTURE_TYPE_ALPHA = 6,
+        VC4_TEXTURE_TYPE_LUMALPHA = 7,
+        VC4_TEXTURE_TYPE_ETC1 = 8,
+        VC4_TEXTURE_TYPE_S16F = 9,
+        VC4_TEXTURE_TYPE_S8 = 10,
+        VC4_TEXTURE_TYPE_S16 = 11,
+        VC4_TEXTURE_TYPE_BW1 = 12,
+        VC4_TEXTURE_TYPE_A4 = 13,
+        VC4_TEXTURE_TYPE_A1 = 14,
+        VC4_TEXTURE_TYPE_RGBA64 = 15,
+        VC4_TEXTURE_TYPE_RGBA32R = 16,
+        VC4_TEXTURE_TYPE_YUV422R = 17,
+};
+
+#define VC4_TEX_P0_OFFSET_MASK                     VC4_MASK(31, 12)
+#define VC4_TEX_P0_OFFSET_SHIFT                    12
+#define VC4_TEX_P0_CSWIZ_MASK                      VC4_MASK(11, 10)
+#define VC4_TEX_P0_CSWIZ_SHIFT                     10
+#define VC4_TEX_P0_CMMODE_MASK                     VC4_MASK(9, 9)
+#define VC4_TEX_P0_CMMODE_SHIFT                    9
+#define VC4_TEX_P0_FLIPY_MASK                      VC4_MASK(8, 8)
+#define VC4_TEX_P0_FLIPY_SHIFT                     8
+#define VC4_TEX_P0_TYPE_MASK                       VC4_MASK(7, 4)
+#define VC4_TEX_P0_TYPE_SHIFT                      4
+#define VC4_TEX_P0_MIPLVLS_MASK                    VC4_MASK(3, 0)
+#define VC4_TEX_P0_MIPLVLS_SHIFT                   0
+
+#define VC4_TEX_P1_TYPE4_MASK                      VC4_MASK(31, 31)
+#define VC4_TEX_P1_TYPE4_SHIFT                     31
+#define VC4_TEX_P1_HEIGHT_MASK                     VC4_MASK(30, 20)
+#define VC4_TEX_P1_HEIGHT_SHIFT                    20
+#define VC4_TEX_P1_ETCFLIP_MASK                    VC4_MASK(19, 19)
+#define VC4_TEX_P1_ETCFLIP_SHIFT                   19
+#define VC4_TEX_P1_WIDTH_MASK                      VC4_MASK(18, 8)
+#define VC4_TEX_P1_WIDTH_SHIFT                     8
+
+#define VC4_TEX_P1_MAGFILT_MASK                    VC4_MASK(7, 7)
+#define VC4_TEX_P1_MAGFILT_SHIFT                   7
+# define VC4_TEX_P1_MAGFILT_LINEAR                 0
+# define VC4_TEX_P1_MAGFILT_NEAREST                1
+
+#define VC4_TEX_P1_MINFILT_MASK                    VC4_MASK(6, 4)
+#define VC4_TEX_P1_MINFILT_SHIFT                   4
+# define VC4_TEX_P1_MINFILT_LINEAR                 0
+# define VC4_TEX_P1_MINFILT_NEAREST                1
+# define VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR          2
+# define VC4_TEX_P1_MINFILT_NEAR_MIP_LIN           3
+# define VC4_TEX_P1_MINFILT_LIN_MIP_NEAR           4
+# define VC4_TEX_P1_MINFILT_LIN_MIP_LIN            5
+
+#define VC4_TEX_P1_WRAP_T_MASK                     VC4_MASK(3, 2)
+#define VC4_TEX_P1_WRAP_T_SHIFT                    2
+#define VC4_TEX_P1_WRAP_S_MASK                     VC4_MASK(1, 0)
+#define VC4_TEX_P1_WRAP_S_SHIFT                    0
+# define VC4_TEX_P1_WRAP_REPEAT                    0
+# define VC4_TEX_P1_WRAP_CLAMP                     1
+# define VC4_TEX_P1_WRAP_MIRROR                    2
+# define VC4_TEX_P1_WRAP_BORDER                    3
+
+#define VC4_TEX_P2_PTYPE_MASK                      VC4_MASK(31, 30)
+#define VC4_TEX_P2_PTYPE_SHIFT                     30
+# define VC4_TEX_P2_PTYPE_IGNORED                  0
+# define VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE          1
+# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS   2
+# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS      3
+
+/* VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE bits */
+#define VC4_TEX_P2_CMST_MASK                       VC4_MASK(29, 12)
+#define VC4_TEX_P2_CMST_SHIFT                      12
+#define VC4_TEX_P2_BSLOD_MASK                      VC4_MASK(0, 0)
+#define VC4_TEX_P2_BSLOD_SHIFT                     0
+
+/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS */
+#define VC4_TEX_P2_CHEIGHT_MASK                    VC4_MASK(22, 12)
+#define VC4_TEX_P2_CHEIGHT_SHIFT                   12
+#define VC4_TEX_P2_CWIDTH_MASK                     VC4_MASK(10, 0)
+#define VC4_TEX_P2_CWIDTH_SHIFT                    0
+
+/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS */
+#define VC4_TEX_P2_CYOFF_MASK                      VC4_MASK(22, 12)
+#define VC4_TEX_P2_CYOFF_SHIFT                     12
+#define VC4_TEX_P2_CXOFF_MASK                      VC4_MASK(10, 0)
+#define VC4_TEX_P2_CXOFF_SHIFT                     0
+
+#endif /* VC4_PACKET_H */
diff --git a/src/gallium/drivers/vc4/kernel/vc4_render_cl.c b/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
new file mode 100644 (file)
index 0000000..e2d907a
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright Â© 2014-2015 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: Render command list generation
+ *
+ * In the VC4 driver, render command list generation is performed by the
+ * kernel instead of userspace.  We do this because validating a
+ * user-submitted command list is hard to get right and has high CPU overhead,
+ * while the number of valid configurations for render command lists is
+ * actually fairly low.
+ */
+
+#include "vc4_drv.h"
+#include "vc4_packet.h"
+
+struct vc4_rcl_setup {
+       struct drm_gem_cma_object *color_read;
+       struct drm_gem_cma_object *color_ms_write;
+       struct drm_gem_cma_object *zs_read;
+       struct drm_gem_cma_object *zs_write;
+
+       struct drm_gem_cma_object *rcl;
+       u32 next_offset;
+};
+
+static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val)
+{
+       *(u8 *)(setup->rcl->vaddr + setup->next_offset) = val;
+       setup->next_offset += 1;
+}
+
+static inline void rcl_u16(struct vc4_rcl_setup *setup, u16 val)
+{
+       *(u16 *)(setup->rcl->vaddr + setup->next_offset) = val;
+       setup->next_offset += 2;
+}
+
+static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val)
+{
+       *(u32 *)(setup->rcl->vaddr + setup->next_offset) = val;
+       setup->next_offset += 4;
+}
+
+
+/*
+ * Emits a no-op STORE_TILE_BUFFER_GENERAL.
+ *
+ * If we emit a PACKET_TILE_COORDINATES, it must be followed by a store of
+ * some sort before another load is triggered.
+ */
+static void vc4_store_before_load(struct vc4_rcl_setup *setup)
+{
+       rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
+       rcl_u16(setup,
+               VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_NONE,
+                             VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
+               VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR |
+               VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR |
+               VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR);
+       rcl_u32(setup, 0); /* no address, since we're in None mode */
+}
+
+/*
+ * Emits a PACKET_TILE_COORDINATES if one isn't already pending.
+ *
+ * The tile coordinates packet triggers a pending load if there is one, are
+ * used for clipping during rendering, and determine where loads/stores happen
+ * relative to their base address.
+ */
+static void vc4_tile_coordinates(struct vc4_rcl_setup *setup,
+                                uint32_t x, uint32_t y)
+{
+       rcl_u8(setup, VC4_PACKET_TILE_COORDINATES);
+       rcl_u8(setup, x);
+       rcl_u8(setup, y);
+}
+
+static void emit_tile(struct vc4_exec_info *exec,
+                     struct vc4_rcl_setup *setup,
+                     uint8_t x, uint8_t y, bool first, bool last)
+{
+       bool has_bin = exec->args->bin_cl_size != 0;
+
+       /* Note that the load doesn't actually occur until the
+        * tile coords packet is processed, and only one load
+        * may be outstanding at a time.
+        */
+       if (setup->color_read) {
+               rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
+               rcl_u16(setup, exec->args->color_read.bits);
+               rcl_u32(setup,
+                       setup->color_read->paddr +
+                       exec->args->color_read.offset);
+       }
+
+       if (setup->zs_read) {
+               if (setup->color_read) {
+                       /* Exec previous load. */
+                       vc4_tile_coordinates(setup, x, y);
+                       vc4_store_before_load(setup);
+               }
+
+               rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
+               rcl_u16(setup, exec->args->zs_read.bits);
+               rcl_u32(setup,
+                       setup->zs_read->paddr + exec->args->zs_read.offset);
+       }
+
+       /* Clipping depends on tile coordinates having been
+        * emitted, so we always need one here.
+        */
+       vc4_tile_coordinates(setup, x, y);
+
+       /* Wait for the binner before jumping to the first
+        * tile's lists.
+        */
+       if (first && has_bin)
+               rcl_u8(setup, VC4_PACKET_WAIT_ON_SEMAPHORE);
+
+       if (has_bin) {
+               rcl_u8(setup, VC4_PACKET_BRANCH_TO_SUB_LIST);
+               rcl_u32(setup, (exec->tile_bo->paddr +
+                               exec->tile_alloc_offset +
+                               (y * exec->bin_tiles_x + x) * 32));
+       }
+
+       if (setup->zs_write) {
+               rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
+               rcl_u16(setup, exec->args->zs_write.bits |
+                       (setup->color_ms_write ?
+                        VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0));
+               rcl_u32(setup,
+                       (setup->zs_write->paddr + exec->args->zs_write.offset) |
+                       ((last && !setup->color_ms_write) ?
+                        VC4_LOADSTORE_TILE_BUFFER_EOF : 0));
+       }
+
+       if (setup->color_ms_write) {
+               if (setup->zs_write) {
+                       /* Reset after previous store */
+                       vc4_tile_coordinates(setup, x, y);
+               }
+
+               if (last)
+                       rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF);
+               else
+                       rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER);
+       }
+}
+
+static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
+                            struct vc4_rcl_setup *setup)
+{
+       bool has_bin = exec->args->bin_cl_size != 0;
+       uint8_t min_x_tile = exec->args->min_x_tile;
+       uint8_t min_y_tile = exec->args->min_y_tile;
+       uint8_t max_x_tile = exec->args->max_x_tile;
+       uint8_t max_y_tile = exec->args->max_y_tile;
+       uint8_t xtiles = max_x_tile - min_x_tile + 1;
+       uint8_t ytiles = max_y_tile - min_y_tile + 1;
+       uint8_t x, y;
+       uint32_t size, loop_body_size;
+
+       size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE;
+       loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE;
+
+       if (exec->args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) {
+               size += VC4_PACKET_CLEAR_COLORS_SIZE +
+                       VC4_PACKET_TILE_COORDINATES_SIZE +
+                       VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
+       }
+
+       if (setup->color_read) {
+               loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE);
+       }
+       if (setup->zs_read) {
+               if (setup->color_read) {
+                       loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
+                       loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
+               }
+               loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
+       }
+
+       if (has_bin) {
+               size += VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE;
+               loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE;
+       }
+
+       if (setup->zs_write)
+               loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
+       if (setup->color_ms_write) {
+               if (setup->zs_write)
+                       loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
+               loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE;
+       }
+       size += xtiles * ytiles * loop_body_size;
+
+       setup->rcl = drm_gem_cma_create(dev, size);
+       if (!setup->rcl)
+               return -ENOMEM;
+       list_addtail(&to_vc4_bo(&setup->rcl->base)->unref_head,
+                    &exec->unref_list);
+
+       rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
+       rcl_u32(setup,
+               (setup->color_ms_write ?
+                (setup->color_ms_write->paddr +
+                 exec->args->color_ms_write.offset) :
+                0));
+       rcl_u16(setup, exec->args->width);
+       rcl_u16(setup, exec->args->height);
+       rcl_u16(setup, exec->args->color_ms_write.bits);
+
+       /* The tile buffer gets cleared when the previous tile is stored.  If
+        * the clear values changed between frames, then the tile buffer has
+        * stale clear values in it, so we have to do a store in None mode (no
+        * writes) so that we trigger the tile buffer clear.
+        */
+       if (exec->args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) {
+               rcl_u8(setup, VC4_PACKET_CLEAR_COLORS);
+               rcl_u32(setup, exec->args->clear_color[0]);
+               rcl_u32(setup, exec->args->clear_color[1]);
+               rcl_u32(setup, exec->args->clear_z);
+               rcl_u8(setup, exec->args->clear_s);
+
+               vc4_tile_coordinates(setup, 0, 0);
+
+               rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
+               rcl_u16(setup, VC4_LOADSTORE_TILE_BUFFER_NONE);
+               rcl_u32(setup, 0); /* no address, since we're in None mode */
+       }
+
+       for (y = min_y_tile; y <= max_y_tile; y++) {
+               for (x = min_x_tile; x <= max_x_tile; x++) {
+                       bool first = (x == min_x_tile && y == min_y_tile);
+                       bool last = (x == max_x_tile && y == max_y_tile);
+                       emit_tile(exec, setup, x, y, first, last);
+               }
+       }
+
+       BUG_ON(setup->next_offset != size);
+       exec->ct1ca = setup->rcl->paddr;
+       exec->ct1ea = setup->rcl->paddr + setup->next_offset;
+
+       return 0;
+}
+
+static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
+                                struct drm_gem_cma_object **obj,
+                                struct drm_vc4_submit_rcl_surface *surf)
+{
+       uint8_t tiling = VC4_GET_FIELD(surf->bits,
+                                      VC4_LOADSTORE_TILE_BUFFER_TILING);
+       uint8_t buffer = VC4_GET_FIELD(surf->bits,
+                                      VC4_LOADSTORE_TILE_BUFFER_BUFFER);
+       uint8_t format = VC4_GET_FIELD(surf->bits,
+                                      VC4_LOADSTORE_TILE_BUFFER_FORMAT);
+       int cpp;
+
+       if (surf->pad != 0) {
+               DRM_ERROR("Padding unset\n");
+               return -EINVAL;
+       }
+
+       if (surf->hindex == ~0)
+               return 0;
+
+       if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj))
+               return -EINVAL;
+
+       if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK |
+                          VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK |
+                          VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) {
+               DRM_ERROR("Unknown bits in load/store: 0x%04x\n",
+                         surf->bits);
+               return -EINVAL;
+       }
+
+       if (tiling > VC4_TILING_FORMAT_LT) {
+               DRM_ERROR("Bad tiling format\n");
+               return -EINVAL;
+       }
+
+       if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) {
+               if (format != 0) {
+                       DRM_ERROR("No color format should be set for ZS\n");
+                       return -EINVAL;
+               }
+               cpp = 4;
+       } else if (buffer == VC4_LOADSTORE_TILE_BUFFER_COLOR) {
+               switch (format) {
+               case VC4_LOADSTORE_TILE_BUFFER_BGR565:
+               case VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER:
+                       cpp = 2;
+                       break;
+               case VC4_LOADSTORE_TILE_BUFFER_RGBA8888:
+                       cpp = 4;
+                       break;
+               default:
+                       DRM_ERROR("Bad tile buffer format\n");
+                       return -EINVAL;
+               }
+       } else {
+               DRM_ERROR("Bad load/store buffer %d.\n", buffer);
+               return -EINVAL;
+       }
+
+       if (surf->offset & 0xf) {
+               DRM_ERROR("load/store buffer must be 16b aligned.\n");
+               return -EINVAL;
+       }
+
+       if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling,
+                               exec->args->width, exec->args->height, cpp)) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int
+vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec,
+                        struct drm_gem_cma_object **obj,
+                        struct drm_vc4_submit_rcl_surface *surf)
+{
+       uint8_t tiling = VC4_GET_FIELD(surf->bits,
+                                      VC4_RENDER_CONFIG_MEMORY_FORMAT);
+       uint8_t format = VC4_GET_FIELD(surf->bits,
+                                      VC4_RENDER_CONFIG_FORMAT);
+       int cpp;
+
+       if (surf->pad != 0) {
+               DRM_ERROR("Padding unset\n");
+               return -EINVAL;
+       }
+
+       if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK |
+                          VC4_RENDER_CONFIG_FORMAT_MASK)) {
+               DRM_ERROR("Unknown bits in render config: 0x%04x\n",
+                         surf->bits);
+               return -EINVAL;
+       }
+
+       if (surf->hindex == ~0)
+               return 0;
+
+       if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj))
+               return -EINVAL;
+
+       if (tiling > VC4_TILING_FORMAT_LT) {
+               DRM_ERROR("Bad tiling format\n");
+               return -EINVAL;
+       }
+
+       switch (format) {
+       case VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED:
+       case VC4_RENDER_CONFIG_FORMAT_BGR565:
+               cpp = 2;
+               break;
+       case VC4_RENDER_CONFIG_FORMAT_RGBA8888:
+               cpp = 4;
+               break;
+       default:
+               DRM_ERROR("Bad tile buffer format\n");
+               return -EINVAL;
+       }
+
+       if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling,
+                               exec->args->width, exec->args->height, cpp)) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
+{
+       struct vc4_rcl_setup setup = {0};
+       struct drm_vc4_submit_cl *args = exec->args;
+       bool has_bin = args->bin_cl_size != 0;
+       int ret;
+
+       if (args->min_x_tile > args->max_x_tile ||
+           args->min_y_tile > args->max_y_tile) {
+               DRM_ERROR("Bad render tile set (%d,%d)-(%d,%d)\n",
+                         args->min_x_tile, args->min_y_tile,
+                         args->max_x_tile, args->max_y_tile);
+               return -EINVAL;
+       }
+
+       if (has_bin &&
+           (args->max_x_tile > exec->bin_tiles_x ||
+            args->max_y_tile > exec->bin_tiles_y)) {
+               DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n",
+                         args->max_x_tile, args->max_y_tile,
+                         exec->bin_tiles_x, exec->bin_tiles_y);
+               return -EINVAL;
+       }
+
+       ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
+       if (ret)
+               return ret;
+
+       ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write,
+                                      &args->color_ms_write);
+       if (ret)
+               return ret;
+
+       ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read);
+       if (ret)
+               return ret;
+
+       ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write);
+       if (ret)
+               return ret;
+
+       /* We shouldn't even have the job submitted to us if there's no
+        * surface to write out.
+        */
+       if (!setup.color_ms_write && !setup.zs_write) {
+               DRM_ERROR("RCL requires color or Z/S write\n");
+               return -EINVAL;
+       }
+
+       return vc4_create_rcl_bo(dev, exec, &setup);
+}
index 2d04a4a7b9aebeac1f16d88d09344754f344361e..a0b67a7e50b784d231797b9973be2a1bb7a150ec 100644 (file)
@@ -94,7 +94,7 @@ size_is_lt(uint32_t width, uint32_t height, int cpp)
                height <= 4 * utile_height(cpp));
 }
 
-static bool
+bool
 vc4_use_bo(struct vc4_exec_info *exec,
           uint32_t hindex,
           enum vc4_bo_mode mode,
@@ -147,33 +147,39 @@ gl_shader_rec_size(uint32_t pointer_bits)
                return 36 + attribute_count * 8;
 }
 
-static bool
-check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
-              uint32_t offset, uint8_t tiling_format,
-              uint32_t width, uint32_t height, uint8_t cpp)
+bool
+vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
+                  uint32_t offset, uint8_t tiling_format,
+                  uint32_t width, uint32_t height, uint8_t cpp)
 {
        uint32_t aligned_width, aligned_height, stride, size;
        uint32_t utile_w = utile_width(cpp);
        uint32_t utile_h = utile_height(cpp);
 
-       /* The values are limited by the packet/texture parameter bitfields,
-        * so we don't need to worry as much about integer overflow.
+       /* The shaded vertex format stores signed 12.4 fixed point
+        * (-2048,2047) offsets from the viewport center, so we should
+        * never have a render target larger than 4096.  The texture
+        * unit can only sample from 2048x2048, so it's even more
+        * restricted.  This lets us avoid worrying about overflow in
+        * our math.
         */
-       BUG_ON(width > 65535);
-       BUG_ON(height > 65535);
+       if (width > 4096 || height > 4096) {
+               DRM_ERROR("Surface dimesions (%d,%d) too large", width, height);
+               return false;
+       }
 
        switch (tiling_format) {
        case VC4_TILING_FORMAT_LINEAR:
-               aligned_width = roundup(width, utile_w);
+               aligned_width = round_up(width, utile_w);
                aligned_height = height;
                break;
        case VC4_TILING_FORMAT_T:
-               aligned_width = roundup(width, utile_w * 8);
-               aligned_height = roundup(height, utile_h * 8);
+               aligned_width = round_up(width, utile_w * 8);
+               aligned_height = round_up(height, utile_h * 8);
                break;
        case VC4_TILING_FORMAT_LT:
-               aligned_width = roundup(width, utile_w);
-               aligned_height = roundup(height, utile_h);
+               aligned_width = round_up(width, utile_w);
+               aligned_height = round_up(height, utile_h);
                break;
        default:
                DRM_ERROR("buffer tiling %d unsupported\n", tiling_format);
@@ -181,13 +187,6 @@ check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
        }
 
        stride = aligned_width * cpp;
-
-       if (INT_MAX / stride < aligned_height) {
-               DRM_ERROR("Overflow in fbo size (%dx%d -> %dx%d)\n",
-                         width, height,
-                         aligned_width, aligned_height);
-               return false;
-       }
        size = stride * aligned_height;
 
        if (size + offset < size ||
@@ -248,122 +247,6 @@ validate_increment_semaphore(VALIDATE_ARGS)
        return 0;
 }
 
-static int
-validate_wait_on_semaphore(VALIDATE_ARGS)
-{
-       if (exec->found_wait_on_semaphore_packet) {
-               DRM_ERROR("Duplicate VC4_PACKET_WAIT_ON_SEMAPHORE\n");
-               return -EINVAL;
-       }
-       exec->found_wait_on_semaphore_packet = true;
-
-       if (!exec->found_increment_semaphore_packet) {
-               DRM_ERROR("VC4_PACKET_WAIT_ON_SEMAPHORE without "
-                         "VC4_PACKET_INCREMENT_SEMAPHORE\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int
-validate_branch_to_sublist(VALIDATE_ARGS)
-{
-       struct drm_gem_cma_object *target;
-       uint32_t offset;
-
-       if (!vc4_use_handle(exec, 0, VC4_MODE_TILE_ALLOC, &target))
-               return -EINVAL;
-
-       if (target != exec->tile_alloc_bo) {
-               DRM_ERROR("Jumping to BOs other than tile alloc unsupported\n");
-               return -EINVAL;
-       }
-
-       if (!exec->found_wait_on_semaphore_packet) {
-               DRM_ERROR("Jumping to tile alloc before binning finished.\n");
-               return -EINVAL;
-       }
-
-       offset = *(uint32_t *)(untrusted + 0);
-       if (offset % exec->tile_alloc_init_block_size ||
-           offset / exec->tile_alloc_init_block_size >=
-           exec->bin_tiles_x * exec->bin_tiles_y) {
-               DRM_ERROR("VC4_PACKET_BRANCH_TO_SUB_LIST must jump to initial "
-                         "tile allocation space.\n");
-               return -EINVAL;
-       }
-
-       *(uint32_t *)(validated + 0) = target->paddr + offset;
-
-       return 0;
-}
-
-/**
- * validate_loadstore_tile_buffer_general() - Validation for
- * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL and
- * VC4_PACKET_STORE_TILE_BUFFER_GENERAL.
- *
- * The two packets are nearly the same, except for the TLB-clearing management
- * bits not being present for loads.  Additionally, while stores are executed
- * immediately (using the current tile coordinates), loads are queued to be
- * executed when the tile coordinates packet occurs.
- *
- * Note that coordinates packets are validated to be within the declared
- * bin_x/y, which themselves are verified to match the rendering-configuration
- * FB width and height (which the hardware uses to clip loads and stores).
- */
-static int
-validate_loadstore_tile_buffer_general(VALIDATE_ARGS)
-{
-       uint32_t packet_b0 = *(uint8_t *)(untrusted + 0);
-       uint32_t packet_b1 = *(uint8_t *)(untrusted + 1);
-       struct drm_gem_cma_object *fbo;
-       uint32_t buffer_type = packet_b0 & 0xf;
-       uint32_t untrusted_address, offset, cpp;
-
-       switch (buffer_type) {
-       case VC4_LOADSTORE_TILE_BUFFER_NONE:
-               return 0;
-       case VC4_LOADSTORE_TILE_BUFFER_COLOR:
-               if ((packet_b1 & VC4_LOADSTORE_TILE_BUFFER_MASK) ==
-                   VC4_LOADSTORE_TILE_BUFFER_RGBA8888) {
-                       cpp = 4;
-               } else {
-                       cpp = 2;
-               }
-               break;
-
-       case VC4_LOADSTORE_TILE_BUFFER_Z:
-       case VC4_LOADSTORE_TILE_BUFFER_ZS:
-               cpp = 4;
-               break;
-
-       default:
-               DRM_ERROR("Load/store type %d unsupported\n", buffer_type);
-               return -EINVAL;
-       }
-
-       if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &fbo))
-               return -EINVAL;
-
-       untrusted_address = *(uint32_t *)(untrusted + 2);
-       offset = untrusted_address & ~0xf;
-
-       if (!check_tex_size(exec, fbo, offset,
-                           ((packet_b0 &
-                             VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK) >>
-                            VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT),
-                           exec->fb_width, exec->fb_height, cpp)) {
-               return -EINVAL;
-       }
-
-       *(uint32_t *)(validated + 2) = (offset + fbo->paddr +
-                                       (untrusted_address & 0xf));
-
-       return 0;
-}
-
 static int
 validate_indexed_prim_list(VALIDATE_ARGS)
 {
@@ -492,14 +375,10 @@ validate_nv_shader_state(VALIDATE_ARGS)
 static int
 validate_tile_binning_config(VALIDATE_ARGS)
 {
-       struct drm_gem_cma_object *tile_allocation;
-       struct drm_gem_cma_object *tile_state_data_array;
+       struct drm_device *dev = exec->exec_bo->base.dev;
        uint8_t flags;
-       uint32_t tile_allocation_size;
-
-       if (!vc4_use_handle(exec, 0, VC4_MODE_TILE_ALLOC, &tile_allocation) ||
-           !vc4_use_handle(exec, 1, VC4_MODE_TSDA, &tile_state_data_array))
-               return -EINVAL;
+       uint32_t tile_state_size, tile_alloc_size;
+       uint32_t tile_count;
 
        if (exec->found_tile_binning_mode_config_packet) {
                DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
@@ -509,6 +388,7 @@ validate_tile_binning_config(VALIDATE_ARGS)
 
        exec->bin_tiles_x = *(uint8_t *)(untrusted + 12);
        exec->bin_tiles_y = *(uint8_t *)(untrusted + 13);
+       tile_count = exec->bin_tiles_x * exec->bin_tiles_y;
        flags = *(uint8_t *)(untrusted + 14);
 
        if (exec->bin_tiles_x == 0 ||
@@ -518,15 +398,6 @@ validate_tile_binning_config(VALIDATE_ARGS)
                return -EINVAL;
        }
 
-       /* Our validation relies on the user not getting to set up their own
-        * tile state/tile allocation BO contents.
-        */
-       if (!(flags & VC4_BIN_CONFIG_AUTO_INIT_TSDA)) {
-               DRM_ERROR("binning config missing "
-                         "VC4_BIN_CONFIG_AUTO_INIT_TSDA\n");
-               return -EINVAL;
-       }
-
        if (flags & (VC4_BIN_CONFIG_DB_NON_MS |
                     VC4_BIN_CONFIG_TILE_BUFFER_64BIT |
                     VC4_BIN_CONFIG_MS_MODE_4X)) {
@@ -534,94 +405,52 @@ validate_tile_binning_config(VALIDATE_ARGS)
                return -EINVAL;
        }
 
-       if (*(uint32_t *)(untrusted + 0) != 0) {
-               DRM_ERROR("tile allocation offset != 0 unsupported\n");
-               return -EINVAL;
-       }
-       tile_allocation_size = *(uint32_t *)(untrusted + 4);
-       if (tile_allocation_size > tile_allocation->base.size) {
-               DRM_ERROR("tile allocation size %d > BO size %d\n",
-                         tile_allocation_size, tile_allocation->base.size);
-               return -EINVAL;
-       }
-       *(uint32_t *)validated = tile_allocation->paddr;
-       exec->tile_alloc_bo = tile_allocation;
-
-       exec->tile_alloc_init_block_size = 1 << (5 + ((flags >> 5) & 3));
-       if (exec->bin_tiles_x * exec->bin_tiles_y *
-           exec->tile_alloc_init_block_size > tile_allocation_size) {
-               DRM_ERROR("tile init exceeds tile alloc size (%d vs %d)\n",
-                         exec->bin_tiles_x * exec->bin_tiles_y *
-                         exec->tile_alloc_init_block_size,
-                         tile_allocation_size);
-               return -EINVAL;
-       }
-       if (*(uint32_t *)(untrusted + 8) != 0) {
-               DRM_ERROR("TSDA offset != 0 unsupported\n");
-               return -EINVAL;
-       }
-       if (exec->bin_tiles_x * exec->bin_tiles_y * 48 >
-           tile_state_data_array->base.size) {
-               DRM_ERROR("TSDA of %db too small for %dx%d bin config\n",
-                         tile_state_data_array->base.size,
-                         exec->bin_tiles_x, exec->bin_tiles_y);
-       }
-       *(uint32_t *)(validated + 8) = tile_state_data_array->paddr;
-
-       return 0;
-}
-
-static int
-validate_tile_rendering_mode_config(VALIDATE_ARGS)
-{
-       struct drm_gem_cma_object *fbo;
-       uint32_t flags, offset, cpp;
-
-       if (exec->found_tile_rendering_mode_config_packet) {
-               DRM_ERROR("Duplicate VC4_PACKET_TILE_RENDERING_MODE_CONFIG\n");
-               return -EINVAL;
-       }
-       exec->found_tile_rendering_mode_config_packet = true;
-
-       if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &fbo))
-               return -EINVAL;
-
-       exec->fb_width = *(uint16_t *)(untrusted + 4);
-       exec->fb_height = *(uint16_t *)(untrusted + 6);
-
-       flags = *(uint16_t *)(untrusted + 8);
-       if ((flags & VC4_RENDER_CONFIG_FORMAT_MASK) ==
-           VC4_RENDER_CONFIG_FORMAT_RGBA8888) {
-               cpp = 4;
-       } else {
-               cpp = 2;
-       }
-
-       offset = *(uint32_t *)untrusted;
-       if (!check_tex_size(exec, fbo, offset,
-                           ((flags &
-                             VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK) >>
-                            VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT),
-                           exec->fb_width, exec->fb_height, cpp)) {
-               return -EINVAL;
-       }
-
-       *(uint32_t *)validated = fbo->paddr + offset;
-
-       return 0;
-}
-
-static int
-validate_tile_coordinates(VALIDATE_ARGS)
-{
-       uint8_t tile_x = *(uint8_t *)(untrusted + 0);
-       uint8_t tile_y = *(uint8_t *)(untrusted + 1);
+       /* The tile state data array is 48 bytes per tile, and we put it at
+        * the start of a BO containing both it and the tile alloc.
+        */
+       tile_state_size = 48 * tile_count;
+
+       /* Since the tile alloc array will follow us, align. */
+       exec->tile_alloc_offset = roundup(tile_state_size, 4096);
+
+       *(uint8_t *)(validated + 14) =
+               ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK |
+                           VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK)) |
+                VC4_BIN_CONFIG_AUTO_INIT_TSDA |
+                VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32,
+                              VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE) |
+                VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128,
+                              VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE));
+
+       /* Initial block size. */
+       tile_alloc_size = 32 * tile_count;
+
+       /*
+        * The initial allocation gets rounded to the next 256 bytes before
+        * the hardware starts fulfilling further allocations.
+        */
+       tile_alloc_size = roundup(tile_alloc_size, 256);
 
-       if (tile_x * 64 >= exec->fb_width || tile_y * 64 >= exec->fb_height) {
-               DRM_ERROR("Tile coordinates %d,%d > render config %dx%d\n",
-                         tile_x, tile_y, exec->fb_width, exec->fb_height);
-               return -EINVAL;
-       }
+       /* Add space for the extra allocations.  This is what gets used first,
+        * before overflow memory.  It must have at least 4096 bytes, but we
+        * want to avoid overflow memory usage if possible.
+        */
+       tile_alloc_size += 1024 * 1024;
+
+       exec->tile_bo = drm_gem_cma_create(dev, exec->tile_alloc_offset +
+                                          tile_alloc_size);
+       if (!exec->tile_bo)
+               return -ENOMEM;
+       list_addtail(&to_vc4_bo(&exec->tile_bo->base)->unref_head,
+                    &exec->unref_list);
+
+       /* tile alloc address. */
+       *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr +
+                                       exec->tile_alloc_offset);
+       /* tile alloc size. */
+       *(uint32_t *)(validated + 4) = tile_alloc_size;
+       /* tile state address. */
+       *(uint32_t *)(validated + 8) = exec->tile_bo->paddr;
 
        return 0;
 }
@@ -633,78 +462,60 @@ validate_gem_handles(VALIDATE_ARGS)
        return 0;
 }
 
+#define VC4_DEFINE_PACKET(packet, name, func) \
+       [packet] = { packet ## _SIZE, name, func }
+
 static const struct cmd_info {
-       bool bin;
-       bool render;
        uint16_t len;
        const char *name;
        int (*func)(struct vc4_exec_info *exec, void *validated,
                    void *untrusted);
 } cmd_info[] = {
-       [VC4_PACKET_HALT] = { 1, 1, 1, "halt", NULL },
-       [VC4_PACKET_NOP] = { 1, 1, 1, "nop", NULL },
-       [VC4_PACKET_FLUSH] = { 1, 1, 1, "flush", NULL },
-       [VC4_PACKET_FLUSH_ALL] = { 1, 0, 1, "flush all state", validate_flush_all },
-       [VC4_PACKET_START_TILE_BINNING] = { 1, 0, 1, "start tile binning", validate_start_tile_binning },
-       [VC4_PACKET_INCREMENT_SEMAPHORE] = { 1, 0, 1, "increment semaphore", validate_increment_semaphore },
-       [VC4_PACKET_WAIT_ON_SEMAPHORE] = { 0, 1, 1, "wait on semaphore", validate_wait_on_semaphore },
-       /* BRANCH_TO_SUB_LIST is actually supported in the binner as well, but
-        * we only use it from the render CL in order to jump into the tile
-        * allocation BO.
-        */
-       [VC4_PACKET_BRANCH_TO_SUB_LIST] = { 0, 1, 5, "branch to sublist", validate_branch_to_sublist },
-       [VC4_PACKET_STORE_MS_TILE_BUFFER] = { 0, 1, 1, "store MS resolved tile color buffer", NULL },
-       [VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF] = { 0, 1, 1, "store MS resolved tile color buffer and EOF", NULL },
+       VC4_DEFINE_PACKET(VC4_PACKET_HALT, "halt", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_NOP, "nop", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, "flush", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, "flush all state", validate_flush_all),
+       VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, "start tile binning", validate_start_tile_binning),
+       VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, "increment semaphore", validate_increment_semaphore),
 
-       [VC4_PACKET_STORE_TILE_BUFFER_GENERAL] = { 0, 1, 7, "Store Tile Buffer General", validate_loadstore_tile_buffer_general },
-       [VC4_PACKET_LOAD_TILE_BUFFER_GENERAL] = { 0, 1, 7, "Load Tile Buffer General", validate_loadstore_tile_buffer_general },
+       VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, "Indexed Primitive List", validate_indexed_prim_list),
 
-       [VC4_PACKET_GL_INDEXED_PRIMITIVE] = { 1, 1, 14, "Indexed Primitive List", validate_indexed_prim_list },
-
-       [VC4_PACKET_GL_ARRAY_PRIMITIVE] = { 1, 1, 10, "Vertex Array Primitives", validate_gl_array_primitive },
+       VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, "Vertex Array Primitives", validate_gl_array_primitive),
 
        /* This is only used by clipped primitives (packets 48 and 49), which
         * we don't support parsing yet.
         */
-       [VC4_PACKET_PRIMITIVE_LIST_FORMAT] = { 1, 1, 2, "primitive list format", NULL },
-
-       [VC4_PACKET_GL_SHADER_STATE] = { 1, 1, 5, "GL Shader State", validate_gl_shader_state },
-       [VC4_PACKET_NV_SHADER_STATE] = { 1, 1, 5, "NV Shader State", validate_nv_shader_state },
-
-       [VC4_PACKET_CONFIGURATION_BITS] = { 1, 1, 4, "configuration bits", NULL },
-       [VC4_PACKET_FLAT_SHADE_FLAGS] = { 1, 1, 5, "flat shade flags", NULL },
-       [VC4_PACKET_POINT_SIZE] = { 1, 1, 5, "point size", NULL },
-       [VC4_PACKET_LINE_WIDTH] = { 1, 1, 5, "line width", NULL },
-       [VC4_PACKET_RHT_X_BOUNDARY] = { 1, 1, 3, "RHT X boundary", NULL },
-       [VC4_PACKET_DEPTH_OFFSET] = { 1, 1, 5, "Depth Offset", NULL },
-       [VC4_PACKET_CLIP_WINDOW] = { 1, 1, 9, "Clip Window", NULL },
-       [VC4_PACKET_VIEWPORT_OFFSET] = { 1, 1, 5, "Viewport Offset", NULL },
-       [VC4_PACKET_CLIPPER_XY_SCALING] = { 1, 1, 9, "Clipper XY Scaling", NULL },
+       VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, "primitive list format", NULL),
+
+       VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, "GL Shader State", validate_gl_shader_state),
+       VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, "NV Shader State", validate_nv_shader_state),
+
+       VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, "configuration bits", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, "flat shade flags", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, "point size", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, "line width", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, "RHT X boundary", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, "Depth Offset", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, "Clip Window", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, "Viewport Offset", NULL),
+       VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, "Clipper XY Scaling", NULL),
        /* Note: The docs say this was also 105, but it was 106 in the
         * initial userland code drop.
         */
-       [VC4_PACKET_CLIPPER_Z_SCALING] = { 1, 1, 9, "Clipper Z Scale and Offset", NULL },
-
-       [VC4_PACKET_TILE_BINNING_MODE_CONFIG] = { 1, 0, 16, "tile binning configuration", validate_tile_binning_config },
+       VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, "Clipper Z Scale and Offset", NULL),
 
-       [VC4_PACKET_TILE_RENDERING_MODE_CONFIG] = { 0, 1, 11, "tile rendering mode configuration", validate_tile_rendering_mode_config},
+       VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, "tile binning configuration", validate_tile_binning_config),
 
-       [VC4_PACKET_CLEAR_COLORS] = { 0, 1, 14, "Clear Colors", NULL },
-
-       [VC4_PACKET_TILE_COORDINATES] = { 0, 1, 3, "Tile Coordinates", validate_tile_coordinates },
-
-       [VC4_PACKET_GEM_HANDLES] = { 1, 1, 9, "GEM handles", validate_gem_handles },
+       VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, "GEM handles", validate_gem_handles),
 };
 
 int
-vc4_validate_cl(struct drm_device *dev,
-               void *validated,
-               void *unvalidated,
-               uint32_t len,
-               bool is_bin,
-               bool has_bin,
-               struct vc4_exec_info *exec)
+vc4_validate_bin_cl(struct drm_device *dev,
+                   void *validated,
+                   void *unvalidated,
+                   struct vc4_exec_info *exec)
 {
+       uint32_t len = exec->args->bin_cl_size;
        uint32_t dst_offset = 0;
        uint32_t src_offset = 0;
 
@@ -732,14 +543,6 @@ vc4_validate_cl(struct drm_device *dev,
                         src_offset, cmd, info->name, info->len);
 #endif
 
-               if ((is_bin && !info->bin) ||
-                   (!is_bin && !info->render)) {
-                       DRM_ERROR("0x%08x: packet %d (%s) invalid for %s\n",
-                                 src_offset, cmd, info->name,
-                                 is_bin ? "binner" : "render");
-                       return -EINVAL;
-               }
-
                if (src_offset + info->len > len) {
                        DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x "
                                  "exceeds bounds (0x%08x)\n",
@@ -770,30 +573,16 @@ vc4_validate_cl(struct drm_device *dev,
                        break;
        }
 
-       if (is_bin) {
-               exec->ct0ea = exec->ct0ca + dst_offset;
+       exec->ct0ea = exec->ct0ca + dst_offset;
 
-               if (has_bin && !exec->found_start_tile_binning_packet) {
-                       DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
-                       return -EINVAL;
-               }
-       } else {
-               if (!exec->found_tile_rendering_mode_config_packet) {
-                       DRM_ERROR("Render CL missing VC4_PACKET_TILE_RENDERING_MODE_CONFIG\n");
-                       return -EINVAL;
-               }
+       if (!exec->found_start_tile_binning_packet) {
+               DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
+               return -EINVAL;
+       }
 
-               /* Make sure that they actually consumed the semaphore
-                * increment from the bin CL.  Otherwise a later submit would
-                * have render execute immediately.
-                */
-               if (exec->found_wait_on_semaphore_packet != has_bin) {
-                       DRM_ERROR("Render CL %s VC4_PACKET_WAIT_ON_SEMAPHORE\n",
-                                 exec->found_wait_on_semaphore_packet ?
-                                 "has" : "missing");
-                       return -EINVAL;
-               }
-               exec->ct1ea = exec->ct1ca + dst_offset;
+       if (!exec->found_increment_semaphore_packet) {
+               DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE\n");
+               return -EINVAL;
        }
 
        return 0;
@@ -814,10 +603,10 @@ reloc_tex(struct vc4_exec_info *exec,
        uint32_t p3 = (sample->p_offset[3] != ~0 ?
                       *(uint32_t *)(uniform_data_u + sample->p_offset[3]) : 0);
        uint32_t *validated_p0 = exec->uniforms_v + sample->p_offset[0];
-       uint32_t offset = p0 & ~0xfff;
-       uint32_t miplevels = (p0 & 15);
-       uint32_t width = (p1 >> 8) & 2047;
-       uint32_t height = (p1 >> 20) & 2047;
+       uint32_t offset = p0 & VC4_TEX_P0_OFFSET_MASK;
+       uint32_t miplevels = VC4_GET_FIELD(p0, VC4_TEX_P0_MIPLVLS);
+       uint32_t width = VC4_GET_FIELD(p1, VC4_TEX_P1_WIDTH);
+       uint32_t height = VC4_GET_FIELD(p1, VC4_TEX_P1_HEIGHT);
        uint32_t cpp, tiling_format, utile_w, utile_h;
        uint32_t i;
        uint32_t cube_map_stride = 0;
@@ -845,16 +634,18 @@ reloc_tex(struct vc4_exec_info *exec,
        if (height == 0)
                height = 2048;
 
-       if (p0 & (1 << 9)) {
-               if ((p2 & (3 << 30)) == (1 << 30))
-                       cube_map_stride = p2 & 0x3ffff000;
-               if ((p3 & (3 << 30)) == (1 << 30)) {
+       if (p0 & VC4_TEX_P0_CMMODE_MASK) {
+               if (VC4_GET_FIELD(p2, VC4_TEX_P2_PTYPE) ==
+                   VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE)
+                       cube_map_stride = p2 & VC4_TEX_P2_CMST_MASK;
+               if (VC4_GET_FIELD(p3, VC4_TEX_P2_PTYPE) ==
+                   VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) {
                        if (cube_map_stride) {
                                DRM_ERROR("Cube map stride set twice\n");
                                return false;
                        }
 
-                       cube_map_stride = p3 & 0x3ffff000;
+                       cube_map_stride = p3 & VC4_TEX_P2_CMST_MASK;
                }
                if (!cube_map_stride) {
                        DRM_ERROR("Cube map stride not set\n");
@@ -862,7 +653,8 @@ reloc_tex(struct vc4_exec_info *exec,
                }
        }
 
-       type = ((p0 >> 4) & 15) | ((p1 >> 31) << 4);
+       type = (VC4_GET_FIELD(p0, VC4_TEX_P0_TYPE) |
+               (VC4_GET_FIELD(p1, VC4_TEX_P1_TYPE4) << 4));
 
        switch (type) {
        case VC4_TEXTURE_TYPE_RGBA8888:
@@ -905,8 +697,8 @@ reloc_tex(struct vc4_exec_info *exec,
                        tiling_format = VC4_TILING_FORMAT_T;
        }
 
-       if (!check_tex_size(exec, tex, offset + cube_map_stride * 5,
-                           tiling_format, width, height, cpp)) {
+       if (!vc4_check_tex_size(exec, tex, offset + cube_map_stride * 5,
+                               tiling_format, width, height, cpp)) {
                return false;
        }
 
@@ -927,15 +719,15 @@ reloc_tex(struct vc4_exec_info *exec,
 
                switch (tiling_format) {
                case VC4_TILING_FORMAT_T:
-                       aligned_width = roundup(level_width, utile_w * 8);
-                       aligned_height = roundup(level_height, utile_h * 8);
+                       aligned_width = round_up(level_width, utile_w * 8);
+                       aligned_height = round_up(level_height, utile_h * 8);
                        break;
                case VC4_TILING_FORMAT_LT:
-                       aligned_width = roundup(level_width, utile_w);
-                       aligned_height = roundup(level_height, utile_h);
+                       aligned_width = round_up(level_width, utile_w);
+                       aligned_height = round_up(level_height, utile_h);
                        break;
                default:
-                       aligned_width = roundup(level_width, utile_w);
+                       aligned_width = round_up(level_width, utile_w);
                        aligned_height = level_height;
                        break;
                }
index e5a75c5f8c26b0087f5350cddcac6d62ee7c2862..ab9a6512e828e8a4d6c4247b494a3c2b34338689 100644 (file)
@@ -58,7 +58,8 @@ struct vc4_shader_validation_state {
         *
         * This is used for the validation of direct address memory reads.
         */
-       uint32_t live_clamp_offsets[32 + 32 + 4];
+       uint32_t live_min_clamp_offsets[32 + 32 + 4];
+       bool live_max_clamp_regs[32 + 32 + 4];
 };
 
 static uint32_t
@@ -77,6 +78,25 @@ waddr_to_live_reg_index(uint32_t waddr, bool is_b)
        }
 }
 
+static uint32_t
+raddr_add_a_to_live_reg_index(uint64_t inst)
+{
+       uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG);
+       uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A);
+       uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A);
+       uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B);
+
+       if (add_a == QPU_MUX_A) {
+               return raddr_a;
+       } else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) {
+               return 32 + raddr_b;
+       } else if (add_a <= QPU_MUX_R3) {
+               return 64 + add_a;
+       } else {
+               return ~0;
+       }
+}
+
 static bool
 is_tmu_submit(uint32_t waddr)
 {
@@ -136,9 +156,8 @@ check_tmu_write(uint64_t inst,
        uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG);
 
        if (is_direct) {
-               uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A);
                uint32_t add_b = QPU_GET_FIELD(inst, QPU_ADD_B);
-               uint32_t clamp_offset = ~0;
+               uint32_t clamp_reg, clamp_offset;
 
                if (sig == QPU_SIG_SMALL_IMM) {
                        DRM_ERROR("direct TMU read used small immediate\n");
@@ -159,14 +178,13 @@ check_tmu_write(uint64_t inst,
                 * This is arbitrary, but simpler than supporting flipping the
                 * two either way.
                 */
-               if (add_a == QPU_MUX_A) {
-                       clamp_offset = validation_state->live_clamp_offsets[raddr_a];
-               } else if (add_a == QPU_MUX_B) {
-                       clamp_offset = validation_state->live_clamp_offsets[32 + raddr_b];
-               } else if (add_a <= QPU_MUX_R4) {
-                       clamp_offset = validation_state->live_clamp_offsets[64 + add_a];
+               clamp_reg = raddr_add_a_to_live_reg_index(inst);
+               if (clamp_reg == ~0) {
+                       DRM_ERROR("direct TMU load wasn't clamped\n");
+                       return false;
                }
 
+               clamp_offset = validation_state->live_min_clamp_offsets[clamp_reg];
                if (clamp_offset == ~0) {
                        DRM_ERROR("direct TMU load wasn't clamped\n");
                        return false;
@@ -229,8 +247,6 @@ check_register_write(uint64_t inst,
        uint32_t waddr = (is_mul ?
                          QPU_GET_FIELD(inst, QPU_WADDR_MUL) :
                          QPU_GET_FIELD(inst, QPU_WADDR_ADD));
-       bool is_b = is_mul != ((inst & QPU_WS) != 0);
-       uint32_t live_reg_index;
 
        switch (waddr) {
        case QPU_W_UNIFORMS_ADDRESS:
@@ -285,14 +301,6 @@ check_register_write(uint64_t inst,
                 return true;
        }
 
-       /* Clear out the live offset clamp tracking for the written register.
-        * If this particular instruction is setting up an offset clamp, it'll
-        * get tracked immediately after we return.
-        */
-       live_reg_index = waddr_to_live_reg_index(waddr, is_b);
-       if (live_reg_index != ~0)
-               validation_state->live_clamp_offsets[live_reg_index] = ~0;
-
        return true;
 }
 
@@ -301,26 +309,72 @@ track_live_clamps(uint64_t inst,
                  struct vc4_validated_shader_info *validated_shader,
                  struct vc4_shader_validation_state *validation_state)
 {
+       uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD);
        uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
+       uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL);
+       uint32_t cond_add = QPU_GET_FIELD(inst, QPU_COND_ADD);
+       uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A);
        uint32_t add_b = QPU_GET_FIELD(inst, QPU_ADD_B);
        uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A);
        uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B);
        uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG);
-       bool is_b = inst & QPU_WS;
-       uint32_t live_reg_index;
+       bool ws = inst & QPU_WS;
+       uint32_t lri_add_a, lri_add, lri_mul;
+       bool add_a_is_min_0;
 
-       if (QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_MIN)
+       /* Check whether OP_ADD's A argumennt comes from a live MAX(x, 0),
+        * before we clear previous live state.
+        */
+       lri_add_a = raddr_add_a_to_live_reg_index(inst);
+       add_a_is_min_0 = (lri_add_a != ~0 &&
+                         validation_state->live_max_clamp_regs[lri_add_a]);
+
+       /* Clear live state for registers written by our instruction. */
+       lri_add = waddr_to_live_reg_index(waddr_add, ws);
+       lri_mul = waddr_to_live_reg_index(waddr_mul, !ws);
+       if (lri_mul != ~0) {
+               validation_state->live_max_clamp_regs[lri_mul] = false;
+               validation_state->live_min_clamp_offsets[lri_mul] = ~0;
+       }
+       if (lri_add != ~0) {
+               validation_state->live_max_clamp_regs[lri_add] = false;
+               validation_state->live_min_clamp_offsets[lri_add] = ~0;
+       } else {
+               /* Nothing further to do for live tracking, since only ADDs
+                * generate new live clamp registers.
+                */
                return;
+       }
+
+       /* Now, handle remaining live clamp tracking for the ADD operation. */
 
-       if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) &&
-           !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF &&
-             sig != QPU_SIG_SMALL_IMM)) {
+       if (cond_add != QPU_COND_ALWAYS)
                return;
-       }
 
-       live_reg_index = waddr_to_live_reg_index(waddr_add, is_b);
-       if (live_reg_index != ~0) {
-               validation_state->live_clamp_offsets[live_reg_index] =
+       if (op_add == QPU_A_MAX) {
+               /* Track live clamps of a value to a minimum of 0 (in either
+                * arg).
+                */
+               if (sig != QPU_SIG_SMALL_IMM || raddr_b != 0 ||
+                   (add_a != QPU_MUX_B && add_b != QPU_MUX_B)) {
+                       return;
+               }
+
+               validation_state->live_max_clamp_regs[lri_add] = true;
+       } if (op_add == QPU_A_MIN) {
+               /* Track live clamps of a value clamped to a minimum of 0 and
+                * a maximum of some uniform's offset.
+                */
+               if (!add_a_is_min_0)
+                       return;
+
+               if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) &&
+                   !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF &&
+                     sig != QPU_SIG_SMALL_IMM)) {
+                       return;
+               }
+
+               validation_state->live_min_clamp_offsets[lri_add] =
                        validated_shader->uniforms_size;
        }
 }
@@ -382,8 +436,8 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
 
        for (i = 0; i < 8; i++)
                validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0;
-       for (i = 0; i < ARRAY_SIZE(validation_state.live_clamp_offsets); i++)
-               validation_state.live_clamp_offsets[i] = ~0;
+       for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++)
+               validation_state.live_min_clamp_offsets[i] = ~0;
 
        shader = shader_obj->vaddr;
        max_ip = shader_obj->base.size / sizeof(uint64_t);
index 2d524c40b4d06df0be3e54c48e1c6ba7b11a3683..d29e2c9c318436496d5ed79286d6e9b5642e43ef 100644 (file)
 #include "util/u_blitter.h"
 #include "vc4_context.h"
 
-static void
-vc4_tile_blit_color_rcl(struct vc4_context *vc4,
-                        struct vc4_surface *dst_surf,
-                        struct vc4_surface *src_surf)
-{
-        struct vc4_resource *src = vc4_resource(src_surf->base.texture);
-        struct vc4_resource *dst = vc4_resource(dst_surf->base.texture);
-
-        uint32_t min_x_tile = 0;
-        uint32_t min_y_tile = 0;
-        uint32_t max_x_tile = (dst_surf->base.width - 1) / 64;
-        uint32_t max_y_tile = (dst_surf->base.height - 1) / 64;
-        uint32_t xtiles = max_x_tile - min_x_tile + 1;
-        uint32_t ytiles = max_y_tile - min_y_tile + 1;
-        uint32_t reloc_size = 9;
-        uint32_t config_size = 11 + reloc_size;
-        uint32_t loadstore_size = 7 + reloc_size;
-        uint32_t tilecoords_size = 3;
-        cl_ensure_space(&vc4->rcl,
-                        config_size +
-                        xtiles * ytiles * (loadstore_size * 2 +
-                                           tilecoords_size * 1));
-        cl_ensure_space(&vc4->bo_handles, 2 * sizeof(uint32_t));
-        cl_ensure_space(&vc4->bo_pointers, 2 * sizeof(struct vc4_bo *));
-
-        cl_start_reloc(&vc4->rcl, 1);
-        cl_u8(&vc4->rcl, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
-        cl_reloc(vc4, &vc4->rcl, dst->bo, dst_surf->offset);
-        cl_u16(&vc4->rcl, dst_surf->base.width);
-        cl_u16(&vc4->rcl, dst_surf->base.height);
-        cl_u16(&vc4->rcl, ((dst_surf->tiling <<
-                            VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT) |
-                           (vc4_rt_format_is_565(dst_surf->base.format) ?
-                            VC4_RENDER_CONFIG_FORMAT_BGR565 :
-                            VC4_RENDER_CONFIG_FORMAT_RGBA8888)));
-
-        uint32_t src_hindex = vc4_gem_hindex(vc4, src->bo);
-
-        for (int y = min_y_tile; y <= max_y_tile; y++) {
-                for (int x = min_x_tile; x <= max_x_tile; x++) {
-                        bool end_of_frame = (x == max_x_tile &&
-                                             y == max_y_tile);
-
-                        cl_start_reloc(&vc4->rcl, 1);
-                        cl_u8(&vc4->rcl, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
-                        cl_u8(&vc4->rcl,
-                              VC4_LOADSTORE_TILE_BUFFER_COLOR |
-                              (src_surf->tiling <<
-                               VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT));
-                        cl_u8(&vc4->rcl,
-                              vc4_rt_format_is_565(src_surf->base.format) ?
-                              VC4_LOADSTORE_TILE_BUFFER_BGR565 :
-                              VC4_LOADSTORE_TILE_BUFFER_RGBA8888);
-                        cl_reloc_hindex(&vc4->rcl, src_hindex,
-                                        src_surf->offset);
-
-                        cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES);
-                        cl_u8(&vc4->rcl, x);
-                        cl_u8(&vc4->rcl, y);
-
-                        if (end_of_frame) {
-                                cl_u8(&vc4->rcl,
-                                      VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF);
-                        } else {
-                                cl_u8(&vc4->rcl,
-                                      VC4_PACKET_STORE_MS_TILE_BUFFER);
-                        }
-                }
-        }
-
-        vc4->draw_min_x = 0;
-        vc4->draw_min_y = 0;
-        vc4->draw_max_x = dst_surf->base.width;
-        vc4->draw_max_y = dst_surf->base.height;
-
-        dst->writes++;
-        vc4->needs_flush = true;
-}
-
-static struct vc4_surface *
+static struct pipe_surface *
 vc4_get_blit_surface(struct pipe_context *pctx,
                      struct pipe_resource *prsc, unsigned level)
 {
@@ -117,7 +38,7 @@ vc4_get_blit_surface(struct pipe_context *pctx,
         tmpl.u.tex.first_layer = 0;
         tmpl.u.tex.last_layer = 0;
 
-        return vc4_surface(pctx->create_surface(pctx, prsc, &tmpl));
+        return pctx->create_surface(pctx, prsc, &tmpl);
 }
 
 static bool
@@ -141,17 +62,28 @@ vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
         if (info->dst.resource->format != info->src.resource->format)
                 return false;
 
-        struct vc4_surface *dst_surf =
+        vc4_flush(pctx);
+
+        struct pipe_surface *dst_surf =
                 vc4_get_blit_surface(pctx, info->dst.resource, info->dst.level);
-        struct vc4_surface *src_surf =
+        struct pipe_surface *src_surf =
                 vc4_get_blit_surface(pctx, info->src.resource, info->src.level);
 
-        vc4_flush(pctx);
-        vc4_tile_blit_color_rcl(vc4, dst_surf, src_surf);
+        pipe_surface_reference(&vc4->color_read, src_surf);
+        pipe_surface_reference(&vc4->color_write, dst_surf);
+        pipe_surface_reference(&vc4->zs_read, NULL);
+        pipe_surface_reference(&vc4->zs_write, NULL);
+        vc4->draw_min_x = 0;
+        vc4->draw_min_y = 0;
+        vc4->draw_max_x = dst_surf->width;
+        vc4->draw_max_y = dst_surf->height;
+        vc4->draw_width = dst_surf->width;
+        vc4->draw_height = dst_surf->height;
+        vc4->needs_flush = true;
         vc4_job_submit(vc4);
 
-        pctx->surface_destroy(pctx, &dst_surf->base);
-        pctx->surface_destroy(pctx, &src_surf->base);
+        pipe_surface_reference(&dst_surf, NULL);
+        pipe_surface_reference(&src_surf, NULL);
 
         return true;
 }
index 4bb2c711e16f34dddbfc054e7526b87f3ae33974..cbdb9e89cf6c1669a0d48806b75028b680be475f 100644 (file)
 #include "vc4_context.h"
 #include "vc4_screen.h"
 
-#define container_of(ptr, type, field) \
-   (type*)((char*)ptr - offsetof(type, field))
+static bool dump_stats = false;
+
+static void
+vc4_bo_dump_stats(struct vc4_screen *screen)
+{
+        struct vc4_bo_cache *cache = &screen->bo_cache;
+
+        fprintf(stderr, "  BOs allocated:   %d\n", screen->bo_count);
+        fprintf(stderr, "  BOs size:        %dkb\n", screen->bo_size / 102);
+        fprintf(stderr, "  BOs cached:      %d\n", cache->bo_count);
+        fprintf(stderr, "  BOs cached size: %dkb\n", cache->bo_size / 102);
+
+        if (!list_empty(&cache->time_list)) {
+                struct vc4_bo *first = LIST_ENTRY(struct vc4_bo,
+                                                  cache->time_list.next,
+                                                  time_list);
+                struct vc4_bo *last = LIST_ENTRY(struct vc4_bo,
+                                                  cache->time_list.prev,
+                                                  time_list);
+
+                fprintf(stderr, "  oldest cache time: %ld\n",
+                        (long)first->free_time);
+                fprintf(stderr, "  newest cache time: %ld\n",
+                        (long)last->free_time);
+
+                struct timespec time;
+                clock_gettime(CLOCK_MONOTONIC, &time);
+                fprintf(stderr, "  now:               %ld\n",
+                        time.tv_sec);
+        }
+}
+
+static void
+vc4_bo_remove_from_cache(struct vc4_bo_cache *cache, struct vc4_bo *bo)
+{
+        list_del(&bo->time_list);
+        list_del(&bo->size_list);
+        cache->bo_count--;
+        cache->bo_size -= bo->size;
+}
 
 static struct vc4_bo *
 vc4_bo_from_cache(struct vc4_screen *screen, uint32_t size, const char *name)
@@ -48,12 +86,21 @@ vc4_bo_from_cache(struct vc4_screen *screen, uint32_t size, const char *name)
 
         struct vc4_bo *bo = NULL;
         pipe_mutex_lock(cache->lock);
-        if (!is_empty_list(&cache->size_list[page_index])) {
-                struct simple_node *node = last_elem(&cache->size_list[page_index]);
-                bo = container_of(node, struct vc4_bo, size_list);
+        if (!list_empty(&cache->size_list[page_index])) {
+                bo = LIST_ENTRY(struct vc4_bo, cache->size_list[page_index].next,
+                                size_list);
+
+                /* Check that the BO has gone idle.  If not, then we want to
+                 * allocate something new instead, since we assume that the
+                 * user will proceed to CPU map it and fill it with stuff.
+                 */
+                if (!vc4_bo_wait(bo, 0)) {
+                        pipe_mutex_unlock(cache->lock);
+                        return NULL;
+                }
+
                 pipe_reference_init(&bo->reference, 1);
-                remove_from_list(&bo->time_list);
-                remove_from_list(&bo->size_list);
+                vc4_bo_remove_from_cache(cache, bo);
 
                 bo->name = name;
         }
@@ -70,8 +117,14 @@ vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name)
         size = align(size, 4096);
 
         bo = vc4_bo_from_cache(screen, size, name);
-        if (bo)
+        if (bo) {
+                if (dump_stats) {
+                        fprintf(stderr, "Allocated %s %dkb from cache:\n",
+                                name, size / 1024);
+                        vc4_bo_dump_stats(screen);
+                }
                 return bo;
+        }
 
         bo = CALLOC_STRUCT(vc4_bo);
         if (!bo)
@@ -108,6 +161,13 @@ vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name)
                 abort();
         }
 
+        screen->bo_count++;
+        screen->bo_size += bo->size;
+        if (dump_stats) {
+                fprintf(stderr, "Allocated %s %dkb:\n", name, size / 1024);
+                vc4_bo_dump_stats(screen);
+        }
+
         return bo;
 }
 
@@ -145,26 +205,47 @@ vc4_bo_free(struct vc4_bo *bo)
         if (ret != 0)
                 fprintf(stderr, "close object %d: %s\n", bo->handle, strerror(errno));
 
+        screen->bo_count--;
+        screen->bo_size -= bo->size;
+
+        if (dump_stats) {
+                fprintf(stderr, "Freed %s%s%dkb:\n",
+                        bo->name ? bo->name : "",
+                        bo->name ? " " : "",
+                        bo->size / 1024);
+                vc4_bo_dump_stats(screen);
+        }
+
         free(bo);
 }
 
 static void
 free_stale_bos(struct vc4_screen *screen, time_t time)
 {
-        while (!is_empty_list(&screen->bo_cache.time_list)) {
-                struct simple_node *node =
-                        first_elem(&screen->bo_cache.time_list);
-                struct vc4_bo *bo = container_of(node, struct vc4_bo, time_list);
+        struct vc4_bo_cache *cache = &screen->bo_cache;
+        bool freed_any = false;
+
+        list_for_each_entry_safe(struct vc4_bo, bo, &cache->time_list,
+                                 time_list) {
+                if (dump_stats && !freed_any) {
+                        fprintf(stderr, "Freeing stale BOs:\n");
+                        vc4_bo_dump_stats(screen);
+                        freed_any = true;
+                }
 
                 /* If it's more than a second old, free it. */
                 if (time - bo->free_time > 2) {
-                        remove_from_list(&bo->time_list);
-                        remove_from_list(&bo->size_list);
+                        vc4_bo_remove_from_cache(cache, bo);
                         vc4_bo_free(bo);
                 } else {
                         break;
                 }
         }
+
+        if (dump_stats && freed_any) {
+                fprintf(stderr, "Freed stale BOs:\n");
+                vc4_bo_dump_stats(screen);
+        }
 }
 
 void
@@ -180,16 +261,16 @@ vc4_bo_last_unreference_locked_timed(struct vc4_bo *bo, time_t time)
         }
 
         if (cache->size_list_size <= page_index) {
-                struct simple_node *new_list =
-                        ralloc_array(screen, struct simple_node, page_index + 1);
+                struct list_head *new_list =
+                        ralloc_array(screen, struct list_head, page_index + 1);
 
                 /* Move old list contents over (since the array has moved, and
-                 * therefore the pointers to the list heads have to change.
+                 * therefore the pointers to the list heads have to change).
                  */
                 for (int i = 0; i < cache->size_list_size; i++) {
-                        struct simple_node *old_head = &cache->size_list[i];
-                        if (is_empty_list(old_head))
-                                make_empty_list(&new_list[i]);
+                        struct list_head *old_head = &cache->size_list[i];
+                        if (list_empty(old_head))
+                                list_inithead(&new_list[i]);
                         else {
                                 new_list[i].next = old_head->next;
                                 new_list[i].prev = old_head->prev;
@@ -198,15 +279,23 @@ vc4_bo_last_unreference_locked_timed(struct vc4_bo *bo, time_t time)
                         }
                 }
                 for (int i = cache->size_list_size; i < page_index + 1; i++)
-                        make_empty_list(&new_list[i]);
+                        list_inithead(&new_list[i]);
 
                 cache->size_list = new_list;
                 cache->size_list_size = page_index + 1;
         }
 
         bo->free_time = time;
-        insert_at_tail(&cache->size_list[page_index], &bo->size_list);
-        insert_at_tail(&cache->time_list, &bo->time_list);
+        list_addtail(&bo->size_list, &cache->size_list[page_index]);
+        list_addtail(&bo->time_list, &cache->time_list);
+        cache->bo_count++;
+        cache->bo_size += bo->size;
+        if (dump_stats) {
+                fprintf(stderr, "Freed %s %dkb to cache:\n",
+                        bo->name, bo->size / 1024);
+                vc4_bo_dump_stats(screen);
+        }
+        bo->name = NULL;
 
         free_stale_bos(screen, time);
 }
@@ -286,6 +375,7 @@ vc4_bo_get_dmabuf(struct vc4_bo *bo)
                         bo->handle);
                 return -1;
         }
+        bo->private = false;
 
         return fd;
 }
@@ -342,15 +432,17 @@ vc4_wait_seqno(struct vc4_screen *screen, uint64_t seqno, uint64_t timeout_ns)
                 ret = 0;
         }
 
-        if (ret == -ETIME) {
-                return false;
-        } else if (ret != 0) {
-                fprintf(stderr, "wait failed\n");
-                abort();
-        } else {
+        if (ret == 0) {
                 screen->finished_seqno = wait.seqno;
                 return true;
         }
+
+        if (errno != ETIME) {
+                fprintf(stderr, "wait failed: %d\n", ret);
+                abort();
+        }
+
+        return false;
 }
 
 bool
@@ -369,14 +461,15 @@ vc4_bo_wait(struct vc4_bo *bo, uint64_t timeout_ns)
         else
                 ret = 0;
 
-        if (ret == -ETIME) {
-                return false;
-        } else if (ret != 0) {
-                fprintf(stderr, "wait failed\n");
-                abort();
-        } else {
+        if (ret == 0)
                 return true;
+
+        if (errno != ETIME) {
+                fprintf(stderr, "wait failed: %d\n", ret);
+                abort();
         }
+
+        return false;
 }
 
 void *
@@ -437,12 +530,14 @@ vc4_bufmgr_destroy(struct pipe_screen *pscreen)
         struct vc4_screen *screen = vc4_screen(pscreen);
         struct vc4_bo_cache *cache = &screen->bo_cache;
 
-        while (!is_empty_list(&cache->time_list)) {
-                struct simple_node *node = first_elem(&cache->time_list);
-                struct vc4_bo *bo = container_of(node, struct vc4_bo, time_list);
-
-                remove_from_list(&bo->time_list);
-                remove_from_list(&bo->size_list);
+        list_for_each_entry_safe(struct vc4_bo, bo, &cache->time_list,
+                                 time_list) {
+                vc4_bo_remove_from_cache(cache, bo);
                 vc4_bo_free(bo);
         }
+
+        if (dump_stats) {
+                fprintf(stderr, "BO stats after screen destroy:\n");
+                vc4_bo_dump_stats(screen);
+        }
 }
index f9559e999a131b35f79d353b52c31c11ffd010dd..7320695ca8ebe18b4044dff2bc771dfd0d7da644 100644 (file)
@@ -44,9 +44,9 @@ struct vc4_bo {
 #endif
 
         /** Entry in the linked list of buffers freed, by age. */
-        struct simple_node time_list;
+        struct list_head time_list;
         /** Entry in the per-page-count linked list of buffers freed (by age). */
-        struct simple_node size_list;
+        struct list_head size_list;
         /** Approximate second when the bo was freed. */
         time_t free_time;
         /**
index 32a2e717379cebaf4f29bc5f4e8e2cd0c312af15..4a50e790942177fe35a18858ca32f315bc400fa2 100644 (file)
@@ -29,7 +29,7 @@
 #include "util/u_math.h"
 #include "util/macros.h"
 
-#include "vc4_packet.h"
+#include "kernel/vc4_packet.h"
 
 struct vc4_bo;
 
index 14239840d321c36f0a28153efa72e6e053b6290f..69055081daa666f29ec4f74dea7036be293be22a 100644 (file)
@@ -173,6 +173,37 @@ dump_VC4_PACKET_CLIPPER_Z_SCALING(void *cl, uint32_t offset, uint32_t hw_offset)
                 scale[0], scale[1]);
 }
 
+static void
+dump_VC4_PACKET_TILE_BINNING_MODE_CONFIG(void *cl, uint32_t offset, uint32_t hw_offset)
+{
+        uint32_t *tile_alloc_addr = cl + offset;
+        uint32_t *tile_alloc_size = cl + offset + 4;
+        uint32_t *tile_state_addr = cl + offset + 8;
+        uint8_t *bin_x = cl + offset + 12;
+        uint8_t *bin_y = cl + offset + 13;
+        uint8_t *flags = cl + offset + 14;
+
+        fprintf(stderr, "0x%08x 0x%08x:       tile alloc addr 0x%08x\n",
+                offset, hw_offset,
+                *tile_alloc_addr);
+
+        fprintf(stderr, "0x%08x 0x%08x:       tile alloc size %db\n",
+                offset + 4, hw_offset + 4,
+                *tile_alloc_size);
+
+        fprintf(stderr, "0x%08x 0x%08x:       tile state addr 0x%08x\n",
+                offset + 8, hw_offset + 8,
+                *tile_state_addr);
+
+        fprintf(stderr, "0x%08x 0x%08x:       tiles (%d, %d)\n",
+                offset + 12, hw_offset + 12,
+                *bin_x, *bin_y);
+
+        fprintf(stderr, "0x%08x 0x%08x:       flags 0x%02x\n",
+                offset + 14, hw_offset + 14,
+                *flags);
+}
+
 static void
 dump_VC4_PACKET_TILE_RENDERING_MODE_CONFIG(void *cl, uint32_t offset, uint32_t hw_offset)
 {
@@ -311,7 +342,7 @@ static const struct packet_info {
         PACKET_DUMP(VC4_PACKET_CLIPPER_XY_SCALING, 9),
         PACKET_DUMP(VC4_PACKET_CLIPPER_Z_SCALING, 9),
 
-        PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, 16),
+        PACKET_DUMP(VC4_PACKET_TILE_BINNING_MODE_CONFIG, 16),
         PACKET_DUMP(VC4_PACKET_TILE_RENDERING_MODE_CONFIG, 11),
         PACKET(VC4_PACKET_CLEAR_COLORS, 14),
         PACKET_DUMP(VC4_PACKET_TILE_COORDINATES, 3),
index b394c186efbc7e8618a51192f6ca8bc1774a27e4..630f8e688967abfbc27b4aa6b71515cb759e514b 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_blitter.h"
+#include "util/u_upload_mgr.h"
 #include "indices/u_primconvert.h"
 #include "pipe/p_screen.h"
 
 #include "vc4_context.h"
 #include "vc4_resource.h"
 
-/**
- * Emits a no-op STORE_TILE_BUFFER_GENERAL.
- *
- * If we emit a PACKET_TILE_COORDINATES, it must be followed by a store of
- * some sort before another load is triggered.
- */
-static void
-vc4_store_before_load(struct vc4_context *vc4, bool *coords_emitted)
-{
-        if (!*coords_emitted)
-                return;
-
-        cl_u8(&vc4->rcl, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
-        cl_u8(&vc4->rcl, VC4_LOADSTORE_TILE_BUFFER_NONE);
-        cl_u8(&vc4->rcl, (VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR |
-                          VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR |
-                          VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR));
-        cl_u32(&vc4->rcl, 0); /* no address, since we're in None mode */
-
-        *coords_emitted = false;
-}
-
-/**
- * Emits a PACKET_TILE_COORDINATES if one isn't already pending.
- *
- * The tile coordinates packet triggers a pending load if there is one, are
- * used for clipping during rendering, and determine where loads/stores happen
- * relative to their base address.
- */
-static void
-vc4_tile_coordinates(struct vc4_context *vc4, uint32_t x, uint32_t y,
-                       bool *coords_emitted)
-{
-        if (*coords_emitted)
-                return;
-
-        cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES);
-        cl_u8(&vc4->rcl, x);
-        cl_u8(&vc4->rcl, y);
-
-        *coords_emitted = true;
-}
-
-static void
-vc4_setup_rcl(struct vc4_context *vc4)
-{
-        struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
-        struct vc4_resource *ctex = csurf ? vc4_resource(csurf->base.texture) : NULL;
-        struct vc4_surface *zsurf = vc4_surface(vc4->framebuffer.zsbuf);
-        struct vc4_resource *ztex = zsurf ? vc4_resource(zsurf->base.texture) : NULL;
-
-        if (!csurf)
-                vc4->resolve &= ~PIPE_CLEAR_COLOR0;
-        if (!zsurf)
-                vc4->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);
-        uint32_t resolve_uncleared = vc4->resolve & ~vc4->cleared;
-        uint32_t width = vc4->framebuffer.width;
-        uint32_t height = vc4->framebuffer.height;
-        uint32_t stride_in_tiles = align(width, 64) / 64;
-
-        assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0);
-        uint32_t min_x_tile = vc4->draw_min_x / 64;
-        uint32_t min_y_tile = vc4->draw_min_y / 64;
-        uint32_t max_x_tile = (vc4->draw_max_x - 1) / 64;
-        uint32_t max_y_tile = (vc4->draw_max_y - 1) / 64;
-        uint32_t xtiles = max_x_tile - min_x_tile + 1;
-        uint32_t ytiles = max_y_tile - min_y_tile + 1;
-
-#if 0
-        fprintf(stderr, "RCL: resolve 0x%x clear 0x%x resolve uncleared 0x%x\n",
-                vc4->resolve,
-                vc4->cleared,
-                resolve_uncleared);
-#endif
-
-        uint32_t reloc_size = 9;
-        uint32_t clear_size = 14;
-        uint32_t config_size = 11 + reloc_size;
-        uint32_t loadstore_size = 7 + reloc_size;
-        uint32_t tilecoords_size = 3;
-        uint32_t branch_size = 5 + reloc_size;
-        uint32_t color_store_size = 1;
-        uint32_t semaphore_size = 1;
-        cl_ensure_space(&vc4->rcl,
-                        clear_size +
-                        config_size +
-                        loadstore_size +
-                        semaphore_size +
-                        xtiles * ytiles * (loadstore_size * 4 +
-                                           tilecoords_size * 3 +
-                                           branch_size +
-                                           color_store_size));
-
-        if (vc4->cleared) {
-                cl_u8(&vc4->rcl, VC4_PACKET_CLEAR_COLORS);
-                cl_u32(&vc4->rcl, vc4->clear_color[0]);
-                cl_u32(&vc4->rcl, vc4->clear_color[1]);
-                cl_u32(&vc4->rcl, vc4->clear_depth);
-                cl_u8(&vc4->rcl, vc4->clear_stencil);
-        }
-
-        /* The rendering mode config determines the pointer that's used for
-         * VC4_PACKET_STORE_MS_TILE_BUFFER address computations.  The kernel
-         * could handle a no-relocation rendering mode config and deny those
-         * packets, but instead we just tell the kernel we're doing our color
-         * rendering to the Z buffer, and just don't emit any of those
-         * packets.
-         */
-        struct vc4_surface *render_surf = csurf ? csurf : zsurf;
-        struct vc4_resource *render_tex = vc4_resource(render_surf->base.texture);
-        cl_start_reloc(&vc4->rcl, 1);
-        cl_u8(&vc4->rcl, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
-        cl_reloc(vc4, &vc4->rcl, render_tex->bo, render_surf->offset);
-        cl_u16(&vc4->rcl, width);
-        cl_u16(&vc4->rcl, height);
-        cl_u16(&vc4->rcl, ((render_surf->tiling <<
-                            VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT) |
-                           (vc4_rt_format_is_565(render_surf->base.format) ?
-                            VC4_RENDER_CONFIG_FORMAT_BGR565 :
-                            VC4_RENDER_CONFIG_FORMAT_RGBA8888)));
-
-        /* The tile buffer normally gets cleared when the previous tile is
-         * stored.  If the clear values changed between frames, then the tile
-         * buffer has stale clear values in it, so we have to do a store in
-         * None mode (no writes) so that we trigger the tile buffer clear.
-         *
-         * Excess clearing is only a performance cost, since per-tile contents
-         * will be loaded/stored in the loop below.
-         */
-        if (vc4->cleared & (PIPE_CLEAR_COLOR0 |
-                            PIPE_CLEAR_DEPTH |
-                            PIPE_CLEAR_STENCIL)) {
-                cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES);
-                cl_u8(&vc4->rcl, 0);
-                cl_u8(&vc4->rcl, 0);
-
-                cl_u8(&vc4->rcl, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
-                cl_u16(&vc4->rcl, VC4_LOADSTORE_TILE_BUFFER_NONE);
-                cl_u32(&vc4->rcl, 0); /* no address, since we're in None mode */
-        }
-
-        uint32_t color_hindex = ctex ? vc4_gem_hindex(vc4, ctex->bo) : 0;
-        uint32_t depth_hindex = ztex ? vc4_gem_hindex(vc4, ztex->bo) : 0;
-        uint32_t tile_alloc_hindex = vc4_gem_hindex(vc4, vc4->tile_alloc);
-
-        for (int y = min_y_tile; y <= max_y_tile; y++) {
-                for (int x = min_x_tile; x <= max_x_tile; x++) {
-                        bool end_of_frame = (x == max_x_tile &&
-                                             y == max_y_tile);
-                        bool coords_emitted = false;
-
-                        /* Note that the load doesn't actually occur until the
-                         * tile coords packet is processed, and only one load
-                         * may be outstanding at a time.
-                         */
-                        if (resolve_uncleared & PIPE_CLEAR_COLOR) {
-                                vc4_store_before_load(vc4, &coords_emitted);
-
-                                cl_start_reloc(&vc4->rcl, 1);
-                                cl_u8(&vc4->rcl, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
-                                cl_u8(&vc4->rcl,
-                                      VC4_LOADSTORE_TILE_BUFFER_COLOR |
-                                      (csurf->tiling <<
-                                       VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT));
-                                cl_u8(&vc4->rcl,
-                                      vc4_rt_format_is_565(csurf->base.format) ?
-                                      VC4_LOADSTORE_TILE_BUFFER_BGR565 :
-                                      VC4_LOADSTORE_TILE_BUFFER_RGBA8888);
-                                cl_reloc_hindex(&vc4->rcl, color_hindex,
-                                                csurf->offset);
-
-                                vc4_tile_coordinates(vc4, x, y, &coords_emitted);
-                        }
-
-                        if (resolve_uncleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
-                                vc4_store_before_load(vc4, &coords_emitted);
-
-                                cl_start_reloc(&vc4->rcl, 1);
-                                cl_u8(&vc4->rcl, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
-                                cl_u8(&vc4->rcl,
-                                      VC4_LOADSTORE_TILE_BUFFER_ZS |
-                                      (zsurf->tiling <<
-                                       VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT));
-                                cl_u8(&vc4->rcl, 0);
-                                cl_reloc_hindex(&vc4->rcl, depth_hindex,
-                                                zsurf->offset);
-
-                                vc4_tile_coordinates(vc4, x, y, &coords_emitted);
-                        }
-
-                        /* Clipping depends on tile coordinates having been
-                         * emitted, so make sure it's happened even if
-                         * everything was cleared to start.
-                         */
-                        vc4_tile_coordinates(vc4, x, y, &coords_emitted);
-
-                        /* Wait for the binner before jumping to the first
-                         * tile's lists.
-                         */
-                        if (x == min_x_tile && y == min_y_tile)
-                                cl_u8(&vc4->rcl, VC4_PACKET_WAIT_ON_SEMAPHORE);
-
-                        cl_start_reloc(&vc4->rcl, 1);
-                        cl_u8(&vc4->rcl, VC4_PACKET_BRANCH_TO_SUB_LIST);
-                        cl_reloc_hindex(&vc4->rcl, tile_alloc_hindex,
-                                        (y * stride_in_tiles + x) * 32);
-
-                        if (vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
-                                vc4_tile_coordinates(vc4, x, y, &coords_emitted);
-
-                                cl_start_reloc(&vc4->rcl, 1);
-                                cl_u8(&vc4->rcl, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
-                                cl_u8(&vc4->rcl,
-                                      VC4_LOADSTORE_TILE_BUFFER_ZS |
-                                      (zsurf->tiling <<
-                                       VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT));
-                                cl_u8(&vc4->rcl,
-                                      VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR);
-                                cl_reloc_hindex(&vc4->rcl, depth_hindex,
-                                                zsurf->offset |
-                                                ((end_of_frame &&
-                                                  !(vc4->resolve & PIPE_CLEAR_COLOR0)) ?
-                                                 VC4_LOADSTORE_TILE_BUFFER_EOF : 0));
-
-                                coords_emitted = false;
-                        }
-
-                        if (vc4->resolve & PIPE_CLEAR_COLOR0) {
-                                vc4_tile_coordinates(vc4, x, y, &coords_emitted);
-                                if (end_of_frame) {
-                                        cl_u8(&vc4->rcl,
-                                              VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF);
-                                } else {
-                                        cl_u8(&vc4->rcl,
-                                              VC4_PACKET_STORE_MS_TILE_BUFFER);
-                                }
-
-                                coords_emitted = false;
-                        }
-
-                        /* One of the bits needs to have been set that would
-                         * have triggered an EOF.
-                         */
-                        assert(vc4->resolve & (PIPE_CLEAR_COLOR0 |
-                                               PIPE_CLEAR_DEPTH |
-                                               PIPE_CLEAR_STENCIL));
-                        /* Any coords emitted must also have been consumed by
-                         * a store.
-                         */
-                        assert(!coords_emitted);
-                }
-        }
-
-        if (vc4->resolve & PIPE_CLEAR_COLOR0)
-                ctex->writes++;
-
-        if (vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))
-                ztex->writes++;
-}
-
 void
 vc4_flush(struct pipe_context *pctx)
 {
         struct vc4_context *vc4 = vc4_context(pctx);
+        struct pipe_surface *cbuf = vc4->framebuffer.cbufs[0];
+        struct pipe_surface *zsbuf = vc4->framebuffer.zsbuf;
 
         if (!vc4->needs_flush)
                 return;
@@ -322,7 +65,31 @@ vc4_flush(struct pipe_context *pctx)
         /* The FLUSH caps all of our bin lists with a VC4_PACKET_RETURN. */
         cl_u8(&vc4->bcl, VC4_PACKET_FLUSH);
 
-        vc4_setup_rcl(vc4);
+        if (cbuf && (vc4->resolve & PIPE_CLEAR_COLOR0)) {
+                pipe_surface_reference(&vc4->color_write, cbuf);
+                if (!(vc4->cleared & PIPE_CLEAR_COLOR0)) {
+                        pipe_surface_reference(&vc4->color_read, cbuf);
+                } else {
+                        pipe_surface_reference(&vc4->color_read, NULL);
+                }
+
+        } else {
+                pipe_surface_reference(&vc4->color_write, NULL);
+                pipe_surface_reference(&vc4->color_read, NULL);
+        }
+
+        if (vc4->framebuffer.zsbuf &&
+            (vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
+                pipe_surface_reference(&vc4->zs_write, zsbuf);
+                if (!(vc4->cleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
+                        pipe_surface_reference(&vc4->zs_read, zsbuf);
+                } else {
+                        pipe_surface_reference(&vc4->zs_read, NULL);
+                }
+        } else {
+                pipe_surface_reference(&vc4->zs_write, NULL);
+                pipe_surface_reference(&vc4->zs_read, NULL);
+        }
 
         vc4_job_submit(vc4);
 }
@@ -410,12 +177,13 @@ vc4_context_destroy(struct pipe_context *pctx)
         if (vc4->primconvert)
                 util_primconvert_destroy(vc4->primconvert);
 
+        if (vc4->uploader)
+                u_upload_destroy(vc4->uploader);
+
         util_slab_destroy(&vc4->transfer_pool);
 
         pipe_surface_reference(&vc4->framebuffer.cbufs[0], NULL);
         pipe_surface_reference(&vc4->framebuffer.zsbuf, NULL);
-        vc4_bo_unreference(&vc4->tile_alloc);
-        vc4_bo_unreference(&vc4->tile_state);
 
         vc4_program_fini(pctx);
 
@@ -466,6 +234,9 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv)
         if (!vc4->primconvert)
                 goto fail;
 
+        vc4->uploader = u_upload_create(pctx, 16 * 1024, 4,
+                                        PIPE_BIND_INDEX_BUFFER);
+
         vc4_debug |= saved_shaderdb_flag;
 
         return &vc4->base;
index d89f1974e121cd98f2c914e8fd96eee64f8e5ab0..d5d6be16f6edebe9d794cf7af66b487947ba453a 100644 (file)
@@ -178,12 +178,18 @@ struct vc4_context {
         struct vc4_screen *screen;
 
         struct vc4_cl bcl;
-        struct vc4_cl rcl;
         struct vc4_cl shader_rec;
         struct vc4_cl uniforms;
         struct vc4_cl bo_handles;
         struct vc4_cl bo_pointers;
         uint32_t shader_rec_count;
+
+        /** @{ Surfaces to submit rendering for. */
+        struct pipe_surface *color_read;
+        struct pipe_surface *color_write;
+        struct pipe_surface *zs_read;
+        struct pipe_surface *zs_write;
+        /** @} */
         /** @{
          * Bounding box of the scissor across all queued drawing.
          *
@@ -194,9 +200,13 @@ struct vc4_context {
         uint32_t draw_max_x;
         uint32_t draw_max_y;
         /** @} */
-
-        struct vc4_bo *tile_alloc;
-        struct vc4_bo *tile_state;
+        /** @{
+         * Width/height of the color framebuffer being rendered to,
+         * for VC4_TILE_RENDERING_MODE_CONFIG.
+        */
+        uint32_t draw_width;
+        uint32_t draw_height;
+        /** @} */
 
         struct util_slab_mempool transfer_pool;
         struct blitter_context *blitter;
@@ -243,6 +253,8 @@ struct vc4_context {
         /** Seqno of the last CL flush's job. */
         uint64_t last_emit_seqno;
 
+        struct u_upload_mgr *uploader;
+
         /** @{ Current pipeline state objects */
         struct pipe_scissor_state scissor;
         struct pipe_blend_state *blend;
index 16418bf12dac7e5199b50255332c1b17ad357697..5e6d70d6f337921bb416b8bfe1ff5dc8a98ae4f7 100644 (file)
@@ -72,44 +72,15 @@ vc4_start_draw(struct vc4_context *vc4)
         uint32_t tilew = align(width, 64) / 64;
         uint32_t tileh = align(height, 64) / 64;
 
-        /* Tile alloc memory setup: We use an initial alloc size of 32b.  The
-         * hardware then aligns that to 256b (we use 4096, because all of our
-         * BO allocations align to that anyway), then for some reason the
-         * simulator wants an extra page available, even if you have overflow
-         * memory set up.
-         *
-         * XXX: The binner only does 28-bit addressing math, so the tile alloc
-         * and tile state should be in the same BO and that BO needs to not
-         * cross a 256MB boundary, somehow.
-         */
-        uint32_t tile_alloc_size = 32 * tilew * tileh;
-        tile_alloc_size = align(tile_alloc_size, 4096);
-        tile_alloc_size += 4096;
-        uint32_t tile_state_size = 48 * tilew * tileh;
-        if (!vc4->tile_alloc || vc4->tile_alloc->size < tile_alloc_size) {
-                vc4_bo_unreference(&vc4->tile_alloc);
-                vc4->tile_alloc = vc4_bo_alloc(vc4->screen, tile_alloc_size,
-                                               "tile_alloc");
-        }
-        if (!vc4->tile_state || vc4->tile_state->size < tile_state_size) {
-                vc4_bo_unreference(&vc4->tile_state);
-                vc4->tile_state = vc4_bo_alloc(vc4->screen, tile_state_size,
-                                               "tile_state");
-        }
-
         //   Tile state data is 48 bytes per tile, I think it can be thrown away
         //   as soon as binning is finished.
-        cl_start_reloc(&vc4->bcl, 2);
         cl_u8(&vc4->bcl, VC4_PACKET_TILE_BINNING_MODE_CONFIG);
-        cl_reloc(vc4, &vc4->bcl, vc4->tile_alloc, 0);
-        cl_u32(&vc4->bcl, vc4->tile_alloc->size);
-        cl_reloc(vc4, &vc4->bcl, vc4->tile_state, 0);
+        cl_u32(&vc4->bcl, 0); /* tile alloc addr, filled by kernel */
+        cl_u32(&vc4->bcl, 0); /* tile alloc size, filled by kernel */
+        cl_u32(&vc4->bcl, 0); /* tile state addr, filled by kernel */
         cl_u8(&vc4->bcl, tilew);
         cl_u8(&vc4->bcl, tileh);
-        cl_u8(&vc4->bcl,
-              VC4_BIN_CONFIG_AUTO_INIT_TSDA |
-              VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_32 |
-              VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32);
+        cl_u8(&vc4->bcl, 0); /* flags, filled by kernel. */
 
         /* START_TILE_BINNING resets the statechange counters in the hardware,
          * which are what is used when a primitive is binned to a tile to
@@ -129,6 +100,8 @@ vc4_start_draw(struct vc4_context *vc4)
 
         vc4->needs_flush = true;
         vc4->draw_call_queued = true;
+        vc4->draw_width = width;
+        vc4->draw_height = height;
 }
 
 static void
@@ -266,13 +239,17 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
          * definitions, up to but not including QUADS.
          */
         if (info->indexed) {
-                struct vc4_resource *rsc = vc4_resource(vc4->indexbuf.buffer);
                 uint32_t offset = vc4->indexbuf.offset;
                 uint32_t index_size = vc4->indexbuf.index_size;
-                if (rsc->shadow_parent) {
-                        vc4_update_shadow_index_buffer(pctx, &vc4->indexbuf);
-                        offset = 0;
+                struct pipe_resource *prsc;
+                if (vc4->indexbuf.index_size == 4) {
+                        prsc = vc4_get_shadow_index_buffer(pctx, &vc4->indexbuf,
+                                                           info->count, &offset);
+                        index_size = 2;
+                } else {
+                        prsc = vc4->indexbuf.buffer;
                 }
+                struct vc4_resource *rsc = vc4_resource(prsc);
 
                 cl_start_reloc(&vc4->bcl, 1);
                 cl_u8(&vc4->bcl, VC4_PACKET_GL_INDEXED_PRIMITIVE);
@@ -284,6 +261,9 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                 cl_u32(&vc4->bcl, info->count);
                 cl_reloc(vc4, &vc4->bcl, rsc->bo, offset);
                 cl_u32(&vc4->bcl, max_index);
+
+                if (vc4->indexbuf.index_size == 4)
+                        pipe_resource_reference(&prsc, NULL);
         } else {
                 cl_u8(&vc4->bcl, VC4_PACKET_GL_ARRAY_PRIMITIVE);
                 cl_u8(&vc4->bcl, info->mode);
index 062fd3b687e94fbd9f863e42753c3822d726d5a8..5f1ee4fa125851c2ed21544ef7bbe26e619d38af 100644 (file)
 #define DRM_IOCTL_VC4_CREATE_BO           DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo)
 #define DRM_IOCTL_VC4_MMAP_BO             DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo)
 
+struct drm_vc4_submit_rcl_surface {
+       uint32_t hindex; /* Handle index, or ~0 if not present. */
+       uint32_t offset; /* Offset to start of buffer. */
+       /*
+         * Bits for either render config (color_ms_write) or load/store packet.
+        */
+       uint16_t bits;
+       uint16_t pad;
+};
 
 /**
  * struct drm_vc4_submit_cl - ioctl argument for submitting commands to the 3D
@@ -62,16 +71,6 @@ struct drm_vc4_submit_cl {
         */
        uint64_t bin_cl;
 
-       /* Pointer to the render command list.
-        *
-        * The render command list contains a set of packets to load the
-        * current tile's state (reading from memory, or just clearing it)
-        * into the GPU, then call into the tile allocation BO to run the
-        * stored rendering for that tile, then store the tile's state back to
-        * memory.
-        */
-       uint64_t render_cl;
-
        /* Pointer to the shader records.
         *
         * Shader records are the structures read by the hardware that contain
@@ -102,8 +101,6 @@ struct drm_vc4_submit_cl {
 
        /* Size in bytes of the binner command list. */
        uint32_t bin_cl_size;
-       /* Size in bytes of the render command list */
-       uint32_t render_cl_size;
        /* Size in bytes of the set of shader records. */
        uint32_t shader_rec_size;
        /* Number of shader records.
@@ -119,8 +116,25 @@ struct drm_vc4_submit_cl {
        /* Number of BO handles passed in (size is that times 4). */
        uint32_t bo_handle_count;
 
+       /* RCL setup: */
+       uint16_t width;
+       uint16_t height;
+       uint8_t min_x_tile;
+       uint8_t min_y_tile;
+       uint8_t max_x_tile;
+       uint8_t max_y_tile;
+       struct drm_vc4_submit_rcl_surface color_read;
+       struct drm_vc4_submit_rcl_surface color_ms_write;
+       struct drm_vc4_submit_rcl_surface zs_read;
+       struct drm_vc4_submit_rcl_surface zs_write;
+       uint32_t clear_color[2];
+       uint32_t clear_z;
+       uint8_t clear_s;
+
+       uint32_t pad:24;
+
+#define VC4_SUBMIT_CL_USE_CLEAR_COLOR                  (1 << 0)
        uint32_t flags;
-       uint32_t pad;
 
        /* Returned value of the seqno of this render job (for the
         * wait ioctl).
index 76037162102f86832d3996ce5651e9e417031aff..dcade15443a8cc21ba94fee5f4d07e9a7ec45352 100644 (file)
@@ -33,7 +33,6 @@ void
 vc4_job_init(struct vc4_context *vc4)
 {
         vc4_init_cl(vc4, &vc4->bcl);
-        vc4_init_cl(vc4, &vc4->rcl);
         vc4_init_cl(vc4, &vc4->shader_rec);
         vc4_init_cl(vc4, &vc4->uniforms);
         vc4_init_cl(vc4, &vc4->bo_handles);
@@ -50,7 +49,6 @@ vc4_job_reset(struct vc4_context *vc4)
                 vc4_bo_unreference(&referenced_bos[i]);
         }
         vc4_reset_cl(&vc4->bcl);
-        vc4_reset_cl(&vc4->rcl);
         vc4_reset_cl(&vc4->shader_rec);
         vc4_reset_cl(&vc4->uniforms);
         vc4_reset_cl(&vc4->bo_handles);
@@ -75,6 +73,70 @@ vc4_job_reset(struct vc4_context *vc4)
         vc4->draw_max_y = 0;
 }
 
+static void
+vc4_submit_setup_rcl_surface(struct vc4_context *vc4,
+                             struct drm_vc4_submit_rcl_surface *submit_surf,
+                             struct pipe_surface *psurf,
+                             bool is_depth, bool is_write)
+{
+        struct vc4_surface *surf = vc4_surface(psurf);
+
+        if (!surf) {
+                submit_surf->hindex = ~0;
+                return;
+        }
+
+        struct vc4_resource *rsc = vc4_resource(psurf->texture);
+        submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
+        submit_surf->offset = surf->offset;
+
+        if (is_depth) {
+                submit_surf->bits =
+                        VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS,
+                                      VC4_LOADSTORE_TILE_BUFFER_BUFFER);
+
+        } else {
+                submit_surf->bits =
+                        VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR,
+                                      VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
+                        VC4_SET_FIELD(vc4_rt_format_is_565(psurf->format) ?
+                                      VC4_LOADSTORE_TILE_BUFFER_BGR565 :
+                                      VC4_LOADSTORE_TILE_BUFFER_RGBA8888,
+                                      VC4_LOADSTORE_TILE_BUFFER_FORMAT);
+        }
+        submit_surf->bits |=
+                VC4_SET_FIELD(surf->tiling, VC4_LOADSTORE_TILE_BUFFER_TILING);
+
+        if (is_write)
+                rsc->writes++;
+}
+
+static void
+vc4_submit_setup_ms_rcl_surface(struct vc4_context *vc4,
+                                struct drm_vc4_submit_rcl_surface *submit_surf,
+                                struct pipe_surface *psurf)
+{
+        struct vc4_surface *surf = vc4_surface(psurf);
+
+        if (!surf) {
+                submit_surf->hindex = ~0;
+                return;
+        }
+
+        struct vc4_resource *rsc = vc4_resource(psurf->texture);
+        submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
+        submit_surf->offset = surf->offset;
+
+        submit_surf->bits =
+                VC4_SET_FIELD(vc4_rt_format_is_565(surf->base.format) ?
+                              VC4_RENDER_CONFIG_FORMAT_BGR565 :
+                              VC4_RENDER_CONFIG_FORMAT_RGBA8888,
+                              VC4_RENDER_CONFIG_FORMAT) |
+                VC4_SET_FIELD(surf->tiling, VC4_RENDER_CONFIG_MEMORY_FORMAT);
+
+        rsc->writes++;
+}
+
 /**
  * Submits the job to the kernel and then reinitializes it.
  */
@@ -84,26 +146,49 @@ vc4_job_submit(struct vc4_context *vc4)
         if (vc4_debug & VC4_DEBUG_CL) {
                 fprintf(stderr, "BCL:\n");
                 vc4_dump_cl(vc4->bcl.base, vc4->bcl.next - vc4->bcl.base, false);
-                fprintf(stderr, "RCL:\n");
-                vc4_dump_cl(vc4->rcl.base, vc4->rcl.next - vc4->rcl.base, true);
         }
 
         struct drm_vc4_submit_cl submit;
         memset(&submit, 0, sizeof(submit));
 
+        cl_ensure_space(&vc4->bo_handles, 4 * sizeof(uint32_t));
+        cl_ensure_space(&vc4->bo_pointers, 4 * sizeof(struct vc4_bo *));
+
+        vc4_submit_setup_rcl_surface(vc4, &submit.color_read,
+                                     vc4->color_read, false, false);
+        vc4_submit_setup_ms_rcl_surface(vc4, &submit.color_ms_write,
+                                        vc4->color_write);
+        vc4_submit_setup_rcl_surface(vc4, &submit.zs_read,
+                                     vc4->zs_read, true, false);
+        vc4_submit_setup_rcl_surface(vc4, &submit.zs_write,
+                                     vc4->zs_write, true, true);
+
         submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
         submit.bo_handle_count = (vc4->bo_handles.next -
                                   vc4->bo_handles.base) / 4;
         submit.bin_cl = (uintptr_t)vc4->bcl.base;
         submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base;
-        submit.render_cl = (uintptr_t)vc4->rcl.base;
-        submit.render_cl_size = vc4->rcl.next - vc4->rcl.base;
         submit.shader_rec = (uintptr_t)vc4->shader_rec.base;
         submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base;
         submit.shader_rec_count = vc4->shader_rec_count;
         submit.uniforms = (uintptr_t)vc4->uniforms.base;
         submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base;
 
+        assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0);
+        submit.min_x_tile = vc4->draw_min_x / 64;
+        submit.min_y_tile = vc4->draw_min_y / 64;
+        submit.max_x_tile = (vc4->draw_max_x - 1) / 64;
+        submit.max_y_tile = (vc4->draw_max_y - 1) / 64;
+        submit.width = vc4->draw_width;
+        submit.height = vc4->draw_height;
+        if (vc4->cleared) {
+                submit.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR;
+                submit.clear_color[0] = vc4->clear_color[0];
+                submit.clear_color[1] = vc4->clear_color[1];
+                submit.clear_z = vc4->clear_depth;
+                submit.clear_s = vc4->clear_stencil;
+        }
+
         if (!(vc4_debug & VC4_DEBUG_NORAST)) {
                 int ret;
 
index e40e0f3b71b428fd277e37f815ce45a80fe91664..7978ea1829fc43ae48be2e1c9aa3763f2c365725 100644 (file)
@@ -136,11 +136,8 @@ bool
 qir_opt_algebraic(struct vc4_compile *c)
 {
         bool progress = false;
-        struct simple_node *node;
-
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
 
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 switch (inst->op) {
                 case QOP_SEL_X_Y_ZS:
                 case QOP_SEL_X_Y_ZC:
index ac9be5c96428573dce1a30e007d393f29828b447..15ec9f0726071022dc6df204806da65ad9c0401b 100644 (file)
@@ -98,10 +98,8 @@ bool
 qir_opt_constant_folding(struct vc4_compile *c)
 {
         bool progress = false;
-        struct simple_node *node;
 
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 if (constant_fold(c, inst))
                         progress = true;
         }
index 5189a401248fcd62b9fc265acfa6992ca89b0dbf..d6d2fbf257f1313a3c6adb80bba230542959b3e2 100644 (file)
@@ -38,13 +38,10 @@ bool
 qir_opt_copy_propagation(struct vc4_compile *c)
 {
         bool progress = false;
-        struct simple_node *node;
         bool debug = false;
         struct qreg *movs = calloc(c->num_temps, sizeof(struct qreg));
 
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
-
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
                         int index = inst->src[i].index;
                         if (inst->src[i].file == QFILE_TEMP &&
index 71794f7d1cf0068690e32e5c55ac80741f79b8a0..92c8260eb591ab55d22ecdc17e95b3abc9b37540 100644 (file)
@@ -121,7 +121,6 @@ bool
 qir_opt_cse(struct vc4_compile *c)
 {
         bool progress = false;
-        struct simple_node *node, *t;
         uint32_t sf_count = 0, r4_count = 0;
 
         struct hash_table *ht = _mesa_hash_table_create(NULL, NULL,
@@ -129,9 +128,7 @@ qir_opt_cse(struct vc4_compile *c)
         if (!ht)
                 return false;
 
-        foreach_s(node, t, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
-
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 if (qir_has_side_effects(c, inst) ||
                     qir_has_side_effect_reads(c, inst)) {
                         continue;
index e4ead46c9c25688806d7f0144b636cefb700ba05..ffd42422de8c7fcfa34f7d808ea770fa8ebebca6 100644 (file)
@@ -86,7 +86,7 @@ qir_opt_dead_code(struct vc4_compile *c)
         /* Whether we're eliminating texture setup currently. */
         bool dce_tex = false;
 
-        struct simple_node *node, *t;
+        struct list_head *node, *t;
         for (node = c->instructions.prev, t = node->prev;
              &c->instructions != node;
              node = t, t = t->prev) {
index a329ac69d11a3a5ea840bbe27c35dfb2b1246e59..d6e98f0aebf730f8f2cc3b5c3830b42c45c1db90 100644 (file)
@@ -37,11 +37,8 @@ bool
 qir_opt_small_immediates(struct vc4_compile *c)
 {
         bool progress = false;
-        struct simple_node *node;
-
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
 
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 /* The small immediate value sits in the raddr B field, so we
                  * can't have 2 small immediates in one instruction (unless
                  * they're the same value, but that should be optimized away
index e9711f222cd5a6497f1fc0649d12edf78cfef647..e04f02859d502586fdc66feccdc81ce336fd709b 100644 (file)
@@ -37,15 +37,12 @@ qir_opt_vpm_writes(struct vc4_compile *c)
                 return false;
 
         bool progress = false;
-        struct simple_node *node;
         struct qinst *vpm_writes[64] = { 0 };
         uint32_t use_count[c->num_temps];
         uint32_t vpm_write_count = 0;
         memset(&use_count, 0, sizeof(use_count));
 
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
-
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 switch (inst->dst.file) {
                 case QFILE_VPM:
                         vpm_writes[vpm_write_count++] = inst;
@@ -102,7 +99,8 @@ qir_opt_vpm_writes(struct vc4_compile *c)
                  * to maintain the order of the VPM writes.
                  */
                 assert(!vpm_writes[i]->sf);
-                move_to_tail(&vpm_writes[i]->link, &inst->link);
+                list_del(&inst->link);
+                list_addtail(&inst->link, &vpm_writes[i]->link);
                 qir_remove_instruction(c, vpm_writes[i]);
 
                 c->defs[inst->dst.index] = NULL;
diff --git a/src/gallium/drivers/vc4/vc4_packet.h b/src/gallium/drivers/vc4/vc4_packet.h
deleted file mode 100644 (file)
index 181f2e0..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright Â© 2014 Broadcom
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef VC4_PACKET_H
-#define VC4_PACKET_H
-
-enum vc4_packet {
-        VC4_PACKET_HALT = 0,
-        VC4_PACKET_NOP = 1,
-
-        VC4_PACKET_FLUSH = 4,
-        VC4_PACKET_FLUSH_ALL = 5,
-        VC4_PACKET_START_TILE_BINNING = 6,
-        VC4_PACKET_INCREMENT_SEMAPHORE = 7,
-        VC4_PACKET_WAIT_ON_SEMAPHORE = 8,
-
-        VC4_PACKET_BRANCH = 16,
-        VC4_PACKET_BRANCH_TO_SUB_LIST = 17,
-
-        VC4_PACKET_STORE_MS_TILE_BUFFER = 24,
-        VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25,
-        VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26,
-        VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27,
-        VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28,
-        VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29,
-
-        VC4_PACKET_GL_INDEXED_PRIMITIVE = 32,
-        VC4_PACKET_GL_ARRAY_PRIMITIVE = 33,
-
-        VC4_PACKET_COMPRESSED_PRIMITIVE = 48,
-        VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49,
-
-        VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56,
-
-        VC4_PACKET_GL_SHADER_STATE = 64,
-        VC4_PACKET_NV_SHADER_STATE = 65,
-        VC4_PACKET_VG_SHADER_STATE = 66,
-
-        VC4_PACKET_CONFIGURATION_BITS = 96,
-        VC4_PACKET_FLAT_SHADE_FLAGS = 97,
-        VC4_PACKET_POINT_SIZE = 98,
-        VC4_PACKET_LINE_WIDTH = 99,
-        VC4_PACKET_RHT_X_BOUNDARY = 100,
-        VC4_PACKET_DEPTH_OFFSET = 101,
-        VC4_PACKET_CLIP_WINDOW = 102,
-        VC4_PACKET_VIEWPORT_OFFSET = 103,
-        VC4_PACKET_Z_CLIPPING = 104,
-        VC4_PACKET_CLIPPER_XY_SCALING = 105,
-        VC4_PACKET_CLIPPER_Z_SCALING = 106,
-
-        VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112,
-        VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113,
-        VC4_PACKET_CLEAR_COLORS = 114,
-        VC4_PACKET_TILE_COORDINATES = 115,
-
-        /* Not an actual hardware packet -- this is what we use to put
-         * references to GEM bos in the command stream, since we need the u32
-         * int the actual address packet in order to store the offset from the
-         * start of the BO.
-         */
-        VC4_PACKET_GEM_HANDLES = 254,
-} __attribute__ ((__packed__));
-
-
-#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
-/* Using the GNU statement expression extension */
-#define VC4_SET_FIELD(value, field)                                       \
-        ({                                                                \
-                uint32_t fieldval = (value) << field ## _SHIFT;                  \
-                assert((fieldval & ~ field ## _MASK) == 0);               \
-                fieldval & field ## _MASK;                                \
-         })
-
-#define VC4_GET_FIELD(word, field) (((word)  & field ## _MASK) >> field ## _SHIFT)
-
-/** @{
- * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
- * VC4_PACKET_TILE_RENDERING_MODE_CONFIG.
-*/
-#define VC4_TILING_FORMAT_LINEAR    0
-#define VC4_TILING_FORMAT_T         1
-#define VC4_TILING_FORMAT_LT        2
-/** @} */
-
-/** @{
- *
- * byte 2 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
- * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL (low bits of the address)
- */
-
-#define VC4_LOADSTORE_TILE_BUFFER_EOF                  (1 << 3)
-#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK (1 << 2)
-#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS      (1 << 1)
-#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR   (1 << 0)
-
-/** @} */
-
-/** @{
- *
- * byte 1 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
- * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL
- */
-#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR (1 << 7)
-#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR     (1 << 6)
-#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR  (1 << 5)
-#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP         (1 << 4)
-
-#define VC4_LOADSTORE_TILE_BUFFER_RGBA8888         (0 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER    (1 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_BGR565           (2 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_MASK             (3 << 0)
-/** @} */
-
-/** @{
- *
- * byte 0 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
- * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL
- */
-#define VC4_STORE_TILE_BUFFER_MODE_SAMPLE0         (0 << 6)
-#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X4     (1 << 6)
-#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X16    (2 << 6)
-
-/** The values of the field are VC4_TILING_FORMAT_* */
-#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK      (3 << 4)
-#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT     4
-
-
-#define VC4_LOADSTORE_TILE_BUFFER_NONE             (0 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_COLOR            (1 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_ZS               (2 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_Z                (3 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_VG_MASK          (4 << 0)
-#define VC4_LOADSTORE_TILE_BUFFER_FULL             (5 << 0)
-/** @} */
-
-#define VC4_INDEX_BUFFER_U8                        (0 << 4)
-#define VC4_INDEX_BUFFER_U16                       (1 << 4)
-
-/* This flag is only present in NV shader state. */
-#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS         (1 << 3)
-#define VC4_SHADER_FLAG_ENABLE_CLIPPING            (1 << 2)
-#define VC4_SHADER_FLAG_VS_POINT_SIZE              (1 << 1)
-#define VC4_SHADER_FLAG_FS_SINGLE_THREAD           (1 << 0)
-
-/** @{ byte 2 of config bits. */
-#define VC4_CONFIG_BITS_EARLY_Z_UPDATE             (1 << 1)
-#define VC4_CONFIG_BITS_EARLY_Z                    (1 << 0)
-/** @} */
-
-/** @{ byte 1 of config bits. */
-#define VC4_CONFIG_BITS_Z_UPDATE                   (1 << 7)
-/** same values in this 3-bit field as PIPE_FUNC_* */
-#define VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT           4
-#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE        (1 << 3)
-
-#define VC4_CONFIG_BITS_COVERAGE_UPDATE_NONZERO    (0 << 1)
-#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ODD        (1 << 1)
-#define VC4_CONFIG_BITS_COVERAGE_UPDATE_OR         (2 << 1)
-#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ZERO       (3 << 1)
-
-#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT       (1 << 0)
-/** @} */
-
-/** @{ byte 0 of config bits. */
-#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_NONE (0 << 6)
-#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X   (1 << 6)
-#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_16X  (2 << 6)
-
-#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES        (1 << 4)
-#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET        (1 << 3)
-#define VC4_CONFIG_BITS_CW_PRIMITIVES              (1 << 2)
-#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK           (1 << 1)
-#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT          (1 << 0)
-/** @} */
-
-/** @{ bits in the last u8 of VC4_PACKET_TILE_BINNING_MODE_CONFIG */
-#define VC4_BIN_CONFIG_DB_NON_MS                   (1 << 7)
-
-#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_32         (0 << 5)
-#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_64         (1 << 5)
-#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128        (2 << 5)
-#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_256        (3 << 5)
-
-#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32    (0 << 3)
-#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_64    (1 << 3)
-#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_128   (2 << 3)
-#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_256   (3 << 3)
-
-#define VC4_BIN_CONFIG_AUTO_INIT_TSDA              (1 << 2)
-#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT           (1 << 1)
-#define VC4_BIN_CONFIG_MS_MODE_4X                  (1 << 0)
-/** @} */
-
-/** @{ bits in the last u16 of VC4_PACKET_TILE_RENDERING_MODE_CONFIG */
-#define VC4_RENDER_CONFIG_DB_NON_MS                (1 << 12)
-#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE (1 << 11)
-#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G      (1 << 10)
-#define VC4_RENDER_CONFIG_COVERAGE_MODE            (1 << 9)
-#define VC4_RENDER_CONFIG_ENABLE_VG_MASK           (1 << 8)
-
-/** The values of the field are VC4_TILING_FORMAT_* */
-#define VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK       (3 << 6)
-#define VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT      6
-
-#define VC4_RENDER_CONFIG_DECIMATE_MODE_1X         (0 << 4)
-#define VC4_RENDER_CONFIG_DECIMATE_MODE_4X         (1 << 4)
-#define VC4_RENDER_CONFIG_DECIMATE_MODE_16X        (2 << 4)
-
-#define VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED   (0 << 2)
-#define VC4_RENDER_CONFIG_FORMAT_RGBA8888          (1 << 2)
-#define VC4_RENDER_CONFIG_FORMAT_BGR565            (2 << 2)
-#define VC4_RENDER_CONFIG_FORMAT_MASK              (3 << 2)
-
-#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT        (1 << 1)
-#define VC4_RENDER_CONFIG_MS_MODE_4X               (1 << 0)
-
-#define VC4_PRIMITIVE_LIST_FORMAT_16_INDEX         (1 << 4)
-#define VC4_PRIMITIVE_LIST_FORMAT_32_XY            (3 << 4)
-#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_POINTS      (0 << 0)
-#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_LINES       (1 << 0)
-#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_TRIANGLES   (2 << 0)
-#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_RHT         (3 << 0)
-
-enum vc4_texture_data_type {
-        VC4_TEXTURE_TYPE_RGBA8888 = 0,
-        VC4_TEXTURE_TYPE_RGBX8888 = 1,
-        VC4_TEXTURE_TYPE_RGBA4444 = 2,
-        VC4_TEXTURE_TYPE_RGBA5551 = 3,
-        VC4_TEXTURE_TYPE_RGB565 = 4,
-        VC4_TEXTURE_TYPE_LUMINANCE = 5,
-        VC4_TEXTURE_TYPE_ALPHA = 6,
-        VC4_TEXTURE_TYPE_LUMALPHA = 7,
-        VC4_TEXTURE_TYPE_ETC1 = 8,
-        VC4_TEXTURE_TYPE_S16F = 9,
-        VC4_TEXTURE_TYPE_S8 = 10,
-        VC4_TEXTURE_TYPE_S16 = 11,
-        VC4_TEXTURE_TYPE_BW1 = 12,
-        VC4_TEXTURE_TYPE_A4 = 13,
-        VC4_TEXTURE_TYPE_A1 = 14,
-        VC4_TEXTURE_TYPE_RGBA64 = 15,
-        VC4_TEXTURE_TYPE_RGBA32R = 16,
-        VC4_TEXTURE_TYPE_YUV422R = 17,
-};
-
-#define VC4_TEX_P0_OFFSET_MASK                     VC4_MASK(31, 12)
-#define VC4_TEX_P0_OFFSET_SHIFT                    12
-#define VC4_TEX_P0_CSWIZ_MASK                      VC4_MASK(11, 10)
-#define VC4_TEX_P0_CSWIZ_SHIFT                     10
-#define VC4_TEX_P0_CMMODE_MASK                     VC4_MASK(9, 9)
-#define VC4_TEX_P0_CMMODE_SHIFT                    9
-#define VC4_TEX_P0_FLIPY_MASK                      VC4_MASK(8, 8)
-#define VC4_TEX_P0_FLIPY_SHIFT                     8
-#define VC4_TEX_P0_TYPE_MASK                       VC4_MASK(7, 4)
-#define VC4_TEX_P0_TYPE_SHIFT                      4
-#define VC4_TEX_P0_MIPLVLS_MASK                    VC4_MASK(3, 0)
-#define VC4_TEX_P0_MIPLVLS_SHIFT                   0
-
-#define VC4_TEX_P1_TYPE4_MASK                      VC4_MASK(31, 31)
-#define VC4_TEX_P1_TYPE4_SHIFT                     31
-#define VC4_TEX_P1_HEIGHT_MASK                     VC4_MASK(30, 20)
-#define VC4_TEX_P1_HEIGHT_SHIFT                    20
-#define VC4_TEX_P1_ETCFLIP_MASK                    VC4_MASK(19, 19)
-#define VC4_TEX_P1_ETCFLIP_SHIFT                   19
-#define VC4_TEX_P1_WIDTH_MASK                      VC4_MASK(18, 8)
-#define VC4_TEX_P1_WIDTH_SHIFT                     8
-
-#define VC4_TEX_P1_MAGFILT_MASK                    VC4_MASK(7, 7)
-#define VC4_TEX_P1_MAGFILT_SHIFT                   7
-# define VC4_TEX_P1_MAGFILT_LINEAR                 0
-# define VC4_TEX_P1_MAGFILT_NEAREST                1
-
-#define VC4_TEX_P1_MINFILT_MASK                    VC4_MASK(6, 4)
-#define VC4_TEX_P1_MINFILT_SHIFT                   4
-# define VC4_TEX_P1_MINFILT_LINEAR                 0
-# define VC4_TEX_P1_MINFILT_NEAREST                1
-# define VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR          2
-# define VC4_TEX_P1_MINFILT_NEAR_MIP_LIN           3
-# define VC4_TEX_P1_MINFILT_LIN_MIP_NEAR           4
-# define VC4_TEX_P1_MINFILT_LIN_MIP_LIN            5
-
-#define VC4_TEX_P1_WRAP_T_MASK                     VC4_MASK(3, 2)
-#define VC4_TEX_P1_WRAP_T_SHIFT                    2
-#define VC4_TEX_P1_WRAP_S_MASK                     VC4_MASK(1, 0)
-#define VC4_TEX_P1_WRAP_S_SHIFT                    0
-# define VC4_TEX_P1_WRAP_REPEAT                    0
-# define VC4_TEX_P1_WRAP_CLAMP                     1
-# define VC4_TEX_P1_WRAP_MIRROR                    2
-# define VC4_TEX_P1_WRAP_BORDER                    3
-
-#define VC4_TEX_P2_PTYPE_MASK                      VC4_MASK(31, 30)
-#define VC4_TEX_P2_PTYPE_SHIFT                     30
-# define VC4_TEX_P2_PTYPE_IGNORED                  0
-# define VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE          1
-# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS   2
-# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS      3
-
-/* VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE bits */
-#define VC4_TEX_P2_CMST_MASK                       VC4_MASK(29, 12)
-#define VC4_TEX_P2_CMST_SHIFT                      12
-#define VC4_TEX_P2_BSLOD_MASK                      VC4_MASK(0, 0)
-#define VC4_TEX_P2_BSLOD_SHIFT                     0
-
-/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS */
-#define VC4_TEX_P2_CHEIGHT_MASK                    VC4_MASK(22, 12)
-#define VC4_TEX_P2_CHEIGHT_SHIFT                   12
-#define VC4_TEX_P2_CWIDTH_MASK                     VC4_MASK(10, 0)
-#define VC4_TEX_P2_CWIDTH_SHIFT                    0
-
-/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS */
-#define VC4_TEX_P2_CYOFF_MASK                      VC4_MASK(22, 12)
-#define VC4_TEX_P2_CYOFF_SHIFT                     12
-#define VC4_TEX_P2_CXOFF_MASK                      VC4_MASK(10, 0)
-#define VC4_TEX_P2_CXOFF_SHIFT                     0
-
-#endif /* VC4_PACKET_H */
index bf156f9b42d5dd09a554f4f516f674a072d8ec50..ba47c51d9bd28e42f94c3eef2176cb7526f11e6b 100644 (file)
@@ -147,6 +147,9 @@ indirect_uniform_load(struct vc4_compile *c,
         indirect_offset = qir_ADD(c, indirect_offset,
                                   qir_uniform_ui(c, (range->dst_offset +
                                                      offset)));
+
+        /* Clamp to [0, array size).  Note that MIN/MAX are signed. */
+        indirect_offset = qir_MAX(c, indirect_offset, qir_uniform_ui(c, 0));
         indirect_offset = qir_MIN(c, indirect_offset,
                                   qir_uniform_ui(c, (range->dst_offset +
                                                      range->size - 4)));
@@ -322,7 +325,9 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
                 switch (instr->src[i].src_type) {
                 case nir_tex_src_coord:
                         s = ntq_get_src(c, instr->src[i].src, 0);
-                        if (instr->sampler_dim != GLSL_SAMPLER_DIM_1D)
+                        if (instr->sampler_dim == GLSL_SAMPLER_DIM_1D)
+                                t = qir_uniform_f(c, 0.5);
+                        else
                                 t = ntq_get_src(c, instr->src[i].src, 1);
                         if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
                                 r = ntq_get_src(c, instr->src[i].src, 2);
@@ -1849,8 +1854,6 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
 
         switch (instr->intrinsic) {
         case nir_intrinsic_load_uniform:
-                assert(instr->const_index[1] == 1);
-
                 for (int i = 0; i < instr->num_components; i++) {
                         dest[i] = qir_uniform(c, QUNIFORM_UNIFORM,
                                               instr->const_index[0] * 4 + i);
@@ -1858,8 +1861,6 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
                 break;
 
         case nir_intrinsic_load_uniform_indirect:
-                assert(instr->const_index[1] == 1);
-
                 for (int i = 0; i < instr->num_components; i++) {
                         dest[i] = indirect_uniform_load(c,
                                                         ntq_get_src(c, instr->src[0], 0),
@@ -1870,8 +1871,6 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
                 break;
 
         case nir_intrinsic_load_input:
-                assert(instr->const_index[1] == 1);
-
                 for (int i = 0; i < instr->num_components; i++)
                         dest[i] = c->inputs[instr->const_index[0] * 4 + i];
 
@@ -2215,11 +2214,9 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
         shader->program_id = vc4->next_compiled_program_id++;
         if (stage == QSTAGE_FRAG) {
                 bool input_live[c->num_input_semantics];
-                struct simple_node *node;
 
                 memset(input_live, 0, sizeof(input_live));
-                foreach(node, &c->instructions) {
-                        struct qinst *inst = (struct qinst *)node;
+                list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                         for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
                                 if (inst->src[i].file == QFILE_VARY)
                                         input_live[inst->src[i].index] = true;
index e2e6a5cdf16b8d093261f5d93110efac94ffbfee..1c96ef4795f987f6128faf4177fbce30f1289921 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include "util/u_memory.h"
-#include "util/simple_list.h"
 #include "util/ralloc.h"
 
 #include "vc4_qir.h"
@@ -301,10 +300,7 @@ qir_dump_inst(struct vc4_compile *c, struct qinst *inst)
 void
 qir_dump(struct vc4_compile *c)
 {
-        struct simple_node *node;
-
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 qir_dump_inst(c, inst);
                 fprintf(stderr, "\n");
         }
@@ -370,7 +366,7 @@ qir_emit(struct vc4_compile *c, struct qinst *inst)
         if (inst->dst.file == QFILE_TEMP)
                 c->defs[inst->dst.index] = inst;
 
-        insert_at_tail(&c->instructions, &inst->link);
+        list_addtail(&inst->link, &c->instructions);
 }
 
 bool
@@ -384,7 +380,7 @@ qir_compile_init(void)
 {
         struct vc4_compile *c = rzalloc(NULL, struct vc4_compile);
 
-        make_empty_list(&c->instructions);
+        list_inithead(&c->instructions);
 
         c->output_position_index = -1;
         c->output_clipvertex_index = -1;
@@ -403,7 +399,7 @@ qir_remove_instruction(struct vc4_compile *c, struct qinst *qinst)
         if (qinst->dst.file == QFILE_TEMP)
                 c->defs[qinst->dst.index] = NULL;
 
-        remove_from_list(&qinst->link);
+        list_del(&qinst->link);
         free(qinst->src);
         free(qinst);
 }
@@ -420,9 +416,9 @@ qir_follow_movs(struct vc4_compile *c, struct qreg reg)
 void
 qir_compile_destroy(struct vc4_compile *c)
 {
-        while (!is_empty_list(&c->instructions)) {
+        while (!list_empty(&c->instructions)) {
                 struct qinst *qinst =
-                        (struct qinst *)first_elem(&c->instructions);
+                        (struct qinst *)c->instructions.next;
                 qir_remove_instruction(c, qinst);
         }
 
@@ -478,7 +474,7 @@ void
 qir_SF(struct vc4_compile *c, struct qreg src)
 {
         struct qinst *last_inst = NULL;
-        if (!is_empty_list(&c->instructions))
+        if (!list_empty(&c->instructions))
                 last_inst = (struct qinst *)c->instructions.prev;
 
         if (!last_inst ||
index adc2c89d2c1051582bd4923b58f3e6620b9c5168..732cfd0b3069ce9c7d0ec402fa7fdb4580b64413 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "util/macros.h"
 #include "glsl/nir/nir.h"
-#include "util/simple_list.h"
+#include "util/list.h"
 #include "util/u_math.h"
 
 enum qfile {
@@ -162,12 +162,12 @@ enum qop {
 };
 
 struct queued_qpu_inst {
-        struct simple_node link;
+        struct list_head link;
         uint64_t inst;
 };
 
 struct qinst {
-        struct simple_node link;
+        struct list_head link;
 
         enum qop op;
         struct qreg dst;
@@ -356,10 +356,10 @@ struct vc4_compile {
         struct qreg undef;
         enum qstage stage;
         uint32_t num_temps;
-        struct simple_node instructions;
+        struct list_head instructions;
         uint32_t immediates[1024];
 
-        struct simple_node qpu_inst_list;
+        struct list_head qpu_inst_list;
         uint64_t *qpu_insts;
         uint32_t qpu_inst_count;
         uint32_t qpu_inst_size;
index 63f5eb2285829d1ce8bd1a1e16f5443d205081b4..910c89dca797c2a11e11aeca8b871407f8495f9c 100644 (file)
@@ -88,7 +88,6 @@ is_lowerable_uniform(struct qinst *inst, int i)
 void
 qir_lower_uniforms(struct vc4_compile *c)
 {
-        struct simple_node *node;
         struct hash_table *ht =
                 _mesa_hash_table_create(c, index_hash, index_compare);
 
@@ -96,8 +95,7 @@ qir_lower_uniforms(struct vc4_compile *c)
          * than one uniform referenced, and add those uniform values to the
          * ht.
          */
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 uint32_t nsrc = qir_get_op_nsrc(inst->op);
 
                 uint32_t count = 0;
@@ -137,10 +135,9 @@ qir_lower_uniforms(struct vc4_compile *c)
                 struct qreg temp = qir_get_temp(c);
                 struct qreg unif = { QFILE_UNIF, max_index };
                 struct qinst *mov = qir_inst(QOP_MOV, temp, unif, c->undef);
-                insert_at_head(&c->instructions, &mov->link);
+                list_add(&mov->link, &c->instructions);
                 c->defs[temp.index] = mov;
-                foreach(node, &c->instructions) {
-                        struct qinst *inst = (struct qinst *)node;
+                list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                         uint32_t nsrc = qir_get_op_nsrc(inst->op);
 
                         uint32_t count = 0;
index eeb8d3a21ff6633811f923fbd62abb6628ae79fe..99afe4b8798427d31db47064107820ba40c73f1d 100644 (file)
@@ -47,14 +47,14 @@ queue(struct vc4_compile *c, uint64_t inst)
 {
         struct queued_qpu_inst *q = rzalloc(c, struct queued_qpu_inst);
         q->inst = inst;
-        insert_at_tail(&c->qpu_inst_list, &q->link);
+        list_addtail(&q->link, &c->qpu_inst_list);
 }
 
 static uint64_t *
 last_inst(struct vc4_compile *c)
 {
         struct queued_qpu_inst *q =
-                (struct queued_qpu_inst *)last_elem(&c->qpu_inst_list);
+                (struct queued_qpu_inst *)c->qpu_inst_list.prev;
         return &q->inst;
 }
 
@@ -117,11 +117,11 @@ fixup_raddr_conflict(struct vc4_compile *c,
                 return;
 
         if (mux0 == QPU_MUX_A) {
-                queue(c, qpu_a_MOV(qpu_rb(31), *src1));
-                *src1 = qpu_rb(31);
+                queue(c, qpu_a_MOV(qpu_rb(31), *src0));
+                *src0 = qpu_rb(31);
         } else {
-                queue(c, qpu_a_MOV(qpu_ra(31), *src1));
-                *src1 = qpu_ra(31);
+                queue(c, qpu_a_MOV(qpu_ra(31), *src0));
+                *src0 = qpu_ra(31);
         }
 }
 
@@ -144,7 +144,7 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                 QPU_UNPACK_16B_TO_F32,
         };
 
-        make_empty_list(&c->qpu_inst_list);
+        list_inithead(&c->qpu_inst_list);
 
         switch (c->stage) {
         case QSTAGE_VERT:
@@ -170,10 +170,7 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                 break;
         }
 
-        struct simple_node *node;
-        foreach(node, &c->instructions) {
-                struct qinst *qinst = (struct qinst *)node;
-
+        list_for_each_entry(struct qinst, qinst, &c->instructions, link) {
 #if 0
                 fprintf(stderr, "translating qinst to qpu: ");
                 qir_dump_inst(qinst);
index f523b4c6fb05e465232bc218cbcc1f8455d8c8b7..19cbf7bb98c35e2d58b51653eba1c983a9d1b73f 100644 (file)
@@ -43,7 +43,7 @@ static bool debug;
 struct schedule_node_child;
 
 struct schedule_node {
-        struct simple_node link;
+        struct list_head link;
         struct queued_qpu_inst *inst;
         struct schedule_node_child *children;
         uint32_t child_count;
@@ -400,22 +400,21 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n)
 }
 
 static void
-calculate_forward_deps(struct vc4_compile *c, struct simple_node *schedule_list)
+calculate_forward_deps(struct vc4_compile *c, struct list_head *schedule_list)
 {
-        struct simple_node *node;
         struct schedule_state state;
 
         memset(&state, 0, sizeof(state));
         state.dir = F;
 
-        foreach(node, schedule_list)
-                calculate_deps(&state, (struct schedule_node *)node);
+        list_for_each_entry(struct schedule_node, node, schedule_list, link)
+                calculate_deps(&state, node);
 }
 
 static void
-calculate_reverse_deps(struct vc4_compile *c, struct simple_node *schedule_list)
+calculate_reverse_deps(struct vc4_compile *c, struct list_head *schedule_list)
 {
-        struct simple_node *node;
+        struct list_head *node;
         struct schedule_state state;
 
         memset(&state, 0, sizeof(state));
@@ -507,15 +506,13 @@ get_instruction_priority(uint64_t inst)
 
 static struct schedule_node *
 choose_instruction_to_schedule(struct choose_scoreboard *scoreboard,
-                               struct simple_node *schedule_list,
+                               struct list_head *schedule_list,
                                struct schedule_node *prev_inst)
 {
         struct schedule_node *chosen = NULL;
-        struct simple_node *node;
         int chosen_prio = 0;
 
-        foreach(node, schedule_list) {
-                struct schedule_node *n = (struct schedule_node *)node;
+        list_for_each_entry(struct schedule_node, n, schedule_list, link) {
                 uint64_t inst = n->inst->inst;
 
                 /* "An instruction must not read from a location in physical
@@ -596,14 +593,11 @@ update_scoreboard_for_chosen(struct choose_scoreboard *scoreboard,
 }
 
 static void
-dump_state(struct simple_node *schedule_list)
+dump_state(struct list_head *schedule_list)
 {
-        struct simple_node *node;
-
         uint32_t i = 0;
-        foreach(node, schedule_list) {
-                struct schedule_node *n = (struct schedule_node *)node;
 
+        list_for_each_entry(struct schedule_node, n, schedule_list, link) {
                 fprintf(stderr, "%3d: ", i++);
                 vc4_qpu_disasm(&n->inst->inst, 1);
                 fprintf(stderr, "\n");
@@ -639,7 +633,7 @@ compute_delay(struct schedule_node *n)
 }
 
 static void
-mark_instruction_scheduled(struct simple_node *schedule_list,
+mark_instruction_scheduled(struct list_head *schedule_list,
                            struct schedule_node *node,
                            bool war_only)
 {
@@ -658,16 +652,15 @@ mark_instruction_scheduled(struct simple_node *schedule_list,
 
                 child->parent_count--;
                 if (child->parent_count == 0)
-                        insert_at_head(schedule_list, &child->link);
+                        list_add(&child->link, schedule_list);
 
                 node->children[i].node = NULL;
         }
 }
 
 static void
-schedule_instructions(struct vc4_compile *c, struct simple_node *schedule_list)
+schedule_instructions(struct vc4_compile *c, struct list_head *schedule_list)
 {
-        struct simple_node *node, *t;
         struct choose_scoreboard scoreboard;
 
         /* We reorder the uniforms as we schedule instructions, so save the
@@ -693,14 +686,12 @@ schedule_instructions(struct vc4_compile *c, struct simple_node *schedule_list)
         }
 
         /* Remove non-DAG heads from the list. */
-        foreach_s(node, t, schedule_list) {
-                struct schedule_node *n = (struct schedule_node *)node;
-
+        list_for_each_entry_safe(struct schedule_node, n, schedule_list, link) {
                 if (n->parent_count != 0)
-                        remove_from_list(&n->link);
+                        list_del(&n->link);
         }
 
-        while (!is_empty_list(schedule_list)) {
+        while (!list_empty(schedule_list)) {
                 struct schedule_node *chosen =
                         choose_instruction_to_schedule(&scoreboard,
                                                        schedule_list,
@@ -724,7 +715,7 @@ schedule_instructions(struct vc4_compile *c, struct simple_node *schedule_list)
                  * find an instruction to pair with it.
                  */
                 if (chosen) {
-                        remove_from_list(&chosen->link);
+                        list_del(&chosen->link);
                         mark_instruction_scheduled(schedule_list, chosen, true);
                         if (chosen->uniform != -1) {
                                 c->uniform_data[next_uniform] =
@@ -738,7 +729,7 @@ schedule_instructions(struct vc4_compile *c, struct simple_node *schedule_list)
                                                                schedule_list,
                                                                chosen);
                         if (merge) {
-                                remove_from_list(&merge->link);
+                                list_del(&merge->link);
                                 inst = qpu_merge_inst(inst, merge->inst->inst);
                                 assert(inst != 0);
                                 if (merge->uniform != -1) {
@@ -813,16 +804,14 @@ void
 qpu_schedule_instructions(struct vc4_compile *c)
 {
         void *mem_ctx = ralloc_context(NULL);
-        struct simple_node schedule_list;
-        struct simple_node *node;
+        struct list_head schedule_list;
 
-        make_empty_list(&schedule_list);
+        list_inithead(&schedule_list);
 
         if (debug) {
                 fprintf(stderr, "Pre-schedule instructions\n");
-                foreach(node, &c->qpu_inst_list) {
-                        struct queued_qpu_inst *q =
-                                (struct queued_qpu_inst *)node;
+                list_for_each_entry(struct queued_qpu_inst, q,
+                                    &c->qpu_inst_list, link) {
                         vc4_qpu_disasm(&q->inst, 1);
                         fprintf(stderr, "\n");
                 }
@@ -831,7 +820,7 @@ qpu_schedule_instructions(struct vc4_compile *c)
 
         /* Wrap each instruction in a scheduler structure. */
         uint32_t next_uniform = 0;
-        while (!is_empty_list(&c->qpu_inst_list)) {
+        while (!list_empty(&c->qpu_inst_list)) {
                 struct queued_qpu_inst *inst =
                         (struct queued_qpu_inst *)c->qpu_inst_list.next;
                 struct schedule_node *n = rzalloc(mem_ctx, struct schedule_node);
@@ -844,16 +833,15 @@ qpu_schedule_instructions(struct vc4_compile *c)
                 } else {
                         n->uniform = -1;
                 }
-                remove_from_list(&inst->link);
-                insert_at_tail(&schedule_list, &n->link);
+                list_del(&inst->link);
+                list_addtail(&n->link, &schedule_list);
         }
         assert(next_uniform == c->num_uniforms);
 
         calculate_forward_deps(c, &schedule_list);
         calculate_reverse_deps(c, &schedule_list);
 
-        foreach(node, &schedule_list) {
-                struct schedule_node *n = (struct schedule_node *)node;
+        list_for_each_entry(struct schedule_node, n, &schedule_list, link) {
                 compute_delay(n);
         }
 
index 1792becb08f4890647529a22438109f111fef15b..270832eae3aa6ed86567615b38fb0aa3cf8abbc9 100644 (file)
@@ -50,9 +50,10 @@ vc4_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
         free(query);
 }
 
-static void
+static boolean
 vc4_begin_query(struct pipe_context *ctx, struct pipe_query *query)
 {
+        return true;
 }
 
 static void
index f40547b815403b4e0670181a2c17cf8eeb4d7ee7..3b0b890b66a43f0ffcd3a3a1891b9562f7fd9048 100644 (file)
@@ -161,7 +161,6 @@ node_to_temp_priority(const void *in_a, const void *in_b)
 struct qpu_reg *
 vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c)
 {
-        struct simple_node *node;
         struct node_to_temp_map map[c->num_temps];
         uint32_t temp_to_node[c->num_temps];
         uint32_t def[c->num_temps];
@@ -189,9 +188,7 @@ vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c)
         /* Compute the live ranges so we can figure out interference.
          */
         uint32_t ip = 0;
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
-
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 if (inst->dst.file == QFILE_TEMP) {
                         def[inst->dst.index] = ip;
                         use[inst->dst.index] = ip;
@@ -227,9 +224,7 @@ vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c)
         }
 
         /* Figure out our register classes and preallocated registers*/
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
-
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 switch (inst->op) {
                 case QOP_FRAG_Z:
                         ra_set_node_reg(g, temp_to_node[inst->dst.index],
index 109724369d5371ef909805af14503d9e2a22079a..7f11fba2340a54754d7c44bc115de2478e2e0fcd 100644 (file)
@@ -42,10 +42,8 @@ qir_reorder_uniforms(struct vc4_compile *c)
         uint32_t *uniform_index = NULL;
         uint32_t uniform_index_size = 0;
         uint32_t next_uniform = 0;
-        struct simple_node *node;
-        foreach(node, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
 
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
                 for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
                         if (inst->src[i].file != QFILE_UNIF)
                                 continue;
index 3f180d5845d86405cadc6f9d1c286648ffda702f..cab764060551ba9c4c7be295e247d4d2a7ed3f92 100644 (file)
@@ -26,6 +26,7 @@
 #include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_surface.h"
+#include "util/u_upload_mgr.h"
 
 #include "vc4_screen.h"
 #include "vc4_context.h"
@@ -161,6 +162,8 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
                 /* We need to align the box to utile boundaries, since that's
                  * what load/store operate on.
                  */
+                uint32_t orig_width = ptrans->box.width;
+                uint32_t orig_height = ptrans->box.height;
                 uint32_t box_start_x = ptrans->box.x & (utile_w - 1);
                 uint32_t box_start_y = ptrans->box.y & (utile_h - 1);
                 ptrans->box.width += box_start_x;
@@ -174,7 +177,9 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
                 ptrans->layer_stride = ptrans->stride;
 
                 trans->map = malloc(ptrans->stride * ptrans->box.height);
-                if (usage & PIPE_TRANSFER_READ) {
+                if (usage & PIPE_TRANSFER_READ ||
+                    ptrans->box.width != orig_width ||
+                    ptrans->box.height != orig_height) {
                         vc4_load_tiled_image(trans->map, ptrans->stride,
                                              buf + slice->offset +
                                              box->z * rsc->cube_map_stride,
@@ -638,41 +643,37 @@ vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
  * was in user memory, it would be nice to not have uploaded it to a VBO
  * before translating.
  */
-void
-vc4_update_shadow_index_buffer(struct pipe_context *pctx,
-                               const struct pipe_index_buffer *ib)
+struct pipe_resource *
+vc4_get_shadow_index_buffer(struct pipe_context *pctx,
+                            const struct pipe_index_buffer *ib,
+                            uint32_t count,
+                            uint32_t *shadow_offset)
 {
-        struct vc4_resource *shadow = vc4_resource(ib->buffer);
-        struct vc4_resource *orig = vc4_resource(shadow->shadow_parent);
-        uint32_t count = shadow->base.b.width0 / 2;
-
-        if (shadow->writes == orig->writes)
-                return;
-
+        struct vc4_context *vc4 = vc4_context(pctx);
+        struct vc4_resource *orig = vc4_resource(ib->buffer);
         perf_debug("Fallback conversion for %d uint indices\n", count);
 
+        void *data;
+        struct pipe_resource *shadow_rsc = NULL;
+        u_upload_alloc(vc4->uploader, 0, count * 2,
+                       shadow_offset, &shadow_rsc, &data);
+        uint16_t *dst = data;
+
         struct pipe_transfer *src_transfer;
         uint32_t *src = pipe_buffer_map_range(pctx, &orig->base.b,
                                               ib->offset,
                                               count * 4,
                                               PIPE_TRANSFER_READ, &src_transfer);
 
-        struct pipe_transfer *dst_transfer;
-        uint16_t *dst = pipe_buffer_map_range(pctx, &shadow->base.b,
-                                              0,
-                                              count * 2,
-                                              PIPE_TRANSFER_WRITE, &dst_transfer);
-
         for (int i = 0; i < count; i++) {
                 uint32_t src_index = src[i];
                 assert(src_index <= 0xffff);
                 dst[i] = src_index;
         }
 
-        pctx->transfer_unmap(pctx, dst_transfer);
         pctx->transfer_unmap(pctx, src_transfer);
 
-        shadow->writes = orig->writes;
+        return shadow_rsc;
 }
 
 void
index 2ed848bc7b96d6ddc2099eeda6c7ac8bbe5661c6..ab8f5d3cd55ee99128d8f0a646e1e142e9a9842d 100644 (file)
@@ -26,7 +26,7 @@
 #define VC4_RESOURCE_H
 
 #include "vc4_screen.h"
-#include "vc4_packet.h"
+#include "kernel/vc4_packet.h"
 #include "util/u_transfer.h"
 
 struct vc4_transfer {
@@ -45,7 +45,6 @@ struct vc4_resource_slice {
 struct vc4_surface {
         struct pipe_surface base;
         uint32_t offset;
-        uint32_t stride;
         uint8_t tiling;
 };
 
@@ -107,8 +106,10 @@ struct pipe_resource *vc4_resource_create(struct pipe_screen *pscreen,
                                           const struct pipe_resource *tmpl);
 void vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
                                          struct pipe_sampler_view *view);
-void vc4_update_shadow_index_buffer(struct pipe_context *pctx,
-                                    const struct pipe_index_buffer *ib);
+struct pipe_resource *vc4_get_shadow_index_buffer(struct pipe_context *pctx,
+                                                  const struct pipe_index_buffer *ib,
+                                                  uint32_t count,
+                                                  uint32_t *offset);
 void vc4_dump_surface(struct pipe_surface *psurf);
 
 #endif /* VC4_RESOURCE_H */
index 84aae918326c53875b6d9583586bf1a06c0ed077..f63bead0fbb93c474270e3b78e4fe60137f291db 100644 (file)
@@ -175,6 +175,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_POLYGON_OFFSET_CLAMP:
         case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
         case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
+        case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
                 return 0;
 
                 /* Stream output. */
@@ -322,6 +323,7 @@ vc4_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
         case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
         case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
         case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
+        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
                 return 0;
         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
         case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
@@ -458,7 +460,7 @@ vc4_screen_create(int fd)
         pscreen->is_format_supported = vc4_screen_is_format_supported;
 
         screen->fd = fd;
-        make_empty_list(&screen->bo_cache.time_list);
+        list_inithead(&screen->bo_cache.time_list);
 
         vc4_fence_init(screen);
 
index 60626285d4ddb7d18921fbd112db6535f328ff25..5992e37109380e4590ba140c01451fe315ef5498 100644 (file)
@@ -27,7 +27,7 @@
 #include "pipe/p_screen.h"
 #include "os/os_thread.h"
 #include "state_tracker/drm_driver.h"
-#include "vc4_qir.h"
+#include "util/list.h"
 
 struct vc4_bo;
 
@@ -61,13 +61,19 @@ struct vc4_screen {
 
         struct vc4_bo_cache {
                 /** List of struct vc4_bo freed, by age. */
-                struct simple_node time_list;
+                struct list_head time_list;
                 /** List of struct vc4_bo freed, per size, by age. */
-                struct simple_node *size_list;
+                struct list_head *size_list;
                 uint32_t size_list_size;
 
                 pipe_mutex lock;
+
+                uint32_t bo_size;
+                uint32_t bo_count;
         } bo_cache;
+
+        uint32_t bo_size;
+        uint32_t bo_count;
 };
 
 static inline struct vc4_screen *
index 2f72e722fc558edf6db5b4f30b33df7c716da0b8..b58013dd2ee3e43802df82c7f19dcd7cbe3f195d 100644 (file)
@@ -39,11 +39,13 @@ vc4_wrap_bo_with_cma(struct drm_device *dev, struct vc4_bo *bo)
 {
         struct vc4_context *vc4 = dev->vc4;
         struct vc4_screen *screen = vc4->screen;
-        struct drm_gem_cma_object *obj = CALLOC_STRUCT(drm_gem_cma_object);
+        struct drm_vc4_bo *drm_bo = CALLOC_STRUCT(drm_vc4_bo);
+        struct drm_gem_cma_object *obj = &drm_bo->base;
         uint32_t size = align(bo->size, 4096);
 
-        obj->bo = bo;
+        drm_bo->bo = bo;
         obj->base.size = size;
+        obj->base.dev = dev;
         obj->vaddr = screen->simulator_mem_base + dev->simulator_mem_next;
         obj->paddr = simpenrose_hw_addr(obj->vaddr);
 
@@ -94,7 +96,7 @@ vc4_simulator_unpin_bos(struct vc4_exec_info *exec)
 {
         for (int i = 0; i < exec->bo_count; i++) {
                 struct drm_gem_cma_object *obj = exec->bo[i].bo;
-                struct vc4_bo *bo = obj->bo;
+                struct vc4_bo *bo = to_vc4_bo(&obj->base)->bo;
 
                 memcpy(bo->map, obj->vaddr, bo->size);
 
@@ -124,6 +126,7 @@ vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
         int ret;
 
         memset(&exec, 0, sizeof(exec));
+        list_inithead(&exec.unref_list);
 
         if (ctex && ctex->bo->simulator_winsys_map) {
 #if 0
@@ -176,8 +179,12 @@ vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
         if (ret)
                 return ret;
 
-        vc4_bo_unreference(&exec.exec_bo->bo);
-        free(exec.exec_bo);
+        list_for_each_entry_safe(struct drm_vc4_bo, bo, &exec.unref_list,
+                                 unref_head) {
+               list_del(&bo->unref_head);
+                vc4_bo_unreference(&bo->bo);
+                free(bo);
+        }
 
         if (ctex && ctex->bo->simulator_winsys_map) {
                 for (int y = 0; y < ctex->base.b.height0; y++) {
index 1f0c6b67c0f48d5b99b6ecc6dc9b0c1bd37a9d79..2bb36b253bba848d66c6ef0b2e71ee029b77eb51 100644 (file)
@@ -43,6 +43,7 @@ struct vc4_exec_info;
 #define kfree(ptr) free(ptr)
 #define krealloc(ptr, size, args) realloc(ptr, size)
 #define roundup(x, y) align(x, y)
+#define round_up(x, y) align(x, y)
 #define max(x, y) MAX2(x, y)
 #define min(x, y) MiN2(x, y)
 #define BUG_ON(condition) assert(!(condition))
@@ -63,16 +64,27 @@ struct drm_device {
         uint32_t simulator_mem_next;
 };
 
-struct drm_gem_cma_object {
-        struct vc4_bo *bo;
+struct drm_gem_object {
+        uint32_t size;
+        struct drm_device *dev;
+};
 
-        struct {
-                uint32_t size;
-        } base;
+struct drm_gem_cma_object {
+        struct drm_gem_object base;
         uint32_t paddr;
         void *vaddr;
 };
 
+struct drm_vc4_bo {
+        struct drm_gem_cma_object base;
+        struct vc4_bo *bo;
+        struct list_head unref_head;
+};
+
+static inline struct drm_vc4_bo *to_vc4_bo(struct drm_gem_object *obj)
+{
+        return (struct drm_vc4_bo *)obj;
+}
 
 struct drm_gem_cma_object *
 drm_gem_cma_create(struct drm_device *dev, size_t size);
index 80e963ea2ee2a3a5c43b494b61f32c732b61a5f0..4a1d4c3a4d64981d85e983c0f21becc45e141e0c 100644 (file)
@@ -304,24 +304,8 @@ vc4_set_index_buffer(struct pipe_context *pctx,
 
         if (ib) {
                 assert(!ib->user_buffer);
-
-                if (ib->index_size == 4) {
-                        struct pipe_resource tmpl = *ib->buffer;
-                        assert(tmpl.format == PIPE_FORMAT_R8_UNORM);
-                        assert(tmpl.height0 == 1);
-                        tmpl.width0 = (tmpl.width0 - ib->offset) / 2;
-                        struct pipe_resource *pshadow =
-                                vc4_resource_create(&vc4->screen->base, &tmpl);
-                        struct vc4_resource *shadow = vc4_resource(pshadow);
-                        pipe_resource_reference(&shadow->shadow_parent, ib->buffer);
-
-                        pipe_resource_reference(&vc4->indexbuf.buffer, NULL);
-                        vc4->indexbuf.buffer = pshadow;
-                        vc4->indexbuf.index_size = 2;
-                } else {
-                        pipe_resource_reference(&vc4->indexbuf.buffer, ib->buffer);
-                        vc4->indexbuf.index_size = ib->index_size;
-                }
+                pipe_resource_reference(&vc4->indexbuf.buffer, ib->buffer);
+                vc4->indexbuf.index_size = ib->index_size;
                 vc4->indexbuf.offset = ib->offset;
         } else {
                 pipe_resource_reference(&vc4->indexbuf.buffer, NULL);
@@ -538,6 +522,7 @@ vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
                 struct pipe_resource tmpl = shadow_parent->base.b;
                 struct vc4_resource *clone;
 
+                tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
                 tmpl.width0 = u_minify(tmpl.width0, so->u.tex.first_level);
                 tmpl.height0 = u_minify(tmpl.height0, so->u.tex.first_level);
                 tmpl.last_level = so->u.tex.last_level - so->u.tex.first_level;
@@ -547,6 +532,8 @@ vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
                 clone->shadow_parent = &shadow_parent->base.b;
                 /* Flag it as needing update of the contents from the parent. */
                 clone->writes = shadow_parent->writes - 1;
+
+                assert(clone->vc4_format != VC4_TEXTURE_TYPE_RGBA32R);
         }
         so->texture = prsc;
         so->reference.count = 1;
index adff67a88c8c62e74f76e99a2d9afbdf8df9ba41..c2eedf8e7c72c6604337c4da5007964beb51d049 100644 (file)
@@ -170,6 +170,16 @@ struct pipe_context {
    void   (*bind_gs_state)(struct pipe_context *, void *);
    void   (*delete_gs_state)(struct pipe_context *, void *);
 
+   void * (*create_tcs_state)(struct pipe_context *,
+                              const struct pipe_shader_state *);
+   void   (*bind_tcs_state)(struct pipe_context *, void *);
+   void   (*delete_tcs_state)(struct pipe_context *, void *);
+
+   void * (*create_tes_state)(struct pipe_context *,
+                              const struct pipe_shader_state *);
+   void   (*bind_tes_state)(struct pipe_context *, void *);
+   void   (*delete_tes_state)(struct pipe_context *, void *);
+
    void * (*create_vertex_elements_state)(struct pipe_context *,
                                           unsigned num_elements,
                                           const struct pipe_vertex_element *);
@@ -221,6 +231,10 @@ struct pipe_context {
                              unsigned start_slot, unsigned num_views,
                              struct pipe_sampler_view **);
 
+   void (*set_tess_state)(struct pipe_context *,
+                          const float default_outer_level[4],
+                          const float default_inner_level[2]);
+
    /**
     * Bind an array of shader resources that will be used by the
     * graphics pipeline.  Any resources that were previously bound to
@@ -562,6 +576,10 @@ struct pipe_context {
    void (*invalidate_resource)(struct pipe_context *ctx,
                                struct pipe_resource *resource);
 
+   /**
+    * Return information about unexpected device resets.
+    */
+   enum pipe_reset_status (*get_device_reset_status)(struct pipe_context *ctx);
 };
 
 
index 8a16fde22e7d9b8038b2a894f8f756c06260eab1..88b7b7699c1719353c4f5a69016c6037808d4a31 100644 (file)
@@ -404,8 +404,10 @@ enum pipe_flush_flags
 #define PIPE_SHADER_VERTEX   0
 #define PIPE_SHADER_FRAGMENT 1
 #define PIPE_SHADER_GEOMETRY 2
-#define PIPE_SHADER_COMPUTE  3
-#define PIPE_SHADER_TYPES    4
+#define PIPE_SHADER_TESS_CTRL 3
+#define PIPE_SHADER_TESS_EVAL 4
+#define PIPE_SHADER_COMPUTE  5
+#define PIPE_SHADER_TYPES    6
 
 
 /**
@@ -425,9 +427,17 @@ enum pipe_flush_flags
 #define PIPE_PRIM_LINE_STRIP_ADJACENCY     11
 #define PIPE_PRIM_TRIANGLES_ADJACENCY      12
 #define PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY 13
-#define PIPE_PRIM_MAX                      14
+#define PIPE_PRIM_PATCHES                  14
+#define PIPE_PRIM_MAX                      15
 
 
+/**
+ * Tessellator spacing types
+ */
+#define PIPE_TESS_SPACING_FRACTIONAL_ODD    0
+#define PIPE_TESS_SPACING_FRACTIONAL_EVEN   1
+#define PIPE_TESS_SPACING_EQUAL             2
+
 /**
  * Query object types
  */
@@ -476,111 +486,125 @@ enum pipe_flush_flags
 
 #define PIPE_TIMEOUT_INFINITE 0xffffffffffffffffull
 
+
+/**
+ * Device reset status.
+ */
+enum pipe_reset_status
+{
+   PIPE_NO_RESET = 0,
+   PIPE_GUILTY_CONTEXT_RESET = 1,
+   PIPE_INNOCENT_CONTEXT_RESET = 2,
+   PIPE_UNKNOWN_CONTEXT_RESET = 3
+};
+
+
 /**
  * Implementation capabilities/limits which are queried through
  * pipe_screen::get_param()
  */
 enum pipe_cap
 {
-   PIPE_CAP_NPOT_TEXTURES = 1,
-   PIPE_CAP_TWO_SIDED_STENCIL = 2,
-   PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS = 4,
-   PIPE_CAP_ANISOTROPIC_FILTER = 5,
-   PIPE_CAP_POINT_SPRITE = 6,
-   PIPE_CAP_MAX_RENDER_TARGETS = 7,
-   PIPE_CAP_OCCLUSION_QUERY = 8,
-   PIPE_CAP_QUERY_TIME_ELAPSED = 9,
-   PIPE_CAP_TEXTURE_SHADOW_MAP = 10,
-   PIPE_CAP_TEXTURE_SWIZZLE = 11,
-   PIPE_CAP_MAX_TEXTURE_2D_LEVELS = 12,
-   PIPE_CAP_MAX_TEXTURE_3D_LEVELS = 13,
-   PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS = 14,
-   PIPE_CAP_TEXTURE_MIRROR_CLAMP = 25,
-   PIPE_CAP_BLEND_EQUATION_SEPARATE = 28,
-   PIPE_CAP_SM3 = 29,  /*< Shader Model, supported */
-   PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS = 30,
-   PIPE_CAP_PRIMITIVE_RESTART = 31,
+   PIPE_CAP_NPOT_TEXTURES,
+   PIPE_CAP_TWO_SIDED_STENCIL,
+   PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS,
+   PIPE_CAP_ANISOTROPIC_FILTER,
+   PIPE_CAP_POINT_SPRITE,
+   PIPE_CAP_MAX_RENDER_TARGETS,
+   PIPE_CAP_OCCLUSION_QUERY,
+   PIPE_CAP_QUERY_TIME_ELAPSED,
+   PIPE_CAP_TEXTURE_SHADOW_MAP,
+   PIPE_CAP_TEXTURE_SWIZZLE,
+   PIPE_CAP_MAX_TEXTURE_2D_LEVELS,
+   PIPE_CAP_MAX_TEXTURE_3D_LEVELS,
+   PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS,
+   PIPE_CAP_TEXTURE_MIRROR_CLAMP,
+   PIPE_CAP_BLEND_EQUATION_SEPARATE,
+   PIPE_CAP_SM3,
+   PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS,
+   PIPE_CAP_PRIMITIVE_RESTART,
    /** blend enables and write masks per rendertarget */
-   PIPE_CAP_INDEP_BLEND_ENABLE = 33,
+   PIPE_CAP_INDEP_BLEND_ENABLE,
    /** different blend funcs per rendertarget */
-   PIPE_CAP_INDEP_BLEND_FUNC = 34,
-   PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS = 36,
-   PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT = 37,
-   PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT = 38,
-   PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER = 39,
-   PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER = 40,
-   PIPE_CAP_DEPTH_CLIP_DISABLE = 41,
-   PIPE_CAP_SHADER_STENCIL_EXPORT = 42,
-   PIPE_CAP_TGSI_INSTANCEID = 43,
-   PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR = 44,
-   PIPE_CAP_FRAGMENT_COLOR_CLAMPED = 45,
-   PIPE_CAP_MIXED_COLORBUFFER_FORMATS = 46,
-   PIPE_CAP_SEAMLESS_CUBE_MAP = 47,
-   PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE = 48,
-   PIPE_CAP_MIN_TEXEL_OFFSET = 50,
-   PIPE_CAP_MAX_TEXEL_OFFSET = 51,
-   PIPE_CAP_CONDITIONAL_RENDER = 52,
-   PIPE_CAP_TEXTURE_BARRIER = 53,
-   PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS = 55,
-   PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS = 56,
-   PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME = 57,
-   PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS = 59, /* temporary */
-   PIPE_CAP_VERTEX_COLOR_UNCLAMPED = 60,
-   PIPE_CAP_VERTEX_COLOR_CLAMPED = 61,
-   PIPE_CAP_GLSL_FEATURE_LEVEL = 62,
-   PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 63,
-   PIPE_CAP_USER_VERTEX_BUFFERS = 64,
-   PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY = 65,
-   PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY = 66,
-   PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY = 67,
-   PIPE_CAP_COMPUTE = 68,
-   PIPE_CAP_USER_INDEX_BUFFERS = 69,
-   PIPE_CAP_USER_CONSTANT_BUFFERS = 70,
-   PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 71,
-   PIPE_CAP_START_INSTANCE = 72,
-   PIPE_CAP_QUERY_TIMESTAMP = 73,
-   PIPE_CAP_TEXTURE_MULTISAMPLE = 74,
-   PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT = 75,
-   PIPE_CAP_CUBE_MAP_ARRAY = 76,
-   PIPE_CAP_TEXTURE_BUFFER_OBJECTS = 77,
-   PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78,
-   PIPE_CAP_TGSI_TEXCOORD = 79,
-   PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER = 80,
-   PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81,
-   PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK = 82,
-   PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE = 83,
-   PIPE_CAP_MAX_VIEWPORTS = 84,
-   PIPE_CAP_ENDIANNESS = 85,
-   PIPE_CAP_MIXED_FRAMEBUFFER_SIZES = 86,
-   PIPE_CAP_TGSI_VS_LAYER_VIEWPORT = 87,
-   PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES = 88,
-   PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 89,
-   PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS = 90,
-   PIPE_CAP_TEXTURE_GATHER_SM5 = 91,
-   PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT = 92,
-   PIPE_CAP_FAKE_SW_MSAA = 93,
-   PIPE_CAP_TEXTURE_QUERY_LOD = 94,
-   PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET = 95,
-   PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET = 96,
-   PIPE_CAP_SAMPLE_SHADING = 97,
-   PIPE_CAP_TEXTURE_GATHER_OFFSETS = 98,
-   PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99,
-   PIPE_CAP_MAX_VERTEX_STREAMS = 100,
-   PIPE_CAP_DRAW_INDIRECT = 101,
-   PIPE_CAP_TGSI_FS_FINE_DERIVATIVE = 102,
-   PIPE_CAP_VENDOR_ID = 103,
-   PIPE_CAP_DEVICE_ID = 104,
-   PIPE_CAP_ACCELERATED = 105,
-   PIPE_CAP_VIDEO_MEMORY = 106,
-   PIPE_CAP_UMA = 107,
-   PIPE_CAP_CONDITIONAL_RENDER_INVERTED = 108,
-   PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE = 109,
-   PIPE_CAP_SAMPLER_VIEW_TARGET = 110,
-   PIPE_CAP_CLIP_HALFZ = 111,
-   PIPE_CAP_VERTEXID_NOBASE = 112,
-   PIPE_CAP_POLYGON_OFFSET_CLAMP = 113,
-   PIPE_CAP_MULTISAMPLE_Z_RESOLVE = 114,
-   PIPE_CAP_RESOURCE_FROM_USER_MEMORY = 115,
+   PIPE_CAP_INDEP_BLEND_FUNC,
+   PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS,
+   PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT,
+   PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT,
+   PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER,
+   PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER,
+   PIPE_CAP_DEPTH_CLIP_DISABLE,
+   PIPE_CAP_SHADER_STENCIL_EXPORT,
+   PIPE_CAP_TGSI_INSTANCEID,
+   PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR,
+   PIPE_CAP_FRAGMENT_COLOR_CLAMPED,
+   PIPE_CAP_MIXED_COLORBUFFER_FORMATS,
+   PIPE_CAP_SEAMLESS_CUBE_MAP,
+   PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE,
+   PIPE_CAP_MIN_TEXEL_OFFSET,
+   PIPE_CAP_MAX_TEXEL_OFFSET,
+   PIPE_CAP_CONDITIONAL_RENDER,
+   PIPE_CAP_TEXTURE_BARRIER,
+   PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS,
+   PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS,
+   PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME,
+   PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS,
+   PIPE_CAP_VERTEX_COLOR_UNCLAMPED,
+   PIPE_CAP_VERTEX_COLOR_CLAMPED,
+   PIPE_CAP_GLSL_FEATURE_LEVEL,
+   PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION,
+   PIPE_CAP_USER_VERTEX_BUFFERS,
+   PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY,
+   PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY,
+   PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY,
+   PIPE_CAP_COMPUTE,
+   PIPE_CAP_USER_INDEX_BUFFERS,
+   PIPE_CAP_USER_CONSTANT_BUFFERS,
+   PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT,
+   PIPE_CAP_START_INSTANCE,
+   PIPE_CAP_QUERY_TIMESTAMP,
+   PIPE_CAP_TEXTURE_MULTISAMPLE,
+   PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT,
+   PIPE_CAP_CUBE_MAP_ARRAY,
+   PIPE_CAP_TEXTURE_BUFFER_OBJECTS,
+   PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT,
+   PIPE_CAP_TGSI_TEXCOORD,
+   PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER,
+   PIPE_CAP_QUERY_PIPELINE_STATISTICS,
+   PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK,
+   PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE,
+   PIPE_CAP_MAX_VIEWPORTS,
+   PIPE_CAP_ENDIANNESS,
+   PIPE_CAP_MIXED_FRAMEBUFFER_SIZES,
+   PIPE_CAP_TGSI_VS_LAYER_VIEWPORT,
+   PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES,
+   PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
+   PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS,
+   PIPE_CAP_TEXTURE_GATHER_SM5,
+   PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT,
+   PIPE_CAP_FAKE_SW_MSAA,
+   PIPE_CAP_TEXTURE_QUERY_LOD,
+   PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET,
+   PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET,
+   PIPE_CAP_SAMPLE_SHADING,
+   PIPE_CAP_TEXTURE_GATHER_OFFSETS,
+   PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION,
+   PIPE_CAP_MAX_VERTEX_STREAMS,
+   PIPE_CAP_DRAW_INDIRECT,
+   PIPE_CAP_TGSI_FS_FINE_DERIVATIVE,
+   PIPE_CAP_VENDOR_ID,
+   PIPE_CAP_DEVICE_ID,
+   PIPE_CAP_ACCELERATED,
+   PIPE_CAP_VIDEO_MEMORY,
+   PIPE_CAP_UMA,
+   PIPE_CAP_CONDITIONAL_RENDER_INVERTED,
+   PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE,
+   PIPE_CAP_SAMPLER_VIEW_TARGET,
+   PIPE_CAP_CLIP_HALFZ,
+   PIPE_CAP_VERTEXID_NOBASE,
+   PIPE_CAP_POLYGON_OFFSET_CLAMP,
+   PIPE_CAP_MULTISAMPLE_Z_RESOLVE,
+   PIPE_CAP_RESOURCE_FROM_USER_MEMORY,
+   PIPE_CAP_DEVICE_RESET_STATUS_QUERY,
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
@@ -645,6 +669,7 @@ enum pipe_shader_cap
    PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED, /* all rounding modes */
    PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED,
    PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED,
+   PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE
 };
 
 /**
index c14bcbca33613cc2c4f8d7674b172011feebfb1e..bb57e805c29137f408eddf847dd90d4fb5965432 100644 (file)
@@ -43,7 +43,9 @@ struct tgsi_header
 #define TGSI_PROCESSOR_FRAGMENT  0
 #define TGSI_PROCESSOR_VERTEX    1
 #define TGSI_PROCESSOR_GEOMETRY  2
-#define TGSI_PROCESSOR_COMPUTE   3
+#define TGSI_PROCESSOR_TESS_CTRL 3
+#define TGSI_PROCESSOR_TESS_EVAL 4
+#define TGSI_PROCESSOR_COMPUTE   5
 
 struct tgsi_processor
 {
@@ -178,7 +180,12 @@ struct tgsi_declaration_interp
 #define TGSI_SEMANTIC_INVOCATIONID 27
 #define TGSI_SEMANTIC_VERTEXID_NOBASE 28
 #define TGSI_SEMANTIC_BASEVERTEX 29
-#define TGSI_SEMANTIC_COUNT      30 /**< number of semantic values */
+#define TGSI_SEMANTIC_PATCH      30 /**< generic per-patch semantic */
+#define TGSI_SEMANTIC_TESSCOORD  31 /**< coordinate being processed by tess */
+#define TGSI_SEMANTIC_TESSOUTER  32 /**< outer tessellation levels */
+#define TGSI_SEMANTIC_TESSINNER  33 /**< inner tessellation levels */
+#define TGSI_SEMANTIC_VERTICESIN 34 /**< number of input vertices */
+#define TGSI_SEMANTIC_COUNT      35 /**< number of semantic values */
 
 struct tgsi_declaration_semantic
 {
@@ -255,7 +262,12 @@ union tgsi_immediate_data
 #define TGSI_PROPERTY_VS_PROHIBIT_UCPS       7
 #define TGSI_PROPERTY_GS_INVOCATIONS         8
 #define TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION 9
-#define TGSI_PROPERTY_COUNT                  10
+#define TGSI_PROPERTY_TCS_VERTICES_OUT       10
+#define TGSI_PROPERTY_TES_PRIM_MODE          11
+#define TGSI_PROPERTY_TES_SPACING            12
+#define TGSI_PROPERTY_TES_VERTEX_ORDER_CW    13
+#define TGSI_PROPERTY_TES_POINT_MODE         14
+#define TGSI_PROPERTY_COUNT                  15
 
 struct tgsi_property {
    unsigned Type         : 4;  /**< TGSI_TOKEN_TYPE_PROPERTY */
@@ -526,10 +538,6 @@ struct tgsi_property_data {
 #define TGSI_OPCODE_DSSG                222
 #define TGSI_OPCODE_LAST                223
 
-#define TGSI_SAT_NONE            0  /* do not saturate */
-#define TGSI_SAT_ZERO_ONE        1  /* clamp to [0,1] */
-#define TGSI_SAT_MINUS_PLUS_ONE  2  /* clamp to [-1,1] */
-
 /**
  * Opcode is the operation code to execute. A given operation defines the
  * semantics how the source registers (if any) are interpreted and what is
@@ -549,13 +557,13 @@ struct tgsi_instruction
    unsigned Type       : 4;  /* TGSI_TOKEN_TYPE_INSTRUCTION */
    unsigned NrTokens   : 8;  /* UINT */
    unsigned Opcode     : 8;  /* TGSI_OPCODE_ */
-   unsigned Saturate   : 2;  /* TGSI_SAT_ */
+   unsigned Saturate   : 1;  /* BOOL */
    unsigned NumDstRegs : 2;  /* UINT */
    unsigned NumSrcRegs : 4;  /* UINT */
    unsigned Predicate  : 1;  /* BOOL */
    unsigned Label      : 1;
    unsigned Texture    : 1;
-   unsigned Padding    : 1;
+   unsigned Padding    : 2;
 };
 
 /*
index e15860c4ca75947f7816d0b52203f14d9dc4261d..a18f12e8a87904d8cb242f6a19af5f6e8bfa2346 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
+ *
  * Copyright 2007 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
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  **************************************************************************/
 
 
 /**
  * @file
- * 
+ *
  * Abstract graphics pipe state objects.
  *
  * Basic notes:
@@ -58,8 +58,8 @@ extern "C" {
 #define PIPE_MAX_COLOR_BUFS        8
 #define PIPE_MAX_CONSTANT_BUFFERS 32
 #define PIPE_MAX_SAMPLERS         18 /* 16 public + 2 driver internal */
-#define PIPE_MAX_SHADER_INPUTS    32
-#define PIPE_MAX_SHADER_OUTPUTS   48 /* 32 GENERICs + POS, PSIZE, FOG, etc. */
+#define PIPE_MAX_SHADER_INPUTS    80 /* 32 GENERIC + 32 PATCH + 16 others */
+#define PIPE_MAX_SHADER_OUTPUTS   80 /* 32 GENERIC + 32 PATCH + 16 others */
 #define PIPE_MAX_SHADER_SAMPLER_VIEWS 32
 #define PIPE_MAX_SHADER_RESOURCES 32
 #define PIPE_MAX_TEXTURE_LEVELS   16
@@ -217,7 +217,7 @@ struct pipe_shader_state
 };
 
 
-struct pipe_depth_state 
+struct pipe_depth_state
 {
    unsigned enabled:1;         /**< depth test enabled? */
    unsigned writemask:1;       /**< allow depth buffer writes? */
@@ -268,6 +268,7 @@ struct pipe_rt_blend_state
    unsigned colormask:4;         /**< bitmask of PIPE_MASK_R/G/B/A */
 };
 
+
 struct pipe_blend_state
 {
    unsigned independent_blend_enable:1;
@@ -285,11 +286,13 @@ struct pipe_blend_color
    float color[4];
 };
 
+
 struct pipe_stencil_ref
 {
    ubyte ref_value[2];
 };
 
+
 struct pipe_framebuffer_state
 {
    unsigned width, height;
@@ -367,10 +370,10 @@ struct pipe_sampler_view
    struct pipe_context *context; /**< context this view belongs to */
    union {
       struct {
-         unsigned first_layer:16;     /**< first layer to use for array textures */
-         unsigned last_layer:16;      /**< last layer to use for array textures */
-         unsigned first_level:8;      /**< first mipmap level to use */
-         unsigned last_level:8;       /**< last mipmap level to use */
+         unsigned first_layer:16;  /**< first layer to use for array textures */
+         unsigned last_layer:16;   /**< last layer to use for array textures */
+         unsigned first_level:8;   /**< first mipmap level to use */
+         unsigned last_level:8;    /**< last mipmap level to use */
       } tex;
       struct {
          unsigned first_element;
@@ -455,7 +458,8 @@ struct pipe_vertex_buffer
  * A constant buffer.  A subrange of an existing buffer can be set
  * as a constant buffer.
  */
-struct pipe_constant_buffer {
+struct pipe_constant_buffer
+{
    struct pipe_resource *buffer; /**< the actual buffer */
    unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
    unsigned buffer_size;   /**< how much data can be read in shader */
@@ -474,8 +478,8 @@ struct pipe_constant_buffer {
  * and the CPU actually doesn't have to query it.
  *
  * Note that the buffer_size variable is actually specifying the available
- * space in the buffer, not the size of the attached buffer. 
- * In other words in majority of cases buffer_size would simply be 
+ * space in the buffer, not the size of the attached buffer.
+ * In other words in majority of cases buffer_size would simply be
  * 'buffer->width0 - buffer_offset', so buffer_size refers to the size
  * of the buffer left, after accounting for buffer offset, for stream output
  * to write to.
@@ -511,7 +515,7 @@ struct pipe_vertex_element
     * this attribute live in?
     */
    unsigned vertex_buffer_index;
+
    enum pipe_format src_format;
 };
 
@@ -543,6 +547,8 @@ struct pipe_draw_info
    unsigned start_instance; /**< first instance id */
    unsigned instance_count; /**< number of instances */
 
+   unsigned vertices_per_patch; /**< the number of vertices per patch */
+
    /**
     * For indexed drawing, these fields apply after index lookup.
     */
@@ -640,5 +646,5 @@ struct pipe_compute_state
 #ifdef __cplusplus
 }
 #endif
-   
+
 #endif
index 86fdc6988ab3c417f4883a250b6e0c0526442f83..ecf1c07fb98f30873f0c12f6a7b4a7df31653f8a 100644 (file)
@@ -89,6 +89,7 @@ enum st_api_feature
 #define ST_CONTEXT_FLAG_DEBUG               (1 << 0)
 #define ST_CONTEXT_FLAG_FORWARD_COMPATIBLE  (1 << 1)
 #define ST_CONTEXT_FLAG_ROBUST_ACCESS       (1 << 2)
+#define ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED (1 << 3)
 
 /**
  * Reasons that context creation might fail.
index ea0c7c73c30ea704659784edf07ded5891556a36..b96069f5167f0125c776d5d451f58cda87c94612 100644 (file)
@@ -31,7 +31,12 @@ extern "C" {
 PUBLIC bool
 opencl_dri_event_add_ref(cl_event event)
 {
-   return clRetainEvent(event) == CL_SUCCESS;
+   /* This should fail if the event hasn't been created by
+    * clEnqueueReleaseGLObjects or clEnqueueReleaseEGLObjects.
+    *
+    * TODO: implement the CL functions
+    */
+   return false; /*return clRetainEvent(event) == CL_SUCCESS;*/
 }
 
 PUBLIC bool
index eb65d629cdd9f23fb0ac20098195a023b8be68a1..780b973383accf448cab720bfe340e6dc46ed1d3 100644 (file)
@@ -26,6 +26,7 @@
 #include "CL/cl.h"
 
 #include <stdexcept>
+#include <string>
 
 namespace clover {
    class command_queue;
index 58de8884457719c8f6ec214f1cc2f5cc86008b0f..e1f9de07f83f371ee7ca5f6be2b8704830c6562d 100644 (file)
@@ -27,7 +27,7 @@ using namespace clover;
 
 event::event(clover::context &ctx, const ref_vector<event> &deps,
              action action_ok, action action_fail) :
-   context(ctx), _status(0), wait_count(1),
+   context(ctx), wait_count(1), _status(0),
    action_ok(action_ok), action_fail(action_fail) {
    for (auto &ev : deps)
       ev.chain(*this);
@@ -36,36 +36,69 @@ event::event(clover::context &ctx, const ref_vector<event> &deps,
 event::~event() {
 }
 
+std::vector<intrusive_ref<event>>
+event::trigger_self() {
+   std::lock_guard<std::mutex> lock(mutex);
+   std::vector<intrusive_ref<event>> evs;
+
+   if (!--wait_count)
+      std::swap(_chain, evs);
+
+   return evs;
+}
+
 void
 event::trigger() {
-   if (!--wait_count) {
-      action_ok(*this);
+   auto evs = trigger_self();
 
-      while (!_chain.empty()) {
-         _chain.back()().trigger();
-         _chain.pop_back();
-      }
+   if (signalled()) {
+      action_ok(*this);
+      cv.notify_all();
    }
+
+   for (event &ev : evs)
+      ev.trigger();
+}
+
+std::vector<intrusive_ref<event>>
+event::abort_self(cl_int status) {
+   std::lock_guard<std::mutex> lock(mutex);
+   std::vector<intrusive_ref<event>> evs;
+
+   _status = status;
+   std::swap(_chain, evs);
+
+   return evs;
 }
 
 void
 event::abort(cl_int status) {
-   _status = status;
+   auto evs = abort_self(status);
+
    action_fail(*this);
 
-   while (!_chain.empty()) {
-      _chain.back()().abort(status);
-      _chain.pop_back();
-   }
+   for (event &ev : evs)
+      ev.abort(status);
 }
 
 bool
 event::signalled() const {
+   std::lock_guard<std::mutex> lock(mutex);
    return !wait_count;
 }
 
+cl_int
+event::status() const {
+   std::lock_guard<std::mutex> lock(mutex);
+   return _status;
+}
+
 void
 event::chain(event &ev) {
+   std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
+   std::unique_lock<std::mutex> lock_ev(ev.mutex, std::defer_lock);
+   std::lock(lock, lock_ev);
+
    if (wait_count) {
       ev.wait_count++;
       _chain.push_back(ev);
@@ -73,6 +106,15 @@ event::chain(event &ev) {
    ev.deps.push_back(*this);
 }
 
+void
+event::wait() const {
+   for (event &ev : deps)
+      ev.wait();
+
+   std::unique_lock<std::mutex> lock(mutex);
+   cv.wait(lock, [=]{ return !wait_count; });
+}
+
 hard_event::hard_event(command_queue &q, cl_command_type command,
                        const ref_vector<event> &deps, action action) :
    event(q.context(), deps, profile(q, action), [](event &ev){}),
@@ -93,8 +135,8 @@ cl_int
 hard_event::status() const {
    pipe_screen *screen = queue()->device().pipe;
 
-   if (_status < 0)
-      return _status;
+   if (event::status() < 0)
+      return event::status();
 
    else if (!_fence)
       return CL_QUEUED;
@@ -120,6 +162,8 @@ void
 hard_event::wait() const {
    pipe_screen *screen = queue()->device().pipe;
 
+   event::wait();
+
    if (status() == CL_QUEUED)
       queue()->flush();
 
@@ -182,8 +226,8 @@ soft_event::soft_event(clover::context &ctx, const ref_vector<event> &deps,
 
 cl_int
 soft_event::status() const {
-   if (_status < 0)
-      return _status;
+   if (event::status() < 0)
+      return event::status();
 
    else if (!signalled() ||
             any_of([](const event &ev) {
@@ -207,8 +251,7 @@ soft_event::command() const {
 
 void
 soft_event::wait() const {
-   for (event &ev : deps)
-      ev.wait();
+   event::wait();
 
    if (status() != CL_COMPLETE)
       throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
index d407c80ce2578b81d9daa40ff4a35c64cf010907..6469e483c73db6f2e68eea9085ec64ceb8f99aa7 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef CLOVER_CORE_EVENT_HPP
 #define CLOVER_CORE_EVENT_HPP
 
+#include <condition_variable>
 #include <functional>
 
 #include "core/object.hpp"
@@ -65,10 +66,10 @@ namespace clover {
       void abort(cl_int status);
       bool signalled() const;
 
-      virtual cl_int status() const = 0;
+      virtual cl_int status() const;
       virtual command_queue *queue() const = 0;
       virtual cl_command_type command() const = 0;
-      virtual void wait() const = 0;
+      virtual void wait() const;
 
       virtual struct pipe_fence_handle *fence() const {
          return NULL;
@@ -79,14 +80,19 @@ namespace clover {
    protected:
       void chain(event &ev);
 
-      cl_int _status;
       std::vector<intrusive_ref<event>> deps;
 
    private:
+      std::vector<intrusive_ref<event>> trigger_self();
+      std::vector<intrusive_ref<event>> abort_self(cl_int status);
+
       unsigned wait_count;
+      cl_int _status;
       action action_ok;
       action action_fail;
       std::vector<intrusive_ref<event>> _chain;
+      mutable std::condition_variable cv;
+      mutable std::mutex mutex;
    };
 
    ///
index 905ebc0fd02996502bd6c9e001031c6d1c599929..055336a33255c236d4f7e7e8b4e22e9bb2372c9d 100644 (file)
@@ -30,7 +30,7 @@ memory_obj::memory_obj(clover::context &ctx, cl_mem_flags flags,
                        size_t size, void *host_ptr) :
    context(ctx), _flags(flags),
    _size(size), _host_ptr(host_ptr) {
-   if (flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR))
+   if (flags & CL_MEM_COPY_HOST_PTR)
       data.append((char *)host_ptr, size);
 }
 
index 24f9326662da17d390fe5cf28185b16d5ce3e01c..87f9dcc647624e26d29b7eb025f7f28a5a8094a3 100644 (file)
@@ -44,6 +44,7 @@ command_queue::flush() {
    pipe_screen *screen = device().pipe;
    pipe_fence_handle *fence = NULL;
 
+   std::lock_guard<std::mutex> lock(queued_events_mutex);
    if (!queued_events.empty()) {
       pipe->flush(pipe, &fence, 0);
 
@@ -69,6 +70,7 @@ command_queue::profiling_enabled() const {
 
 void
 command_queue::sequence(hard_event &ev) {
+   std::lock_guard<std::mutex> lock(queued_events_mutex);
    if (!queued_events.empty())
       queued_events.back()().chain(ev);
 
index b7166e685b75e50987546bfa868a9680f55616a4..bddb86c0e4c9c3acab1e2de94b3a5ccd5fbb89c0 100644 (file)
@@ -24,6 +24,7 @@
 #define CLOVER_CORE_QUEUE_HPP
 
 #include <deque>
+#include <mutex>
 
 #include "core/object.hpp"
 #include "core/context.hpp"
@@ -69,6 +70,7 @@ namespace clover {
 
       cl_command_queue_properties props;
       pipe_context *pipe;
+      std::mutex queued_events_mutex;
       std::deque<intrusive_ref<hard_event>> queued_events;
    };
 }
index bcf87e15480b8ca68012b03245601a21ecb4ee65..78ebafb644fa1ff72501dda4a9e2d7296d0d393f 100644 (file)
@@ -118,6 +118,8 @@ root_resource::root_resource(clover::device &dev, memory_obj &obj,
                              command_queue &q, const std::string &data) :
    resource(dev, obj) {
    pipe_resource info {};
+   const bool user_ptr_support = dev.pipe->get_param(dev.pipe,
+         PIPE_CAP_RESOURCE_FROM_USER_MEMORY);
 
    if (image *img = dynamic_cast<image *>(&obj)) {
       info.format = translate_format(img->format());
@@ -137,16 +139,29 @@ root_resource::root_resource(clover::device &dev, memory_obj &obj,
                 PIPE_BIND_TRANSFER_READ |
                 PIPE_BIND_TRANSFER_WRITE);
 
+   if (obj.flags() & CL_MEM_USE_HOST_PTR && user_ptr_support) {
+      // Page alignment is normally required for this, just try, hope for the
+      // best and fall back if it fails.
+      pipe = dev.pipe->resource_from_user_memory(dev.pipe, &info, obj.host_ptr());
+      if (pipe)
+         return;
+   }
+
+   if (obj.flags() & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_HOST_PTR)) {
+      info.usage = PIPE_USAGE_STAGING;
+   }
+
    pipe = dev.pipe->resource_create(dev.pipe, &info);
    if (!pipe)
       throw error(CL_OUT_OF_RESOURCES);
 
-   if (!data.empty()) {
+   if (obj.flags() & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)) {
+      const void *data_ptr = !data.empty() ? data.data() : obj.host_ptr();
       box rect { {{ 0, 0, 0 }}, {{ info.width0, info.height0, info.depth0 }} };
       unsigned cpp = util_format_get_blocksize(info.format);
 
       q.pipe->transfer_inline_write(q.pipe, pipe, 0, PIPE_TRANSFER_WRITE,
-                                    rect, data.data(), cpp * info.width0,
+                                    rect, data_ptr, cpp * info.width0,
                                     cpp * info.width0 * info.height0);
    }
 }
index 7d2d941407e4af1fdbba79c44834a6f37334d60e..9b91fee9032a70094fcb172476e6cdd52b5d3b24 100644 (file)
@@ -709,7 +709,7 @@ clover::compile_program_llvm(const std::string &source,
    llvm_ctx.setDiagnosticHandler(diagnostic_handler, &r_log);
 
    if (get_debug_flags() & DBG_CLC)
-      debug_log(source, ".cl");
+      debug_log("// Build options: " + opts + '\n' + source, ".cl");
 
    // The input file name must have the .cl extension in order for the
    // CompilerInvocation class to recognize it as an OpenCL source file.
diff --git a/src/gallium/state_trackers/dri/Android.mk b/src/gallium/state_trackers/dri/Android.mk
new file mode 100644 (file)
index 0000000..188e4a1
--- /dev/null
@@ -0,0 +1,64 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2015 Chih-Wei Huang <cwhuang@linux.org.tw>
+# Copyright (C) 2015 Android-x86 Open Source Project
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(common_SOURCES)
+
+LOCAL_CFLAGS := \
+       -DGALLIUM_STATIC_TARGETS=1 \
+
+LOCAL_C_INCLUDES := \
+       $(MESA_TOP)/src/mapi \
+       $(MESA_TOP)/src/mesa \
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+       $(LOCAL_PATH) \
+       $(LOCAL_C_INCLUDES) \
+
+LOCAL_STATIC_LIBRARIES := \
+       libmesa_dri_common \
+
+ifneq ($(filter swrast,$(MESA_GPU_DRIVERS)),)
+LOCAL_CFLAGS += -DGALLIUM_SOFTPIPE
+LOCAL_SRC_FILES += $(drisw_SOURCES)
+endif
+
+# swrast only?
+ifeq ($(MESA_GPU_DRIVERS),swrast)
+LOCAL_CFLAGS += -D__NOT_HAVE_DRM_H
+else
+LOCAL_SRC_FILES += $(dri2_SOURCES)
+LOCAL_SHARED_LIBRARIES := libdrm
+endif
+
+LOCAL_MODULE := libmesa_st_dri
+
+LOCAL_GENERATED_SOURCES := $(MESA_DRI_OPTIONS_H)
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
index 8b6fe67dc914c6a3d59fa56174e7fdbab5c32068..8d93f786433f0262a390428b91956200c01741f7 100644 (file)
@@ -1399,6 +1399,10 @@ static __DRI2fenceExtension dri2FenceExtension = {
    .server_wait_sync = dri2_server_wait_sync
 };
 
+static const __DRIrobustnessExtension dri2Robustness = {
+   .base = { __DRI2_ROBUSTNESS, 1 }
+};
+
 /*
  * Backend function init_screen.
  */
@@ -1414,6 +1418,18 @@ static const __DRIextension *dri_screen_extensions[] = {
    NULL
 };
 
+static const __DRIextension *dri_robust_screen_extensions[] = {
+   &driTexBufferExtension.base,
+   &dri2FlushExtension.base,
+   &dri2ImageExtension.base,
+   &dri2RendererQueryExtension.base,
+   &dri2ConfigQueryExtension.base,
+   &dri2ThrottleExtension.base,
+   &dri2FenceExtension.base,
+   &dri2Robustness.base,
+   NULL
+};
+
 /**
  * This is the driver specific part of the createNewScreen entry point.
  *
@@ -1467,7 +1483,12 @@ dri2_init_screen(__DRIscreen * sPriv)
       }
    }
 
-   sPriv->extensions = dri_screen_extensions;
+   if (pscreen && pscreen->get_param(pscreen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY)) {
+      sPriv->extensions = dri_robust_screen_extensions;
+      screen->has_reset_status_query = true;
+   }
+   else
+      sPriv->extensions = dri_screen_extensions;
 
    /* dri_init_screen_helper checks pscreen for us */
 
index 8ac81b7364bce286e4b0bbef40f116b799c582c5..3d8af65ca6160b7bcfbd72d8405033bd21b86c77 100644 (file)
@@ -56,6 +56,21 @@ dri_create_context(gl_api api, const struct gl_config * visual,
    struct st_context_iface *st_share = NULL;
    struct st_context_attribs attribs;
    enum st_context_error ctx_err = 0;
+   unsigned allowed_flags = __DRI_CTX_FLAG_DEBUG |
+                            __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+
+   if (screen->has_reset_status_query)
+      allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
+
+   if (flags & ~allowed_flags) {
+      *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
+      goto fail;
+   }
+
+   if (!screen->has_reset_status_query && notify_reset) {
+      *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+      goto fail;
+   }
 
    memset(&attribs, 0, sizeof(attribs));
    switch (api) {
@@ -83,15 +98,11 @@ dri_create_context(gl_api api, const struct gl_config * visual,
    if ((flags & __DRI_CTX_FLAG_DEBUG) != 0)
       attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
 
-   if (flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) {
-      *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
-      goto fail;
-   }
+   if (flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
+      attribs.flags |= ST_CONTEXT_FLAG_ROBUST_ACCESS;
 
-   if (notify_reset) {
-      *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
-      goto fail;
-   }
+   if (notify_reset)
+      attribs.flags |= ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED;
 
    if (sharedContextPrivate) {
       st_share = ((struct dri_context *)sharedContextPrivate)->st;
@@ -233,11 +244,10 @@ dri_make_current(__DRIcontext * cPriv,
 
    ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);
 
-   // This is ok to call here. If they are already init, it's a no-op.
-   if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]
-      && ctx->pp)
-         pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
-            draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
+   /* This is ok to call here. If they are already init, it's a no-op. */
+   if (ctx->pp && draw->textures[ST_ATTACHMENT_BACK_LEFT])
+      pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
+                   draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
 
    return GL_TRUE;
 }
index bdab74f2802cd91897dd9c0b818f76496a280e92..173f4038cdb9f49547b8e72454008c9e97390fb6 100644 (file)
@@ -82,6 +82,7 @@ struct dri_screen
    boolean d_depth_bits_last;
    boolean sd_depth_bits_last;
    boolean auto_fake_front;
+   boolean has_reset_status_query;
    enum pipe_texture_target target;
 
    /* hooks filled in by dri2 & drisw */
index 5f69a2d670e744c9ab6c3ceab7896b3d8c041a18..4a2c1bbc2ee33f71d4f551b472e7f76e76aa548f 100644 (file)
@@ -333,6 +333,7 @@ drisw_update_tex_buffer(struct dri_drawable *drawable,
 static const __DRIextension *drisw_screen_extensions[] = {
    &driTexBufferExtension.base,
    &dri2RendererQueryExtension.base,
+   &dri2ConfigQueryExtension.base,
    NULL
 };
 
index 0508255c4be15bcf9e9c4cf09f4270adf88f7076..0456d44104e3ebb3af5409f53f661081bb324325 100644 (file)
 
 #include "xm_api.h"
 
+/* An "Atrribs/Attribs" typo was fixed in glxproto.h in Nov 2014.
+ * This is in case we don't have the updated header.
+ */
+#if !defined(X_GLXCreateContextAttribsARB) && \
+     defined(X_GLXCreateContextAtrribsARB)
+#define X_GLXCreateContextAttribsARB X_GLXCreateContextAtrribsARB
+#endif 
 
 /* This indicates the client-side GLX API and GLX encoder version. */
 #define CLIENT_MAJOR_VERSION 1
@@ -2168,7 +2175,7 @@ glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
 #endif
 
       default:
-         generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, true);
+         generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, true);
          return;
    }
 }
@@ -2762,14 +2769,14 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
          break;
       default:
          /* bad attribute */
-         generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, True);
+         generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, True);
          return NULL;
       }
    }
 
    /* check contextFlags */
    if (contextFlags & ~contextFlagsAll) {
-      generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, True);
+      generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, True);
       return NULL;
    }
 
@@ -2777,14 +2784,14 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
    if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
        profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
        profileMask != GLX_CONTEXT_ES_PROFILE_BIT_EXT) {
-      generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAtrribsARB, False);
+      generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAttribsARB, False);
       return NULL;
    }
 
    /* check renderType */
    if (renderType != GLX_RGBA_TYPE &&
        renderType != GLX_COLOR_INDEX_TYPE) {
-      generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, True);
+      generate_error(dpy, BadValue, 0, X_GLXCreateContextAttribsARB, True);
       return NULL;
    }
 
@@ -2797,7 +2804,7 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
          (majorVersion == 3 && minorVersion > 3) ||
          (majorVersion == 4 && minorVersion > 5) ||
          majorVersion > 4))) {
-      generate_error(dpy, BadMatch, 0, X_GLXCreateContextAtrribsARB, True);
+      generate_error(dpy, BadMatch, 0, X_GLXCreateContextAttribsARB, True);
       return NULL;
    }
    if (profileMask == GLX_CONTEXT_ES_PROFILE_BIT_EXT &&
@@ -2809,18 +2816,18 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
        * different error code for invalid ES versions, but this is what NVIDIA
        * does and piglit expects.
        */
-      generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAtrribsARB, False);
+      generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAttribsARB, False);
       return NULL;
    }
 
    if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
        majorVersion < 3) {
-      generate_error(dpy, BadMatch, 0, X_GLXCreateContextAtrribsARB, True);
+      generate_error(dpy, BadMatch, 0, X_GLXCreateContextAttribsARB, True);
       return NULL;
    }
 
    if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3) {
-      generate_error(dpy, BadMatch, 0, X_GLXCreateContextAtrribsARB, True);
+      generate_error(dpy, BadMatch, 0, X_GLXCreateContextAttribsARB, True);
       return NULL;
    }
 
@@ -2830,7 +2837,7 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
                         majorVersion, minorVersion,
                         profileMask, contextFlags);
    if (!ctx) {
-      generate_error(dpy, GLXBadFBConfig, 0, X_GLXCreateContextAtrribsARB, False);
+      generate_error(dpy, GLXBadFBConfig, 0, X_GLXCreateContextAttribsARB, False);
    }
 
    return ctx;
index b75dc26bc39ed939e1d87331c5b5ef5e4da39767..1e804c07e6b413013978fefe4afc79c855e2c6fd 100644 (file)
@@ -7,16 +7,18 @@
  *      Alexander von Gluck IV, kallisti5@unixzen.com
  */
 
+#include "hgl_context.h"
 
-#include "GLView.h"
+#include <stdio.h>
 
 #include "pipe/p_format.h"
 #include "util/u_atomic.h"
 #include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
+#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
 
-#include "hgl_context.h"
+#include "GLView.h"
 
 
 #ifdef DEBUG
@@ -91,7 +93,7 @@ hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
                for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
                        pipe_resource_reference(&buffer->textures[i], NULL);
        }
-       
+
        memset(&templat, 0, sizeof(templat));
        templat.target = buffer->target;
        templat.width0 = width;
@@ -256,6 +258,14 @@ hgl_create_st_framebuffer(struct hgl_context* context)
 }
 
 
+struct st_api*
+hgl_create_st_api()
+{
+       CALLED();
+       return st_gl_api_create();
+}
+
+
 struct st_manager *
 hgl_create_st_manager(struct hgl_context* context)
 {
index 4840d9e2ee459639bf5fba4f50544d4c1b9c3552..d2ec7fb49c4397cb2eba8b90dc7665d5950cc25a 100644 (file)
@@ -9,9 +9,6 @@
 #define HGL_CONTEXT_H
 
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 #include "state_tracker/st_api.h"
 #include "state_tracker/st_manager.h"
 #include "pipe/p_compiler.h"
@@ -20,8 +17,10 @@ extern "C" {
 #include "os/os_thread.h"
 
 #include "bitmap_wrapper.h"
+
+
 #ifdef __cplusplus
-}
+extern "C" {
 #endif
 
 
@@ -82,6 +81,9 @@ struct hgl_context
 };
 
 
+// hgl state_tracker api
+struct st_api* hgl_create_st_api(void);
+
 // hgl state_tracker framebuffer
 struct hgl_buffer* hgl_create_st_framebuffer(struct hgl_context* context);
 
@@ -94,4 +96,8 @@ struct st_visual* hgl_create_st_visual(ulong options);
 void hgl_destroy_st_visual(struct st_visual* visual);
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* HGL_CONTEXT_H */
index e6f2b21dd4d2494439701dea069f561abf5c8b08..c2213e6bf111d1e0461e44d6ceed4bb7f71ec171 100644 (file)
@@ -422,13 +422,15 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs)
     oCol[1] = ureg_saturate(ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 1));
 
     if (key->vertexpointsize || key->pointscale) {
-        oPsz = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_PSIZE, 0, TGSI_WRITEMASK_X);
+        oPsz = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_PSIZE, 0,
+                                       TGSI_WRITEMASK_X, 0, 1);
         oPsz = ureg_writemask(oPsz, TGSI_WRITEMASK_X);
     }
     if (key->fog_mode) {
         /* We apply fog to the vertex colors, oFog is for programmable shaders only ?
          */
-        oFog = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_FOG, 0, TGSI_WRITEMASK_X);
+        oFog = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_FOG, 0,
+                                       TGSI_WRITEMASK_X, 0, 1);
         oFog = ureg_writemask(oFog, TGSI_WRITEMASK_X);
     }
 
index fd0f76e1118d622e609f2aebbff5c31ea3b5fc97..22a58825f78d649820dc42e1cd820f34a1dfc20a 100644 (file)
@@ -1098,7 +1098,7 @@ _tx_dst_param(struct shader_translator *tx, const struct sm1_dst_param *param)
         if (ureg_dst_is_undef(tx->regs.oDepth))
            tx->regs.oDepth =
               ureg_DECL_output_masked(tx->ureg, TGSI_SEMANTIC_POSITION, 0,
-                                      TGSI_WRITEMASK_Z);
+                                      TGSI_WRITEMASK_Z, 0, 1);
         dst = tx->regs.oDepth; /* XXX: must write .z component */
         break;
     case D3DSPR_PREDICATE:
@@ -1966,7 +1966,7 @@ DECL_SPECIAL(DCL)
                 tx->info->position_t = TRUE;
             assert(sem.reg.idx < Elements(tx->regs.o));
             tx->regs.o[sem.reg.idx] = ureg_DECL_output_masked(
-                ureg, tgsi.Name, tgsi.Index, sem.reg.mask);
+                ureg, tgsi.Name, tgsi.Index, sem.reg.mask, 0, 1);
 
             if (tgsi.Name == TGSI_SEMANTIC_PSIZE)
                 tx->regs.oPts = tx->regs.o[sem.reg.idx];
@@ -1979,12 +1979,13 @@ DECL_SPECIAL(DCL)
                 ureg, tgsi.Name, tgsi.Index,
                 nine_tgsi_to_interp_mode(&tgsi),
                 0, /* cylwrap */
-                sem.reg.mod & NINED3DSPDM_CENTROID);
+                sem.reg.mod & NINED3DSPDM_CENTROID, 0, 1);
         } else
         if (!is_input && 0) { /* declare in COLOROUT/DEPTHOUT case */
             /* FragColor or FragDepth */
             assert(sem.reg.mask != 0);
-            ureg_DECL_output_masked(ureg, tgsi.Name, tgsi.Index, sem.reg.mask);
+            ureg_DECL_output_masked(ureg, tgsi.Name, tgsi.Index, sem.reg.mask,
+                                    0, 1);
         }
     }
     return D3D_OK;
@@ -2312,7 +2313,8 @@ DECL_SPECIAL(TEXM3x2DEPTH)
     ureg_CMP(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_negate(ureg_abs(ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y))),
              ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(ureg, 1.0f));
     /* replace the depth for depth testing with the result */
-    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0, TGSI_WRITEMASK_Z);
+    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                              TGSI_WRITEMASK_Z, 0, 1);
     ureg_MOV(ureg, tx->regs.oDepth, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
     /* note that we write nothing to the destination, since it's disallowed to use it afterward */
     return D3D_OK;
@@ -2410,7 +2412,8 @@ DECL_SPECIAL(TEXDEPTH)
     ureg_CMP(ureg, ureg_writemask(r5, TGSI_WRITEMASK_X), ureg_negate(ureg_abs(r5g)),
              r5r, ureg_imm1f(ureg, 1.0f));
     /* replace the depth for depth testing with the result */
-    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0, TGSI_WRITEMASK_Z);
+    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                              TGSI_WRITEMASK_Z, 0, 1);
     ureg_MOV(ureg, tx->regs.oDepth, r5r);
 
     return D3D_OK;
index d204efd429a8cf0607b34444b8d48b6e95c42d9d..8c463d5f18eeb724dd4f62ecf43d032ee5d14dd3 100644 (file)
@@ -8,6 +8,7 @@ C_SOURCES := \
        stw_ext_swapinterval.c \
        stw_framebuffer.c \
        stw_getprocaddress.c \
+       stw_nopfuncs.c \
        stw_pixelformat.c \
        stw_st.c \
        stw_tls.c \
index 2ed6c2bfac98a631392a7c733d1f035508b368f1..3e99cc44db752e4a1c2c6e05e9ad8efb910536fa 100644 (file)
@@ -226,14 +226,13 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
        *         be implemented, as determined by the implementation.
        *       * The core profile of version 3.2 or greater."
        *
-       * and because Mesa doesn't support GL_ARB_compatibility, the only chance to
-       * honour a 3.1 context is through core profile.
+       * But Mesa doesn't support GL_ARB_compatibility, while most prevalent
+       * Windows OpenGL implementations do, and unfortunately many Windows
+       * applications don't check whether they receive or not a context with
+       * GL_ARB_compatibility, so returning a core profile here does more harm
+       * than good.
        */
-      if (majorVersion == 3 && minorVersion == 1) {
-         attribs.profile = ST_PROFILE_OPENGL_CORE;
-      } else {
-         attribs.profile = ST_PROFILE_DEFAULT;
-      }
+      attribs.profile = ST_PROFILE_DEFAULT;
       break;
    case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
       if (majorVersion >= 2) {
index 91682d115a4f00131ac9ece8bb2d06e4f8a85138..e38086e86d78b9f3558bfd749a35bb683a0af272 100644 (file)
@@ -88,7 +88,12 @@ stw_query_attrib(
       return TRUE;
 
    case WGL_SWAP_METHOD_ARB:
-      *pvalue = pfi->pfd.dwFlags & PFD_SWAP_COPY ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB;
+      if (pfi->pfd.dwFlags & PFD_SWAP_COPY)
+         *pvalue = WGL_SWAP_COPY_ARB;
+      else if (pfi->pfd.dwFlags & PFD_SWAP_EXCHANGE)
+         *pvalue = WGL_SWAP_EXCHANGE_EXT;
+      else
+         *pvalue = WGL_SWAP_UNDEFINED_ARB;
       return TRUE;
 
    case WGL_SWAP_LAYER_BUFFERS_ARB:
@@ -232,7 +237,7 @@ stw_query_attrib(
       break;
 
    case WGL_SAMPLE_BUFFERS_ARB:
-      *pvalue = 1;
+      *pvalue = (pfi->stvis.samples > 1);
       break;
 
    case WGL_SAMPLES_ARB:
index 2ffeec1a2fb7316c519601119a2b8a96cc140101..33949b6606f817b29511f090b6b10b339114d04c 100644 (file)
@@ -35,6 +35,7 @@
 #include "glapi/glapi.h"
 #include "stw_device.h"
 #include "stw_icd.h"
+#include "stw_nopfuncs.h"
 
 struct stw_extension_entry
 {
@@ -79,6 +80,7 @@ DrvGetProcAddress(
    LPCSTR lpszProc )
 {
    const struct stw_extension_entry *entry;
+   PROC p;
 
    if (!stw_dev)
       return NULL;
@@ -88,8 +90,23 @@ DrvGetProcAddress(
          if (strcmp( lpszProc, entry->name ) == 0)
             return entry->proc;
 
-   if (lpszProc[0] == 'g' && lpszProc[1] == 'l')
-      return (PROC) _glapi_get_proc_address( lpszProc );
-
+   if (lpszProc[0] == 'g' && lpszProc[1] == 'l') {
+      p = (PROC) _glapi_get_proc_address(lpszProc);
+      if (p)
+         return p;
+   }
+
+   /* If we get here, we'd normally just return NULL, but since some apps
+    * (like Viewperf12) crash when they try to use the null pointer, try
+    * returning a pointer to a no-op function instead.
+    */
+   p = stw_get_nop_function(lpszProc);
+   if (p) {
+      debug_printf("wglGetProcAddress(\"%s\") returning no-op function\n",
+                   lpszProc);
+      return p;
+   }
+
+   debug_printf("wglGetProcAddress(\"%s\") returning NULL\n", lpszProc);
    return NULL;
 }
diff --git a/src/gallium/state_trackers/wgl/stw_nopfuncs.c b/src/gallium/state_trackers/wgl/stw_nopfuncs.c
new file mode 100644 (file)
index 0000000..d69c013
--- /dev/null
@@ -0,0 +1,464 @@
+/**************************************************************************
+ *
+ * Copyright 2015 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * No-op GL API functions.
+ *
+ * Some OpenGL apps (like Viewperf12) call wglGetProcAddress() to get
+ * a pointer to an extension function, get a NULL pointer, but don't bother
+ * to check for NULL before jumping through the pointer.  This causes a
+ * crash.
+ *
+ * As a work-around we provide some no-op functions here to avoid those
+ * crashes.
+ */
+
+#include <GL/gl.h>
+#include "stw_nopfuncs.h"
+#include "util/u_debug.h"
+
+
+static void
+warning(const char *name)
+{
+   /* use name+4 to skip "nop_" prefix */
+   _debug_printf("Application calling unsupported %s function\n", name+4);
+}
+
+static void APIENTRY
+nop_glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glColor3hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glColor3hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glColor4hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glColor4hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glDisableClientStateIndexedEXT(GLenum array, GLuint index)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glEnableClientStateIndexedEXT(GLenum array, GLuint index)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glFogCoordhNV(GLhalfNV fog)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glFogCoordhvNV(const GLhalfNV *fog)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data)
+{
+   warning(__func__);
+}
+
+static void *APIENTRY
+nop_glMapNamedBufferEXT(GLuint buffer, GLenum access)
+{
+   warning(__func__);
+   return NULL;
+}
+
+static void APIENTRY
+nop_glMatrixLoadfEXT(GLenum mode, const GLfloat *m)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMatrixLoadIdentityEXT(GLenum mode)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord1hNV(GLenum target, GLhalfNV s)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord1hvNV(GLenum target, const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord2hNV(GLenum target, GLhalfNV s, GLhalfNV t)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord2hvNV(GLenum target, const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord3hNV(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord3hvNV(GLenum target, const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord4hNV(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoord4hvNV(GLenum target, const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexGenfvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glMultiTexGeniEXT(GLenum texunit, GLenum coord, GLenum pname, GLint param)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glNamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index, const GLfloat *params)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glNamedProgramLocalParameters4fvEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glNormal3hNV(GLhalfNV nx, GLhalfNV ny, GLhalfNV nz)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glNormal3hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glPatchParameterfv(GLenum pname, const GLfloat *values)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glPatchParameteri(GLenum pname, GLint value)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glSecondaryColor3hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glSecondaryColor3hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord1hNV(GLhalfNV s)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord1hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord2hNV(GLhalfNV s, GLhalfNV t)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord2hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord3hNV(GLhalfNV s, GLhalfNV t, GLhalfNV r)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord3hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord4hNV(GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTexCoord4hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)
+{
+   warning(__func__);
+}
+
+static GLboolean APIENTRY
+nop_glUnmapNamedBufferEXT(GLuint buffer)
+{
+   warning(__func__);
+   return GL_FALSE;
+}
+
+static void APIENTRY
+nop_glVertex2hNV(GLhalfNV x, GLhalfNV y)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glVertex2hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glVertex3hNV(GLhalfNV x, GLhalfNV y, GLhalfNV z)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glVertex3hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glVertex4hNV(GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w)
+{
+   warning(__func__);
+}
+
+static void APIENTRY
+nop_glVertex4hvNV(const GLhalfNV *v)
+{
+   warning(__func__);
+}
+
+
+PROC
+stw_get_nop_function(const char *name)
+{
+   struct {
+      const char *name;
+      PROC p;
+   } table[] = {
+      { "glBindMultiTextureEXT", (PROC) nop_glBindMultiTextureEXT },
+      { "glColor3hNV", (PROC) nop_glColor3hNV },
+      { "glColor3hvNV", (PROC) nop_glColor3hvNV },
+      { "glColor4hNV", (PROC) nop_glColor4hNV },
+      { "glColor4hvNV", (PROC) nop_glColor4hvNV },
+      { "glDisableClientStateIndexedEXT", (PROC) nop_glDisableClientStateIndexedEXT },
+      { "glEnableClientStateIndexedEXT", (PROC) nop_glEnableClientStateIndexedEXT },
+      { "glFogCoordhNV", (PROC) nop_glFogCoordhNV },
+      { "glFogCoordhvNV", (PROC) nop_glFogCoordhvNV },
+      { "glGetNamedBufferParameterivEXT", (PROC) nop_glGetNamedBufferParameterivEXT },
+      { "glGetNamedBufferSubDataEXT", (PROC) nop_glGetNamedBufferSubDataEXT },
+      { "glMapNamedBufferEXT", (PROC) nop_glMapNamedBufferEXT },
+      { "glMatrixLoadfEXT", (PROC) nop_glMatrixLoadfEXT },
+      { "glMatrixLoadIdentityEXT", (PROC) nop_glMatrixLoadIdentityEXT },
+      { "glMultiTexCoord1hNV", (PROC) nop_glMultiTexCoord1hNV },
+      { "glMultiTexCoord1hvNV", (PROC) nop_glMultiTexCoord1hvNV },
+      { "glMultiTexCoord2hNV", (PROC) nop_glMultiTexCoord2hNV },
+      { "glMultiTexCoord2hvNV", (PROC) nop_glMultiTexCoord2hvNV },
+      { "glMultiTexCoord3hNV", (PROC) nop_glMultiTexCoord3hNV },
+      { "glMultiTexCoord3hvNV", (PROC) nop_glMultiTexCoord3hvNV },
+      { "glMultiTexCoord4hNV", (PROC) nop_glMultiTexCoord4hNV },
+      { "glMultiTexCoord4hvNV", (PROC) nop_glMultiTexCoord4hvNV },
+      { "glMultiTexCoordPointerEXT", (PROC) nop_glMultiTexCoordPointerEXT },
+      { "glMultiTexEnvfEXT", (PROC) nop_glMultiTexEnvfEXT },
+      { "glMultiTexEnvfvEXT", (PROC) nop_glMultiTexEnvfvEXT },
+      { "glMultiTexEnviEXT", (PROC) nop_glMultiTexEnviEXT },
+      { "glMultiTexGenfvEXT", (PROC) nop_glMultiTexGenfvEXT },
+      { "glMultiTexGeniEXT", (PROC) nop_glMultiTexGeniEXT },
+      { "glNamedBufferDataEXT", (PROC) nop_glNamedBufferDataEXT },
+      { "glNamedBufferSubDataEXT", (PROC) nop_glNamedBufferSubDataEXT },
+      { "glNamedProgramLocalParameter4fvEXT", (PROC) nop_glNamedProgramLocalParameter4fvEXT },
+      { "glNamedProgramLocalParameters4fvEXT", (PROC) nop_glNamedProgramLocalParameters4fvEXT },
+      { "glNormal3hNV", (PROC) nop_glNormal3hNV },
+      { "glNormal3hvNV", (PROC) nop_glNormal3hvNV },
+      { "glPatchParameterfv", (PROC) nop_glPatchParameterfv },
+      { "glPatchParameteri", (PROC) nop_glPatchParameteri },
+      { "glSecondaryColor3hNV", (PROC) nop_glSecondaryColor3hNV },
+      { "glSecondaryColor3hvNV", (PROC) nop_glSecondaryColor3hvNV },
+      { "glTexCoord1hNV", (PROC) nop_glTexCoord1hNV },
+      { "glTexCoord1hvNV", (PROC) nop_glTexCoord1hvNV },
+      { "glTexCoord2hNV", (PROC) nop_glTexCoord2hNV },
+      { "glTexCoord2hvNV", (PROC) nop_glTexCoord2hvNV },
+      { "glTexCoord3hNV", (PROC) nop_glTexCoord3hNV },
+      { "glTexCoord3hvNV", (PROC) nop_glTexCoord3hvNV },
+      { "glTexCoord4hNV", (PROC) nop_glTexCoord4hNV },
+      { "glTexCoord4hvNV", (PROC) nop_glTexCoord4hvNV },
+      { "glTextureParameterfEXT", (PROC) nop_glTextureParameterfEXT },
+      { "glTextureParameterfvEXT", (PROC) nop_glTextureParameterfvEXT },
+      { "glTextureParameteriEXT", (PROC) nop_glTextureParameteriEXT },
+      { "glUnmapNamedBufferEXT", (PROC) nop_glUnmapNamedBufferEXT },
+      { "glVertex2hNV", (PROC) nop_glVertex2hNV },
+      { "glVertex2hvNV", (PROC) nop_glVertex2hvNV },
+      { "glVertex3hNV", (PROC) nop_glVertex3hNV },
+      { "glVertex3hvNV", (PROC) nop_glVertex3hvNV },
+      { "glVertex4hNV", (PROC) nop_glVertex4hNV },
+      { "glVertex4hvNV", (PROC) nop_glVertex4hvNV },
+      { NULL, NULL }
+   };
+
+   int i;
+
+   for (i = 0; table[i].name; i++) {
+      if (strcmp(table[i].name, name) == 0)
+         return table[i].p;
+   }
+   return NULL;
+}
diff --git a/src/gallium/state_trackers/wgl/stw_nopfuncs.h b/src/gallium/state_trackers/wgl/stw_nopfuncs.h
new file mode 100644 (file)
index 0000000..f00d420
--- /dev/null
@@ -0,0 +1,11 @@
+
+
+#ifndef STW_NOPFUNCS_H
+#define STW_NOPFUNCS_H
+
+
+PROC
+stw_get_nop_function(const char *name);
+
+
+#endif /* STW_NOPFUNCS_H */
index b0cd5abd27afa713e371d7ebdec04fe177899b9f..db6cf8ee30f05f40176f176ba549fb4f5975c895 100644 (file)
@@ -113,7 +113,9 @@ stw_pf_doublebuffer[] = {
 const unsigned 
 stw_pf_multisample[] = {
    0,
-   4
+   4,
+   8,
+   16
 };
 
 
@@ -222,23 +224,32 @@ add_color_format_variants(const struct stw_pf_color_info *color,
    unsigned ms, db, ds, acc;
    unsigned bind_flags = PIPE_BIND_RENDER_TARGET;
    unsigned num_added = 0;
+   int force_samples = 0;
 
-   if (!extended) {
-      bind_flags |= PIPE_BIND_DISPLAY_TARGET;
+   /* Since GLUT for Windows doesn't support MSAA we have an env var
+    * to force all pixel formats to have a particular number of samples.
+    */
+   {
+      const char *samples= getenv("SVGA_FORCE_MSAA");
+      if (samples)
+         force_samples = atoi(samples);
    }
 
-   if (!screen->is_format_supported(screen, color->format,
-                                    PIPE_TEXTURE_2D, 0, bind_flags)) {
-      return 0;
+   if (!extended) {
+      bind_flags |= PIPE_BIND_DISPLAY_TARGET;
    }
 
    for (ms = 0; ms < Elements(stw_pf_multisample); ms++) {
       unsigned samples = stw_pf_multisample[ms];
 
-      /* FIXME: re-enabled MSAA when we can query it */
-      if (samples)
+      if (force_samples && samples != force_samples)
          continue;
 
+      if (!screen->is_format_supported(screen, color->format,
+                                       PIPE_TEXTURE_2D, samples, bind_flags)) {
+         continue;
+      }
+
       for (db = 0; db < Elements(stw_pf_doublebuffer); db++) {
          unsigned doublebuffer = stw_pf_doublebuffer[db];
 
@@ -246,7 +257,7 @@ add_color_format_variants(const struct stw_pf_color_info *color,
             const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[ds];
 
             if (!screen->is_format_supported(screen, depth->format,
-                                             PIPE_TEXTURE_2D, 0,
+                                             PIPE_TEXTURE_2D, samples,
                                              PIPE_BIND_DEPTH_STENCIL)) {
                continue;
             }
index e95c37fcecd15e1f5c2f2f83053cc163861782ec..0a9116cbb7382c51c32b6a82cf9168436050ac73 100644 (file)
@@ -77,6 +77,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
    templ.depth0 = 1;
    templ.array_size = 1;
    templ.last_level = 0;
+   templ.nr_samples = stwfb->stvis.samples;
 
    for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
       enum pipe_format format;
@@ -95,6 +96,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
       case ST_ATTACHMENT_BACK_LEFT:
          format = stwfb->stvis.color_format;
          bind = PIPE_BIND_DISPLAY_TARGET |
+                PIPE_BIND_SAMPLER_VIEW |
                 PIPE_BIND_RENDER_TARGET;
          break;
       case ST_ATTACHMENT_DEPTH_STENCIL:
index 89019988d57af8cf8914c122dba3b17a284f7fa2..f69ac8edf2774a1dfd2d824d4a2ea6fc0c55ef4f 100644 (file)
@@ -535,15 +535,3 @@ xa_surface_format(const struct xa_surface *srf)
 {
     return srf->fdesc.xa_format;
 }
-
-/*
- * _mesa_error_no_memory() is expected by NIR to be provided by the
- * user.  Normally this is in mesa st, but other state trackers
- * must provide their own.
- */
-void _mesa_error_no_memory(const char *caller);
-void
-_mesa_error_no_memory(const char *caller)
-{
-       debug_printf("Mesa error: out of memory in %s", caller);
-}
index 1dc55f5c1cd5a0b0c17f49df2a2374fbc2d76205..591978f1f61d4d8cc2f49c6e5abeed98b4c0819d 100644 (file)
@@ -74,6 +74,8 @@ endif # HAVE_LD_VERSION_SCRIPT
 d3dadapter9_la_LIBADD = \
        $(top_builddir)/src/gallium/auxiliary/libgalliumvl_stub.la \
        $(top_builddir)/src/gallium/auxiliary/libgallium.la \
+       $(top_builddir)/src/glsl/libnir.la \
+       $(top_builddir)/src/libglsl_util.la \
        $(top_builddir)/src/gallium/state_trackers/nine/libninetracker.la \
        $(top_builddir)/src/util/libmesautil.la \
        $(top_builddir)/src/gallium/winsys/sw/wrapper/libwsw.la \
diff --git a/src/gallium/targets/dri/Android.mk b/src/gallium/targets/dri/Android.mk
new file mode 100644 (file)
index 0000000..5ba129b
--- /dev/null
@@ -0,0 +1,127 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2015 Chih-Wei Huang <cwhuang@linux.org.tw>
+# Copyright (C) 2015 Android-x86 Open Source Project
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gallium_dri
+
+ifeq ($(MESA_LOLLIPOP_BUILD),true)
+LOCAL_MODULE_RELATIVE_PATH := $(notdir $(MESA_DRI_MODULE_PATH))
+else
+LOCAL_MODULE_PATH := $(MESA_DRI_MODULE_PATH)
+endif
+
+LOCAL_SRC_FILES := target.c
+
+LOCAL_CFLAGS := -DDRI_TARGET -DHAVE_LIBDRM
+
+LOCAL_SHARED_LIBRARIES := \
+       libdl \
+       libglapi \
+       libexpat \
+
+# swrast only?
+ifeq ($(MESA_GPU_DRIVERS),swrast)
+LOCAL_CFLAGS += -D__NOT_HAVE_DRM_H
+else
+LOCAL_SHARED_LIBRARIES += libdrm
+endif
+
+ifneq ($(filter freedreno,$(MESA_GPU_DRIVERS)),)
+LOCAL_CFLAGS += -DGALLIUM_FREEDRENO
+gallium_DRIVERS += libmesa_winsys_freedreno libmesa_pipe_freedreno
+LOCAL_SHARED_LIBRARIES += libdrm_freedreno
+endif
+ifneq ($(filter i915g,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_winsys_i915 libmesa_pipe_i915
+LOCAL_SHARED_LIBRARIES += libdrm_intel
+LOCAL_CFLAGS += -DGALLIUM_I915
+endif
+ifneq ($(filter ilo,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_winsys_intel libmesa_pipe_ilo
+LOCAL_SHARED_LIBRARIES += libdrm_intel
+LOCAL_CFLAGS += -DGALLIUM_ILO
+endif
+ifneq ($(filter nouveau,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS +=  libmesa_winsys_nouveau libmesa_pipe_nouveau
+LOCAL_CFLAGS += -DGALLIUM_NOUVEAU
+LOCAL_SHARED_LIBRARIES += libdrm_nouveau
+endif
+ifneq ($(filter r%,$(MESA_GPU_DRIVERS)),)
+ifneq ($(filter r300g,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_pipe_r300
+LOCAL_CFLAGS += -DGALLIUM_R300
+endif
+ifneq ($(filter r600g,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_pipe_r600
+LOCAL_CFLAGS += -DGALLIUM_R600
+endif
+ifneq ($(filter radeonsi,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_pipe_radeonsi
+LOCAL_SHARED_LIBRARIES += libLLVM
+LOCAL_CFLAGS += -DGALLIUM_RADEONSI
+endif
+gallium_DRIVERS += libmesa_winsys_radeon libmesa_pipe_radeon
+LOCAL_SHARED_LIBRARIES += libdrm_radeon
+endif
+ifneq ($(filter swrast,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_pipe_softpipe libmesa_winsys_sw_dri libmesa_winsys_sw_kms_dri
+LOCAL_CFLAGS += -DGALLIUM_SOFTPIPE
+endif
+ifneq ($(filter vc4,$(MESA_GPU_DRIVERS)),)
+LOCAL_CFLAGS += -DGALLIUM_VC4
+gallium_DRIVERS += libmesa_winsys_vc4 libmesa_pipe_vc4
+endif
+ifneq ($(filter vmwgfx,$(MESA_GPU_DRIVERS)),)
+gallium_DRIVERS += libmesa_winsys_svga libmesa_pipe_svga
+LOCAL_CFLAGS += -DGALLIUM_VMWGFX
+endif
+ifneq ($(filter nouveau r600g,$(MESA_GPU_DRIVERS)),)
+LOCAL_SHARED_LIBRARIES += $(if $(filter true,$(MESA_LOLLIPOP_BUILD)),libc++,libstlport)
+endif
+
+LOCAL_STATIC_LIBRARIES := \
+       $(gallium_DRIVERS) \
+       libmesa_st_dri \
+       libmesa_st_mesa \
+       libmesa_glsl \
+       libmesa_dri_common \
+       libmesa_megadriver_stub \
+       libmesa_gallium \
+       libmesa_util \
+       libmesa_loader \
+
+ifeq ($(MESA_ENABLE_LLVM),true)
+LOCAL_STATIC_LIBRARIES += \
+       libLLVMR600CodeGen \
+       libLLVMR600Desc \
+       libLLVMR600Info \
+       libLLVMR600AsmPrinter \
+       libelf
+LOCAL_LDLIBS += $(if $(filter true,$(MESA_LOLLIPOP_BUILD)),-lgcc)
+endif
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_SHARED_LIBRARY)
index f9e4ada9338a01c22d83b4d9b79d48a57eb70965..96483964589f49d64bbc11c78f3f918e2efab2f0 100644 (file)
@@ -53,12 +53,6 @@ gallium_dri_la_LIBADD = \
        $(LIBDRM_LIBS) \
        $(GALLIUM_COMMON_LIB_DEPS)
 
-# XXX: Temporary allow duplicated symbols, as the loader pulls in xmlconfig.c
-# which already provides driParse* and driQuery* amongst others.
-# Remove this hack as we come up with a cleaner solution.
-gallium_dri_la_LDFLAGS += \
-       -Wl,--allow-multiple-definition
-
 EXTRA_gallium_dri_la_DEPENDENCIES = \
        dri.sym \
        $(top_srcdir)/src/gallium/targets/dri-vdpau.dyn
index f9d7dfc873496ad16ed36c83898575d7e2f34ffd..1e3874bdb17905334f43a484bb61ca8c8dc7f5b6 100644 (file)
 
 #include "GalliumContext.h"
 
+#include <stdio.h>
+
 #include "GLView.h"
 
 #include "bitmap_wrapper.h"
-extern "C" {
+
 #include "glapi/glapi.h"
 #include "pipe/p_format.h"
-#include "state_tracker/st_cb_fbo.h"
-#include "state_tracker/st_cb_flush.h"
+//#include "state_tracker/st_cb_fbo.h"
+//#include "state_tracker/st_cb_flush.h"
 #include "state_tracker/st_context.h"
 #include "state_tracker/st_gl_api.h"
-#include "state_tracker/st_manager.h"
 #include "state_tracker/sw_winsys.h"
 #include "sw/hgl/hgl_sw_winsys.h"
 #include "util/u_atomic.h"
@@ -28,7 +29,6 @@ extern "C" {
 
 #include "target-helpers/inline_sw_helper.h"
 #include "target-helpers/inline_debug_helper.h"
-}
 
 
 #ifdef DEBUG
@@ -125,7 +125,8 @@ GalliumContext::CreateContext(Bitmap *bitmap)
        context->read = NULL;
        context->st = NULL;
 
-       context->api = st_gl_api_create();
+       // Create st_gl_api
+       context->api = hgl_create_st_api();
        if (!context->api) {
                ERROR("%s: Couldn't obtain Mesa state tracker API!\n", __func__);
                return -1;
@@ -157,12 +158,10 @@ GalliumContext::CreateContext(Bitmap *bitmap)
        attribs.minor = 0;
        //attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
 
-       struct st_api* api = context->api;
-
        // Create context using state tracker api call
        enum st_context_error result;
-       context->st = api->create_context(api, context->manager, &attribs,
-               &result, context->st);
+       context->st = context->api->create_context(context->api, context->manager,
+               &attribs, &result, context->st);
 
        if (!context->st) {
                ERROR("%s: Couldn't create mesa state tracker context!\n",
@@ -287,10 +286,8 @@ GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
                return B_ERROR;
        }
 
-       struct st_api* api = context->api;
-
        if (!bitmap) {
-               api->make_current(context->api, NULL, NULL, NULL);
+               context->api->make_current(context->api, NULL, NULL, NULL);
                return B_OK;
        }
 
@@ -303,7 +300,7 @@ GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
        }
 
        // We need to lock and unlock framebuffers before accessing them
-       api->make_current(context->api, context->st, context->draw->stfbi,
+       context->api->make_current(context->api, context->st, context->draw->stfbi,
                context->read->stfbi);
 
        //if (context->textures[ST_ATTACHMENT_BACK_LEFT]
index b50d52895fc573a919ae71fc9169973cd7dc2a6d..22076cbb141315c157d5927f95c95e909e0d14eb 100644 (file)
 #include <stddef.h>
 #include <kernel/image.h>
 
-extern "C" {
-//#include "state_tracker/st_api.h"
 #include "pipe/p_compiler.h"
 #include "pipe/p_screen.h"
 #include "postprocess/filters.h"
-#include "os/os_thread.h"
 #include "hgl_context.h"
-}
 
 #include "bitmap_wrapper.h"
 
@@ -56,6 +52,6 @@ private:
                context_id                      fCurrentContext;
                pipe_mutex                      fMutex;
 };
-       
+
 
 #endif /* GALLIUMCONTEXT_H */
index 33b0d1345def7a8c38021237302fe522a99594ac..d99caae3cb047476d25f39e9b0dfe1ed894c98f2 100644 (file)
@@ -24,6 +24,11 @@ GL_MAJOR = 1
 GL_MINOR = 5
 GL_TINY = $(MESA_MAJOR)$(MESA_MINOR)0$(MESA_TINY)
 
+if HAVE_SHARED_GLAPI
+SHARED_GLAPI_CFLAGS = -DGLX_SHARED_GLAPI
+SHARED_GLAPI_LIB = $(top_builddir)/src/mapi/shared-glapi/libglapi.la
+endif
+
 AM_CPPFLAGS = \
        -I$(top_srcdir)/include \
        -I$(top_srcdir)/src \
@@ -35,6 +40,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/gallium/state_trackers/glx/xlib \
        -I$(top_srcdir)/src/gallium/auxiliary \
        -I$(top_srcdir)/src/gallium/winsys \
+       $(SHARED_GLAPI_CFLAGS) \
        -DGALLIUM_SOFTPIPE \
        -DGALLIUM_RBUG \
        -DGALLIUM_TRACE
@@ -65,6 +71,7 @@ lib@GL_LIB@_la_LIBADD = \
        $(top_builddir)/src/mapi/glapi/libglapi.la \
        $(top_builddir)/src/mesa/libmesagallium.la \
        $(top_builddir)/src/gallium/auxiliary/libgallium.la \
+       $(SHARED_GLAPI_LIB) \
        $(GL_LIB_DEPS) \
        $(CLOCK_LIB)
 
index 2c09736714a2f7e4a4eb377f4d609d50c5167cf7..38e515f82528c76dad97309c473f85611707754e 100644 (file)
@@ -42,7 +42,6 @@ nodist_EXTRA_lib@OSMESA_LIB@_la_SOURCES = dummy.cpp
 lib@OSMESA_LIB@_la_SOURCES = target.c
 
 lib@OSMESA_LIB@_la_LDFLAGS = \
-       -module \
        -no-undefined \
        -version-number @OSMESA_VERSION@ \
        $(GC_SECTIONS) \
index 967cdb7654204202a1b8635587c775924c554638..e4048b58605bc3db902f3aa35adb861b576ac083 100644 (file)
@@ -52,6 +52,8 @@ endif
 
 PIPE_LIBS += \
        $(top_builddir)/src/gallium/auxiliary/libgallium.la \
+       $(top_builddir)/src/glsl/libnir.la \
+       $(top_builddir)/src/libglsl_util.la \
        $(top_builddir)/src/util/libmesautil.la \
        $(top_builddir)/src/gallium/drivers/rbug/librbug.la \
        $(top_builddir)/src/gallium/drivers/trace/libtrace.la \
index abecedbd594cf054b1fb1ef9dfda4727c4c38bb3..daae577ec4b804a1154b4d4d838f306b5e350f35 100644 (file)
@@ -270,7 +270,9 @@ static void init_prog(struct program *p)
        }
 
        /* fragment shader */
-       p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
+       p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D,
+                                             TGSI_INTERPOLATE_LINEAR,
+                                             TGSI_RETURN_TYPE_FLOAT);
 }
 
 static void close_prog(struct program *p)
diff --git a/src/gallium/winsys/sw/android/Android.mk b/src/gallium/winsys/sw/android/Android.mk
deleted file mode 100644 (file)
index 4fb2715..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# Mesa 3-D graphics library
-#
-# Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
-# Copyright (C) 2010-2011 LunarG Inc.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-       android_sw_winsys.cpp
-
-LOCAL_MODULE := libmesa_winsys_sw_android
-
-include $(GALLIUM_COMMON_MK)
-include $(BUILD_STATIC_LIBRARY)
diff --git a/src/gallium/winsys/sw/android/android_sw_winsys.cpp b/src/gallium/winsys/sw/android/android_sw_winsys.cpp
deleted file mode 100644 (file)
index 4b1040c..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2010-2011 LunarG Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_state.h"
-#include "util/u_memory.h"
-#include "util/u_format.h"
-#include "state_tracker/sw_winsys.h"
-
-#include <hardware/gralloc.h>
-#include <utils/Errors.h>
-
-#if ANDROID_VERSION < 0x0300
-#include <private/ui/sw_gralloc_handle.h>
-#endif
-
-#include "android_sw_winsys.h"
-
-struct android_sw_winsys
-{
-   struct sw_winsys base;
-
-   const gralloc_module_t *grmod;
-};
-
-struct android_sw_displaytarget
-{
-   buffer_handle_t handle;
-   int stride;
-   int width, height;
-   int usage; /* gralloc usage */
-
-   void *mapped;
-};
-
-static INLINE struct android_sw_winsys *
-android_sw_winsys(struct sw_winsys *ws)
-{
-   return (struct android_sw_winsys *) ws;
-}
-
-static INLINE struct android_sw_displaytarget *
-android_sw_displaytarget(struct sw_displaytarget *dt)
-{
-   return (struct android_sw_displaytarget *) dt;
-}
-
-namespace android {
-
-static void
-android_displaytarget_display(struct sw_winsys *ws,
-                              struct sw_displaytarget *dt,
-                              void *context_private,
-                              struct pipe_box *box)
-{
-}
-
-static struct sw_displaytarget *
-android_displaytarget_create(struct sw_winsys *ws,
-                             unsigned tex_usage,
-                             enum pipe_format format,
-                             unsigned width, unsigned height,
-                             unsigned alignment,
-                             unsigned *stride)
-{
-   return NULL;
-}
-
-static void
-android_displaytarget_destroy(struct sw_winsys *ws,
-                              struct sw_displaytarget *dt)
-{
-   struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
-
-   assert(!adt->mapped);
-   FREE(adt);
-}
-
-static void
-android_displaytarget_unmap(struct sw_winsys *ws,
-                            struct sw_displaytarget *dt)
-{
-   struct android_sw_winsys *droid = android_sw_winsys(ws);
-   struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
-
-#if ANDROID_VERSION < 0x0300
-   /* try sw_gralloc first */
-   if (adt->mapped && sw_gralloc_handle_t::validate(adt->handle) >= 0) {
-      adt->mapped = NULL;
-      return;
-   }
-#endif
-
-   if (adt->mapped) {
-      droid->grmod->unlock(droid->grmod, adt->handle);
-      adt->mapped = NULL;
-   }
-}
-
-static void *
-android_displaytarget_map(struct sw_winsys *ws,
-                          struct sw_displaytarget *dt,
-                          unsigned flags)
-{
-   struct android_sw_winsys *droid = android_sw_winsys(ws);
-   struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
-
-#if ANDROID_VERSION < 0x0300
-   /* try sw_gralloc first */
-   if (sw_gralloc_handle_t::validate(adt->handle) >= 0) {
-      const sw_gralloc_handle_t *swhandle =
-         reinterpret_cast<const sw_gralloc_handle_t *>(adt->handle);
-      adt->mapped = reinterpret_cast<void *>(swhandle->base);
-
-      return adt->mapped;
-   }
-#endif
-
-   if (!adt->mapped) {
-      /* lock the buffer for CPU access */
-      droid->grmod->lock(droid->grmod, adt->handle,
-            adt->usage, 0, 0, adt->width, adt->height, &adt->mapped);
-   }
-
-   return adt->mapped;
-}
-
-static struct sw_displaytarget *
-android_displaytarget_from_handle(struct sw_winsys *ws,
-                                  const struct pipe_resource *templ,
-                                  struct winsys_handle *whandle,
-                                  unsigned *stride)
-{
-   struct android_winsys_handle *ahandle =
-      (struct android_winsys_handle *) whandle;
-   struct android_sw_displaytarget *adt;
-
-   adt = CALLOC_STRUCT(android_sw_displaytarget);
-   if (!adt)
-      return NULL;
-
-   adt->handle = ahandle->handle;
-   adt->stride = ahandle->stride;
-   adt->width = templ->width0;
-   adt->height = templ->height0;
-
-   if (templ->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_WRITE))
-      adt->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
-   if (templ->bind & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ))
-      adt->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
-
-   if (stride)
-      *stride = adt->stride;
-
-   return reinterpret_cast<struct sw_displaytarget *>(adt);
-}
-
-static boolean
-android_displaytarget_get_handle(struct sw_winsys *ws,
-                                 struct sw_displaytarget *dt,
-                                 struct winsys_handle *whandle)
-{
-   return FALSE;
-}
-
-static boolean
-android_is_displaytarget_format_supported(struct sw_winsys *ws,
-                                          unsigned tex_usage,
-                                          enum pipe_format format)
-{
-   struct android_sw_winsys *droid = android_sw_winsys(ws);
-   int fmt = -1;
-
-   switch (format) {
-   case PIPE_FORMAT_R8G8B8A8_UNORM:
-      fmt = HAL_PIXEL_FORMAT_RGBA_8888;
-      break;
-   case PIPE_FORMAT_R8G8B8X8_UNORM:
-      fmt = HAL_PIXEL_FORMAT_RGBX_8888;
-      break;
-   case PIPE_FORMAT_R8G8B8_UNORM:
-      fmt = HAL_PIXEL_FORMAT_RGB_888;
-      break;
-   case PIPE_FORMAT_B5G6R5_UNORM:
-      fmt = HAL_PIXEL_FORMAT_RGB_565;
-      break;
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
-      fmt = HAL_PIXEL_FORMAT_BGRA_8888;
-      break;
-   default:
-      break;
-   }
-
-   return (fmt != -1);
-}
-
-static void
-android_destroy(struct sw_winsys *ws)
-{
-   struct android_sw_winsys *droid = android_sw_winsys(ws);
-
-   FREE(droid);
-}
-
-}; /* namespace android */
-
-using namespace android;
-
-struct sw_winsys *
-android_create_sw_winsys(void)
-{
-   struct android_sw_winsys *droid;
-   const hw_module_t *mod;
-
-   droid = CALLOC_STRUCT(android_sw_winsys);
-   if (!droid)
-      return NULL;
-
-   if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod)) {
-      FREE(droid);
-      return NULL;
-   }
-
-   droid->grmod = (const gralloc_module_t *) mod;
-
-   droid->base.destroy = android_destroy;
-   droid->base.is_displaytarget_format_supported =
-      android_is_displaytarget_format_supported;
-
-   droid->base.displaytarget_create = android_displaytarget_create;
-   droid->base.displaytarget_destroy = android_displaytarget_destroy;
-   droid->base.displaytarget_from_handle = android_displaytarget_from_handle;
-   droid->base.displaytarget_get_handle = android_displaytarget_get_handle;
-
-   droid->base.displaytarget_map = android_displaytarget_map;
-   droid->base.displaytarget_unmap = android_displaytarget_unmap;
-   droid->base.displaytarget_display = android_displaytarget_display;
-
-   return &droid->base;
-}
diff --git a/src/gallium/winsys/sw/android/android_sw_winsys.h b/src/gallium/winsys/sw/android/android_sw_winsys.h
deleted file mode 100644 (file)
index 24c85ed..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2010-2011 LunarG Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ANDROID_SW_WINSYS
-#define ANDROID_SW_WINSYS
-
-#include <sys/cdefs.h>
-#include <hardware/gralloc.h>
-
-__BEGIN_DECLS
-
-struct sw_winsys;
-
-struct android_winsys_handle {
-   buffer_handle_t handle;
-   int stride;
-};
-
-struct sw_winsys *
-android_create_sw_winsys(void);
-
-__END_DECLS
-
-#endif /* ANDROID_SW_WINSYS */
diff --git a/src/gallium/winsys/sw/dri/Android.mk b/src/gallium/winsys/sw/dri/Android.mk
new file mode 100644 (file)
index 0000000..72fb920
--- /dev/null
@@ -0,0 +1,35 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2015 Chih-Wei Huang <cwhuang@linux.org.tw>
+# Copyright (C) 2015 Android-x86 Open Source Project
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(C_SOURCES)
+
+LOCAL_MODULE := libmesa_winsys_sw_dri
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
index bdcddfb4f2b3234d7c6aee17c5c1b664a92305d1..a81f890826ee1ddb323edff7eb3f2a37fd1c44dd 100644 (file)
 #ifndef _HGL_SOFTWAREWINSYS_H
 #define _HGL_SOFTWAREWINSYS_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct sw_winsys;
 
 struct sw_winsys* hgl_create_sw_winsys(void);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/gallium/winsys/sw/kms-dri/Android.mk b/src/gallium/winsys/sw/kms-dri/Android.mk
new file mode 100644 (file)
index 0000000..b065242
--- /dev/null
@@ -0,0 +1,37 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2015 Chih-Wei Huang <cwhuang@linux.org.tw>
+# Copyright (C) 2015 Android-x86 Open Source Project
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(C_SOURCES)
+
+LOCAL_MODULE := libmesa_winsys_sw_kms_dri
+
+LOCAL_SHARED_LIBRARIES := libdrm
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/gallium/winsys/vc4/drm/Android.mk b/src/gallium/winsys/vc4/drm/Android.mk
new file mode 100644 (file)
index 0000000..55edc17
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright (C) 2014 Emil Velikov <emil.l.velikov@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+# get C_SOURCES
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(C_SOURCES)
+
+LOCAL_SHARED_LIBRARIES := libdrm
+LOCAL_MODULE := libmesa_winsys_vc4
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
index dbd4f8338677b4ec0c48da85fc6deae32ca16442..918fdf7d6adac7a6d00d2f26b00ba75b44c9a7c2 100644 (file)
@@ -52,7 +52,8 @@ libgbm_dri_la_CFLAGS = \
        $(LIBDRM_CFLAGS)
 
 libgbm_la_LIBADD += \
-       libgbm_dri.la $(top_builddir)/src/mapi/shared-glapi/libglapi.la $(LIBDRM_LIBS)
+       libgbm_dri.la \
+       $(LIBDRM_LIBS)
 endif
 
 TESTS = gbm-symbols-check
index 62bdf891d57c928afce250b009b3d5b052910ae1..ccc3cc6930f8f4402fd45824b95ae4e02f5733bc 100644 (file)
@@ -311,6 +311,14 @@ dri_open_driver(struct gbm_dri_device *dri)
    if (search_paths == NULL)
       search_paths = DEFAULT_DRIVER_DIR;
 
+   /* Temporarily work around dri driver libs that need symbols in libglapi
+    * but don't automatically link it in.
+    */
+   /* XXX: Library name differs on per platforms basis. Update this as
+    * osx/cygwin/windows/bsd gets support for GBM..
+    */
+   dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
+
    dri->driver = NULL;
    end = search_paths + strlen(search_paths);
    for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) {
index f20741e0d0fc1259eb45191e368b43af7a3fd9d9..f63b7daf26ea988facdbffef34d26bd6352c428e 100644 (file)
@@ -46,7 +46,6 @@ LOCAL_C_INCLUDES := \
 
 LOCAL_MODULE := libmesa_glsl
 
-include external/stlport/libstlport.mk
 include $(LOCAL_PATH)/Android.gen.mk
 include $(MESA_COMMON_MK)
 include $(BUILD_STATIC_LIBRARY)
index 7af9a709d5adcd7a62b109ece5e0249f098d433a..74da9e5b979987efc852d9908986ca1c74c90a3d 100644 (file)
@@ -89,8 +89,7 @@ tests_general_ir_test_SOURCES =               \
        tests/builtin_variable_test.cpp                 \
        tests/invalidate_locations_test.cpp             \
        tests/general_ir_test.cpp                       \
-       tests/varyings_test.cpp                         \
-       tests/common.c
+       tests/varyings_test.cpp
 tests_general_ir_test_CFLAGS =                         \
        $(PTHREAD_CFLAGS)
 tests_general_ir_test_LDADD =                          \
@@ -103,8 +102,7 @@ tests_uniform_initializer_test_SOURCES =            \
        tests/copy_constant_to_storage_tests.cpp        \
        tests/set_uniform_initializer_tests.cpp         \
        tests/uniform_initializer_utils.cpp             \
-       tests/uniform_initializer_utils.h               \
-       tests/common.c
+       tests/uniform_initializer_utils.h
 tests_uniform_initializer_test_CFLAGS =                        \
        $(PTHREAD_CFLAGS)
 tests_uniform_initializer_test_LDADD =                 \
@@ -114,8 +112,7 @@ tests_uniform_initializer_test_LDADD =                      \
        $(PTHREAD_LIBS)
 
 tests_sampler_types_test_SOURCES =                     \
-       tests/sampler_types_test.cpp                    \
-       tests/common.c
+       tests/sampler_types_test.cpp
 tests_sampler_types_test_CFLAGS =                      \
        $(PTHREAD_CFLAGS)
 tests_sampler_types_test_LDADD =                       \
@@ -133,8 +130,7 @@ libglcpp_la_SOURCES =                                       \
        $(LIBGLCPP_FILES)
 
 glcpp_glcpp_SOURCES =                                  \
-       glcpp/glcpp.c                                   \
-       tests/common.c
+       glcpp/glcpp.c
 glcpp_glcpp_LDADD =                                    \
        libglcpp.la                                     \
        $(top_builddir)/src/libglsl_util.la             \
@@ -174,7 +170,6 @@ spirv2nir_LDADD =                                   \
 
 glsl_test_SOURCES = \
        standalone_scaffolding.cpp \
-       tests/common.c \
        test.cpp \
        test_optpass.cpp \
        test_optpass.h
@@ -257,21 +252,21 @@ dist-hook:
        $(RM) glcpp/tests/subtest*/*.out
 
 nir/nir_builder_opcodes.h: nir/nir_opcodes.py nir/nir_builder_opcodes_h.py
-       $(MKDIR_P) nir;                                                 \
-       $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_builder_opcodes_h.py > $@
+       $(AM_V_at)$(MKDIR_P) nir
+       $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_builder_opcodes_h.py > $@
 
 nir/nir_constant_expressions.c: nir/nir_opcodes.py nir/nir_constant_expressions.py nir/nir_constant_expressions.h
-       $(MKDIR_P) nir;                                                 \
-       $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_constant_expressions.py > $@
+       $(AM_V_at)$(MKDIR_P) nir
+       $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_constant_expressions.py > $@
 
 nir/nir_opcodes.h: nir/nir_opcodes.py nir/nir_opcodes_h.py
-       $(MKDIR_P) nir;                                                 \
-       $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_h.py > $@
+       $(AM_V_at)$(MKDIR_P) nir
+       $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_h.py > $@
 
 nir/nir_opcodes.c: nir/nir_opcodes.py nir/nir_opcodes_c.py
-       $(MKDIR_P) nir;                                                 \
-       $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_c.py > $@
+       $(AM_V_at)$(MKDIR_P) nir
+       $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_c.py > $@
 
 nir/nir_opt_algebraic.c: nir/nir_opt_algebraic.py nir/nir_algebraic.py
-       $(MKDIR_P) nir;                                                 \
-       $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opt_algebraic.py > $@
+       $(AM_V_at)$(MKDIR_P) nir
+       $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opt_algebraic.py > $@
index 284b375844fd9de8f3163b33f7d9ba9a121325fa..89c603580a5d76e7cf1619cfe97353f37f62d35a 100644 (file)
@@ -71,6 +71,7 @@ env.Command('imports.c', '#src/mesa/main/imports.c', Copy('$TARGET', '$SOURCE'))
 env.Prepend(CPPPATH = ['#src/mesa/program'])
 env.Command('prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE'))
 env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
+env.Command('dummy_errors.c', '#src/mesa/program/dummy_errors.c', Copy('$TARGET', '$SOURCE'))
 
 compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES'])
 
@@ -78,6 +79,7 @@ mesa_objs = env.StaticObject([
     'imports.c',
     'prog_hash_table.c',
     'symbol_table.c',
+    'dummy_errors.c',
 ])
 
 compiler_objs += mesa_objs
@@ -115,6 +117,6 @@ env.Alias('glsl_compiler', glsl_compiler)
 
 glcpp = env.Program(
     target = 'glcpp/glcpp',
-    source = ['glcpp/glcpp.c', 'tests/common.c'] + mesa_objs,
+    source = ['glcpp/glcpp.c'] + mesa_objs,
 )
 env.Alias('glcpp', glcpp)
index ecef651f75218fde83ee3789fa240faba8858799..752d86f72fd8e86e2177cf89be762f2daef1c13b 100644 (file)
@@ -225,7 +225,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
        * values *do* diverge, then the behavior of the operation requiring a
        * dynamically uniform expression is undefined.
        */
-      if (array->type->element_type()->is_sampler()) {
+      if (array->type->without_array()->is_sampler()) {
         if (!state->is_version(130, 100)) {
            if (state->es_shader) {
               _mesa_glsl_warning(&loc, state,
index 758361324e3673db47b6133748c5c22612bada32..92e26bf2416683e7db4255ba5f68f5d871921d12 100644 (file)
@@ -863,7 +863,7 @@ process_array_constructor(exec_list *instructions,
 
    if (is_unsized_array) {
       constructor_type =
-        glsl_type::get_array_instance(constructor_type->element_type(),
+        glsl_type::get_array_instance(constructor_type->fields.array,
                                       parameter_count);
       assert(constructor_type != NULL);
       assert(constructor_type->length == parameter_count);
@@ -876,7 +876,7 @@ process_array_constructor(exec_list *instructions,
       ir_rvalue *result = ir;
 
       const glsl_base_type element_base_type =
-         constructor_type->element_type()->base_type;
+         constructor_type->fields.array->base_type;
 
       /* Apply implicit conversions (not the scalar constructor rules!). See
        * the spec quote above. */
@@ -896,10 +896,10 @@ process_array_constructor(exec_list *instructions,
         }
       }
 
-      if (result->type != constructor_type->element_type()) {
+      if (result->type != constructor_type->fields.array) {
         _mesa_glsl_error(loc, state, "type error in array constructor: "
                          "expected: %s, found %s",
-                         constructor_type->element_type()->name,
+                         constructor_type->fields.array->name,
                          result->type->name);
          return ir_rvalue::error_value(ctx);
       }
@@ -993,11 +993,15 @@ emit_inline_vector_constructor(const glsl_type *type,
    ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary);
    instructions->push_tail(var);
 
-   /* There are two kinds of vector constructors.
+   /* There are three kinds of vector constructors.
     *
     *  - Construct a vector from a single scalar by replicating that scalar to
     *    all components of the vector.
     *
+    *  - Construct a vector from at least a matrix. This case should already
+    *    have been taken care of in ast_function_expression::hir by breaking
+    *    down the matrix into a series of column vectors.
+    *
     *  - Construct a vector from an arbirary combination of vectors and
     *    scalars.  The components of the constructor parameters are assigned
     *    to the vector in order until the vector is full.
@@ -1091,6 +1095,14 @@ emit_inline_vector_constructor(const glsl_type *type,
            rhs_components = lhs_components - base_component;
         }
 
+        /* If we do not have any components left to copy, break out of the
+         * loop. This can happen when initializing a vec4 with a mat3 as the
+         * mat3 would have been broken into a series of column vectors.
+         */
+        if (rhs_components == 0) {
+           break;
+        }
+
         const ir_constant *const c = param->as_constant();
         if (c == NULL) {
            /* Mask of fields to be written in the assignment.
@@ -1681,11 +1693,11 @@ ast_function_expression::hir(exec_list *instructions,
         return ir_rvalue::error_value(ctx);
       }
 
-      /* Later, we cast each parameter to the same base type as the
-       * constructor.  Since there are no non-floating point matrices, we
-       * need to break them up into a series of column vectors.
+      /* Matrices can never be consumed as is by any constructor but matrix
+       * constructors. If the constructor type is not matrix, always break the
+       * matrix up into a series of column vectors.
        */
-      if (constructor_type->base_type != GLSL_TYPE_FLOAT) {
+      if (!constructor_type->is_matrix()) {
         foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) {
            if (!matrix->type->is_matrix())
               continue;
index cd6a068e97d87743e35929d05789a214e7a47d87..6896b700cd6a0216a3df41de9b2326aa53364e8c 100644 (file)
@@ -678,7 +678,7 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
     * is handled by ir_dereference::is_lvalue.
     */
    if (lhs_type->is_unsized_array() && rhs->type->is_array()
-       && (lhs_type->element_type() == rhs->type->element_type())) {
+       && (lhs_type->fields.array == rhs->type->fields.array)) {
       if (is_initializer) {
          return rhs;
       } else {
@@ -820,7 +820,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                              var->data.max_array_access);
          }
 
-         var->type = glsl_type::get_array_instance(lhs->type->element_type(),
+         var->type = glsl_type::get_array_instance(lhs->type->fields.array,
                                                    rhs->type->array_size());
          d->type = var->type;
       }
@@ -2087,7 +2087,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
        *  with an array of size N, all elements of the array from binding
        *  through binding + N - 1 must be within this range."
        */
-      unsigned limit = ctx->Const.Program[state->stage].MaxTextureImageUnits;
+      unsigned limit = ctx->Const.MaxCombinedTextureImageUnits;
 
       if (max_index >= limit) {
          _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers "
@@ -2331,8 +2331,7 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
                                   struct _mesa_glsl_parse_state *state,
                                   YYLTYPE *loc)
 {
-   const glsl_type *base_type =
-      (var->type->is_array() ? var->type->element_type() : var->type);
+   const glsl_type *base_type = var->type->without_array();
 
    if (base_type->is_image()) {
       if (var->data.mode != ir_var_uniform &&
@@ -2740,7 +2739,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
     *    GL_ARB_conservative_depth
     *    GL_ARB_gpu_shader5
     *    GL_ARB_separate_shader_objects
-    *    GL_ARB_tesselation_shader
+    *    GL_ARB_tessellation_shader
     *    GL_ARB_transform_feedback3
     *    GL_ARB_uniform_buffer_object
     *
@@ -2865,7 +2864,7 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
     *  type and specify a size."
     */
    if (earlier->type->is_unsized_array() && var->type->is_array()
-       && (var->type->element_type() == earlier->type->element_type())) {
+       && (var->type->fields.array == earlier->type->fields.array)) {
       /* FINISHME: This doesn't match the qualifiers on the two
        * FINISHME: declarations.  It's not 100% clear whether this is
        * FINISHME: required or not.
@@ -3618,6 +3617,51 @@ ast_declarator_list::hir(exec_list *instructions,
             }
 
             handle_geometry_shader_input_decl(state, loc, var);
+         } else if (state->stage == MESA_SHADER_FRAGMENT) {
+            /* From section 4.3.4 (Input Variables) of the GLSL ES 3.10 spec:
+             *
+             *     It is a compile-time error to declare a fragment shader
+             *     input with, or that contains, any of the following types:
+             *
+             *     * A boolean type
+             *     * An opaque type
+             *     * An array of arrays
+             *     * An array of structures
+             *     * A structure containing an array
+             *     * A structure containing a structure
+             */
+            if (state->es_shader) {
+               const glsl_type *check_type = var->type->without_array();
+               if (check_type->is_boolean() ||
+                   check_type->contains_opaque()) {
+                  _mesa_glsl_error(&loc, state,
+                                   "fragment shader input cannot have type %s",
+                                   check_type->name);
+               }
+               if (var->type->is_array() &&
+                   var->type->fields.array->is_array()) {
+                  _mesa_glsl_error(&loc, state,
+                                   "%s shader output "
+                                   "cannot have an array of arrays",
+                                   _mesa_shader_stage_to_string(state->stage));
+               }
+               if (var->type->is_array() &&
+                   var->type->fields.array->is_record()) {
+                  _mesa_glsl_error(&loc, state,
+                                   "fragment shader input "
+                                   "cannot have an array of structs");
+               }
+               if (var->type->is_record()) {
+                  for (unsigned i = 0; i < var->type->length; i++) {
+                     if (var->type->fields.structure[i].type->is_array() ||
+                         var->type->fields.structure[i].type->is_record())
+                        _mesa_glsl_error(&loc, state,
+                                         "fragement shader input cannot have "
+                                         "a struct that contains an "
+                                         "array or struct");
+                  }
+               }
+            }
          }
       } else if (var->data.mode == ir_var_shader_out) {
          const glsl_type *check_type = var->type->without_array();
@@ -3652,7 +3696,7 @@ ast_declarator_list::hir(exec_list *instructions,
             if (check_type->is_record() || check_type->is_matrix())
                _mesa_glsl_error(&loc, state,
                                 "fragment shader output "
-                                "cannot have struct or array type");
+                                "cannot have struct or matrix type");
             switch (check_type->base_type) {
             case GLSL_TYPE_UINT:
             case GLSL_TYPE_INT:
@@ -3664,6 +3708,55 @@ ast_declarator_list::hir(exec_list *instructions,
                                 "type %s", check_type->name);
             }
          }
+
+         /* From section 4.3.6 (Output Variables) of the GLSL ES 3.10 spec:
+          *
+          *     It is a compile-time error to declare a vertex shader output
+          *     with, or that contains, any of the following types:
+          *
+          *     * A boolean type
+          *     * An opaque type
+          *     * An array of arrays
+          *     * An array of structures
+          *     * A structure containing an array
+          *     * A structure containing a structure
+          *
+          *     It is a compile-time error to declare a fragment shader output
+          *     with, or that contains, any of the following types:
+          *
+          *     * A boolean type
+          *     * An opaque type
+          *     * A matrix
+          *     * A structure
+          *     * An array of array
+          */
+         if (state->es_shader) {
+            if (var->type->is_array() &&
+                var->type->fields.array->is_array()) {
+               _mesa_glsl_error(&loc, state,
+                                "%s shader output "
+                                "cannot have an array of arrays",
+                                _mesa_shader_stage_to_string(state->stage));
+            }
+            if (state->stage == MESA_SHADER_VERTEX) {
+               if (var->type->is_array() &&
+                   var->type->fields.array->is_record()) {
+                  _mesa_glsl_error(&loc, state,
+                                   "vertex shader output "
+                                   "cannot have an array of structs");
+               }
+               if (var->type->is_record()) {
+                  for (unsigned i = 0; i < var->type->length; i++) {
+                     if (var->type->fields.structure[i].type->is_array() ||
+                         var->type->fields.structure[i].type->is_record())
+                        _mesa_glsl_error(&loc, state,
+                                         "vertex shader output cannot have a "
+                                         "struct that contains an "
+                                         "array or struct");
+                  }
+               }
+            }
+         }
       }
 
       /* Integer fragment inputs must be qualified with 'flat'.  In GLSL ES,
@@ -5756,6 +5849,17 @@ ast_interface_block::hir(exec_list *instructions,
          const glsl_type *block_array_type =
             process_array_type(&loc, block_type, this->array_specifier, state);
 
+          /* From section 4.3.9 (Interface Blocks) of the GLSL ES 3.10 spec:
+          *
+          *     * Arrays of arrays of blocks are not allowed
+          */
+         if (state->es_shader && block_array_type->is_array() &&
+             block_array_type->fields.array->is_array()) {
+            _mesa_glsl_error(&loc, state,
+                             "arrays of arrays interface blocks are "
+                             "not allowed");
+         }
+
          var = new(state) ir_variable(block_array_type,
                                       this->instance_name,
                                       var_mode);
index 97055d85d585ffdf033a7b104f9acf8c781be874..efab2991993379ca5bc32b6f5581e72b6cfb23ba 100644 (file)
@@ -410,6 +410,13 @@ fp64(const _mesa_glsl_parse_state *state)
    return state->has_double();
 }
 
+static bool
+barrier_supported(const _mesa_glsl_parse_state *state)
+{
+   return state->stage == MESA_SHADER_COMPUTE;
+   /* TODO: || stage->state == MESA_SHADER_TESS_CTRL; */
+}
+
 /** @} */
 
 /******************************************************************************/
@@ -654,6 +661,7 @@ private:
                                             const glsl_type *stream_type);
    ir_function_signature *_EndStreamPrimitive(builtin_available_predicate avail,
                                               const glsl_type *stream_type);
+   B0(barrier)
 
    B2(textureQueryLod);
    B1(textureQueryLevels);
@@ -1933,6 +1941,7 @@ builtin_builder::create_builtins()
                 _EndStreamPrimitive(gs_streams, glsl_type::uint_type),
                 _EndStreamPrimitive(gs_streams, glsl_type::int_type),
                 NULL);
+   add_function("barrier", _barrier(), NULL);
 
    add_function("textureQueryLOD",
                 _textureQueryLod(glsl_type::sampler1D_type,  glsl_type::float_type),
@@ -4295,6 +4304,15 @@ builtin_builder::_EndStreamPrimitive(builtin_available_predicate avail,
    return sig;
 }
 
+ir_function_signature *
+builtin_builder::_barrier()
+{
+   MAKE_SIG(glsl_type::void_type, barrier_supported, 0);
+
+   body.emit(new(mem_ctx) ir_barrier());
+   return sig;
+}
+
 ir_function_signature *
 builtin_builder::_textureQueryLod(const glsl_type *sampler_type,
                                   const glsl_type *coord_type)
index 6806aa1f962f51f6411f8814f7d544498fbe12a5..a765d35fde0658e19a42eae1950970c843be88aa 100644 (file)
@@ -764,7 +764,8 @@ builtin_variable_generator::generate_constants()
 void
 builtin_variable_generator::generate_uniforms()
 {
-   add_uniform(int_t, "gl_NumSamples");
+   if (state->is_version(400, 0) || state->ARB_sample_shading_enable)
+      add_uniform(int_t, "gl_NumSamples");
    add_uniform(type("gl_DepthRangeParameters"), "gl_DepthRange");
    add_uniform(array(vec4_t, VERT_ATTRIB_MAX), "gl_CurrentAttribVertMESA");
    add_uniform(array(vec4_t, VARYING_SLOT_MAX), "gl_CurrentAttribFragMESA");
@@ -876,9 +877,9 @@ void
 builtin_variable_generator::generate_gs_special_vars()
 {
    add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer");
-   if (state->ARB_viewport_array_enable)
+   if (state->is_version(410, 0) || state->ARB_viewport_array_enable)
       add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex");
-   if (state->ARB_gpu_shader5_enable)
+   if (state->is_version(400, 0) || state->ARB_gpu_shader5_enable)
       add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID");
 
    /* Although gl_PrimitiveID appears in tessellation control and tessellation
@@ -946,7 +947,7 @@ builtin_variable_generator::generate_fs_special_vars()
          var->enable_extension_warning("GL_AMD_shader_stencil_export");
    }
 
-   if (state->ARB_sample_shading_enable) {
+   if (state->is_version(400, 0) || state->ARB_sample_shading_enable) {
       add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, "gl_SampleID");
       add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, "gl_SamplePosition");
       /* From the ARB_sample_shading specification:
@@ -959,11 +960,11 @@ builtin_variable_generator::generate_fs_special_vars()
       add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask");
    }
 
-   if (state->ARB_gpu_shader5_enable) {
+   if (state->is_version(400, 0) || state->ARB_gpu_shader5_enable) {
       add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), "gl_SampleMaskIn");
    }
 
-   if (state->ARB_fragment_layer_viewport_enable) {
+   if (state->is_version(430, 0) || state->ARB_fragment_layer_viewport_enable) {
       add_input(VARYING_SLOT_LAYER, int_t, "gl_Layer");
       add_input(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex");
    }
index 982ade6a70a9f10abc373b9b72719cce901ed1e8..e26931de42f80cb8b2a3d565bc80b61ba76697c3 100644 (file)
@@ -780,7 +780,7 @@ _mesa_ast_set_aggregate_type(const glsl_type *type,
 
    /* If the aggregate is an array, recursively set its elements' types. */
    if (type->is_array()) {
-      /* Each array element has the type type->element_type().
+      /* Each array element has the type type->fields.array.
        *
        * E.g., if <type> if struct S[2] we want to set each element's type to
        * struct S.
@@ -792,7 +792,7 @@ _mesa_ast_set_aggregate_type(const glsl_type *type,
                                                link);
 
          if (expr->oper == ast_aggregate)
-            _mesa_ast_set_aggregate_type(type->element_type(), expr);
+            _mesa_ast_set_aggregate_type(type->fields.array, expr);
       }
 
    /* If the aggregate is a struct, recursively set its fields' types. */
index 0d83ee68e427d5d095a8ba0831ff99769ab2da72..37406b8073efb9acb26ea3316342f2c9e26d4db7 100644 (file)
@@ -251,7 +251,7 @@ glsl_type::contains_opaque() const {
    case GLSL_TYPE_ATOMIC_UINT:
       return true;
    case GLSL_TYPE_ARRAY:
-      return element_type()->contains_opaque();
+      return fields.array->contains_opaque();
    case GLSL_TYPE_STRUCT:
       for (unsigned int i = 0; i < length; i++) {
          if (fields.structure[i].type->contains_opaque())
index 2d4718572afd498dd1fdad9404baee0617894147..836259a506cb1724b45c4f449c33c65149c09558 100644 (file)
@@ -228,18 +228,6 @@ struct glsl_type {
     */
    const glsl_type *get_scalar_type() const;
 
-   /**
-    * Query the type of elements in an array
-    *
-    * \return
-    * Pointer to the type of elements in the array for array types, or \c NULL
-    * for non-array types.
-    */
-   const glsl_type *element_type() const
-   {
-      return is_array() ? fields.array : NULL;
-   }
-
    /**
     * Get the instance of a built-in scalar, vector, or matrix type
     */
@@ -564,7 +552,7 @@ struct glsl_type {
       if (base_type == GLSL_TYPE_ATOMIC_UINT)
          return ATOMIC_COUNTER_SIZE;
       else if (is_array())
-         return length * element_type()->atomic_size();
+         return length * fields.array->atomic_size();
       else
          return 0;
    }
index 9e3238552e96e57d86800bb65f8c89ae07646a4a..dbd064feecc26f3a026028e88cb4fbf36e2bb572 100644 (file)
@@ -912,7 +912,7 @@ ir_constant::zero(void *mem_ctx, const glsl_type *type)
       c->array_elements = ralloc_array(c, ir_constant *, type->length);
 
       for (unsigned i = 0; i < type->length; i++)
-        c->array_elements[i] = ir_constant::zero(c, type->element_type());
+        c->array_elements[i] = ir_constant::zero(c, type->fields.array);
    }
 
    if (type->is_record()) {
@@ -1341,7 +1341,7 @@ ir_dereference_array::set_array(ir_rvalue *value)
    const glsl_type *const vt = this->array->type;
 
    if (vt->is_array()) {
-      type = vt->element_type();
+      type = vt->fields.array;
    } else if (vt->is_matrix()) {
       type = vt->column_type();
    } else if (vt->is_vector()) {
index fdb595106c2bb7c6ea05583a2646d0af795700b2..5af029b97655f1d9675a002ae3bbf98d4ebb3b9b 100644 (file)
@@ -78,6 +78,7 @@ enum ir_node_type {
    ir_type_discard,
    ir_type_emit_vertex,
    ir_type_end_primitive,
+   ir_type_barrier,
    ir_type_max, /**< maximum ir_type enum number, for validation */
    ir_type_unset = ir_type_max
 };
@@ -2408,6 +2409,29 @@ public:
    ir_rvalue *stream;
 };
 
+/**
+ * IR instruction for tessellation control and compute shader barrier.
+ */
+class ir_barrier : public ir_instruction {
+public:
+   ir_barrier()
+      : ir_instruction(ir_type_barrier)
+   {
+   }
+
+   virtual void accept(ir_visitor *v)
+   {
+      v->visit(this);
+   }
+
+   virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const
+   {
+      return new(mem_ctx) ir_barrier();
+   }
+
+   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+};
+
 /*@}*/
 
 /**
index 2b2643c64a2c0b4718c13cebb4669b14b0c96a90..13194439003153f9441a845578a76bd821fb528c 100644 (file)
@@ -148,9 +148,11 @@ get_parameter_match_type(const ir_variable *param,
    if (from_type == to_type)
       return PARAMETER_EXACT_MATCH;
 
-   /* XXX: When ARB_gpu_shader_fp64 support is added, check for float->double,
-    * and int/uint->double conversions
-    */
+   if (to_type->base_type == GLSL_TYPE_DOUBLE) {
+      if (from_type->base_type == GLSL_TYPE_FLOAT)
+         return PARAMETER_FLOAT_TO_DOUBLE;
+      return PARAMETER_INT_TO_DOUBLE;
+   }
 
    if (to_type->base_type == GLSL_TYPE_FLOAT)
       return PARAMETER_INT_TO_FLOAT;
index adb629414a2c644e339fb7591d4fecb650f0e9c7..1d23a776643dc12dbd60bb9c4cc3661a44c54657 100644 (file)
@@ -79,6 +79,15 @@ ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
    return visit_continue;
 }
 
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_barrier *ir)
+{
+   if (this->callback_enter != NULL)
+      this->callback_enter(ir, this->data_enter);
+
+   return visit_continue;
+}
+
 ir_visitor_status
 ir_hierarchical_visitor::visit_enter(ir_loop *ir)
 {
index faa52fd79c0deeffe7764c0c7addb65d8826f19f..28517b6e4f47c7527d79aaced98c0441a71b4847 100644 (file)
@@ -59,7 +59,7 @@ enum ir_visitor_status {
  * in the composite's \c accept method.  The \c accept method for a leaf-node
  * class will simply call the \c visit method, as usual, and pass its return
  * value on.  The \c accept method for internal-node classes will call the \c
- * visit_enter method, call the \c accpet method of each child node, and,
+ * visit_enter method, call the \c accept method of each child node, and,
  * finally, call the \c visit_leave method.  If any of these return a value
  * other that \c visit_continue, the correct action must be taken.
  *
@@ -87,6 +87,7 @@ public:
    virtual ir_visitor_status visit(class ir_variable *);
    virtual ir_visitor_status visit(class ir_constant *);
    virtual ir_visitor_status visit(class ir_loop_jump *);
+   virtual ir_visitor_status visit(class ir_barrier *);
 
    /**
     * ir_dereference_variable isn't technically a leaf, but it is treated as a
index be5b3eaa00de88c88bc4858316dea42adfce42d5..d3662cf5063e7a08f4c5e8ca9c9c460495013695 100644 (file)
@@ -429,3 +429,9 @@ ir_end_primitive::accept(ir_hierarchical_visitor *v)
 
    return (s == visit_stop) ? s : v->visit_leave(this);
 }
+
+ir_visitor_status
+ir_barrier::accept(ir_hierarchical_visitor *v)
+{
+   return v->visit(this);
+}
index 01f52e85f4a990249d5e19db0a28e6cb5fbade67..4cbcad4ec6154d4151c448d69721ed1d37397a70 100644 (file)
@@ -72,7 +72,7 @@ _mesa_print_ir(FILE *f, exec_list *instructions,
       if (ir->ir_type != ir_type_function)
         fprintf(f, "\n");
    }
-   fprintf(f, "\n)");
+   fprintf(f, ")\n");
 }
 
 void
@@ -161,6 +161,10 @@ void ir_print_visitor::visit(ir_variable *ir)
 {
    fprintf(f, "(declare ");
 
+   char loc[256] = {0};
+   if (ir->data.location != -1)
+      snprintf(loc, sizeof(loc), "location=%i ", ir->data.location);
+
    const char *const cent = (ir->data.centroid) ? "centroid " : "";
    const char *const samp = (ir->data.sample) ? "sample " : "";
    const char *const inv = (ir->data.invariant) ? "invariant " : "";
@@ -172,8 +176,8 @@ void ir_print_visitor::visit(ir_variable *ir)
    const char *const interp[] = { "", "smooth", "flat", "noperspective" };
    STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
 
-   fprintf(f, "(%s%s%s%s%s%s) ",
-           cent, samp, inv, mode[ir->data.mode],
+   fprintf(f, "(%s%s%s%s%s%s%s) ",
+           loc, cent, samp, inv, mode[ir->data.mode],
            stream[ir->data.stream],
            interp[ir->data.interpolation]);
 
@@ -573,5 +577,10 @@ ir_print_visitor::visit(ir_end_primitive *ir)
    fprintf(f, "(end-primitive ");
    ir->stream->accept(this);
    fprintf(f, ")\n");
+}
 
+void
+ir_print_visitor::visit(ir_barrier *ir)
+{
+   fprintf(f, "(barrier)\n");
 }
index 98f041d1a7f9c1736179aebf0c964fef3190a92b..965e63ade8bec07fe8f7bc28a0548cd6d8e4aaec 100644 (file)
@@ -71,6 +71,7 @@ public:
    virtual void visit(ir_loop_jump *);
    virtual void visit(ir_emit_vertex *);
    virtual void visit(ir_end_primitive *);
+   virtual void visit(ir_barrier *);
    /*@}*/
 
 private:
index fd318c046e200436ea32d1d799004a8bca048900..4eae4131c57ff3ccc0d8f11deed00ca7cb5a9043 100644 (file)
@@ -63,6 +63,7 @@ private:
    ir_texture *read_texture(s_expression *);
    ir_emit_vertex *read_emit_vertex(s_expression *);
    ir_end_primitive *read_end_primitive(s_expression *);
+   ir_barrier *read_barrier(s_expression *);
 
    ir_dereference *read_dereference(s_expression *);
    ir_dereference_variable *read_var_ref(s_expression *);
@@ -375,6 +376,8 @@ ir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx)
       inst = read_emit_vertex(list);
    } else if (strcmp(tag->value(), "end-primitive") == 0) {
       inst = read_end_primitive(list);
+   } else if (strcmp(tag->value(), "barrier") == 0) {
+      inst = read_barrier(list);
    } else {
       inst = read_rvalue(list);
       if (inst == NULL)
@@ -1142,3 +1145,15 @@ ir_reader::read_end_primitive(s_expression *expr)
    ir_read_error(NULL, "when reading end-primitive");
    return NULL;
 }
+
+ir_barrier *
+ir_reader::read_barrier(s_expression *expr)
+{
+   s_pattern pat[] = { "barrier" };
+
+   if (MATCH(expr, pat)) {
+      return new(mem_ctx) ir_barrier();
+   }
+   ir_read_error(NULL, "when reading barrier");
+   return NULL;
+}
index 21b5d05c11a03c5d7882552fbda462bb4c6b5415..e1b80147788f32d98bce78df9a0a38c8616deff8 100644 (file)
@@ -181,6 +181,11 @@ struct gl_uniform_storage {
     * via the API.
     */
    bool hidden;
+
+   /**
+    * This is a built-in uniform that should not be modified through any gl API.
+    */
+   bool builtin;
 };
 
 #ifdef __cplusplus
index 40f96ffbca0384a7673396fdf7386be163f78a61..7c38481cd53a8826e44d6ff24135f7c28f77d262 100644 (file)
@@ -65,6 +65,7 @@ public:
    virtual void visit(class ir_loop_jump *) = 0;
    virtual void visit(class ir_emit_vertex *) = 0;
    virtual void visit(class ir_end_primitive *) = 0;
+   virtual void visit(class ir_barrier *) = 0;
    /*@}*/
 };
 
@@ -85,6 +86,7 @@ public:
    virtual void visit(class ir_call *) {}
    virtual void visit(class ir_emit_vertex *) {}
    virtual void visit(class ir_end_primitive *) {}
+   virtual void visit(class ir_barrier *) {}
 };
 #endif /* __cplusplus */
 
index 603873a5d4fda6d1b09215f8bac6ca1237b19a67..100d03c4e8f719826e6aa0a340ad87a4cdf66ea6 100644 (file)
@@ -207,7 +207,7 @@ link_assign_atomic_counter_resources(struct gl_context *ctx,
          storage->atomic_buffer_index = i;
          storage->offset = var->data.atomic.offset;
          storage->array_stride = (var->type->is_array() ?
-                                  var->type->element_type()->atomic_size() : 0);
+                                  var->type->without_array()->atomic_size() : 0);
       }
 
       /* Assign stage-specific fields. */
index 60bfc9c15c9458452c341946b230bc3b5ddbff86..5f57079d1b8ccaf422cf147f7865fedf1c32ffc0 100644 (file)
@@ -104,7 +104,7 @@ void
 set_sampler_binding(gl_shader_program *prog, const char *name, int binding)
 {
    struct gl_uniform_storage *const storage =
-      get_storage(prog->UniformStorage, prog->NumUserUniformStorage, name);
+      get_storage(prog->UniformStorage, prog->NumUniformStorage, name);
 
    if (storage == NULL) {
       assert(storage != NULL);
@@ -194,7 +194,7 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
 
    struct gl_uniform_storage *const storage =
       get_storage(prog->UniformStorage,
-                 prog->NumUserUniformStorage,
+                  prog->NumUniformStorage,
                  name);
    if (storage == NULL) {
       assert(storage != NULL);
index 2c928e1445bd09dfda2aaaffd7249eb47fb6a64b..11ae06f9bfba523748ab708d0449b26def20e83a 100644 (file)
@@ -589,12 +589,13 @@ private:
       handle_samplers(base_type, &this->uniforms[id]);
       handle_images(base_type, &this->uniforms[id]);
 
-      /* If there is already storage associated with this uniform, it means
-       * that it was set while processing an earlier shader stage.  For
-       * example, we may be processing the uniform in the fragment shader, but
-       * the uniform was already processed in the vertex shader.
+      /* If there is already storage associated with this uniform or if the
+       * uniform is set as builtin, it means that it was set while processing
+       * an earlier shader stage.  For example, we may be processing the
+       * uniform in the fragment shader, but the uniform was already processed
+       * in the vertex shader.
        */
-      if (this->uniforms[id].storage != NULL) {
+      if (this->uniforms[id].storage != NULL || this->uniforms[id].builtin) {
          return;
       }
 
@@ -619,10 +620,15 @@ private:
       this->uniforms[id].initialized = 0;
       this->uniforms[id].num_driver_storage = 0;
       this->uniforms[id].driver_storage = NULL;
-      this->uniforms[id].storage = this->values;
       this->uniforms[id].atomic_buffer_index = -1;
       this->uniforms[id].hidden =
          current_var->data.how_declared == ir_var_hidden;
+      this->uniforms[id].builtin = is_gl_identifier(name);
+
+      /* Do not assign storage if the uniform is builtin */
+      if (!this->uniforms[id].builtin)
+         this->uniforms[id].storage = this->values;
+
       if (this->ubo_block_index != -1) {
         this->uniforms[id].block_index = this->ubo_block_index;
 
@@ -894,7 +900,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
 {
    ralloc_free(prog->UniformStorage);
    prog->UniformStorage = NULL;
-   prog->NumUserUniformStorage = 0;
+   prog->NumUniformStorage = 0;
 
    if (prog->UniformHash != NULL) {
       prog->UniformHash->clear();
@@ -940,14 +946,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
         if ((var == NULL) || (var->data.mode != ir_var_uniform))
            continue;
 
-        /* FINISHME: Update code to process built-in uniforms!
-         */
-        if (is_gl_identifier(var->name)) {
-           uniform_size.num_shader_uniform_components +=
-              var->type->component_slots();
-           continue;
-        }
-
         uniform_size.process(var);
       }
 
@@ -962,16 +960,16 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
       }
    }
 
-   const unsigned num_user_uniforms = uniform_size.num_active_uniforms;
+   const unsigned num_uniforms = uniform_size.num_active_uniforms;
    const unsigned num_data_slots = uniform_size.num_values;
 
    /* On the outside chance that there were no uniforms, bail out.
     */
-   if (num_user_uniforms == 0)
+   if (num_uniforms == 0)
       return;
 
    struct gl_uniform_storage *uniforms =
-      rzalloc_array(prog, struct gl_uniform_storage, num_user_uniforms);
+      rzalloc_array(prog, struct gl_uniform_storage, num_uniforms);
    union gl_constant_value *data =
       rzalloc_array(uniforms, union gl_constant_value, num_data_slots);
 #ifndef NDEBUG
@@ -992,11 +990,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
         if ((var == NULL) || (var->data.mode != ir_var_uniform))
            continue;
 
-        /* FINISHME: Update code to process built-in uniforms!
-         */
-        if (is_gl_identifier(var->name))
-           continue;
-
         parcel.set_and_process(prog, var);
       }
 
@@ -1009,10 +1002,10 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
    }
 
    const unsigned hidden_uniforms =
-      move_hidden_uniforms_to_end(prog, uniforms, num_user_uniforms);
+      move_hidden_uniforms_to_end(prog, uniforms, num_uniforms);
 
    /* Reserve all the explicit locations of the active uniforms. */
-   for (unsigned i = 0; i < num_user_uniforms; i++) {
+   for (unsigned i = 0; i < num_uniforms; i++) {
       if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) {
          /* How many new entries for this uniform? */
          const unsigned entries = MAX2(1, uniforms[i].array_elements);
@@ -1028,7 +1021,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
    }
 
    /* Reserve locations for rest of the uniforms. */
-   for (unsigned i = 0; i < num_user_uniforms; i++) {
+   for (unsigned i = 0; i < num_uniforms; i++) {
+
+      /* Built-in uniforms should not get any location. */
+      if (uniforms[i].builtin)
+         continue;
 
       /* Explicit ones have been set already. */
       if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC)
@@ -1055,14 +1052,14 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
    }
 
 #ifndef NDEBUG
-   for (unsigned i = 0; i < num_user_uniforms; i++) {
-      assert(uniforms[i].storage != NULL);
+   for (unsigned i = 0; i < num_uniforms; i++) {
+      assert(uniforms[i].storage != NULL || uniforms[i].builtin);
    }
 
    assert(parcel.values == data_end);
 #endif
 
-   prog->NumUserUniformStorage = num_user_uniforms;
+   prog->NumUniformStorage = num_uniforms;
    prog->NumHiddenUniforms = hidden_uniforms;
    prog->UniformStorage = uniforms;
 
index 605748a9c2aacd35eb9c0db4c687e2bca9c0b8b0..278a778797b8f21ac288f4b787f961f7f543ad2b 100644 (file)
@@ -56,7 +56,7 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
    const glsl_type *type_to_match = input->type;
    if (consumer_stage == MESA_SHADER_GEOMETRY) {
       assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
-      type_to_match = type_to_match->element_type();
+      type_to_match = type_to_match->fields.array;
    }
    if (type_to_match != output->type) {
       /* There is a bit of a special case for gl_TexCoord.  This
@@ -1540,13 +1540,15 @@ check_against_output_limit(struct gl_context *ctx,
    const unsigned output_components = output_vectors * 4;
    if (output_components > max_output_components) {
       if (ctx->API == API_OPENGLES2 || prog->IsES)
-         linker_error(prog, "shader uses too many output vectors "
+         linker_error(prog, "%s shader uses too many output vectors "
                       "(%u > %u)\n",
+                      _mesa_shader_stage_to_string(producer->Stage),
                       output_vectors,
                       max_output_components / 4);
       else
-         linker_error(prog, "shader uses too many output components "
+         linker_error(prog, "%s shader uses too many output components "
                       "(%u > %u)\n",
+                      _mesa_shader_stage_to_string(producer->Stage),
                       output_components,
                       max_output_components);
 
@@ -1579,13 +1581,15 @@ check_against_input_limit(struct gl_context *ctx,
    const unsigned input_components = input_vectors * 4;
    if (input_components > max_input_components) {
       if (ctx->API == API_OPENGLES2 || prog->IsES)
-         linker_error(prog, "shader uses too many input vectors "
+         linker_error(prog, "%s shader uses too many input vectors "
                       "(%u > %u)\n",
+                      _mesa_shader_stage_to_string(consumer->Stage),
                       input_vectors,
                       max_input_components / 4);
       else
-         linker_error(prog, "shader uses too many input components "
+         linker_error(prog, "%s shader uses too many input components "
                       "(%u > %u)\n",
+                      _mesa_shader_stage_to_string(consumer->Stage),
                       input_components,
                       max_input_components);
 
index ea73c6f9da140996e4efbd305d7d030aef5d522d..4a726d4e2e7f2c06a77d3a236ca85f54eb58da0e 100644 (file)
@@ -224,7 +224,7 @@ public:
          return visit_continue;
       }
 
-      var->type = glsl_type::get_array_instance(var->type->element_type(),
+      var->type = glsl_type::get_array_instance(var->type->fields.array,
                                                 this->num_vertices);
       var->data.max_array_access = this->num_vertices - 1;
 
@@ -245,7 +245,7 @@ public:
    {
       const glsl_type *const vt = ir->array->type;
       if (vt->is_array())
-         ir->type = vt->element_type();
+         ir->type = vt->fields.array;
       return visit_continue;
    }
 };
@@ -1400,8 +1400,8 @@ link_fs_input_layout_qualifiers(struct gl_shader_program *prog,
                       "layout qualifiers for gl_FragCoord\n");
       }
 
-      /* Update the linked shader state. Â Note that uses_gl_fragcoord should
-       * accumulate the results. Â The other values should replace. Â If there
+      /* Update the linked shader state.  Note that uses_gl_fragcoord should
+       * accumulate the results.  The other values should replace.  If there
        * are multiple redeclarations, all the fields except uses_gl_fragcoord
        * are already known to be the same.
        */
@@ -2355,6 +2355,13 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
    unsigned total_uniform_blocks = 0;
 
    for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
+      if (prog->UniformBlocks[i].UniformBufferSize > ctx->Const.MaxUniformBlockSize) {
+         linker_error(prog, "Uniform block %s too big (%d/%d)\n",
+                      prog->UniformBlocks[i].Name,
+                      prog->UniformBlocks[i].UniformBufferSize,
+                      ctx->Const.MaxUniformBlockSize);
+      }
+
       for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
         if (prog->UniformBlockStageIndex[j][i] != -1) {
            blocks[j]++;
@@ -2693,13 +2700,23 @@ build_program_resource_list(struct gl_context *ctx,
    }
 
    /* Add uniforms from uniform storage. */
-   for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
+   for (unsigned i = 0; i < shProg->NumUniformStorage; i++) {
       /* Do not add uniforms internally used by Mesa. */
       if (shProg->UniformStorage[i].hidden)
          continue;
 
       uint8_t stageref =
          build_stageref(shProg, shProg->UniformStorage[i].name);
+
+      /* Add stagereferences for uniforms in a uniform block. */
+      int block_index = shProg->UniformStorage[i].block_index;
+      if (block_index != -1) {
+         for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
+             if (shProg->UniformBlockStageIndex[j][block_index] != -1)
+                stageref |= (1 << j);
+         }
+      }
+
       if (!add_program_resource(shProg, GL_UNIFORM,
                                 &shProg->UniformStorage[i], stageref))
          return;
@@ -2819,8 +2836,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
             link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage],
                                     num_shaders[stage]);
 
-         if (!prog->LinkStatus)
+         if (!prog->LinkStatus) {
+            if (sh)
+               ctx->Driver.DeleteShader(ctx, sh);
             goto done;
+         }
 
          switch (stage) {
          case MESA_SHADER_VERTEX:
@@ -2833,8 +2853,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
             validate_fragment_shader_executable(prog, sh);
             break;
          }
-         if (!prog->LinkStatus)
+         if (!prog->LinkStatus) {
+            if (sh)
+               ctx->Driver.DeleteShader(ctx, sh);
             goto done;
+         }
 
          _mesa_reference_shader(ctx, &prog->_LinkedShaders[stage], sh);
       }
index 2d6138d5abde870cd993e5a8748521fc50729604..01f028b1f37ce2bf2f4091ed7a06004d6a03d60f 100644 (file)
@@ -114,7 +114,7 @@ lower_clip_distance_visitor::visit(ir_variable *ir)
       return visit_continue;
    assert (ir->type->is_array());
 
-   if (!ir->type->element_type()->is_array()) {
+   if (!ir->type->fields.array->is_array()) {
       /* 1D gl_ClipDistance (used for vertex and geometry output, and fragment
        * input).
        */
@@ -123,7 +123,7 @@ lower_clip_distance_visitor::visit(ir_variable *ir)
 
       this->progress = true;
       this->old_clip_distance_1d_var = ir;
-      assert (ir->type->element_type() == glsl_type::float_type);
+      assert (ir->type->fields.array == glsl_type::float_type);
       unsigned new_size = (ir->type->array_size() + 3) / 4;
 
       /* Clone the old var so that we inherit all of its properties */
@@ -148,8 +148,8 @@ lower_clip_distance_visitor::visit(ir_variable *ir)
 
       this->progress = true;
       this->old_clip_distance_2d_var = ir;
-      assert (ir->type->element_type()->element_type() == glsl_type::float_type);
-      unsigned new_size = (ir->type->element_type()->array_size() + 3) / 4;
+      assert (ir->type->fields.array->fields.array == glsl_type::float_type);
+      unsigned new_size = (ir->type->fields.array->array_size() + 3) / 4;
 
       /* Clone the old var so that we inherit all of its properties */
       this->new_clip_distance_2d_var = ir->clone(ralloc_parent(ir), NULL);
index fc54ddd7eb14b3d0d672bf0d32b30596337a91b6..23412980dce1ba3570314ae5e5700b02d98f4826 100644 (file)
@@ -276,7 +276,7 @@ usage_fail(const char *name)
       "usage: %s [options] <file.vert | file.geom | file.frag>\n"
       "\n"
       "Possible options are:\n";
-   printf(header, name, name);
+   printf(header, name);
    for (const struct option *o = compiler_opts; o->name != 0; ++o) {
       printf("    --%s\n", o->name);
    }
index 7c30be3fa720ff25a72f4ac0601243c28f502ef1..0338af67567e537dfb2a00a19e67493706ce5b10 100644 (file)
@@ -65,6 +65,7 @@ public:
    virtual void visit(ir_dereference_variable *);
    virtual void visit(ir_dereference_record *);
    virtual void visit(ir_dereference_array *);
+   virtual void visit(ir_barrier *);
 
    void create_function(ir_function *ir);
 
@@ -615,27 +616,135 @@ nir_visitor::visit(ir_call *ir)
          op = nir_intrinsic_atomic_counter_inc_var;
       } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_predecrement") == 0) {
          op = nir_intrinsic_atomic_counter_dec_var;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_load") == 0) {
+         op = nir_intrinsic_image_load;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_store") == 0) {
+         op = nir_intrinsic_image_store;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_add") == 0) {
+         op = nir_intrinsic_image_atomic_add;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_min") == 0) {
+         op = nir_intrinsic_image_atomic_min;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_max") == 0) {
+         op = nir_intrinsic_image_atomic_max;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_and") == 0) {
+         op = nir_intrinsic_image_atomic_and;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_or") == 0) {
+         op = nir_intrinsic_image_atomic_or;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_xor") == 0) {
+         op = nir_intrinsic_image_atomic_xor;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_exchange") == 0) {
+         op = nir_intrinsic_image_atomic_exchange;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_comp_swap") == 0) {
+         op = nir_intrinsic_image_atomic_comp_swap;
+      } else if (strcmp(ir->callee_name(), "__intrinsic_memory_barrier") == 0) {
+         op = nir_intrinsic_memory_barrier;
       } else {
          unreachable("not reached");
       }
 
       nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op);
-      ir_dereference *param =
-         (ir_dereference *) ir->actual_parameters.get_head();
-      instr->variables[0] = evaluate_deref(&instr->instr, param);
-      nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
+
+      switch (op) {
+      case nir_intrinsic_atomic_counter_read_var:
+      case nir_intrinsic_atomic_counter_inc_var:
+      case nir_intrinsic_atomic_counter_dec_var: {
+         ir_dereference *param =
+            (ir_dereference *) ir->actual_parameters.get_head();
+         instr->variables[0] = evaluate_deref(&instr->instr, param);
+         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
+         break;
+      }
+      case nir_intrinsic_image_load:
+      case nir_intrinsic_image_store:
+      case nir_intrinsic_image_atomic_add:
+      case nir_intrinsic_image_atomic_min:
+      case nir_intrinsic_image_atomic_max:
+      case nir_intrinsic_image_atomic_and:
+      case nir_intrinsic_image_atomic_or:
+      case nir_intrinsic_image_atomic_xor:
+      case nir_intrinsic_image_atomic_exchange:
+      case nir_intrinsic_image_atomic_comp_swap: {
+         nir_ssa_undef_instr *instr_undef =
+            nir_ssa_undef_instr_create(shader, 1);
+         nir_instr_insert_after_cf_list(this->cf_node_list,
+                                        &instr_undef->instr);
+
+         /* Set the image variable dereference. */
+         exec_node *param = ir->actual_parameters.get_head();
+         ir_dereference *image = (ir_dereference *)param;
+         const glsl_type *type =
+            image->variable_referenced()->type->without_array();
+
+         instr->variables[0] = evaluate_deref(&instr->instr, image);
+         param = param->get_next();
+
+         /* Set the address argument, extending the coordinate vector to four
+          * components.
+          */
+         const nir_src src_addr = evaluate_rvalue((ir_dereference *)param);
+         nir_alu_instr *instr_addr = nir_alu_instr_create(shader, nir_op_vec4);
+         nir_ssa_dest_init(&instr_addr->instr, &instr_addr->dest.dest, 4, NULL);
+
+         for (int i = 0; i < 4; i++) {
+            if (i < type->coordinate_components()) {
+               instr_addr->src[i].src = src_addr;
+               instr_addr->src[i].swizzle[0] = i;
+            } else {
+               instr_addr->src[i].src = nir_src_for_ssa(&instr_undef->def);
+            }
+         }
+
+         nir_instr_insert_after_cf_list(cf_node_list, &instr_addr->instr);
+         instr->src[0] = nir_src_for_ssa(&instr_addr->dest.dest.ssa);
+         param = param->get_next();
+
+         /* Set the sample argument, which is undefined for single-sample
+          * images.
+          */
+         if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) {
+            instr->src[1] = evaluate_rvalue((ir_dereference *)param);
+            param = param->get_next();
+         } else {
+            instr->src[1] = nir_src_for_ssa(&instr_undef->def);
+         }
+
+         /* Set the intrinsic parameters. */
+         if (!param->is_tail_sentinel()) {
+            instr->src[2] = evaluate_rvalue((ir_dereference *)param);
+            param = param->get_next();
+         }
+
+         if (!param->is_tail_sentinel()) {
+            instr->src[3] = evaluate_rvalue((ir_dereference *)param);
+            param = param->get_next();
+         }
+
+         /* Set the intrinsic destination. */
+         if (ir->return_deref)
+            nir_ssa_dest_init(&instr->instr, &instr->dest,
+                              ir->return_deref->type->vector_elements, NULL);
+         break;
+      }
+      case nir_intrinsic_memory_barrier:
+         break;
+      default:
+         unreachable("not reached");
+      }
 
       nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
 
-      nir_intrinsic_instr *store_instr =
-         nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
-      store_instr->num_components = 1;
+      if (ir->return_deref) {
+         nir_intrinsic_instr *store_instr =
+            nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
+         store_instr->num_components = ir->return_deref->type->vector_elements;
 
-      store_instr->variables[0] = evaluate_deref(&store_instr->instr, ir->return_deref);
-      store_instr->src[0].is_ssa = true;
-      store_instr->src[0].ssa = &instr->dest.ssa;
+         store_instr->variables[0] =
+            evaluate_deref(&store_instr->instr, ir->return_deref);
+         store_instr->src[0] = nir_src_for_ssa(&instr->dest.ssa);
 
-      nir_instr_insert_after_cf_list(this->cf_node_list, &store_instr->instr);
+         nir_instr_insert_after_cf_list(this->cf_node_list,
+                                        &store_instr->instr);
+      }
 
       return;
    }
@@ -823,13 +932,9 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir)
    }
 
    nir_dest *dest = get_instr_dest(this->result);
-
    assert(dest->is_ssa);
-   nir_src src = NIR_SRC_INIT;
-   src.is_ssa = true;
-   src.ssa = &dest->ssa;
 
-   return src;
+   return nir_src_for_ssa(&dest->ssa);
 }
 
 nir_alu_instr *
@@ -1786,3 +1891,11 @@ nir_visitor::visit(ir_dereference_array *ir)
    ralloc_steal(this->deref_tail, deref);
    this->deref_tail = &deref->deref;
 }
+
+void
+nir_visitor::visit(ir_barrier *ir)
+{
+   nir_intrinsic_instr *instr =
+      nir_intrinsic_instr_create(this->shader, nir_intrinsic_barrier);
+   nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
+}
index 8e28765c13a4d34e7018f678984903db89e57267..bc6e6b8f4985cdaba9dba00d5542ebce26bc85ee 100644 (file)
@@ -67,7 +67,15 @@ INTRINSIC(interp_var_at_offset, 1, ARR(2), true, 0, 1, 0,
  */
 #define BARRIER(name) INTRINSIC(name, 0, ARR(), false, 0, 0, 0, 0)
 
+BARRIER(barrier)
 BARRIER(discard)
+
+/*
+ * Memory barrier with semantics analogous to the memoryBarrier() GLSL
+ * intrinsic.
+ */
+BARRIER(memory_barrier)
+
 /** A conditional discard, with a single boolean source. */
 INTRINSIC(discard_if, 1, ARR(1), false, 0, 0, 0, 0)
 
@@ -89,6 +97,33 @@ ATOMIC(inc, 0)
 ATOMIC(dec, 0)
 ATOMIC(read, NIR_INTRINSIC_CAN_ELIMINATE)
 
+/*
+ * Image load, store and atomic intrinsics.
+ *
+ * All image intrinsics take an image target passed as a nir_variable.  Image
+ * variables contain a number of memory and layout qualifiers that influence
+ * the semantics of the intrinsic.
+ *
+ * All image intrinsics take a four-coordinate vector and a sample index as
+ * first two sources, determining the location within the image that will be
+ * accessed by the intrinsic.  Components not applicable to the image target
+ * in use are undefined.  Image store takes an additional four-component
+ * argument with the value to be written, and image atomic operations take
+ * either one or two additional scalar arguments with the same meaning as in
+ * the ARB_shader_image_load_store specification.
+ */
+INTRINSIC(image_load, 2, ARR(4, 1), true, 4, 1, 0,
+          NIR_INTRINSIC_CAN_ELIMINATE)
+INTRINSIC(image_store, 3, ARR(4, 1, 4), false, 0, 1, 0, 0)
+INTRINSIC(image_atomic_add, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_min, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_max, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_and, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_or, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_xor, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_exchange, 3, ARR(4, 1, 1), true, 1, 1, 0, 0)
+INTRINSIC(image_atomic_comp_swap, 4, ARR(4, 1, 1, 1), true, 1, 1, 0, 0)
+
 #define SYSTEM_VALUE(name, components) \
    INTRINSIC(load_##name, 0, ARR(), true, components, 0, 0, \
    NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
@@ -104,12 +139,11 @@ SYSTEM_VALUE(sample_mask_in, 1)
 SYSTEM_VALUE(invocation_id, 1)
 
 /*
- * The first index is the address to load from, and the second index is the
- * number of array elements to load.  Indirect loads have an additional
- * register input, which is added to the constant address to compute the
- * final address to load from.  For UBO's (and SSBO's), the first source is
- * the (possibly constant) UBO buffer index and the indirect (if it exists)
- * is the second source.
+ * The first and only index is the base address to load from.  Indirect
+ * loads have an additional register input, which is added to the constant
+ * address to compute the final address to load from.  For UBO's (and
+ * SSBO's), the first source is the (possibly constant) UBO buffer index
+ * and the indirect (if it exists) is the second source.
  *
  * For vector backends, the address is in terms of one vec4, and so each array
  * element is +4 scalar components from the previous array element. For scalar
@@ -118,9 +152,9 @@ SYSTEM_VALUE(invocation_id, 1)
  */
 
 #define LOAD(name, extra_srcs, flags) \
-   INTRINSIC(load_##name, extra_srcs, ARR(1), true, 0, 0, 2, flags) \
+   INTRINSIC(load_##name, extra_srcs, ARR(1), true, 0, 0, 1, flags) \
    INTRINSIC(load_##name##_indirect, extra_srcs + 1, ARR(1, 1), \
-             true, 0, 0, 2, flags)
+             true, 0, 0, 1, flags)
 
 LOAD(uniform, 0, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 LOAD(ubo, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
@@ -138,7 +172,7 @@ LOAD(input, 0, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
    INTRINSIC(store_##name##_indirect, 2, ARR(0, 1), false, 0, 0, \
              num_indices, flags) \
 
-STORE(output, 2, 0)
-/* STORE(ssbo, 3, 0) */
+STORE(output, 1, 0)
+/* STORE(ssbo, 2, 0) */
 
 LAST_INTRINSIC(store_output_indirect)
index e82df0169694ac5fe88a339c89801bfa943192a9..0457de60d9a66dcfc6e316c49e414e82b99d22ee 100644 (file)
@@ -78,7 +78,8 @@ lower_instr(nir_intrinsic_instr *instr, nir_function_impl *impl)
          nir_deref_as_array(instr->variables[0]->deref.child);
       assert(deref_array->deref.child == NULL);
 
-      offset_const->value.u[0] += deref_array->base_offset;
+      offset_const->value.u[0] +=
+         deref_array->base_offset * ATOMIC_COUNTER_SIZE;
 
       if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
          nir_load_const_instr *atomic_counter_size =
@@ -108,7 +109,7 @@ lower_instr(nir_intrinsic_instr *instr, nir_function_impl *impl)
    }
 
    new_instr->src[0].is_ssa = true;
-   new_instr->src[0].ssa = offset_def;;
+   new_instr->src[0].ssa = offset_def;
 
    if (instr->dest.is_ssa) {
       nir_ssa_dest_init(&new_instr->instr, &new_instr->dest,
index 561bebd3a9c114a585255b4706bb06de6cac7cff..4c59298ecb7ccf332f29679621187b6ac93258bf 100644 (file)
@@ -289,7 +289,6 @@ nir_lower_io_block(nir_block *block, void *void_state)
          offset += intrin->variables[0]->var->data.driver_location;
 
          load->const_index[0] = offset;
-         load->const_index[1] = 1;
 
          if (has_indirect)
             load->src[0] = indirect;
@@ -332,7 +331,6 @@ nir_lower_io_block(nir_block *block, void *void_state)
          offset += intrin->variables[0]->var->data.driver_location;
 
          store->const_index[0] = offset;
-         store->const_index[1] = 1;
 
          nir_src_copy(&store->src[0], &intrin->src[0], state->mem_ctx);
 
index 4bdb80072ab5ecdea514d706ab05b71195aaad29..a57d253975df1543e46c0bc159dc6474cdb415cc 100644 (file)
@@ -153,6 +153,11 @@ should_lower_phi(nir_phi_instr *phi, struct lower_phis_to_scalar_state *state)
          break;
    }
 
+   /* The hash table entry for 'phi' may have changed while recursing the
+    * dependence graph, so we need to reset it */
+   entry = _mesa_hash_table_search(state->phi_table, phi);
+   assert(entry);
+
    entry->data = (void *)(intptr_t)scalarizable;
 
    return scalarizable;
index 6ed5a4cb2b5814c65b558b8ea5735299e880f479..9a9cdd16a9ac1be49a439b8ae2a00e4f3ead75a9 100644 (file)
@@ -94,34 +94,45 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
       case nir_deref_type_array: {
          nir_deref_array *deref_array = nir_deref_as_array(deref->child);
 
+         assert(deref_array->deref_array_type != nir_deref_array_type_wildcard);
+
+         if (deref_array->deref.child) {
+            ralloc_asprintf_append(&name, "[%u]",
+               deref_array->deref_array_type == nir_deref_array_type_direct ?
+                  deref_array->base_offset : 0);
+         } else {
+            assert(deref->child->type->base_type == GLSL_TYPE_SAMPLER);
+            instr->sampler_index = deref_array->base_offset;
+         }
+
          /* XXX: We're assuming here that the indirect is the last array
           * thing we have.  This should be ok for now as we don't support
           * arrays_of_arrays yet.
           */
-
-         instr->sampler_index *= glsl_get_length(deref->type);
-         switch (deref_array->deref_array_type) {
-         case nir_deref_array_type_direct:
-            instr->sampler_index += deref_array->base_offset;
-            if (deref_array->deref.child)
-               ralloc_asprintf_append(&name, "[%u]", deref_array->base_offset);
-            break;
-         case nir_deref_array_type_indirect: {
-            add_indirect_to_tex(instr, deref_array->indirect);
-            nir_instr_rewrite_src(&instr->instr, &deref_array->indirect,
-                                  NIR_SRC_INIT);
+         if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
+            /* First, we have to resize the array of texture sources */
+            nir_tex_src *new_srcs = rzalloc_array(instr, nir_tex_src,
+                                                  instr->num_srcs + 1);
+
+            for (unsigned i = 0; i < instr->num_srcs; i++) {
+               new_srcs[i].src_type = instr->src[i].src_type;
+               nir_instr_move_src(&instr->instr, &new_srcs[i].src,
+                                  &instr->src[i].src);
+            }
+
+            ralloc_free(instr->src);
+            instr->src = new_srcs;
+
+            /* Now we can go ahead and move the source over to being a
+             * first-class texture source.
+             */
+            instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset;
+            instr->num_srcs++;
+            nir_instr_move_src(&instr->instr,
+                               &instr->src[instr->num_srcs - 1].src,
+                               &deref_array->indirect);
 
             instr->sampler_array_size = glsl_get_length(deref->type);
-
-            if (deref_array->deref.child)
-               ralloc_strcat(&name, "[0]");
-            break;
-         }
-
-         case nir_deref_array_type_wildcard:
-            unreachable("Cannot copy samplers");
-         default:
-            unreachable("Invalid deref array type");
          }
          break;
       }
index fa039222fd2890327605f973509e91a128a0b1a1..eace791f5b0c5fec749f5174c86f01dabb7ff7cc 100644 (file)
@@ -156,6 +156,8 @@ optimizations = [
    (('fpow', a, 2.0), ('fmul', a, a)),
    (('fpow', a, 4.0), ('fmul', ('fmul', a, a), ('fmul', a, a))),
    (('fpow', 2.0, a), ('fexp2', a)),
+   (('fpow', ('fpow', a, 2.2), 0.454545), a),
+   (('fpow', ('fabs', ('fpow', a, 2.2)), 0.454545), ('fabs', a)),
    (('fsqrt', ('fexp2', a)), ('fexp2', ('fmul', 0.5, a))),
    (('frcp', ('fexp2', a)), ('fexp2', ('fneg', a))),
    (('frsq', ('fexp2', a)), ('fexp2', ('fmul', -0.5, a))),
index b430eac8eab2c591bc0418af761744d05a9b0562..798506b7595b18e8f8ab7792adb406bb1f30190c 100644 (file)
@@ -73,7 +73,8 @@ are_all_uses_fadd(nir_ssa_def *def)
 }
 
 static nir_alu_instr *
-get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs)
+get_mul_for_src(nir_alu_src *src, int num_components,
+                uint8_t swizzle[4], bool *negate, bool *abs)
 {
    assert(src->src.is_ssa && !src->abs && !src->negate);
 
@@ -85,16 +86,16 @@ get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs)
    switch (alu->op) {
    case nir_op_imov:
    case nir_op_fmov:
-      alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs);
+      alu = get_mul_for_src(&alu->src[0], num_components, swizzle, negate, abs);
       break;
 
    case nir_op_fneg:
-      alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs);
+      alu = get_mul_for_src(&alu->src[0], num_components, swizzle, negate, abs);
       *negate = !*negate;
       break;
 
    case nir_op_fabs:
-      alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs);
+      alu = get_mul_for_src(&alu->src[0], num_components, swizzle, negate, abs);
       *negate = false;
       *abs = true;
       break;
@@ -115,12 +116,8 @@ get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs)
    if (!alu)
       return NULL;
 
-   for (unsigned i = 0; i < 4; i++) {
-      if (!(alu->dest.write_mask & (1 << i)))
-         break;
-
+   for (unsigned i = 0; i < num_components; i++)
       swizzle[i] = swizzle[src->swizzle[i]];
-   }
 
    return alu;
 }
@@ -160,7 +157,9 @@ nir_opt_peephole_ffma_block(nir_block *block, void *void_state)
          negate = false;
          abs = false;
 
-         mul = get_mul_for_src(&add->src[add_mul_src], swizzle, &negate, &abs);
+         mul = get_mul_for_src(&add->src[add_mul_src],
+                               add->dest.dest.ssa.num_components,
+                               swizzle, &negate, &abs);
 
          if (mul != NULL)
             break;
index 82c65bb442fa1724ff641e5a719ec3f05a45ff30..ef7c9775aa3071b3c4c4beb489a65007d6777f1c 100644 (file)
@@ -86,7 +86,9 @@ block_check_for_allowed_instrs(nir_block *block)
          nir_alu_instr *mov = nir_instr_as_alu(instr);
          if (mov->op != nir_op_fmov && mov->op != nir_op_imov &&
              mov->op != nir_op_fneg && mov->op != nir_op_ineg &&
-             mov->op != nir_op_fabs && mov->op != nir_op_iabs)
+             mov->op != nir_op_fabs && mov->op != nir_op_iabs &&
+             mov->op != nir_op_vec2 && mov->op != nir_op_vec3 &&
+             mov->op != nir_op_vec4)
             return false;
 
          /* Can't handle saturate */
index 6e1ecec32350d4a6f46ca686ad094314b88144d2..050e733d549cc3adf9b025e8d36f7502f23f1b40 100644 (file)
@@ -95,7 +95,7 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
 {
    unsigned i;
 
-   shProg->NumUserUniformStorage = 0;
+   shProg->NumUniformStorage = 0;
    shProg->UniformStorage = NULL;
    shProg->NumUniformRemapTable = 0;
    shProg->UniformRemapTable = NULL;
diff --git a/src/glsl/tests/common.c b/src/glsl/tests/common.c
deleted file mode 100644 (file)
index d69f54d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright Â© 2014 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <stdio.h>
-#include "main/errors.h"
-
-void
-_mesa_error_no_memory(const char *caller)
-{
-   fprintf(stderr, "Mesa error: out of memory in %s", caller);
-}
index d3fdeb3a844e2386fe36b12f11d8534e4a32fd70..91227d9487af5fc6957cad3317d9579476778809 100644 (file)
@@ -110,7 +110,7 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
 
    prog->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage,
                                        num_storage);
-   prog->NumUserUniformStorage = num_storage;
+   prog->NumUniformStorage = num_storage;
 
    prog->UniformStorage[index_to_set].name = (char *) name;
    prog->UniformStorage[index_to_set].type = type;
@@ -155,7 +155,7 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
 static void
 verify_initialization(struct gl_shader_program *prog, unsigned actual_index)
 {
-   for (unsigned i = 0; i < prog->NumUserUniformStorage; i++) {
+   for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
       if (i == actual_index) {
         EXPECT_TRUE(prog->UniformStorage[actual_index].initialized);
       } else {
index b91c0bdd7585afb31c62ccc911378db991fb1d79..619e4c373ed533d43c9df6f50a4ede55cd594b56 100644 (file)
@@ -125,7 +125,7 @@ env.CodeGenerate(
     target = 'indirect_size.h',
     script = GLAPI + 'gen/glX_proto_size.py',
     source = sources,
-    command = python_cmd + ' $SCRIPT -f $SOURCE -m size_h --only-set -h _INDIRECT_SIZE_H > $TARGET'
+    command = python_cmd + ' $SCRIPT -f $SOURCE -m size_h --only-set --header-tag _INDIRECT_SIZE_H > $TARGET'
 )
 
 env.CodeGenerate(
index 538cf1adb828f45009b77dc5963fcc9ff3e6203d..27ea9521e50a68df780c047ad3ec9178089f05ea 100644 (file)
@@ -1183,15 +1183,7 @@ dri2CreateScreen(int screen, struct glx_display * priv)
       return NULL;
    }
 
-#ifdef O_CLOEXEC
-   psc->fd = open(deviceName, O_RDWR | O_CLOEXEC);
-   if (psc->fd == -1 && errno == EINVAL)
-#endif
-   {
-      psc->fd = open(deviceName, O_RDWR);
-      if (psc->fd != -1)
-         fcntl(psc->fd, F_SETFD, fcntl(psc->fd, F_GETFD) | FD_CLOEXEC);
-   }
+   psc->fd = loader_open_device(deviceName);
    if (psc->fd < 0) {
       ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
       goto handle_error;
index ff77a91b15f6562cdd5480fee9630e562d53997a..dfb0093395f75488947cd2ca5df70d91f8896573 100644 (file)
@@ -1985,6 +1985,11 @@ dri3_create_screen(int screen, struct glx_display * priv)
       goto handle_error;
    }
 
+   if (psc->is_different_gpu && !psc->image->blitImage) {
+      ErrorMessageF("Different GPU, but blitImage not implemented for this driver\n");
+      goto handle_error;
+   }
+
    if (!psc->is_different_gpu && (
        !psc->texBuffer || psc->texBuffer->base.version < 2 ||
        !psc->texBuffer->setTexBuffer2
index 46b91d57c4990a3c8e2c3e231d7e313a2a51ccb0..a1e9053617c916d346adbc5808c95218e6172615 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000-2012 Haiku, Inc. All Rights Reserved.
+ * Copyright 2000-2015 Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  */
 
 
-extern "C" {
 #include "glapi/glapi.h"
 #include "glapi/glapi_priv.h"
 
+
+extern "C" {
 /*
  * NOTE: this file portion implements C-based dispatch of the OpenGL entrypoints
  * (glAccum, glBegin, etc).
index 44bca8ce5863ca435b7c0f6a8367ec2b1d2403a6..7ee095d917b75dcdc0f0a76c19813c8dd6330e3d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000-2012 Haiku, Inc. All Rights Reserved.
+ * Copyright 2000-2015 Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -17,9 +17,7 @@
 
 #include "glheader.h"
 
-extern "C" {
 #include "glapi/glapi.h"
-}
 
 
 class BGLDispatcher
index 70db1494df80cb1ac2b7c3f26e91aa8cb9aa0bb8..71881f504c98bc74bc49378120b3c835adcace91 100644 (file)
@@ -6,6 +6,7 @@ Import('*')
 env = env.Clone()
 
 env.Append(CPPPATH = [
+    '#/src',
     '#/src/mapi',
     '#/src/mesa',
     '#/src/mesa/main',
index 8e215de3cda0ad79f19e868c927f850bb9bbe46a..92d9fd20d3c65a85b1ee5009e430b6f988c66885 100644 (file)
@@ -40,6 +40,8 @@ else
 LOCAL_SHARED_LIBRARIES := libdrm
 endif
 
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
 LOCAL_MODULE := libmesa_loader
 
 include $(MESA_COMMON_MK)
index 36ddba82bd39daf57312ce86779615d8e8ae34cc..aef1bd61beab78bbddf6f5a02129cd8d98650bdb 100644 (file)
@@ -41,15 +41,11 @@ libloader_la_CPPFLAGS += \
        -I$(top_builddir)/src/mesa/drivers/dri/common/ \
        -I$(top_srcdir)/src/mesa/ \
        -I$(top_srcdir)/src/mapi/ \
-       -DUSE_DRICONF \
-       $(EXPAT_CFLAGS)
+       -DUSE_DRICONF
 
-libloader_la_SOURCES += \
-       $(top_srcdir)/src/mesa/drivers/dri/common/xmlconfig.c
+ libloader_la_LIBADD += \
+       $(top_builddir)/src/mesa/drivers/dri/common/libxmlconfig.la
 
-libloader_la_LIBADD += \
-       -lm \
-       $(EXPAT_LIBS)
 endif
 
 if !HAVE_LIBDRM
index 17bf13360057f11a43ce903e00f66261507c38bb..fc468153425029916c68d9ce2d9ab13a689c64ed 100644 (file)
@@ -314,8 +314,8 @@ get_id_path_tag_from_fd(struct udev *udev, int fd)
    return id_path_tag;
 }
 
-static int
-drm_open_device(const char *device_name)
+int
+loader_open_device(const char *device_name)
 {
    int fd;
 #ifdef O_CLOEXEC
@@ -404,7 +404,7 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
       goto default_device_clean;
    }
 
-   fd = drm_open_device(device_name);
+   fd = loader_open_device(device_name);
    if (fd >= 0) {
       close(default_fd);
    } else {
index 810e7da7f9f280ff78a15e933b7be5ab6a0291fd..055dc786892113ca61c9522796ee63bae1f8010b 100644 (file)
 #ifndef LOADER_H
 #define LOADER_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Helpers to figure out driver and device name, eg. from pci-id, etc. */
 
 #define _LOADER_DRI          (1 << 0)
 #define _LOADER_GALLIUM      (1 << 1)
 
+int
+loader_open_device(const char *);
+
 int
 loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
 
@@ -61,4 +68,9 @@ loader_get_user_preferred_fd(int default_fd, int *different_device);
 void
 loader_set_logger(void (*logger)(int level, const char *fmt, ...));
 
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LOADER_H */
index b96b263db03df5760c72f685dfe4f7b686e4b36f..41b5208388391acba409d9e22091ccedec0a765a 100644 (file)
@@ -5,13 +5,13 @@
 
 <category name="GL_AMD_performance_monitor" number="360">
 
-    <function name="GetPerfMonitorGroupsAMD" offset="assign">
+    <function name="GetPerfMonitorGroupsAMD">
         <param name="numGroups" type="GLint *"/>
         <param name="groupsSize" type="GLsizei"/>
         <param name="groups" type="GLuint *"/>
     </function>
 
-    <function name="GetPerfMonitorCountersAMD" offset="assign">
+    <function name="GetPerfMonitorCountersAMD">
         <param name="group" type="GLuint"/>
         <param name="numCounters" type="GLint *"/>
         <param name="maxActiveCounters" type="GLint *"/>
         <param name="counters" type="GLuint *"/>
     </function>
 
-    <function name="GetPerfMonitorGroupStringAMD" offset="assign">
+    <function name="GetPerfMonitorGroupStringAMD">
         <param name="group" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *"/>
         <param name="groupString" type="GLchar *"/>
     </function>
 
-    <function name="GetPerfMonitorCounterStringAMD" offset="assign">
+    <function name="GetPerfMonitorCounterStringAMD">
         <param name="group" type="GLuint"/>
         <param name="counter" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="counterString" type="GLchar *"/>
     </function>
 
-    <function name="GetPerfMonitorCounterInfoAMD" offset="assign">
+    <function name="GetPerfMonitorCounterInfoAMD">
         <param name="group" type="GLuint"/>
         <param name="counter" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="data" type="GLvoid *"/>
     </function>
 
-    <function name="GenPerfMonitorsAMD" offset="assign">
+    <function name="GenPerfMonitorsAMD">
         <param name="n" type="GLsizei"/>
         <param name="monitors" type="GLuint *"/>
     </function>
 
-    <function name="DeletePerfMonitorsAMD" offset="assign">
+    <function name="DeletePerfMonitorsAMD">
         <param name="n" type="GLsizei"/>
         <param name="monitors" type="GLuint *"/>
     </function>
 
-    <function name="SelectPerfMonitorCountersAMD" offset="assign">
+    <function name="SelectPerfMonitorCountersAMD">
         <param name="monitor" type="GLuint"/>
         <param name="enable" type="GLboolean"/>
         <param name="group" type="GLuint"/>
         <param name="counterList" type="GLuint *"/>
     </function>
 
-    <function name="BeginPerfMonitorAMD" offset="assign">
+    <function name="BeginPerfMonitorAMD">
         <param name="monitor" type="GLuint"/>
     </function>
 
-    <function name="EndPerfMonitorAMD" offset="assign">
+    <function name="EndPerfMonitorAMD">
         <param name="monitor" type="GLuint"/>
     </function>
 
-    <function name="GetPerfMonitorCounterDataAMD" offset="assign">
+    <function name="GetPerfMonitorCounterDataAMD">
         <param name="monitor" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="dataSize" type="GLsizei"/>
index 62fa64ad2126883a65fe64455e7210b246bfc434..829fc263156486e242c27b387fc7ce166a7e47fa 100644 (file)
 
     <enum name="BUFFER_OBJECT_APPLE"          value="0x85B3"/>
 
-    <function name="ObjectPurgeableAPPLE" offset="assign">
+    <function name="ObjectPurgeableAPPLE">
         <param name="objectType" type="GLenum"/>
         <param name="name" type="GLuint"/>
         <param name="option" type="GLenum"/>
        <return type="GLenum"/>
     </function>
 
-    <function name="ObjectUnpurgeableAPPLE" offset="assign">
+    <function name="ObjectUnpurgeableAPPLE">
         <param name="objectType" type="GLenum"/>
         <param name="name" type="GLuint"/>
         <param name="option" type="GLenum"/>
        <return type="GLenum"/>
     </function>
 
-    <function name="GetObjectParameterivAPPLE" offset="assign">
+    <function name="GetObjectParameterivAPPLE">
         <param name="objectType" type="GLenum"/>
         <param name="name" type="GLuint"/>
         <param name="pname" type="GLenum"/>
index 5eb53b14e9f9062b0018ca57108f4321533d66f4..7312f9b35f05af21eb7909d0374525df89378bf9 100644 (file)
@@ -5,23 +5,21 @@
 <category name="GL_APPLE_vertex_array_object" number="273">
     <enum name="VERTEX_ARRAY_BINDING_APPLE"               value="0x85B5"/>
 
-    <function name="BindVertexArrayAPPLE" offset="assign"
-              static_dispatch="false" deprecated="3.1">
+    <function name="BindVertexArrayAPPLE" deprecated="3.1">
         <param name="array" type="GLuint"/>
     </function>
 
-    <function name="DeleteVertexArraysAPPLE" static_dispatch="false" alias="DeleteVertexArrays">
+    <function name="DeleteVertexArraysAPPLE" alias="DeleteVertexArrays">
         <param name="n" type="GLsizei"/>
        <param name="arrays" type="const GLuint *"/>
     </function>
 
-    <function name="GenVertexArraysAPPLE" offset="assign"
-              static_dispatch="false" deprecated="3.1">
+    <function name="GenVertexArraysAPPLE" deprecated="3.1">
         <param name="n" type="GLsizei"/>
        <param name="arrays" type="GLuint *" count="n" output="true"/>
     </function>
 
-    <function name="IsVertexArrayAPPLE" static_dispatch="false" alias="IsVertexArray">
+    <function name="IsVertexArrayAPPLE" alias="IsVertexArray">
         <param name="array" type="GLuint"/>
        <return type="GLboolean"/>
     </function>
index d157366122b3d8e6eb0fecf111f4a36d05884a85..c96e71c44f287a8ee435663bc4bf3cc3043f344b 100644 (file)
     <enum name="MAX_VARYING_VECTORS"                          value="0x8DFC"/>
     <enum name="MAX_FRAGMENT_UNIFORM_VECTORS"                 value="0x8DFD"/>
 
-    <function name="GetShaderPrecisionFormat" offset="assign" es2="2.0">
+    <function name="GetShaderPrecisionFormat" es2="2.0">
         <param name="shadertype" type="GLenum"/>
         <param name="precisiontype" type="GLenum"/>
         <param name="range" type="GLint *"/>
         <param name="precision" type="GLint *"/>
     </function>
 
-    <function name="ReleaseShaderCompiler" offset="assign" es2="2.0">
+    <function name="ReleaseShaderCompiler" es2="2.0">
     </function>
 
-    <function name="ShaderBinary" offset="assign" es2="2.0">
+    <function name="ShaderBinary" es2="2.0">
         <param name="n" type="GLsizei"/>
         <param name="shaders" type="const GLuint *"/>
         <param name="binaryformat" type="GLenum"/>
     <enum name="IMPLEMENTATION_COLOR_READ_FORMAT"         value="0x8B9B"/>
 
     <!-- from GL_OES_single_precision -->
-    <function name="ClearDepthf" offset="assign" es1="1.0" es2="2.0">
+    <function name="ClearDepthf" es1="1.0" es2="2.0">
         <param name="depth" type="GLclampf"/>
     </function>
 
-    <function name="DepthRangef" offset="assign" es1="1.0" es2="2.0">
+    <function name="DepthRangef" es1="1.0" es2="2.0">
         <param name="zNear" type="GLclampf"/>
         <param name="zFar" type="GLclampf"/>
     </function>
index 1478e39700c55a9eec397d6b0019d062b636c426..56de639e907e25d436d8ddfc3b720a447fe6f298 100644 (file)
@@ -8,8 +8,7 @@
 
 <category name="GL_ARB_base_instance" number="107">
 
-  <function name="DrawArraysInstancedBaseInstance" offset="assign"
-            exec="dynamic">
+  <function name="DrawArraysInstancedBaseInstance" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="first" type="GLint"/>
     <param name="count" type="GLsizei"/>
@@ -17,8 +16,7 @@
     <param name="baseinstance" type="GLuint"/>
   </function>
 
-  <function name="DrawElementsInstancedBaseInstance" offset="assign"
-            exec="dynamic">
+  <function name="DrawElementsInstancedBaseInstance" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="count" type="GLsizei"/>
     <param name="type" type="GLenum"/>
@@ -27,8 +25,7 @@
     <param name="baseinstance" type="GLuint"/>
   </function>
 
-  <function name="DrawElementsInstancedBaseVertexBaseInstance" offset="assign"
-            exec="dynamic">
+  <function name="DrawElementsInstancedBaseVertexBaseInstance" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="count" type="GLsizei"/>
     <param name="type" type="GLenum"/>
index 32adcde7733b421ce94ca09e773d4a9ac426754a..406140f7ddf46e76b7efa8748e6262f05e9094ae 100644 (file)
@@ -8,14 +8,14 @@
 
 <category name="GL_ARB_blend_func_extended" number="78">
 
-    <function name="BindFragDataLocationIndexed" offset="assign">
+    <function name="BindFragDataLocationIndexed">
         <param name="program" type="GLuint"/>
         <param name="colorNumber" type="GLuint"/>
         <param name="index" type="GLuint"/>
         <param name="name" type="const GLchar *"/>
     </function>
 
-    <function name="GetFragDataIndex" offset="assign">
+    <function name="GetFragDataIndex">
         <param name="program" type="GLuint"/>
         <param name="name" type="const GLchar *"/>
          <return type="GLint"/>
index cb97a0185b0f198563505d4dfe5e0c3c123210f5..2284eacd656c0cea723db224d62d207fcfb03c61 100644 (file)
@@ -8,7 +8,7 @@
 
 <category name="GL_ARB_clear_buffer_object" number="121">
 
-    <function name ="ClearBufferData" offset="assign">
+    <function name ="ClearBufferData">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="format" type="GLenum"/>
@@ -16,7 +16,7 @@
         <param name="data" type="const GLvoid *"/>
     </function>
 
-    <function name ="ClearBufferSubData" offset="assign">
+    <function name ="ClearBufferSubData">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
@@ -26,7 +26,7 @@
         <param name="data" type="const GLvoid *"/>
     </function>
 
-<!--    <function name="ClearNamedBufferDataEXT" offset="assign">
+<!--    <function name="ClearNamedBufferDataEXT">
         <param name="buffer" type="GLuint"/>
         <param name="internalformat" type="GLenum"/>
         <param name="format" type="GLenum"/>
@@ -35,7 +35,7 @@
     </function>
 
 
-    <function name="ClearNamedBufferSubDataEXT" offset="assign">
+    <function name="ClearNamedBufferSubDataEXT">
         <param name="buffer" type="GLuint"/>
         <param name="internalformat" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
index bd9116f8b01835e67205ffa489dd3b52e63af41b..1ff981ea8a85071a94c49dcd94f856e096154323 100644 (file)
@@ -7,7 +7,7 @@
 
     <enum name="CLEAR_TEXTURE" value="0x9365"/>
 
-    <function name ="ClearTexImage" offset="assign">
+    <function name ="ClearTexImage">
         <param name="texture" type="GLuint"/>
         <param name="level" type="GLint"/>
         <param name="format" type="GLenum"/>
@@ -15,7 +15,7 @@
         <param name="data" type="const GLvoid *"/>
     </function>
 
-    <function name ="ClearTexSubImage" offset="assign">
+    <function name ="ClearTexSubImage">
         <param name="texture" type="GLuint"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
index ab1a3883ea7f3f990f2604117c4319c26385ef41..ecce133bb990f6b7d465e78e151b3f4b0e069330 100644 (file)
@@ -14,7 +14,7 @@
     <enum name="CLIP_ORIGIN" value = "0x935C"/>
     <enum name="CLIP_DEPTH_MODE" value = "0x935D"/>
 
-    <function name="ClipControl" offset="assign">
+    <function name="ClipControl">
         <param name="origin" type="GLenum"/>
         <param name="depth" type="GLenum"/>
         <!-- <glx rop="1340"/> -->
index 1db373e9901d0b21cfccd9711d154ed1bc52f344..c2ec842efe1e4ef593067e898aee062befb80dd5 100644 (file)
   <enum name="DISPATCH_INDIRECT_BUFFER_BINDING"                value="0x90EF"/>
   <enum name="COMPUTE_SHADER_BIT"                              value="0x00000020"/>
 
-  <function name="DispatchCompute" offset="assign">
+  <function name="DispatchCompute" es2="3.1">
     <param name="num_groups_x" type="GLuint"/>
     <param name="num_groups_y" type="GLuint"/>
     <param name="num_groups_z" type="GLuint"/>
   </function>
 
-  <function name="DispatchComputeIndirect" offset="assign">
+  <function name="DispatchComputeIndirect" es2="3.1">
     <param name="indirect" type="GLintptr"/>
   </function>
 </category>
index 6982ed1d26fb279276f685c4756192f2975e7a1d..d1c6f1fecce07a6ef3cc6420a7ac64b5071c88a1 100644 (file)
@@ -11,7 +11,7 @@
     <enum name="COPY_READ_BUFFER"   value="0x8F36"/>
     <enum name="COPY_WRITE_BUFFER"  value="0x8F37"/>
 
-    <function name="CopyBufferSubData" offset="assign" es2="3.0">
+    <function name="CopyBufferSubData" es2="3.0">
         <param name="readTarget" type="GLenum"/>
         <param name="writeTarget" type="GLenum"/>
         <param name="readOffset" type="GLintptr"/>
index 2fbd84557a949986fdd8d1722e4ee909116931b3..af672cd38bfc7e6adabc8f828397956ff6114621 100644 (file)
@@ -5,7 +5,7 @@
 
 <category name="GL_ARB_copy_image" number="123">
 
-    <function name="CopyImageSubData" offset="assign">
+    <function name="CopyImageSubData">
         <param name="srcName" type="GLuint"/>
         <param name="srcTarget" type="GLenum"/>
         <param name="srcLevel" type="GLint"/>
index 9e0cf2d6ce176b953723db49c777f4a09ae2fe1f..4c8f73ede7d2fe34e1e8c957420a34d65fc4feb8 100644 (file)
@@ -9,18 +9,18 @@
 
    <!-- Transform Feedback object functions -->
 
-  <function name="CreateTransformFeedbacks" offset="assign">
+  <function name="CreateTransformFeedbacks">
       <param name="n" type="GLsizei" />
       <param name="ids" type="GLuint *" />
    </function>
 
-   <function name="TransformFeedbackBufferBase" offset="assign">
+   <function name="TransformFeedbackBufferBase">
       <param name="xfb" type="GLuint" />
       <param name="index" type="GLuint" />
       <param name="buffer" type="GLuint" />
    </function>
 
-   <function name="TransformFeedbackBufferRange" offset="assign">
+   <function name="TransformFeedbackBufferRange">
       <param name="xfb" type="GLuint" />
       <param name="index" type="GLuint" />
       <param name="buffer" type="GLuint" />
       <param name="size" type="GLsizeiptr" />
    </function>
 
-   <function name="GetTransformFeedbackiv" offset="assign">
+   <function name="GetTransformFeedbackiv">
       <param name="xfb" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="GLint *" />
    </function>
 
-   <function name="GetTransformFeedbacki_v" offset="assign">
+   <function name="GetTransformFeedbacki_v">
       <param name="xfb" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="index" type="GLuint" />
       <param name="param" type="GLint *" />
    </function>
 
-   <function name="GetTransformFeedbacki64_v" offset="assign">
+   <function name="GetTransformFeedbacki64_v">
       <param name="xfb" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="index" type="GLuint" />
 
    <!-- Buffer object functions -->
 
-   <function name="CreateBuffers" offset="assign">
+   <function name="CreateBuffers">
       <param name="n" type="GLsizei" />
       <param name="buffers" type="GLuint *" />
    </function>
 
-   <function name="NamedBufferStorage" offset="assign">
+   <function name="NamedBufferStorage">
       <param name="buffer" type="GLuint" />
       <param name="size" type="GLsizeiptr" />
       <param name="data" type="const GLvoid *" />
       <param name="flags" type="GLbitfield" />
    </function>
 
-   <function name="NamedBufferData" offset="assign">
+   <function name="NamedBufferData">
       <param name="buffer" type="GLuint" />
       <param name="size" type="GLsizeiptr" />
       <param name="data" type="const GLvoid *" />
       <param name="usage" type="GLenum" />
    </function>
 
-   <function name="NamedBufferSubData" offset="assign">
+   <function name="NamedBufferSubData">
       <param name="buffer" type="GLuint" />
       <param name="offset" type="GLintptr" />
       <param name="size" type="GLsizeiptr" />
       <param name="data" type="const GLvoid *" />
    </function>
 
-   <function name="CopyNamedBufferSubData" offset="assign">
+   <function name="CopyNamedBufferSubData">
       <param name="readBuffer" type="GLuint" />
       <param name="writeBuffer" type="GLuint" />
       <param name="readOffset" type="GLintptr" />
@@ -84,7 +84,7 @@
       <param name="size" type="GLsizeiptr" />
    </function>
 
-   <function name="ClearNamedBufferData" offset="assign">
+   <function name="ClearNamedBufferData">
       <param name="buffer" type="GLuint" />
       <param name="internalformat" type="GLenum" />
       <param name="format" type="GLenum" />
@@ -92,7 +92,7 @@
       <param name="data" type="const GLvoid *" />
    </function>
 
-   <function name="ClearNamedBufferSubData" offset="assign">
+   <function name="ClearNamedBufferSubData">
       <param name="buffer" type="GLuint" />
       <param name="internalformat" type="GLenum" />
       <param name="offset" type="GLintptr" />
       <param name="data" type="const GLvoid *" />
    </function>
 
-   <function name="MapNamedBuffer" offset="assign">
+   <function name="MapNamedBuffer">
       <return type="GLvoid *" />
       <param name="buffer" type="GLuint" />
       <param name="access" type="GLenum" />
    </function>
 
-   <function name="MapNamedBufferRange" offset="assign">
+   <function name="MapNamedBufferRange">
       <return type="GLvoid *" />
       <param name="buffer" type="GLuint" />
       <param name="offset" type="GLintptr" />
       <param name="access" type="GLbitfield" />
    </function>
 
-   <function name="UnmapNamedBuffer" offset="assign">
+   <function name="UnmapNamedBuffer">
       <return type="GLboolean" />
       <param name="buffer" type="GLuint" />
    </function>
 
-   <function name="FlushMappedNamedBufferRange" offset="assign">
+   <function name="FlushMappedNamedBufferRange">
       <param name="buffer" type="GLuint" />
       <param name="offset" type="GLintptr" />
       <param name="length" type="GLsizeiptr" />
    </function>
 
-   <function name="GetNamedBufferParameteriv" offset="assign">
+   <function name="GetNamedBufferParameteriv">
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLint *" />
    </function>
 
-   <function name="GetNamedBufferParameteri64v" offset="assign">
+   <function name="GetNamedBufferParameteri64v">
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLint64 *" />
    </function>
 
-   <function name="GetNamedBufferPointerv" offset="assign">
+   <function name="GetNamedBufferPointerv">
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLvoid **" />
    </function>
 
-   <function name="GetNamedBufferSubData" offset="assign">
+   <function name="GetNamedBufferSubData">
       <param name="buffer" type="GLuint" />
       <param name="offset" type="GLintptr" />
       <param name="size" type="GLsizeiptr" />
       <param name="data" type="GLvoid *" />
    </function>
 
+   <!-- Framebuffer object functions -->
+
+   <function name="CreateFramebuffers" offset="assign">
+      <param name="n" type="GLsizei" />
+      <param name="framebuffers" type="GLuint *" />
+   </function>
+
+   <function name="NamedFramebufferRenderbuffer" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="attachment" type="GLenum" />
+      <param name="renderbuffertarget" type="GLenum" />
+      <param name="renderbuffer" type="GLuint" />
+   </function>
+
+   <function name="NamedFramebufferParameteri" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="pname" type="GLenum" />
+      <param name="param" type="GLint" />
+   </function>
+
+   <function name="NamedFramebufferTexture" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="attachment" type="GLenum" />
+      <param name="texture" type="GLuint" />
+      <param name="level" type="GLint" />
+   </function>
+
+   <function name="NamedFramebufferTextureLayer" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="attachment" type="GLenum" />
+      <param name="texture" type="GLuint" />
+      <param name="level" type="GLint" />
+      <param name="layer" type="GLint" />
+   </function>
+
+   <function name="NamedFramebufferDrawBuffer" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="buf" type="GLenum" />
+   </function>
+
+   <function name="NamedFramebufferDrawBuffers" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="n" type="GLsizei" />
+      <param name="bufs" type="const GLenum *" />
+   </function>
+
+   <function name="NamedFramebufferReadBuffer" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="buf" type="GLenum" />
+   </function>
+
+   <function name="InvalidateNamedFramebufferData" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="numAttachments" type="GLsizei" />
+      <param name="attachments" type="const GLenum *" />
+   </function>
+
+   <function name="InvalidateNamedFramebufferSubData" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="numAttachments" type="GLsizei" />
+      <param name="attachments" type="const GLenum *" />
+      <param name="x" type="GLint" />
+      <param name="y" type="GLint" />
+      <param name="width" type="GLsizei" />
+      <param name="height" type="GLsizei" />
+   </function>
+
+   <function name="ClearNamedFramebufferiv" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="buffer" type="GLenum" />
+      <param name="drawbuffer" type="GLint" />
+      <param name="value" type="const GLint *" />
+   </function>
+
+   <function name="ClearNamedFramebufferuiv" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="buffer" type="GLenum" />
+      <param name="drawbuffer" type="GLint" />
+      <param name="value" type="const GLuint *" />
+   </function>
+
+   <function name="ClearNamedFramebufferfv" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="buffer" type="GLenum" />
+      <param name="drawbuffer" type="GLint" />
+      <param name="value" type="const GLfloat *" />
+   </function>
+
+   <function name="ClearNamedFramebufferfi" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="buffer" type="GLenum" />
+      <param name="depth" type="GLfloat" />
+      <param name="stencil" type="GLint" />
+   </function>
+
+   <function name="BlitNamedFramebuffer" offset="assign">
+      <param name="readFramebuffer" type="GLuint" />
+      <param name="drawFramebuffer" type="GLuint" />
+      <param name="srcX0" type="GLint" />
+      <param name="srcY0" type="GLint" />
+      <param name="srcX1" type="GLint" />
+      <param name="srcY1" type="GLint" />
+      <param name="dstX0" type="GLint" />
+      <param name="dstY0" type="GLint" />
+      <param name="dstX1" type="GLint" />
+      <param name="dstY1" type="GLint" />
+      <param name="mask" type="GLbitfield" />
+      <param name="filter" type="GLenum" />
+   </function>
+
+   <function name="CheckNamedFramebufferStatus" offset="assign">
+      <return type="GLenum" />
+      <param name="framebuffer" type="GLuint" />
+      <param name="target" type="GLenum" />
+   </function>
+
+   <function name="GetNamedFramebufferParameteriv" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="pname" type="GLenum" />
+      <param name="param" type="GLint *" />
+   </function>
+
+   <function name="GetNamedFramebufferAttachmentParameteriv" offset="assign">
+      <param name="framebuffer" type="GLuint" />
+      <param name="attachment" type="GLenum" />
+      <param name="pname" type="GLenum" />
+      <param name="params" type="GLint *" />
+   </function>
+
    <!-- Renderbuffer object functions -->
 
-   <function name="CreateRenderbuffers" offset="assign">
+   <function name="CreateRenderbuffers">
       <param name="n" type="GLsizei" />
       <param name="renderbuffers" type="GLuint *" />
    </function>
 
-   <function name="NamedRenderbufferStorage" offset="assign">
+   <function name="NamedRenderbufferStorage">
       <param name="renderbuffer" type="GLuint" />
       <param name="internalformat" type="GLenum" />
       <param name="width" type="GLsizei" />
       <param name="height" type="GLsizei" />
    </function>
 
-   <function name="NamedRenderbufferStorageMultisample" offset="assign">
+   <function name="NamedRenderbufferStorageMultisample">
       <param name="renderbuffer" type="GLuint" />
       <param name="samples" type="GLsizei" />
       <param name="internalformat" type="GLenum" />
       <param name="height" type="GLsizei" />
    </function>
 
-   <function name="GetNamedRenderbufferParameteriv" offset="assign">
+   <function name="GetNamedRenderbufferParameteriv">
       <param name="renderbuffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLint *" />
 
    <!-- Texture object functions -->
 
-   <function name="CreateTextures" offset="assign">
+   <function name="CreateTextures">
       <param name="target" type="GLenum" />
       <param name="n" type="GLsizei" />
       <param name="textures" type="GLuint *" />
    </function>
 
-   <function name="TextureBuffer" offset="assign">
+   <function name="TextureBuffer">
       <param name="texture" type="GLuint" />
       <param name="internalformat" type="GLenum" />
       <param name="buffer" type="GLuint" />
    </function>
 
-   <function name="TextureBufferRange" offset="assign">
+   <function name="TextureBufferRange">
       <param name="texture" type="GLuint" />
       <param name="internalformat" type="GLenum" />
       <param name="buffer" type="GLuint" />
       <param name="size" type="GLsizeiptr" />
    </function>
 
-   <function name="TextureStorage1D" offset="assign">
+   <function name="TextureStorage1D">
       <param name="texture" type="GLuint" />
       <param name="levels" type="GLsizei" />
       <param name="internalformat" type="GLenum" />
       <param name="width" type="GLsizei" />
    </function>
 
-   <function name="TextureStorage2D" offset="assign">
+   <function name="TextureStorage2D">
       <param name="texture" type="GLuint" />
       <param name="levels" type="GLsizei" />
       <param name="internalformat" type="GLenum" />
       <param name="height" type="GLsizei" />
    </function>
 
-   <function name="TextureStorage3D" offset="assign">
+   <function name="TextureStorage3D">
       <param name="texture" type="GLuint" />
       <param name="levels" type="GLsizei" />
       <param name="internalformat" type="GLenum" />
       <param name="depth" type="GLsizei" />
    </function>
 
-   <function name="TextureStorage2DMultisample" offset="assign">
+   <function name="TextureStorage2DMultisample">
       <param name="texture" type="GLuint" />
       <param name="samples" type="GLsizei" />
       <param name="internalformat" type="GLenum" />
       <param name="fixedsamplelocations" type="GLboolean" />
    </function>
 
-   <function name="TextureStorage3DMultisample" offset="assign">
+   <function name="TextureStorage3DMultisample">
       <param name="texture" type="GLuint" />
       <param name="samples" type="GLsizei" />
       <param name="internalformat" type="GLenum" />
       <param name="fixedsamplelocations" type="GLboolean" />
    </function>
 
-   <function name="TextureSubImage1D" offset="assign">
+   <function name="TextureSubImage1D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="pixels" type="const GLvoid *" />
    </function>
 
-   <function name="TextureSubImage2D" offset="assign">
+   <function name="TextureSubImage2D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="pixels" type="const GLvoid *" />
    </function>
 
-   <function name="TextureSubImage3D" offset="assign">
+   <function name="TextureSubImage3D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="pixels" type="const GLvoid *" />
    </function>
 
-   <function name="CompressedTextureSubImage1D" offset="assign">
+   <function name="CompressedTextureSubImage1D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="data" type="const GLvoid *" />
    </function>
 
-   <function name="CompressedTextureSubImage2D" offset="assign">
+   <function name="CompressedTextureSubImage2D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="data" type="const GLvoid *" />
    </function>
 
-   <function name="CompressedTextureSubImage3D" offset="assign">
+   <function name="CompressedTextureSubImage3D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="data" type="const GLvoid *" />
    </function>
 
-   <function name="CopyTextureSubImage1D" offset="assign">
+   <function name="CopyTextureSubImage1D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="width" type="GLsizei" />
    </function>
 
-   <function name="CopyTextureSubImage2D" offset="assign">
+   <function name="CopyTextureSubImage2D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="height" type="GLsizei" />
    </function>
 
-   <function name="CopyTextureSubImage3D" offset="assign">
+   <function name="CopyTextureSubImage3D">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="xoffset" type="GLint" />
       <param name="height" type="GLsizei" />
    </function>
 
-   <function name="TextureParameterf" offset="assign">
+   <function name="TextureParameterf">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="GLfloat" />
    </function>
 
-   <function name="TextureParameterfv" offset="assign">
+   <function name="TextureParameterfv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="const GLfloat *" />
    </function>
 
-   <function name="TextureParameteri" offset="assign">
+   <function name="TextureParameteri">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="GLint" />
    </function>
 
-   <function name="TextureParameterIiv" offset="assign">
+   <function name="TextureParameterIiv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="const GLint *" />
    </function>
 
-   <function name="TextureParameterIuiv" offset="assign">
+   <function name="TextureParameterIuiv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="const GLuint *" />
    </function>
 
-   <function name="TextureParameteriv" offset="assign">
+   <function name="TextureParameteriv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="const GLint *" />
    </function>
 
-   <function name="GenerateTextureMipmap" offset="assign">
+   <function name="GenerateTextureMipmap">
       <param name="texture" type="GLuint" />
    </function>
 
-   <function name="BindTextureUnit" offset="assign">
+   <function name="BindTextureUnit">
       <param name="unit" type="GLuint" />
       <param name="texture" type="GLuint" />
    </function>
 
-   <function name="GetTextureImage" offset="assign">
+   <function name="GetTextureImage">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="format" type="GLenum" />
       <param name="pixels" type="GLvoid *" />
    </function>
 
-   <function name="GetCompressedTextureImage" offset="assign">
+   <function name="GetCompressedTextureImage">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="bufSize" type="GLsizei" />
       <param name="pixels" type="GLvoid *" />
    </function>
 
-   <function name="GetTextureLevelParameterfv" offset="assign">
+   <function name="GetTextureLevelParameterfv">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLfloat *" />
    </function>
 
-   <function name="GetTextureLevelParameteriv" offset="assign">
+   <function name="GetTextureLevelParameteriv">
       <param name="texture" type="GLuint" />
       <param name="level" type="GLint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLint *" />
    </function>
 
-   <function name="GetTextureParameterfv" offset="assign">
+   <function name="GetTextureParameterfv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLfloat *" />
    </function>
 
-   <function name="GetTextureParameterIiv" offset="assign">
+   <function name="GetTextureParameterIiv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLint *" />
    </function>
 
-   <function name="GetTextureParameterIuiv" offset="assign">
+   <function name="GetTextureParameterIuiv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLuint *" />
    </function>
 
-   <function name="GetTextureParameteriv" offset="assign">
+   <function name="GetTextureParameteriv">
       <param name="texture" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="params" type="GLint *" />
 
    <!-- Vertex Array object functions -->
 
-   <function name="CreateVertexArrays" offset="assign">
+   <function name="CreateVertexArrays">
       <param name="n" type="GLsizei" />
       <param name="arrays" type="GLuint *" />
    </function>
 
-   <function name="DisableVertexArrayAttrib" offset="assign">
+   <function name="DisableVertexArrayAttrib">
       <param name="vaobj" type="GLuint" />
       <param name="index" type="GLuint" />
    </function>
 
-   <function name="EnableVertexArrayAttrib" offset="assign">
+   <function name="EnableVertexArrayAttrib">
       <param name="vaobj" type="GLuint" />
       <param name="index" type="GLuint" />
    </function>
 
-   <function name="VertexArrayElementBuffer" offset="assign">
+   <function name="VertexArrayElementBuffer">
       <param name="vaobj" type="GLuint" />
       <param name="buffer" type="GLuint" />
    </function>
 
-   <function name="VertexArrayVertexBuffer" offset="assign">
+   <function name="VertexArrayVertexBuffer">
       <param name="vaobj" type="GLuint" />
       <param name="bindingindex" type="GLuint" />
       <param name="buffer" type="GLuint" />
       <param name="stride" type="GLsizei" />
    </function>
 
-   <function name="VertexArrayVertexBuffers" offset="assign">
+   <function name="VertexArrayVertexBuffers">
       <param name="vaobj" type="GLuint" />
       <param name="first" type="GLuint" />
       <param name="count" type="GLsizei" />
       <param name="strides" type="const GLsizei *" />
    </function>
 
-   <function name="VertexArrayAttribFormat" offset="assign">
+   <function name="VertexArrayAttribFormat">
       <param name="vaobj" type="GLuint" />
       <param name="attribindex" type="GLuint" />
       <param name="size" type="GLint" />
       <param name="relativeoffset" type="GLuint" />
    </function>
 
-   <function name="VertexArrayAttribIFormat" offset="assign">
+   <function name="VertexArrayAttribIFormat">
       <param name="vaobj" type="GLuint" />
       <param name="attribindex" type="GLuint" />
       <param name="size" type="GLint" />
       <param name="relativeoffset" type="GLuint" />
    </function>
 
-   <function name="VertexArrayAttribLFormat" offset="assign">
+   <function name="VertexArrayAttribLFormat">
       <param name="vaobj" type="GLuint" />
       <param name="attribindex" type="GLuint" />
       <param name="size" type="GLint" />
       <param name="relativeoffset" type="GLuint" />
    </function>
 
-   <function name="VertexArrayAttribBinding" offset="assign">
+   <function name="VertexArrayAttribBinding">
       <param name="vaobj" type="GLuint" />
       <param name="attribindex" type="GLuint" />
       <param name="bindingindex" type="GLuint" />
    </function>
 
-   <function name="VertexArrayBindingDivisor" offset="assign">
+   <function name="VertexArrayBindingDivisor">
       <param name="vaobj" type="GLuint" />
       <param name="bindingindex" type="GLuint" />
       <param name="divisor" type="GLuint" />
    </function>
 
-   <function name="GetVertexArrayiv" offset="assign">
+   <function name="GetVertexArrayiv">
       <param name="vaobj" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="GLint *" />
    </function>
 
-   <function name="GetVertexArrayIndexediv" offset="assign">
+   <function name="GetVertexArrayIndexediv">
       <param name="vaobj" type="GLuint" />
       <param name="index" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="param" type="GLint *" />
    </function>
 
-   <function name="GetVertexArrayIndexed64iv" offset="assign">
+   <function name="GetVertexArrayIndexed64iv">
       <param name="vaobj" type="GLuint" />
       <param name="index" type="GLuint" />
       <param name="pname" type="GLenum" />
 
    <!-- Sampler object functions -->
 
-   <function name="CreateSamplers" offset="assign">
+   <function name="CreateSamplers">
       <param name="n" type="GLsizei" />
       <param name="samplers" type="GLuint *" />
    </function>
 
    <!-- Program Pipeline object functions -->
 
-   <function name="CreateProgramPipelines" offset="assign">
+   <function name="CreateProgramPipelines">
       <param name="n" type="GLsizei" />
       <param name="pipelines" type="GLuint *" />
    </function>
 
    <!-- Query object functions -->
 
-   <function name="CreateQueries" offset="assign">
+   <function name="CreateQueries">
       <param name="target" type="GLenum" />
       <param name="n" type="GLsizei" />
       <param name="ids" type="GLuint *" />
    </function>
 
-   <function name="GetQueryBufferObjectiv" offset="assign">
+   <function name="GetQueryBufferObjectiv">
       <param name="id" type="GLuint" />
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="offset" type="GLintptr" />
    </function>
 
-   <function name="GetQueryBufferObjectuiv" offset="assign">
+   <function name="GetQueryBufferObjectuiv">
       <param name="id" type="GLuint" />
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="offset" type="GLintptr" />
    </function>
 
-   <function name="GetQueryBufferObjecti64v" offset="assign">
+   <function name="GetQueryBufferObjecti64v">
       <param name="id" type="GLuint" />
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
       <param name="offset" type="GLintptr" />
    </function>
 
-   <function name="GetQueryBufferObjectui64v" offset="assign">
+   <function name="GetQueryBufferObjectui64v">
       <param name="id" type="GLuint" />
       <param name="buffer" type="GLuint" />
       <param name="pname" type="GLenum" />
index 0b6947cc5f3d2a1eec9deaa9d7fa2a6bc8efd0e1..8c33fbf89b821929c3d218540d240e4f9fb35bcf 100644 (file)
@@ -8,24 +8,24 @@
 
 <category name="GL_ARB_draw_buffers_blend" number="69">
 
-    <function name="BlendEquationiARB" offset="assign">
+    <function name="BlendEquationiARB">
         <param name="buf" type="GLuint"/>
         <param name="mode" type="GLenum"/>
     </function>
 
-    <function name="BlendEquationSeparateiARB" offset="assign">
+    <function name="BlendEquationSeparateiARB">
         <param name="buf" type="GLuint"/>
         <param name="modeRGB" type="GLenum"/>
         <param name="modeA" type="GLenum"/>
     </function>
 
-    <function name="BlendFunciARB" offset="assign">
+    <function name="BlendFunciARB">
         <param name="buf" type="GLuint"/>
         <param name="src" type="GLenum"/>
         <param name="dst" type="GLenum"/>
     </function>
 
-    <function name="BlendFuncSeparateiARB" offset="assign">
+    <function name="BlendFuncSeparateiARB">
         <param name="buf" type="GLuint"/>
         <param name="srcRGB" type="GLenum"/>
         <param name="dstRGB" type="GLenum"/>
index 986654848cacdb0fa38c504a904f28e2feec9467..120bda13dd8fb457bd55e9bdf846b8b00ac6fc37 100644 (file)
@@ -8,7 +8,7 @@
 
 <category name="GL_ARB_draw_elements_base_vertex" number="62">
 
-    <function name="DrawElementsBaseVertex" offset="assign" exec="dynamic">
+    <function name="DrawElementsBaseVertex" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
@@ -16,8 +16,7 @@
         <param name="basevertex" type="GLint"/>
     </function>
 
-    <function name="DrawRangeElementsBaseVertex" offset="assign"
-              exec="dynamic">
+    <function name="DrawRangeElementsBaseVertex" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="start" type="GLuint"/>
         <param name="end" type="GLuint"/>
@@ -27,8 +26,7 @@
         <param name="basevertex" type="GLint"/>
     </function>
 
-    <function name="MultiDrawElementsBaseVertex" offset="assign"
-              exec="dynamic">
+    <function name="MultiDrawElementsBaseVertex" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="count" type="const GLsizei *"/>
         <param name="type" type="GLenum"/>
@@ -37,8 +35,7 @@
         <param name="basevertex" type="const GLint *"/>
     </function>
 
-    <function name="DrawElementsInstancedBaseVertex" offset="assign"
-              exec="dynamic">
+    <function name="DrawElementsInstancedBaseVertex" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
index 7de03cd3502a3e0e9a7b7b1dafa4e1ecae51b1ba..3b29d6b867425214e8af4e7f45b57fca78e07be4 100644 (file)
@@ -8,12 +8,12 @@
     <enum name="DRAW_INDIRECT_BUFFER"                   value="0x8F3F"/>
     <enum name="DRAW_INDIRECT_BUFFER_BINDING"           value="0x8F43"/>
 
-    <function name="DrawArraysIndirect" offset="assign" exec="dynamic">
+    <function name="DrawArraysIndirect" exec="dynamic" es2="3.1">
         <param name="mode" type="GLenum"/>
         <param name="indirect" type="const GLvoid *"/>
     </function>
 
-    <function name="DrawElementsIndirect" offset="assign" exec="dynamic">
+    <function name="DrawElementsIndirect" exec="dynamic" es2="3.1">
         <param name="mode" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="indirect" type="const GLvoid *"/>
 
 <category name="GL_ARB_multi_draw_indirect" number="133">
 
-    <function name="MultiDrawArraysIndirect" offset="assign" exec="dynamic">
+    <function name="MultiDrawArraysIndirect" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="indirect" type="const GLvoid *"/>
         <param name="primcount" type="GLsizei"/>
         <param name="stride" type="GLsizei"/>
     </function>
 
-    <function name="MultiDrawElementsIndirect" offset="assign" exec="dynamic">
+    <function name="MultiDrawElementsIndirect" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="indirect" type="const GLvoid *"/>
index 7ee7629c706706f81d2bbe07cc526feac245d816..b1c8221444a48514e7d56e57915d2ed2ae9004a4 100644 (file)
@@ -8,14 +8,14 @@
 
 <category name="GL_ARB_draw_instanced" number="44">
 
-  <function name="DrawArraysInstancedARB" offset="assign" exec="dynamic">
+  <function name="DrawArraysInstancedARB" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="first" type="GLint"/>
     <param name="count" type="GLsizei"/>
     <param name="primcount" type="GLsizei"/>
   </function>
 
-  <function name="DrawElementsInstancedARB" offset="assign" exec="dynamic">
+  <function name="DrawElementsInstancedARB" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="count" type="GLsizei"/>
     <param name="type" type="GLenum"/>
diff --git a/src/mapi/glapi/gen/ARB_framebuffer_no_attachments.xml b/src/mapi/glapi/gen/ARB_framebuffer_no_attachments.xml
new file mode 100644 (file)
index 0000000..59839a0
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_framebuffer_no_attachments" number="130">
+
+   <enum name="FRAMEBUFFER_DEFAULT_WIDTH"                  value="0x9310" />
+   <enum name="FRAMEBUFFER_DEFAULT_HEIGHT"                 value="0x9311" />
+   <enum name="FRAMEBUFFER_DEFAULT_LAYERS"                 value="0x9312" />
+   <enum name="FRAMEBUFFER_DEFAULT_SAMPLES"                value="0x9313" />
+   <enum name="FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS" value="0x9314" />
+   <enum name="MAX_FRAMEBUFFER_WIDTH"                      value="0x9315" />
+   <enum name="MAX_FRAMEBUFFER_HEIGHT"                     value="0x9316" />
+   <enum name="MAX_FRAMEBUFFER_LAYERS"                     value="0x9317" />
+   <enum name="MAX_FRAMEBUFFER_SAMPLES"                    value="0x9318" />
+
+    <function name="FramebufferParameteri">
+       <param name="target" type="GLenum"/>
+       <param name="pname"  type="GLenum"/>
+       <param name="param"  type="GLint" />
+    </function>
+
+    <function name="GetFramebufferParameteriv">
+       <param name="target" type="GLenum" />
+       <param name="pname"  type="GLenum" />
+       <param name="params" type="GLint *" output="true" />
+    </function>
+
+</category>
+
+</OpenGLAPI>
index 7c547c16742341c17313150a7ada7acdb55119db..1573e7e969cf74a0dff0fe3a1de0363c8125ffca 100644 (file)
 
 
 
-    <function name="IsRenderbuffer" es2="2.0" offset="assign">
+    <function name="IsRenderbuffer" es2="2.0">
         <param name="renderbuffer" type="GLuint"/>
        <return type="GLboolean"/>
        <glx vendorpriv="1422"/>
     </function>
 
-    <function name="BindRenderbuffer" es2="2.0" offset="assign">
+    <function name="BindRenderbuffer" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="renderbuffer" type="GLuint"/>
         <glx rop="235"/>
     </function>
 
-    <function name="DeleteRenderbuffers"
-              es2="2.0" offset="assign">
+    <function name="DeleteRenderbuffers" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="renderbuffers" type="const GLuint *" count="n"/>
        <glx rop="4317"/>
     </function>
 
-    <function name="GenRenderbuffers" es2="2.0" offset="assign">
+    <function name="GenRenderbuffers" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="renderbuffers" type="GLuint *" count="n" output="true"/>
        <glx vendorpriv="1423" always_array="true"/>
     </function>
 
-    <function name="RenderbufferStorage"
-              es2="2.0" offset="assign">
+    <function name="RenderbufferStorage" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
        <glx rop="4318"/>
     </function>
 
-    <function name="RenderbufferStorageMultisample" offset="assign" es2="3.0">
+    <function name="RenderbufferStorageMultisample" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="samples" type="GLsizei"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="4331"/>
     </function>
 
-    <function name="GetRenderbufferParameteriv" es2="2.0" offset="assign">
+    <function name="GetRenderbufferParameteriv" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true"/>
        <glx vendorpriv="1424"/>
     </function>
 
-    <function name="IsFramebuffer" es2="2.0" offset="assign">
+    <function name="IsFramebuffer" es2="2.0">
         <param name="framebuffer" type="GLuint"/>
        <return type="GLboolean"/>
        <glx vendorpriv="1425"/>
     </function>
 
-    <function name="BindFramebuffer" es2="2.0" offset="assign">
+    <function name="BindFramebuffer" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="framebuffer" type="GLuint"/>
         <glx rop="236"/>
     </function>
 
-    <function name="DeleteFramebuffers"
-              es2="2.0" offset="assign">
+    <function name="DeleteFramebuffers" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="framebuffers" type="const GLuint *" count="n"/>
        <glx rop="4320"/>
     </function>
 
-    <function name="GenFramebuffers" es2="2.0" offset="assign">
+    <function name="GenFramebuffers" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="framebuffers" type="GLuint *" count="n" output="true"/>
        <glx vendorpriv="1426" always_array="true"/>
     </function>
 
-    <function name="CheckFramebufferStatus"
-              es2="2.0" offset="assign">
+    <function name="CheckFramebufferStatus" es2="2.0">
         <param name="target" type="GLenum"/>
        <return type="GLenum"/>
        <glx vendorpriv="1427"/>
     </function>
 
-    <function name="FramebufferTexture1D" offset="assign">
+    <function name="FramebufferTexture1D">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="textarget" type="GLenum"/>
        <glx rop="4321"/>
     </function>
 
-    <function name="FramebufferTexture2D"
-              es2="2.0" offset="assign">
+    <function name="FramebufferTexture2D" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="textarget" type="GLenum"/>
        <glx rop="4322"/>
     </function>
 
-    <function name="FramebufferTexture3D" offset="assign">
+    <function name="FramebufferTexture3D">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="textarget" type="GLenum"/>
         <param name="texture" type="GLuint"/>
         <param name="level" type="GLint"/>
-        <param name="zoffset" type="GLint"/>
+        <param name="layer" type="GLint"/>
        <glx rop="4323"/>
     </function>
 
-    <function name="FramebufferTextureLayer" es2="3.0" offset="assign">
+    <function name="FramebufferTextureLayer" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="texture" type="GLuint"/>
        <glx rop="237"/>
     </function>
 
-    <function name="FramebufferRenderbuffer"
-              es2="2.0" offset="assign">
+    <function name="FramebufferRenderbuffer" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="renderbuffertarget" type="GLenum"/>
        <glx rop="4324"/>
     </function>
 
-    <function name="GetFramebufferAttachmentParameteriv" es2="2.0" offset="assign">
+    <function name="GetFramebufferAttachmentParameteriv" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="pname" type="GLenum"/>
        <glx vendorpriv="1428"/>
     </function>
 
-    <function name="BlitFramebuffer" es2="3.0" offset="assign">
+    <function name="BlitFramebuffer" es2="3.0">
         <param name="srcX0" type="GLint"/>
         <param name="srcY0" type="GLint"/>
         <param name="srcX1" type="GLint"/>
         <glx rop="4330"/>
     </function>
 
-    <function name="GenerateMipmap" es2="2.0" offset="assign">
+    <function name="GenerateMipmap" es2="2.0">
         <param name="target" type="GLenum"/>
        <glx rop="4325"/>
     </function>
index e62047c9bd65f3495d03fca33e9d0be18f81ed69..280e7a075994fa800f7577c2fa7aef3d7eb290ca 100644 (file)
@@ -45,7 +45,7 @@
         <param name="level" type="GLint"/>
         <param name="layer" type="GLint"/>
     </function>
-    <function name="FramebufferTextureFaceARB" exec="skip" offset="assign">
+    <function name="FramebufferTextureFaceARB" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="texture" type="GLuint"/>
index e84d0678e7208c0edf9dea37da129538b1c35317..25e0a37c84b5e0b38cabc18c068c837fbdf4124b 100644 (file)
@@ -11,7 +11,7 @@
     <enum name="NUM_PROGRAM_BINARY_FORMATS"               value="0x87FE"/>
     <enum name="PROGRAM_BINARY_FORMATS"                   value="0x87FF"/>
 
-    <function name="GetProgramBinary" offset="assign" es2="3.0">
+    <function name="GetProgramBinary" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *"/>
         <param name="binary" type="GLvoid *"/>
     </function>
 
-    <function name="ProgramBinary" offset="assign" es2="3.0">
+    <function name="ProgramBinary" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="binaryFormat" type="GLenum"/>
         <param name="binary" type="const GLvoid *"/>
         <param name="length" type="GLsizei"/>
     </function>
 
-    <function name="ProgramParameteri" offset="assign" es2="3.0">
+    <function name="ProgramParameteri" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="value" type="GLint"/>
index 4f860ef8c69f679bdd848f197644b3eee499b7ad..fd1ad117e514b06b93df13a031244e872cf24a98 100644 (file)
@@ -5,25 +5,25 @@
 
 <category name="GL_ARB_gpu_shader_fp64" number="89">
 
-    <function name="Uniform1d" offset="assign">
+    <function name="Uniform1d">
         <param name="location" type="GLint"/>
         <param name="x" type="GLdouble"/>
     </function>
 
-    <function name="Uniform2d" offset="assign">
+    <function name="Uniform2d">
         <param name="location" type="GLint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
     </function>
 
-    <function name="Uniform3d" offset="assign">
+    <function name="Uniform3d">
         <param name="location" type="GLint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
     </function>
 
-    <function name="Uniform4d" offset="assign">
+    <function name="Uniform4d">
         <param name="location" type="GLint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="Uniform1dv" offset="assign">
+    <function name="Uniform1dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="Uniform2dv" offset="assign">
+    <function name="Uniform2dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="Uniform3dv" offset="assign">
+    <function name="Uniform3dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="Uniform4dv" offset="assign">
+    <function name="Uniform4dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix2dv" offset="assign">
+    <function name="UniformMatrix2dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix3dv" offset="assign">
+    <function name="UniformMatrix3dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix4dv" offset="assign">
+    <function name="UniformMatrix4dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix2x3dv" offset="assign">
+    <function name="UniformMatrix2x3dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix2x4dv" offset="assign">
+    <function name="UniformMatrix2x4dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix3x2dv" offset="assign">
+    <function name="UniformMatrix3x2dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix3x4dv" offset="assign">
+    <function name="UniformMatrix3x4dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix4x2dv" offset="assign">
+    <function name="UniformMatrix4x2dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="UniformMatrix4x3dv" offset="assign">
+    <function name="UniformMatrix4x3dv">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLdouble *"/>
     </function>
 
-    <function name="GetUniformdv" offset="assign">
+    <function name="GetUniformdv">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="params" type="GLdouble *"/>
index 70a2a310975225168373b9016d33f82991d1eecd..16d14b1b7ab1375e04ea138a1e81d78537a30ff2 100644 (file)
@@ -8,8 +8,7 @@
 
     <enum name="NUM_SAMPLE_COUNTS"                        value="0x9380"/>
 
-    <function name="GetInternalformativ" offset="assign" static_dispatch="false"
-              es2="3.0">
+    <function name="GetInternalformativ" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="pname" type="GLenum"/>
index 31b515cdb8547bed4e5c8e3cf3aa09972d6fb9b9..052816ad7e0dcd05aa5ced0706d6caab21961dc5 100644 (file)
@@ -3,7 +3,7 @@
 
 <OpenGLAPI>
 <category name="GL_ARB_invalidate_subdata" number="666">
-  <function name="InvalidateTexSubImage" offset="assign">
+  <function name="InvalidateTexSubImage">
     <param name="texture" type="GLuint"/>
     <param name="level" type="GLint"/>
     <param name="xoffset" type="GLint"/>
     <param name="depth" type="GLsizei"/>
   </function>
 
-  <function name="InvalidateTexImage" offset="assign">
+  <function name="InvalidateTexImage">
     <param name="texture" type="GLuint"/>
     <param name="level" type="GLint"/>
   </function>
 
-  <function name="InvalidateBufferSubData" offset="assign">
+  <function name="InvalidateBufferSubData">
     <param name="buffer" type="GLuint"/>
     <param name="offset" type="GLintptr"/>
     <param name="length" type="GLsizeiptr"/>
   </function>
 
-  <function name="InvalidateBufferData" offset="assign">
+  <function name="InvalidateBufferData">
     <param name="buffer" type="GLuint"/>
   </function>
 
-  <function name="InvalidateSubFramebuffer" offset="assign" es2="3.0">
+  <function name="InvalidateSubFramebuffer" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="numAttachments" type="GLsizei" counter="true"/>
     <param name="attachments" type="const GLenum *" count="numAttachments"/>
@@ -39,7 +39,7 @@
     <param name="height" type="GLsizei"/>
   </function>
 
-  <function name="InvalidateFramebuffer" offset="assign" es2="3.0">
+  <function name="InvalidateFramebuffer" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="numAttachments" type="GLsizei" counter="true"/>
     <param name="attachments" type="const GLenum *" count="numAttachments"/>
index d8745044694c00372a728747cdadb864c6f28489..cf7b211482d54e4b22252a641b0c2dd429d5710e 100644 (file)
@@ -15,7 +15,7 @@
     <enum name="MAP_FLUSH_EXPLICIT_BIT"      value="0x0010"/>
     <enum name="MAP_UNSYNCHRONIZED_BIT"      value="0x0020"/>
 
-    <function name="MapBufferRange" offset="assign" es2="3.0">
+    <function name="MapBufferRange" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="length" type="GLsizeiptr"/>
@@ -23,7 +23,7 @@
         <return type="GLvoid *"/>
     </function>
 
-    <function name="FlushMappedBufferRange" offset="assign" es2="3.0">
+    <function name="FlushMappedBufferRange" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="length" type="GLsizeiptr"/>
index 4f2f2a2596be30682ca006bbaec33fa8d0683078..f42eaa28e967c07bbb548a3ecfd0ba3ea30ae0e5 100644 (file)
@@ -7,14 +7,14 @@
 
 <category name="GL_ARB_multi_bind" number="147">
 
-    <function name="BindBuffersBase" offset="assign">
+    <function name="BindBuffersBase">
         <param name="target" type="GLenum"/>
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="buffers" type="const GLuint *"/>
     </function>
 
-    <function name="BindBuffersRange" offset="assign">
+    <function name="BindBuffersRange">
         <param name="target" type="GLenum"/>
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="sizes" type="const GLsizeiptr *"/>
     </function>
 
-    <function name="BindTextures" offset="assign">
+    <function name="BindTextures">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="textures" type="const GLuint *"/>
     </function>
 
-    <function name="BindSamplers" offset="assign">
+    <function name="BindSamplers">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="samplers" type="const GLuint *"/>
     </function>
 
-    <function name="BindImageTextures" offset="assign">
+    <function name="BindImageTextures">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="textures" type="const GLuint *"/>
     </function>
 
-    <function name="BindVertexBuffers" offset="assign">
+    <function name="BindVertexBuffers">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="buffers" type="const GLuint *"/>
index 59eb59c64d5581132ecbf3f7425cd6c7f2502ebd..c3162f5ed16ffde6f54d64623c601d7773143a6f 100644 (file)
     <enum name="NUM_COMPATIBLE_SUBROUTINES"                      value="0x8E4A"/>
     <enum name="COMPATIBLE_SUBROUTINES"                          value="0x8E4B"/>
 
-    <function name="GetProgramInterfaceiv" offset="assign">
+    <function name="GetProgramInterfaceiv" es2="3.1">
         <param name="program" type="GLuint"/>
         <param name="programInterface" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true"/>
     </function>
 
-    <function name="GetProgramResourceIndex" offset="assign">
+    <function name="GetProgramResourceIndex" es2="3.1">
         <param name="program" type="GLuint"/>
         <param name="programInterface" type="GLenum"/>
         <param name="name" type="const GLchar *"/>
         <return type="GLuint"/>
     </function>
 
-    <function name="GetProgramResourceName" offset="assign">
+    <function name="GetProgramResourceName" es2="3.1">
         <param name="program" type="GLuint"/>
         <param name="programInterface" type="GLenum"/>
         <param name="index" type="GLuint"/>
@@ -79,7 +79,7 @@
         <param name="name" type="GLchar *" output="true"/>
     </function>
 
-    <function name="GetProgramResourceiv" offset="assign">
+    <function name="GetProgramResourceiv" es2="3.1">
         <param name="program" type="GLuint"/>
         <param name="programInterface" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="params" type="GLint *" output="true"/>
     </function>
 
-    <function name="GetProgramResourceLocation" offset="assign">
+    <function name="GetProgramResourceLocation" es2="3.1">
         <param name="program" type="GLuint"/>
         <param name="programInterface" type="GLenum"/>
         <param name="name" type="const GLchar *"/>
         <return type="GLint"/>
     </function>
 
-    <function name="GetProgramResourceLocationIndex" offset="assign">
+    <function name="GetProgramResourceLocationIndex">
         <param name="program" type="GLuint"/>
         <param name="programInterface" type="GLenum"/>
         <param name="name" type="const GLchar *"/>
index 65843149cd8c4307093a0d4cbb1d5499cb7904f6..9b2f2f0a74cc59b24dac94a8e82301eced93133c 100644 (file)
 
     <enum name="CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB"       value="0x00000004"/>
 
-    <function name="GetGraphicsResetStatusARB" offset="assign">
+    <function name="GetGraphicsResetStatusARB">
         <return type="GLenum"/>
     </function>
 
 <!-- OpenGL 1.0 sized buffer queries -->
-    <function name="GetnMapdvARB" offset="assign" deprecated="3.1">
+    <function name="GetnMapdvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="query" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="v" type="GLdouble *" output="true"/>
     </function>
 
-    <function name="GetnMapfvARB" offset="assign" deprecated="3.1">
+    <function name="GetnMapfvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="query" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="v" type="GLfloat *" output="true"/>
     </function>
 
-    <function name="GetnMapivARB" offset="assign" deprecated="3.1">
+    <function name="GetnMapivARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="query" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
 
 
 
-    <function name="GetnPixelMapfvARB" offset="assign" deprecated="3.1">
+    <function name="GetnPixelMapfvARB" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="values" type="GLfloat *" output="true"/>
     </function>
 
-    <function name="GetnPixelMapuivARB" offset="assign" deprecated="3.1">
+    <function name="GetnPixelMapuivARB" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="values" type="GLuint *" output="true"/>
     </function>
 
-    <function name="GetnPixelMapusvARB" offset="assign" deprecated="3.1">
+    <function name="GetnPixelMapusvARB" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="values" type="GLushort *" output="true"/>
 
 
 
-    <function name="GetnPolygonStippleARB" offset="assign">
+    <function name="GetnPolygonStippleARB">
         <param name="bufSize" type="GLsizei"/>
         <param name="pattern" type="GLubyte *" output="true"/>
     </function>
 
-    <function name="GetnTexImageARB" offset="assign">
+    <function name="GetnTexImageARB">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="format" type="GLenum"/>
@@ -82,7 +82,7 @@
         <param name="img" type="GLvoid *" output="true"/>
     </function>
 
-    <function name="ReadnPixelsARB" offset="assign">
+    <function name="ReadnPixelsARB">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="width" type="GLsizei"/>
@@ -95,7 +95,7 @@
 
 
 <!-- ARB_imaging sized buffer queries -->
-    <function name="GetnColorTableARB" offset="assign" deprecated="3.1">
+    <function name="GetnColorTableARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="table" type="GLvoid *" output="true"/>
     </function>
 
-    <function name="GetnConvolutionFilterARB" offset="assign" deprecated="3.1">
+    <function name="GetnConvolutionFilterARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="image" type="GLvoid *" output="true"/>
     </function>
 
-    <function name="GetnSeparableFilterARB" offset="assign" deprecated="3.1">
+    <function name="GetnSeparableFilterARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="span" type="GLvoid *" output="true"/>
     </function>
 
-    <function name="GetnHistogramARB" offset="assign" deprecated="3.1">
+    <function name="GetnHistogramARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="reset" type="GLboolean"/>
         <param name="format" type="GLenum"/>
         <param name="values" type="GLvoid *" output="true"/>
     </function>
 
-    <function name="GetnMinmaxARB" offset="assign" deprecated="3.1">
+    <function name="GetnMinmaxARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="reset" type="GLboolean"/>
         <param name="format" type="GLenum"/>
 
 
 <!-- OpenGL 1.3 sized buffer queries -->
-    <function name="GetnCompressedTexImageARB" offset="assign">
+    <function name="GetnCompressedTexImageARB">
         <param name="target" type="GLenum"/>
         <param name="lod" type="GLint"/>
         <param name="bufSize" type="GLsizei"/>
 
 
 <!-- OpenGL 2.0 sized buffer queries -->
-    <function name="GetnUniformfvARB" offset="assign">
+    <function name="GetnUniformfvARB">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="params" type="GLfloat *" output="true"/>
     </function>
 
-    <function name="GetnUniformivARB" offset="assign">
+    <function name="GetnUniformivARB">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="params" type="GLint *" output="true"/>
     </function>
 
-    <function name="GetnUniformuivARB" offset="assign">
+    <function name="GetnUniformuivARB">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="params" type="GLuint *" output="true"/>
     </function>
 
-    <function name="GetnUniformdvARB" offset="assign">
+    <function name="GetnUniformdvARB">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="bufSize" type="GLsizei"/>
index 9173dee5c73ee5f69ce6d4cb8bed87d0132b1110..bc69e97bde7dd939d75bfd98917d91f810fede46 100644 (file)
@@ -7,81 +7,81 @@
 
 <category name="GL_ARB_sampler_objects" number="81">
 
-    <function name="GenSamplers" offset="assign" es2="3.0">
+    <function name="GenSamplers" es2="3.0">
       <param name="count" type="GLsizei"/>
       <param name="samplers" type="GLuint *"/>
     </function>
 
-    <function name="DeleteSamplers" offset="assign" es2="3.0">
+    <function name="DeleteSamplers" es2="3.0">
       <param name="count" type="GLsizei"/>
       <param name="samplers" type="const GLuint *"/>
     </function>
 
-    <function name="IsSampler" offset="assign" es2="3.0">
+    <function name="IsSampler" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <return type="GLboolean"/>
     </function>
 
-    <function name="BindSampler" offset="assign" es2="3.0">
+    <function name="BindSampler" es2="3.0">
       <param name="unit" type="GLuint"/>
       <param name="sampler" type="GLuint"/>
     </function>
 
-    <function name="SamplerParameteri" offset="assign" es2="3.0">
+    <function name="SamplerParameteri" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="param" type="GLint"/>
     </function>
 
-    <function name="SamplerParameterf" offset="assign" es2="3.0">
+    <function name="SamplerParameterf" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="param" type="GLfloat"/>
     </function>
 
-    <function name="SamplerParameteriv" offset="assign" es2="3.0">
+    <function name="SamplerParameteriv" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="const GLint *"/>
     </function>
 
-    <function name="SamplerParameterfv" offset="assign" es2="3.0">
+    <function name="SamplerParameterfv" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="const GLfloat *"/>
     </function>
 
-    <function name="SamplerParameterIiv" offset="assign">
+    <function name="SamplerParameterIiv">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="const GLint *"/>
     </function>
 
-    <function name="SamplerParameterIuiv" offset="assign">
+    <function name="SamplerParameterIuiv">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="const GLuint *"/>
     </function>
 
-    <function name="GetSamplerParameteriv" offset="assign" es2="3.0">
+    <function name="GetSamplerParameteriv" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="GLint *"/>
     </function>
 
-    <function name="GetSamplerParameterfv" offset="assign" es2="3.0">
+    <function name="GetSamplerParameterfv" es2="3.0">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="GLfloat *"/>
     </function>
 
-    <function name="GetSamplerParameterIiv" offset="assign">
+    <function name="GetSamplerParameterIiv">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="GLint *"/>
     </function>
 
-    <function name="GetSamplerParameterIuiv" offset="assign">
+    <function name="GetSamplerParameterIuiv">
       <param name="sampler" type="GLuint"/>
       <param name="pname" type="GLenum"/>
       <param name="params" type="GLuint *"/>
index 96ae2b9cb62204c428bb39f8a79876ed9f586b6c..c9f481d8b6b47a50a3f0812b1340e28b7aacafd3 100644 (file)
       <enum   name="ALL_SHADER_BITS"                              value="0xFFFFFFFF"/>
       <enum   name="PROGRAM_SEPARABLE"                            value="0x8258"/>
 
-      <function name="UseProgramStages" offset="assign" static_dispatch="false">
+      <function name="UseProgramStages" es2="3.1">
          <param name="pipeline" type="GLuint" />
          <param name="stages" type="GLbitfield" />
          <param name="program" type="GLuint" />
       </function>
-      <function name="ActiveShaderProgram" offset="assign" static_dispatch="false">
+      <function name="ActiveShaderProgram" es2="3.1">
          <param name="pipeline" type="GLuint" />
          <param name="program" type="GLuint" />
       </function>
-      <function name="CreateShaderProgramv" offset="assign" static_dispatch="false">
+      <function name="CreateShaderProgramv" es2="3.1">
          <param name="type" type="GLenum" />
          <param name="count" type="GLsizei" />
          <param name="strings" type="const GLchar * const *" />
          <return type="GLuint"/>
       </function>
-      <function name="BindProgramPipeline" offset="assign" static_dispatch="false">
+      <function name="BindProgramPipeline" es2="3.1">
          <param name="pipeline" type="GLuint" />
       </function>
-      <function name="DeleteProgramPipelines" offset="assign" static_dispatch="false">
+      <function name="DeleteProgramPipelines" es2="3.1">
          <param name="n" type="GLsizei" />
          <param name="pipelines" type="const GLuint *" />
       </function>
-      <function name="GenProgramPipelines" offset="assign" static_dispatch="false">
+      <function name="GenProgramPipelines" es2="3.1">
          <param name="n" type="GLsizei" />
          <param name="pipelines" type="GLuint *" />
       </function>
-      <function name="IsProgramPipeline" offset="assign" static_dispatch="false">
+      <function name="IsProgramPipeline" es2="3.1">
          <param name="pipeline" type="GLuint" />
          <return type="GLboolean"/>
       </function>
       <!-- Function already included on ARB_get_program_binary.xml. Keep a commented
       version here for completeness -->
       <!--
-      <function name="ProgramParameteri" offset="assign" es2="3.0" static_dispatch="false">
+      <function name="ProgramParameteri" es2="3.0">
          <param name="program" type="GLuint"/>
          <param name="pname" type="GLenum"/>
          <param name="value" type="GLint"/>
       </function>
       -->
-      <function name="GetProgramPipelineiv" offset="assign" static_dispatch="false">
+      <function name="GetProgramPipelineiv" es2="3.1">
          <param name="pipeline" type="GLuint" />
          <param name="pname" type="GLenum" />
          <param name="params" type="GLint *" />
       </function>
-      <function name="ProgramUniform1i" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1i" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLint" />
       </function>
-      <function name="ProgramUniform2i" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2i" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLint" />
          <param name="y" type="GLint" />
       </function>
-      <function name="ProgramUniform3i" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3i" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLint" />
          <param name="y" type="GLint" />
          <param name="z" type="GLint" />
       </function>
-      <function name="ProgramUniform4i" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4i" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLint" />
          <param name="z" type="GLint" />
          <param name="w" type="GLint" />
       </function>
-      <function name="ProgramUniform1ui" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1ui" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLuint" />
       </function>
-      <function name="ProgramUniform2ui" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2ui" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLuint" />
          <param name="y" type="GLuint" />
       </function>
-      <function name="ProgramUniform3ui" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3ui" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLuint" />
          <param name="y" type="GLuint" />
          <param name="z" type="GLuint" />
       </function>
-      <function name="ProgramUniform4ui" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4ui" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLuint" />
          <param name="z" type="GLuint" />
          <param name="w" type="GLuint" />
       </function>
-      <function name="ProgramUniform1f" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1f" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLfloat" />
       </function>
-      <function name="ProgramUniform2f" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2f" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLfloat" />
          <param name="y" type="GLfloat" />
       </function>
-      <function name="ProgramUniform3f" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3f" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLfloat" />
          <param name="y" type="GLfloat" />
          <param name="z" type="GLfloat" />
       </function>
-      <function name="ProgramUniform4f" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4f" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLfloat" />
          <param name="z" type="GLfloat" />
          <param name="w" type="GLfloat" />
       </function>
-      <function name="ProgramUniform1iv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1iv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLint *" />
       </function>
-      <function name="ProgramUniform2iv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2iv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLint *" />
       </function>
-      <function name="ProgramUniform3iv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3iv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLint *" />
       </function>
-      <function name="ProgramUniform4iv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4iv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLint *" />
       </function>
-      <function name="ProgramUniform1uiv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1uiv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLuint *" />
       </function>
-      <function name="ProgramUniform2uiv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2uiv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLuint *" />
       </function>
-      <function name="ProgramUniform3uiv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3uiv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLuint *" />
       </function>
-      <function name="ProgramUniform4uiv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4uiv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLuint *" />
       </function>
-      <function name="ProgramUniform1fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniform2fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniform3fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniform4fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix2fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix2fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix3fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix3fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix4fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix4fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix2x3fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix2x3fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix3x2fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix3x2fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix2x4fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix2x4fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix4x2fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix4x2fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix3x4fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix3x4fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ProgramUniformMatrix4x3fv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix4x3fv" es2="3.1">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLfloat *" />
       </function>
-      <function name="ValidateProgramPipeline" offset="assign" static_dispatch="false">
+      <function name="ValidateProgramPipeline" es2="3.1">
          <param name="pipeline" type="GLuint" />
       </function>
-      <function name="GetProgramPipelineInfoLog" offset="assign" static_dispatch="false">
+      <function name="GetProgramPipelineInfoLog" es2="3.1">
          <param name="pipeline" type="GLuint" />
          <param name="bufSize" type="GLsizei" />
          <param name="length" type="GLsizei *" />
          <param name="infoLog" type="GLchar *" />
       </function>
 
-      <function name="ProgramUniform1d" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1d">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLdouble" />
       </function>
-      <function name="ProgramUniform2d" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2d">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLdouble" />
          <param name="y" type="GLdouble" />
       </function>
-      <function name="ProgramUniform3d" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3d">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLdouble" />
          <param name="y" type="GLdouble" />
          <param name="z" type="GLdouble" />
       </function>
-      <function name="ProgramUniform4d" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4d">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="x" type="GLdouble" />
          <param name="z" type="GLdouble" />
          <param name="w" type="GLdouble" />
       </function>
-      <function name="ProgramUniformMatrix2x3dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix2x3dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix3x2dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix3x2dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix2x4dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix2x4dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix4x2dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix4x2dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix3x4dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix3x4dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix4x3dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix4x3dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix2dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix2dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix3dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix3dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniformMatrix4dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniformMatrix4dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="transpose" type="GLboolean" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniform1dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform1dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniform2dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform2dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniform3dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform3dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
          <param name="value" type="const GLdouble *" />
       </function>
-      <function name="ProgramUniform4dv" offset="assign" static_dispatch="false">
+      <function name="ProgramUniform4dv">
          <param name="program" type="GLuint" />
          <param name="location" type="GLint" />
          <param name="count" type="GLsizei" />
index f3b74e9c28c8dbdb9fa9b3931e52538cfc7b38e7..0b0b60fa7b209d1a5264716f8707e861610d24a9 100644 (file)
@@ -35,7 +35,7 @@
 <enum name="UNSIGNED_INT_ATOMIC_COUNTER" value="0x92DB"/>
 <enum name="MAX_ATOMIC_COUNTER_BUFFER_BINDINGS" value="0x92DC"/>
 
-<function name="GetActiveAtomicCounterBufferiv" offset="assign">
+<function name="GetActiveAtomicCounterBufferiv">
     <param name="program" type="GLuint" />
     <param name="bufferIndex" type="GLuint" />
     <param name="pname" type="GLenum" />
index 7ccfca41d816cf81585a12f346119b243fb767f6..178e930f1d5f43d060fedaa3b1e14a5fb37afc08 100644 (file)
@@ -70,7 +70,7 @@
 <enum name="MAX_FRAGMENT_IMAGE_UNIFORMS" value="0x90CE"/>
 <enum name="MAX_COMBINED_IMAGE_UNIFORMS" value="0x90CF"/>
 
-<function name="BindImageTexture" offset="assign">
+<function name="BindImageTexture" es2="3.1">
   <param name="unit" type="GLuint"/>
   <param name="texture" type="GLuint"/>
   <param name="level" type="GLint"/>
@@ -80,7 +80,7 @@
   <param name="format" type="GLenum"/>
 </function>
 
-<function name="MemoryBarrier" offset="assign">
+<function name="MemoryBarrier" es2="3.1">
   <param name="barriers" type="GLbitfield"/>
 </function>
 
index 58f1639c42101110fae3a62026ef733ec29353bf..d8a1c34e0c8257874a592dd9c3a828c8dbc0fd19 100644 (file)
     -->
 
 
-    <function name="FenceSync" offset="assign" es2="3.0">
+    <function name="FenceSync" es2="3.0">
         <param name="condition" type="GLenum"/>
         <param name="flags" type="GLbitfield"/>
         <return type="GLsync"/>
     </function>
 
-    <function name="IsSync" offset="assign" es2="3.0">
+    <function name="IsSync" es2="3.0">
         <param name="sync" type="GLsync"/>
        <return type="GLboolean"/>
     </function>
 
-    <function name="DeleteSync" offset="assign" es2="3.0">
+    <function name="DeleteSync" es2="3.0">
         <param name="sync" type="GLsync"/>
     </function>
 
-    <function name="ClientWaitSync" offset="assign" es2="3.0">
+    <function name="ClientWaitSync" es2="3.0">
         <param name="sync" type="GLsync"/>
         <param name="flags" type="GLbitfield"/>
        <param name="timeout" type="GLuint64"/>
         <return type="GLenum"/>
     </function>
 
-    <function name="WaitSync" offset="assign" es2="3.0">
+    <function name="WaitSync" es2="3.0">
         <param name="sync" type="GLsync"/>
         <param name="flags" type="GLbitfield"/>
        <param name="timeout" type="GLuint64"/>
     </function>
 
-    <function name="GetInteger64v" offset="assign" es2="3.0">
+    <function name="GetInteger64v" es2="3.0">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint64 *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="GetSynciv" offset="assign" es2="3.0">
+    <function name="GetSynciv" es2="3.0">
         <param name="sync" type="GLsync"/>
         <param name="pname" type="GLenum"/>
         <param name="bufSize" type="GLsizei"/>
index 2176c08efcb0a47fab2480509a8777489c853df9..36bcc49325fc52f1c77aabc86df1918f315df2ac 100644 (file)
@@ -9,7 +9,7 @@
     <enum name="TEXTURE_BUFFER_SIZE"                    value="0x919E"/>
     <enum name="TEXTURE_BUFFER_OFFSET_ALIGNMENT"        value="0x919F"/>
 
-    <function name="TexBufferRange" offset="assign">
+    <function name="TexBufferRange">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="buffer" type="GLuint"/>
index 1f65a8bcf80bf40d03065f5f6d9f14da281e4543..595e1c7eae6e9f01af8696fd550e67d48ed3e8bd 100644 (file)
@@ -34,7 +34,7 @@
    <enum name="INT_SAMPLER_2D_MULTISAMPLE_ARRAY"            value="0x910C"/>
    <enum name="UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY"   value="0x910D"/>
 
-   <function name="TexImage2DMultisample" offset="assign">
+   <function name="TexImage2DMultisample">
       <param name="target" type="GLenum"/>
       <param name="samples" type="GLsizei"/>
       <param name="internalformat" type="GLenum"/>
@@ -43,7 +43,7 @@
       <param name="fixedsamplelocations" type="GLboolean"/>
    </function>
 
-   <function name="TexImage3DMultisample" offset="assign">
+   <function name="TexImage3DMultisample">
       <param name="target" type="GLenum"/>
       <param name="samples" type="GLsizei"/>
       <param name="internalformat" type="GLenum"/>
       <param name="fixedsamplelocations" type="GLboolean"/>
    </function>
 
-   <function name="GetMultisamplefv" offset="assign">
+   <function name="GetMultisamplefv" es2="3.1">
       <param name="pname" type="GLenum"/>
       <param name="index" type="GLuint"/>
       <param name="val" type="GLfloat *"/>
    </function>
 
-   <function name="SampleMaski" offset="assign">
+   <function name="SampleMaski" es2="3.1">
       <param name="index" type="GLuint"/>
       <param name="mask" type="GLbitfield"/>
    </function>
index 1d63e7ce3a4fad056f603661d9ae61726e614058..7df39424157db5e4a674847d9594614d6125cc9c 100644 (file)
 
   <enum name="TEXTURE_IMMUTABLE_FORMAT" value="0x912F"/>
 
-  <function name="TexStorage1D" offset="assign">
+  <function name="TexStorage1D">
     <param name="target" type="GLenum"/>
     <param name="levels" type="GLsizei"/>
     <param name="internalFormat" type="GLenum"/>
     <param name="width" type="GLsizei"/>
   </function>
 
-  <function name="TexStorage2D" offset="assign" es2="3.0">
+  <function name="TexStorage2D" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="levels" type="GLsizei"/>
     <param name="internalFormat" type="GLenum"/>
@@ -25,7 +25,7 @@
     <param name="height" type="GLsizei"/>
   </function>
 
-  <function name="TexStorage3D" offset="assign" es2="3.0">
+  <function name="TexStorage3D" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="levels" type="GLsizei"/>
     <param name="internalFormat" type="GLenum"/>
@@ -34,7 +34,7 @@
     <param name="depth" type="GLsizei"/>
   </function>
 
-  <function name="TextureStorage1DEXT" offset="assign">
+  <function name="TextureStorage1DEXT">
     <param name="texture" type="GLuint"/>
     <param name="target" type="GLenum"/>
     <param name="levels" type="GLsizei"/>
@@ -42,7 +42,7 @@
     <param name="width" type="GLsizei"/>
   </function>
 
-  <function name="TextureStorage2DEXT" offset="assign">
+  <function name="TextureStorage2DEXT">
     <param name="texture" type="GLuint"/>
     <param name="target" type="GLenum"/>
     <param name="levels" type="GLsizei"/>
@@ -51,7 +51,7 @@
     <param name="height" type="GLsizei"/>
   </function>
 
-  <function name="TextureStorage3DEXT" offset="assign">
+  <function name="TextureStorage3DEXT">
     <param name="texture" type="GLuint"/>
     <param name="target" type="GLenum"/>
     <param name="levels" type="GLsizei"/>
index 0f9d323d4ffd3b4104e0c59c05894a3788feada2..6ed8f1a01d822d2519a9506fa6e19ca78ad892f4 100644 (file)
@@ -7,7 +7,7 @@
 
 <category name="GL_ARB_texture_storage_multisample" number="141">
 
-   <function name="TexStorage2DMultisample" offset="assign">
+   <function name="TexStorage2DMultisample" es2="3.1">
       <param name="target" type="GLenum"/>
       <param name="samples" type="GLsizei"/>
       <param name="internalformat" type="GLenum"/>
@@ -16,7 +16,7 @@
       <param name="fixedsamplelocations" type="GLboolean"/>
    </function>
 
-   <function name="TexStorage3DMultisample" offset="assign">
+   <function name="TexStorage3DMultisample">
       <param name="target" type="GLenum"/>
       <param name="samples" type="GLsizei"/>
       <param name="internalformat" type="GLenum"/>
index 3e6b8c904ce617d07310513dabb4e2303141139f..4215fc5bd541b7d79df8cae1a44bf67fbcb1b8e1 100644 (file)
@@ -7,7 +7,7 @@
 
 <category name="GL_ARB_texture_view" number="124">
 
-   <function name="TextureView" offset="assign">
+   <function name="TextureView">
       <param name="texture" type="GLuint"/>
       <param name="target" type="GLenum"/>
       <param name="origtexture" type="GLuint"/>
index 11aacb03309903aae56398c99a9cbc51c0c99d84..cf86bbb2f8ad7153f915ba1e94f09a672d10225c 100644 (file)
 <enum name="UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER" value="0x8A46" />
 <enum name="INVALID_INDEX" value="0xFFFFFFFF" />
 
-<function name="GetUniformIndices" offset="assign" es2="3.0">
+<function name="GetUniformIndices" es2="3.0">
     <param name="program" type="GLuint" />
     <param name="uniformCount" type="GLsizei" />
     <param name="uniformNames" type="const GLchar * const *" />
     <param name="uniformIndices" type="GLuint *" />
 </function>
 
-<function name="GetActiveUniformsiv" offset="assign" es2="3.0">
+<function name="GetActiveUniformsiv" es2="3.0">
     <param name="program" type="GLuint" />
     <param name="uniformCount" type="GLsizei" />
     <param name="uniformIndices" type="const GLuint *" />
@@ -54,7 +54,7 @@
     <param name="params" type="GLint *" />
 </function>
 
-<function name="GetActiveUniformName" offset="assign">
+<function name="GetActiveUniformName">
     <param name="program" type="GLuint" />
     <param name="uniformIndex" type="GLuint" />
     <param name="bufSize" type="GLsizei" />
     <param name="uniformName" type="GLchar *" />
 </function>
 
-<function name="GetUniformBlockIndex" offset="assign" es2="3.0">
+<function name="GetUniformBlockIndex" es2="3.0">
     <return type="GLuint"/>
     <param name="program" type="GLuint" />
     <param name="uniformBlockName" type="const GLchar *" />
 </function>
 
-<function name="GetActiveUniformBlockiv" offset="assign" es2="3.0">
+<function name="GetActiveUniformBlockiv" es2="3.0">
     <param name="program" type="GLuint" />
     <param name="uniformBlockIndex" type="GLuint" />
     <param name="pname" type="GLenum" />
     <param name="params" type="GLint *" />
 </function>
 
-<function name="GetActiveUniformBlockName" offset="assign" es2="3.0">
+<function name="GetActiveUniformBlockName" es2="3.0">
     <param name="program" type="GLuint" />
     <param name="uniformBlockIndex" type="GLuint" />
     <param name="bufSize" type="GLsizei" />
@@ -86,7 +86,7 @@
 <!-- Duplicated with GL3x.xml: BindBufferRange, BindBufferBase,
      GetIntegeri_v -->
 
-<function name="UniformBlockBinding" offset="assign" es2="3.0">
+<function name="UniformBlockBinding" es2="3.0">
     <param name="program" type="GLuint" />
     <param name="uniformBlockIndex" type="GLuint" />
     <param name="uniformBlockBinding" type="GLuint" />
index f2277d2bc2821de8619f97524e6505d4dd48e2ee..4a392dbb42703c5470529c71ed4c8930182713b7 100644 (file)
 
     <enum name="VERTEX_ARRAY_BINDING" value="0x85B5"/>
 
-    <function name="BindVertexArray" offset="assign" es2="3.0">
+    <function name="BindVertexArray" es2="3.0">
         <param name="array" type="GLuint"/>
     </function>
 
-    <function name="DeleteVertexArrays" es2="3.0" offset="assign">
+    <function name="DeleteVertexArrays" es2="3.0">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="const GLuint *" count="n"/>
     </function>
 
-    <function name="GenVertexArrays" offset="assign" es2="3.0">
+    <function name="GenVertexArrays" es2="3.0">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="GLuint *"/>
     </function>
 
-    <function name="IsVertexArray" es2="3.0" offset="assign">
+    <function name="IsVertexArray" es2="3.0">
         <param name="array" type="GLuint"/>
         <return type="GLboolean"/>
     </function>
index fc49f84b5bae834e838bff207ea696633481e8b3..211642fc317d6bb157a684bd199e25da5421147d 100644 (file)
@@ -5,25 +5,25 @@
 
 <category name="GL_ARB_vertex_attrib_64bit" number="99">
 
-    <function name="VertexAttribL1d" offset="assign">
+    <function name="VertexAttribL1d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttribL2d" offset="assign">
+    <function name="VertexAttribL2d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttribL3d" offset="assign">
+    <function name="VertexAttribL3d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttribL4d" offset="assign">
+    <function name="VertexAttribL4d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttribL1dv" offset="assign">
+    <function name="VertexAttribL1dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttribL2dv" offset="assign">
+    <function name="VertexAttribL2dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttribL3dv" offset="assign">
+    <function name="VertexAttribL3dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttribL4dv" offset="assign">
+    <function name="VertexAttribL4dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttribLPointer" offset="assign">
+    <function name="VertexAttribLPointer">
         <param name="index" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
@@ -59,7 +59,7 @@
         <param name="pointer" type="const GLvoid *"/>
     </function>
 
-    <function name="GetVertexAttribLdv" offset="assign">
+    <function name="GetVertexAttribLdv">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLdouble *"/>
index 7e62688779d824de914f8891a021a27b4dfd2ce1..ba9ca57bb54216531ade0cb886de1a4643036d37 100644 (file)
@@ -7,14 +7,14 @@
 
 <category name="GL_ARB_vertex_attrib_binding" number="125">
 
-    <function name="BindVertexBuffer" offset="assign">
+    <function name="BindVertexBuffer" es2="3.1">
         <param name="bindingindex" type="GLuint"/>
         <param name="buffer" type="GLuint"/>
         <param name="offset" type="GLintptr"/>
         <param name="stride" type="GLsizei"/>
     </function>
 
-    <function name="VertexAttribFormat" offset="assign">
+    <function name="VertexAttribFormat" es2="3.1">
         <param name="attribindex" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="relativeoffset" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribIFormat" offset="assign">
+    <function name="VertexAttribIFormat" es2="3.1">
         <param name="attribindex" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="relativeoffset" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribLFormat" offset="assign">
+    <function name="VertexAttribLFormat">
         <param name="attribindex" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="relativeoffset" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribBinding" offset="assign">
+    <function name="VertexAttribBinding" es2="3.1">
         <param name="attribindex" type="GLuint"/>
         <param name="bindingindex" type="GLuint"/>
     </function>
 
-    <function name="VertexBindingDivisor" offset="assign">
+    <function name="VertexBindingDivisor" es2="3.1">
         <param name="attribindex" type="GLuint"/>
         <param name="divisor" type="GLuint"/>
     </function>
index 6c6090c1cf0bc31dd1cc2dc2ef9c376d1789734d..92ec6e167cbf7400ee4722730352f4f19a1d0c0c 100644 (file)
 
     <enum name="INT_2_10_10_10_REV"                value = "0x8D9F"/>
 
-    <function name="VertexP2ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexP2ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexP3ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexP3ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexP4ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexP4ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexP2uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexP2uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="value" type="const GLuint *"/>
     </function>
 
-    <function name="VertexP3uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexP3uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="value" type="const GLuint *"/>
     </function>
 
-    <function name="VertexP4uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexP4uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="value" type="const GLuint *"/>
     </function>
 
-    <function name="TexCoordP1ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP1ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="TexCoordP2ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP2ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="TexCoordP3ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP3ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="TexCoordP4ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP4ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="TexCoordP1uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP1uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="TexCoordP2uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP2uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="TexCoordP3uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP3uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="TexCoordP4uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoordP4uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="MultiTexCoordP1ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP1ui" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="MultiTexCoordP2ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP2ui" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="MultiTexCoordP3ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP3ui" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="MultiTexCoordP4ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP4ui" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="MultiTexCoordP1uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP1uiv" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="MultiTexCoordP2uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP2uiv" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="MultiTexCoordP3uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP3uiv" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="MultiTexCoordP4uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="MultiTexCoordP4uiv" deprecated="3.1" exec="dynamic">
         <param name="texture" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="NormalP3ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="NormalP3ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="GLuint"/>
     </function>
 
-    <function name="NormalP3uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="NormalP3uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="coords" type="const GLuint *"/>
     </function>
 
-    <function name="ColorP3ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="ColorP3ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="color" type="GLuint"/>
     </function>
 
-    <function name="ColorP4ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="ColorP4ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="color" type="GLuint"/>
     </function>
 
-    <function name="ColorP3uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="ColorP3uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="color" type="const GLuint *"/>
     </function>
 
-    <function name="ColorP4uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="ColorP4uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="color" type="const GLuint *"/>
     </function>
 
-    <function name="SecondaryColorP3ui" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="SecondaryColorP3ui" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="color" type="GLuint"/>
     </function>
 
-    <function name="SecondaryColorP3uiv" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="SecondaryColorP3uiv" deprecated="3.1" exec="dynamic">
         <param name="type" type="GLenum"/>
         <param name="color" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribP1ui" offset="assign" exec="dynamic">
+    <function name="VertexAttribP1ui" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribP2ui" offset="assign" exec="dynamic">
+    <function name="VertexAttribP2ui" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribP3ui" offset="assign" exec="dynamic">
+    <function name="VertexAttribP3ui" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribP4ui" offset="assign" exec="dynamic">
+    <function name="VertexAttribP4ui" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribP1uiv" offset="assign" exec="dynamic">
+    <function name="VertexAttribP1uiv" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribP2uiv" offset="assign" exec="dynamic">
+    <function name="VertexAttribP2uiv" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribP3uiv" offset="assign" exec="dynamic">
+    <function name="VertexAttribP3uiv" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="value" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribP4uiv" offset="assign" exec="dynamic">
+    <function name="VertexAttribP4uiv" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
index e1c6c2d81ab8170925b362fb6b3f3146f73a2979..b20cf612cc3cc3624c07d5dfce0a6ee5033e232d 100644 (file)
     <enum name="PROVOKING_VERTEX" value="0x8E4F"/>
     <enum name="UNDEFINED_VERTEX" value="0x8260"/>
 
-    <function name="ViewportArrayv" offset="assign">
+    <function name="ViewportArrayv">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="v" type="const GLfloat *"/>
     </function>
-    <function name="ViewportIndexedf" offset="assign">
+    <function name="ViewportIndexedf">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="w" type="GLfloat"/>
         <param name="h" type="GLfloat"/>
     </function>
-    <function name="ViewportIndexedfv" offset="assign">
+    <function name="ViewportIndexedfv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *"/>
     </function>
-    <function name="ScissorArrayv" offset="assign">
+    <function name="ScissorArrayv">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="v" type="const int *"/>
     </function>
-    <function name="ScissorIndexed" offset="assign">
+    <function name="ScissorIndexed">
         <param name="index" type="GLuint"/>
         <param name="left" type="GLint"/>
         <param name="bottom" type="GLint"/>
         <param name="width" type="GLsizei"/>
         <param name="height" type="GLsizei"/>
     </function>
-    <function name="ScissorIndexedv" offset="assign">
+    <function name="ScissorIndexedv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLint *"/>
     </function>
-    <function name="DepthRangeArrayv" offset="assign">
+    <function name="DepthRangeArrayv">
         <param name="first" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="v" type="const GLclampd *"/>
     </function>
-    <function name="DepthRangeIndexed" offset="assign">
+    <function name="DepthRangeIndexed">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLclampd"/>
         <param name="f" type="GLclampd"/>
     </function>
-    <function name="GetFloati_v" offset="assign">
+    <function name="GetFloati_v">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="data" type="GLfloat *"/>
     </function>
-    <function name="GetDoublei_v" offset="assign">
+    <function name="GetDoublei_v">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="data" type="GLdouble *"/>
index 2cf75bc67837645e7e157c17a54ada2d1f2a8aa8..9ae029152320f5d6647c37e9324cc6d5d3f202c4 100644 (file)
@@ -78,7 +78,7 @@
        <return type="GLboolean"/>
     </function>
 
-    <function name="BindRenderbufferEXT" offset="assign" deprecated="3.1">
+    <function name="BindRenderbufferEXT" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="renderbuffer" type="GLuint"/>
         <glx rop="4316"/>
        <return type="GLboolean"/>
     </function>
 
-    <function name="BindFramebufferEXT" offset="assign" deprecated="3.1">
+    <function name="BindFramebufferEXT" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="framebuffer" type="GLuint"/>
         <glx rop="4319"/>
     <enum name="READ_FRAMEBUFFER_BINDING_EXT" count="1" value="0x8CAA">
         <size name="Get" mode="get"/>
     </enum>
-    <function name="BlitFramebufferEXT" static_dispatch="false" alias="BlitFramebuffer">
+    <function name="BlitFramebufferEXT" alias="BlitFramebuffer">
         <param name="srcX0" type="GLint"/>
         <param name="srcY0" type="GLint"/>
         <param name="srcX1" type="GLint"/>
index d204c3fc7a1a502f6e42e807e744e2bcaf44882b..b1f7eae26100c9b559b6ecf06b9e6567e66e63a0 100644 (file)
     </enum>
 
 
-    <function name="VertexAttribI1iEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI1iEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLint"/>
     </function>
 
-    <function name="VertexAttribI2iEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI2iEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
     </function>
 
-    <function name="VertexAttribI3iEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI3iEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
     </function>
 
-    <function name="VertexAttribI4iEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI4iEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="w" type="GLint"/>
     </function>
 
-    <function name="VertexAttribI1uiEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI1uiEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribI2uiEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI2uiEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLuint"/>
         <param name="y" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribI3uiEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI3uiEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLuint"/>
         <param name="y" type="GLuint"/>
         <param name="z" type="GLuint"/>
     </function>
 
-    <function name="VertexAttribI4uiEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI4uiEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLuint"/>
         <param name="y" type="GLuint"/>
         <param name="v" type="const GLint *"/>
     </function>
 
-    <function name="VertexAttribI2ivEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI2ivEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLint *"/>
     </function>
 
-    <function name="VertexAttribI3ivEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI3ivEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLint *"/>
     </function>
 
-    <function name="VertexAttribI4ivEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI4ivEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLint *"/>
     </function>
         <param name="v" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribI2uivEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI2uivEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribI3uivEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI3uivEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLuint *"/>
     </function>
 
-    <function name="VertexAttribI4uivEXT" offset="assign" exec="dynamic">
+    <function name="VertexAttribI4uivEXT" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLuint *"/>
     </function>
index eb872098d464ca897697c71eaa7d2f1f13808d1b..3d1ae771ebf6e03b5430fa0006b8ec0b7732bb9d 100644 (file)
@@ -26,7 +26,7 @@
     <enum name="PROVOKING_VERTEX"                         value="0x8E4F"/>
     <enum name="QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION" value="0x8E4C"/>
 
-    <function name="ProvokingVertex" offset="assign">
+    <function name="ProvokingVertex">
         <param name="mode" type="GLenum"/>
     </function>
 
index c6163a193b8dcb1fb4c05a9845907a6cf32fded5..1fa699fbc68a956f3668f8b417316bb5bdbabaf9 100644 (file)
@@ -8,16 +8,16 @@
     <!-- Alias of CURRENT_PROGRAM -->
 <!--    <enum name="ACTIVE_PROGRAM_EXT"               value="0x8B8D"/> -->
 
-    <function name="UseShaderProgramEXT" deprecated="3.1" offset="assign" exec="skip">
+    <function name="UseShaderProgramEXT" deprecated="3.1" exec="skip">
         <param name="type" type="GLenum"/>
        <param name="program" type="GLuint"/>
     </function>
 
-    <function name="ActiveProgramEXT" deprecated="3.1" offset="assign" exec="skip">
+    <function name="ActiveProgramEXT" deprecated="3.1" exec="skip">
        <param name="program" type="GLuint"/>
     </function>
 
-    <function name="CreateShaderProgramEXT" deprecated="3.1" offset="assign" exec="skip">
+    <function name="CreateShaderProgramEXT" deprecated="3.1" exec="skip">
         <param name="type" type="GLenum"/>
         <param name="string" type="const GLchar *"/>
         <return type="GLuint"/>
     <enum name="ALL_SHADER_BITS_EXT"                          value="0xFFFFFFFF"/>
     <enum name="PROGRAM_SEPARABLE_EXT"                        value="0x8258"/>
 
-    <function name="UseProgramStagesEXT" alias="UseProgramStages" static_dispatch="false" es2="2.0">
+    <function name="UseProgramStagesEXT" alias="UseProgramStages" es2="2.0">
         <param name="pipeline" type="GLuint"/>
         <param name="stages" type="GLbitfield"/>
         <param name="program" type="GLuint"/>
     </function>
-    <function name="ActiveShaderProgramEXT" alias="ActiveShaderProgram" static_dispatch="false" es2="2.0">
+    <function name="ActiveShaderProgramEXT" alias="ActiveShaderProgram" es2="2.0">
         <param name="pipeline" type="GLuint"/>
         <param name="program" type="GLuint"/>
     </function>
-    <function name="CreateShaderProgramvEXT" alias="CreateShaderProgramv" static_dispatch="false" es2="2.0">
+    <function name="CreateShaderProgramvEXT" alias="CreateShaderProgramv" es2="2.0">
         <param name="type" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="strings" type="const GLchar * const *"/>
         <return type="GLuint"/>
     </function>
-    <function name="BindProgramPipelineEXT" alias="BindProgramPipeline" static_dispatch="false" es2="2.0">
+    <function name="BindProgramPipelineEXT" alias="BindProgramPipeline" es2="2.0">
         <param name="pipeline" type="GLuint"/>
     </function>
-    <function name="DeleteProgramPipelinesEXT" alias="DeleteProgramPipelines" static_dispatch="false" es2="2.0">
+    <function name="DeleteProgramPipelinesEXT" alias="DeleteProgramPipelines" es2="2.0">
         <param name="n" type="GLsizei"/>
         <param name="pipelines" type="const GLuint *"/>
     </function>
-    <function name="GenProgramPipelinesEXT" alias="GenProgramPipelines" static_dispatch="false" es2="2.0">
+    <function name="GenProgramPipelinesEXT" alias="GenProgramPipelines" es2="2.0">
         <param name="n" type="GLsizei"/>
         <param name="pipelines" type="GLuint *"/>
     </function>
-    <function name="IsProgramPipelineEXT" alias="IsProgramPipeline" static_dispatch="false" es2="2.0">
+    <function name="IsProgramPipelineEXT" alias="IsProgramPipeline" es2="2.0">
         <param name="pipeline" type="GLuint"/>
         <return type="GLboolean"/>
     </function>
-    <function name="ProgramParameteriEXT" alias="ProgramParameteri" static_dispatch="false" es2="2.0">
+    <function name="ProgramParameteriEXT" alias="ProgramParameteri" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="value" type="GLint"/>
     </function>
-    <function name="GetProgramPipelineivEXT" alias="GetProgramPipelineiv" static_dispatch="false" es2="2.0">
+    <function name="GetProgramPipelineivEXT" alias="GetProgramPipelineiv" es2="2.0">
         <param name="pipeline" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *"/>
     </function>
-    <function name="ProgramUniform1iEXT" alias="ProgramUniform1i" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform1iEXT" alias="ProgramUniform1i" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLint"/>
     </function>
-    <function name="ProgramUniform2iEXT" alias="ProgramUniform2i" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform2iEXT" alias="ProgramUniform2i" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
     </function>
-    <function name="ProgramUniform3iEXT" alias="ProgramUniform3i" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform3iEXT" alias="ProgramUniform3i" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
     </function>
-    <function name="ProgramUniform4iEXT" alias="ProgramUniform4i" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform4iEXT" alias="ProgramUniform4i" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLint"/>
         <param name="z" type="GLint"/>
         <param name="w" type="GLint"/>
     </function>
-    <function name="ProgramUniform1uiEXT" alias="ProgramUniform1ui" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform1uiEXT" alias="ProgramUniform1ui" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLuint"/>
     </function>
-    <function name="ProgramUniform2uiEXT" alias="ProgramUniform2ui" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform2uiEXT" alias="ProgramUniform2ui" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLuint"/>
         <param name="y" type="GLuint"/>
     </function>
-    <function name="ProgramUniform3uiEXT" alias="ProgramUniform3ui" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform3uiEXT" alias="ProgramUniform3ui" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLuint"/>
         <param name="y" type="GLuint"/>
         <param name="z" type="GLuint"/>
     </function>
-    <function name="ProgramUniform4uiEXT" alias="ProgramUniform4ui" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform4uiEXT" alias="ProgramUniform4ui" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLuint"/>
         <param name="z" type="GLuint"/>
         <param name="w" type="GLuint"/>
     </function>
-    <function name="ProgramUniform1fEXT" alias="ProgramUniform1f" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform1fEXT" alias="ProgramUniform1f" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLfloat"/>
     </function>
-    <function name="ProgramUniform2fEXT" alias="ProgramUniform2f" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform2fEXT" alias="ProgramUniform2f" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
     </function>
-    <function name="ProgramUniform3fEXT" alias="ProgramUniform3f" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform3fEXT" alias="ProgramUniform3f" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
     </function>
-    <function name="ProgramUniform4fEXT" alias="ProgramUniform4f" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform4fEXT" alias="ProgramUniform4f" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="x" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
         <param name="w" type="GLfloat"/>
     </function>
-    <function name="ProgramUniform1ivEXT" alias="ProgramUniform1iv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform1ivEXT" alias="ProgramUniform1iv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLint *"/>
     </function>
-    <function name="ProgramUniform2ivEXT" alias="ProgramUniform2iv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform2ivEXT" alias="ProgramUniform2iv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLint *"/>
     </function>
-    <function name="ProgramUniform3ivEXT" alias="ProgramUniform3iv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform3ivEXT" alias="ProgramUniform3iv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLint *"/>
     </function>
-    <function name="ProgramUniform4ivEXT" alias="ProgramUniform4iv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform4ivEXT" alias="ProgramUniform4iv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLint *"/>
     </function>
-    <function name="ProgramUniform1uivEXT" alias="ProgramUniform1uiv" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform1uivEXT" alias="ProgramUniform1uiv" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLuint *"/>
     </function>
-    <function name="ProgramUniform2uivEXT" alias="ProgramUniform2uiv" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform2uivEXT" alias="ProgramUniform2uiv" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLuint *"/>
     </function>
-    <function name="ProgramUniform3uivEXT" alias="ProgramUniform3uiv" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform3uivEXT" alias="ProgramUniform3uiv" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLuint *"/>
     </function>
-    <function name="ProgramUniform4uivEXT" alias="ProgramUniform4uiv" static_dispatch="false" es2="3.0">
+    <function name="ProgramUniform4uivEXT" alias="ProgramUniform4uiv" es2="3.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLuint *"/>
     </function>
-    <function name="ProgramUniform1fvEXT" alias="ProgramUniform1fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform1fvEXT" alias="ProgramUniform1fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniform2fvEXT" alias="ProgramUniform2fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform2fvEXT" alias="ProgramUniform2fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniform3fvEXT" alias="ProgramUniform3fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform3fvEXT" alias="ProgramUniform3fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniform4fvEXT" alias="ProgramUniform4fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniform4fvEXT" alias="ProgramUniform4fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix2fvEXT" alias="ProgramUniformMatrix2fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix2fvEXT" alias="ProgramUniformMatrix2fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix3fvEXT" alias="ProgramUniformMatrix3fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix3fvEXT" alias="ProgramUniformMatrix3fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix4fvEXT" alias="ProgramUniformMatrix4fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix4fvEXT" alias="ProgramUniformMatrix4fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix2x3fvEXT" alias="ProgramUniformMatrix2x3fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix2x3fvEXT" alias="ProgramUniformMatrix2x3fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix3x2fvEXT" alias="ProgramUniformMatrix3x2fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix3x2fvEXT" alias="ProgramUniformMatrix3x2fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix2x4fvEXT" alias="ProgramUniformMatrix2x4fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix2x4fvEXT" alias="ProgramUniformMatrix2x4fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix4x2fvEXT" alias="ProgramUniformMatrix4x2fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix4x2fvEXT" alias="ProgramUniformMatrix4x2fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix3x4fvEXT" alias="ProgramUniformMatrix3x4fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix3x4fvEXT" alias="ProgramUniformMatrix3x4fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ProgramUniformMatrix4x3fvEXT" alias="ProgramUniformMatrix4x3fv" static_dispatch="false" es2="2.0">
+    <function name="ProgramUniformMatrix4x3fvEXT" alias="ProgramUniformMatrix4x3fv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *"/>
     </function>
-    <function name="ValidateProgramPipelineEXT" alias="ValidateProgramPipeline" static_dispatch="false" es2="2.0">
+    <function name="ValidateProgramPipelineEXT" alias="ValidateProgramPipeline" es2="2.0">
         <param name="pipeline" type="GLuint"/>
     </function>
-    <function name="GetProgramPipelineInfoLogEXT" alias="GetProgramPipelineInfoLog" static_dispatch="false" es2="2.0">
+    <function name="GetProgramPipelineInfoLogEXT" alias="GetProgramPipelineInfoLog" es2="2.0">
         <param name="pipeline" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *"/>
index aca21f4b1253b3e36da2582586b7d8aa3dbc4be8..5f9ea2963d3f095db2397d00d7cb90c7ea857cd6 100644 (file)
     <enum name="LUMINANCE_INTEGER_EXT"                  value="0x8D9C"/>
     <enum name="LUMINANCE_ALPHA_INTEGER_EXT"            value="0x8D9D"/>
 
-    <function name="ClearColorIiEXT" offset="assign">
+    <function name="ClearColorIiEXT">
         <param name="r" type="GLint"/>
         <param name="g" type="GLint"/>
         <param name="b" type="GLint"/>
         <param name="a" type="GLint"/>
     </function>
 
-    <function name="ClearColorIuiEXT" offset="assign">
+    <function name="ClearColorIuiEXT">
         <param name="r" type="GLuint"/>
         <param name="g" type="GLuint"/>
         <param name="b" type="GLuint"/>
index 65259fc1fd4b1bf28ede566c6f5b5448b20ef01b..2aa26ad72514115c01faa0469406e797a0bf4e8e 100644 (file)
@@ -32,7 +32,7 @@
     <param name="size" type="GLsizeiptr"/>
   </function>
 
-  <function name="BindBufferOffsetEXT" offset="assign">
+  <function name="BindBufferOffsetEXT">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="buffer" type="GLuint"/>
   <enum name="TRANSFORM_FEEDBACK_BUFFER_ACTIVE"    value="0x8E24"/>
   <enum name="TRANSFORM_FEEDBACK_BINDING"          value="0x8E25"/>
 
-  <function name="BindTransformFeedback" offset="assign" es2="3.0">
+  <function name="BindTransformFeedback" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="id" type="GLuint"/>
   </function>
 
-  <function name="DeleteTransformFeedbacks" offset="assign" es2="3.0">
+  <function name="DeleteTransformFeedbacks" es2="3.0">
     <param name="n" type="GLsizei"/>
     <param name="ids" type="const GLuint *"/>
   </function>
 
-  <function name="GenTransformFeedbacks" offset="assign" es2="3.0">
+  <function name="GenTransformFeedbacks" es2="3.0">
     <param name="n" type="GLsizei"/>
     <param name="ids" type="GLuint *"/>
   </function>
 
-  <function name="IsTransformFeedback" offset="assign" es2="3.0">
+  <function name="IsTransformFeedback" es2="3.0">
     <param name="id" type="GLuint"/>
     <return type="GLboolean"/>
   </function>
 
-  <function name="PauseTransformFeedback" offset="assign" es2="3.0">
+  <function name="PauseTransformFeedback" es2="3.0">
   </function>
 
-  <function name="ResumeTransformFeedback" offset="assign" es2="3.0">
+  <function name="ResumeTransformFeedback" es2="3.0">
   </function>
 
-  <function name="DrawTransformFeedback" offset="assign" exec="dynamic">
+  <function name="DrawTransformFeedback" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="id" type="GLuint"/>
   </function>
index 5078f7b6d91ae1820867423399ec3ecbf0ead1b7..7919d6577740ac6e18236184e6266e90fe576fd8 100644 (file)
 
   <!-- These functions are unique to GL3 -->
 
-  <function name="ClearBufferiv" offset="assign" es2="3.0">
+  <function name="ClearBufferiv" es2="3.0">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="value" type="const GLint *"/>
   </function>
 
-  <function name="ClearBufferuiv" offset="assign" es2="3.0">
+  <function name="ClearBufferuiv" es2="3.0">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="value" type="const GLuint *"/>
   </function>
 
-  <function name="ClearBufferfv" offset="assign" es2="3.0">
+  <function name="ClearBufferfv" es2="3.0">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="value" type="const GLfloat *"/>
   </function>
 
-  <function name="ClearBufferfi" offset="assign" es2="3.0">
+  <function name="ClearBufferfi" es2="3.0">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="depth" type="GLfloat"/>
     <param name="stencil" type="GLint"/>
   </function>
 
-  <function name="GetStringi" offset="assign" es2="3.0">
+  <function name="GetStringi" es2="3.0">
     <param name="name" type="GLenum"/>
     <param name="index" type="GLuint"/>
       <return type="const GLubyte *"/>
   </function>
 
-  <function name="ClampColor" offset="assign">
+  <function name="ClampColor">
     <param name="target" type="GLenum"/>
     <param name="clamp" type="GLenum"/>
     <glx rop="234"/>
 
   <!-- These functions alias ones form GL_ARB_draw_buffers2 -->
 
-  <function name="ColorMaski" offset="assign">
+  <function name="ColorMaski">
     <param name="buf" type="GLuint"/>
     <param name="r" type="GLboolean"/>
     <param name="g" type="GLboolean"/>
     <param name="a" type="GLboolean"/>
   </function>
 
-  <function name="GetBooleani_v" offset="assign">
+  <function name="GetBooleani_v" es2="3.1">
     <param name="value" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="data" type="GLboolean *"/>
   </function>
 
-  <function name="GetIntegeri_v" es2="3.0" offset="assign">
+  <function name="GetIntegeri_v" es2="3.0">
     <param name="value" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="data" type="GLint *"/>
   </function>
 
-  <function name="Enablei" offset="assign">
+  <function name="Enablei">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
   </function>
 
-  <function name="Disablei" offset="assign">
+  <function name="Disablei">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
   </function>
 
-  <function name="IsEnabledi" offset="assign">
+  <function name="IsEnabledi">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
       <return type="GLboolean"/>
 
   <!-- These functions alias ones form GL_EXT_transform_feedback -->
 
-  <function name="GetFragDataLocation" es2="3.0" offset="assign">
+  <function name="GetFragDataLocation" es2="3.0">
     <param name="program" type="GLuint"/>
     <param name="name" type="const GLchar *"/>
       <return type="GLint"/>
   </function>
 
-  <function name="BindFragDataLocation" offset="assign">
+  <function name="BindFragDataLocation">
     <param name="program" type="GLuint"/>
     <param name="colorNumber" type="GLuint"/>
     <param name="name" type="const GLchar *"/>
   </function>
 
-  <function name="BeginTransformFeedback" es2="3.0" offset="assign">
+  <function name="BeginTransformFeedback" es2="3.0">
     <param name="mode" type="GLenum"/>
   </function>
 
-  <function name="EndTransformFeedback" es2="3.0" offset="assign">
+  <function name="EndTransformFeedback" es2="3.0">
   </function>
 
-  <function name="BindBufferRange" es2="3.0" offset="assign">
+  <function name="BindBufferRange" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="buffer" type="GLuint"/>
     <param name="size" type="GLsizeiptr"/>
   </function>
 
-  <function name="BindBufferBase" es2="3.0" offset="assign">
+  <function name="BindBufferBase" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="buffer" type="GLuint"/>
   </function>
 
-  <function name="TransformFeedbackVaryings" es2="3.0" offset="assign">
+  <function name="TransformFeedbackVaryings" es2="3.0">
     <param name="program" type="GLuint"/>
     <param name="count" type="GLsizei"/>
     <param name="varyings" type="const GLchar * const *"/>
     <param name="bufferMode" type="GLenum"/>
   </function>
 
-  <function name="GetTransformFeedbackVarying" es2="3.0" offset="assign">
+  <function name="GetTransformFeedbackVarying" es2="3.0">
     <param name="program" type="GLuint"/>
     <param name="index" type="GLuint"/>
     <param name="bufSize" type="GLsizei"/>
 
   <!-- These functions alias ones from GL_NV_conditional_render -->
 
-  <function name="BeginConditionalRender" offset="assign">
+  <function name="BeginConditionalRender">
     <param name="query" type="GLuint"/>
     <param name="mode" type="GLenum"/>
   </function>
 
-  <function name="EndConditionalRender" offset="assign">
+  <function name="EndConditionalRender">
   </function>
 
   <!-- These functions alias ones from GL_EXT_gpu_shader4 -->
 
-  <function name="VertexAttribIPointer" es2="3.0" offset="assign">
+  <function name="VertexAttribIPointer" es2="3.0">
     <param name="index" type="GLuint"/>
     <param name="size" type="GLint"/>
     <param name="type" type="GLenum"/>
     <param name="pointer" type="const GLvoid *"/>
   </function>
 
-  <function name="GetVertexAttribIiv" es2="3.0" offset="assign">
+  <function name="GetVertexAttribIiv" es2="3.0">
     <param name="index" type="GLuint"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="GLint *"/>
   </function>
 
-  <function name="GetVertexAttribIuiv" es2="3.0" offset="assign">
+  <function name="GetVertexAttribIuiv" es2="3.0">
     <param name="index" type="GLuint"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="GLuint *"/>
     <param name="w" type="GLuint"/>
   </function>
 
-  <function name="VertexAttribI1iv" offset="assign">
+  <function name="VertexAttribI1iv">
     <param name="index" type="GLuint"/>
     <param name="v" type="const GLint *"/>
   </function>
     <param name="v" type="const GLint *"/>
   </function>
 
-  <function name="VertexAttribI1uiv" offset="assign">
+  <function name="VertexAttribI1uiv">
     <param name="index" type="GLuint"/>
     <param name="v" type="const GLuint *"/>
   </function>
     <param name="v" type="const GLuint *"/>
   </function>
 
-  <function name="VertexAttribI4bv" offset="assign">
+  <function name="VertexAttribI4bv">
     <param name="index" type="GLuint"/>
     <param name="v" type="const GLbyte *"/>
   </function>
 
-  <function name="VertexAttribI4sv" offset="assign">
+  <function name="VertexAttribI4sv">
     <param name="index" type="GLuint"/>
     <param name="v" type="const GLshort *"/>
   </function>
 
-  <function name="VertexAttribI4ubv" offset="assign">
+  <function name="VertexAttribI4ubv">
     <param name="index" type="GLuint"/>
     <param name="v" type="const GLubyte *"/>
   </function>
 
-  <function name="VertexAttribI4usv" offset="assign">
+  <function name="VertexAttribI4usv">
     <param name="index" type="GLuint"/>
     <param name="v" type="const GLushort *"/>
   </function>
 
-  <function name="GetUniformuiv" es2="3.0" offset="assign">
+  <function name="GetUniformuiv" es2="3.0">
     <param name="program" type="GLuint"/>
     <param name="location" type="GLint"/>
     <param name="params" type="GLuint *"/>
   </function>
 
-  <function name="Uniform1ui" es2="3.0" offset="assign">
+  <function name="Uniform1ui" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="x" type="GLuint"/>
   </function>
 
-  <function name="Uniform2ui" es2="3.0" offset="assign">
+  <function name="Uniform2ui" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="x" type="GLuint"/>
     <param name="y" type="GLuint"/>
   </function>
 
-  <function name="Uniform3ui" es2="3.0" offset="assign">
+  <function name="Uniform3ui" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="x" type="GLuint"/>
     <param name="y" type="GLuint"/>
     <param name="z" type="GLuint"/>
   </function>
 
-  <function name="Uniform4ui" es2="3.0" offset="assign">
+  <function name="Uniform4ui" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="x" type="GLuint"/>
     <param name="y" type="GLuint"/>
     <param name="w" type="GLuint"/>
   </function>
 
-  <function name="Uniform1uiv" es2="3.0" offset="assign">
+  <function name="Uniform1uiv" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="count" type="GLsizei" counter="true"/>
     <param name="value" type="const GLuint *" count="count"/>
   </function>
 
-  <function name="Uniform2uiv" es2="3.0" offset="assign">
+  <function name="Uniform2uiv" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="count" type="GLsizei" counter="true"/>
     <param name="value" type="const GLuint *" count="count" count_scale="2"/>
   </function>
 
-  <function name="Uniform3uiv" es2="3.0" offset="assign">
+  <function name="Uniform3uiv" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="count" type="GLsizei" counter="true"/>
     <param name="value" type="const GLuint *" count="count" count_scale="3"/>
   </function>
 
-  <function name="Uniform4uiv" es2="3.0" offset="assign">
+  <function name="Uniform4uiv" es2="3.0">
     <param name="location" type="GLint"/>
     <param name="count" type="GLsizei" counter="true"/>
     <param name="value" type="const GLuint *" count="count" count_scale="4"/>
 
   <!-- These functions alias ones from GL_EXT_texture_integer -->
 
-  <function name="TexParameterIiv" offset="assign">
+  <function name="TexParameterIiv">
     <param name="target" type="GLenum"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="const GLint *"/>
   </function>
 
-  <function name="TexParameterIuiv" offset="assign">
+  <function name="TexParameterIuiv">
     <param name="target" type="GLenum"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="const GLuint *"/>
   </function>
 
-  <function name="GetTexParameterIiv" offset="assign">
+  <function name="GetTexParameterIiv">
     <param name="target" type="GLenum"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="GLint *"/>
   </function>
 
-  <function name="GetTexParameterIuiv" offset="assign">
+  <function name="GetTexParameterIuiv">
     <param name="target" type="GLenum"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="GLuint *"/>
     <param name="primcount" type="GLsizei"/>
   </function>
 
-  <function name="TexBuffer" offset="assign">
+  <function name="TexBuffer">
     <param name="target" type="GLenum"/>
     <param name="internalFormat" type="GLenum"/>
     <param name="buffer" type="GLuint"/>
   </function>
 
-  <function name="PrimitiveRestartIndex" offset="assign">
+  <function name="PrimitiveRestartIndex">
     <param name="index" type="GLuint"/>
   </function>
 
   <enum name="MAX_FRAGMENT_INPUT_COMPONENTS"        value="0x9125"/>
   <enum name="CONTEXT_PROFILE_MASK"                 value="0x9126"/>
 
-  <function name="GetInteger64i_v" offset="assign" es2="3.0">
+  <function name="GetInteger64i_v" es2="3.0">
     <param name="cap" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="data" type="GLint64 *"/>
   </function>
 
-  <function name="GetBufferParameteri64v" offset="assign" es2="3.0">
+  <function name="GetBufferParameteri64v" es2="3.0">
     <param name="target" type="GLenum"/>
     <param name="pname" type="GLenum"/>
     <param name="params" type="GLint64 *"/>
   </function>
 
-  <function name="FramebufferTexture" offset="assign">
+  <function name="FramebufferTexture">
     <param name="target" type="GLenum"/>
     <param name="attachment" type="GLenum"/>
     <param name="texture" type="GLuint"/>
   <enum name="TEXTURE_SWIZZLE_A"                value="0x8E45"/>
   <enum name="TEXTURE_SWIZZLE_RGBA"             value="0x8E46"/>
 
-  <function name="VertexAttribDivisor" offset="assign" es2="3.0">
+  <function name="VertexAttribDivisor" es2="3.0">
     <param name="index" type="GLuint"/>
     <param name="divisor" type="GLuint"/>
   </function>
index 848316e9eda56740d885dafee6762026004b4cc2..94ddfb7296078d8d9b8e5d7d762f50a7f9ab38e9 100644 (file)
@@ -9,17 +9,17 @@
   <enum name="SAMPLE_SHADING"                          value="0x8C36"/>
   <enum name="MIN_SAMPLE_SHADING_VALUE"                value="0x8C37"/>
 
-  <function name="MinSampleShading" offset="assign">
+  <function name="MinSampleShading">
     <param name="value" type="GLfloat"/>
   </function>
 
-  <function name="BlendFunci" static_dispatch="false" alias="BlendFunciARB">
+  <function name="BlendFunci" alias="BlendFunciARB">
     <param name="buf" type="GLuint"/>
     <param name="sfactor" type="GLenum"/>
     <param name="dfactor" type="GLenum"/>
   </function>
 
-  <function name="BlendFuncSeparatei" static_dispatch="false" alias="BlendFuncSeparateiARB">
+  <function name="BlendFuncSeparatei" alias="BlendFuncSeparateiARB">
     <param name="buf" type="GLuint"/>
     <param name="sfactorRGB" type="GLenum"/>
     <param name="dfactorRGB" type="GLenum"/>
     <param name="dfactorAlpha" type="GLenum"/>
   </function>
 
-  <function name="BlendEquationi" static_dispatch="false" alias="BlendEquationiARB">
+  <function name="BlendEquationi" alias="BlendEquationiARB">
     <param name="buf" type="GLuint"/>
     <param name="mode" type="GLenum"/>
   </function>
 
-  <function name="BlendEquationSeparatei" static_dispatch="false" alias="BlendEquationSeparateiARB" >
+  <function name="BlendEquationSeparatei" alias="BlendEquationSeparateiARB" >
     <param name="buf" type="GLuint"/>
     <param name="modeRGB" type="GLenum"/>
     <param name="modeA" type="GLenum"/>
index 25cd1817f5755aa17e589de21acfc18b996b765a..9573cb1bd6e4bda558d3590eb5abf686b56ff633 100644 (file)
@@ -5,21 +5,21 @@
 
 <category name="GL_INTEL_performance_query" number="443">
 
-  <function name="GetFirstPerfQueryIdINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="GetFirstPerfQueryIdINTEL" es2="2.0">
     <param name="queryId" type="GLuint *"/>
   </function>
 
-  <function name="GetNextPerfQueryIdINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="GetNextPerfQueryIdINTEL" es2="2.0">
     <param name="queryId" type="GLuint"/>
     <param name="nextQueryId" type="GLuint *"/>
   </function>
 
-  <function name="GetPerfQueryIdByNameINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="GetPerfQueryIdByNameINTEL" es2="2.0">
     <param name="queryName" type="GLchar *"/>
     <param name="queryId" type="GLuint *"/>
   </function>
 
-  <function name="GetPerfQueryInfoINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="GetPerfQueryInfoINTEL" es2="2.0">
     <param name="queryId" type="GLuint"/>
     <param name="queryNameLength" type="GLuint"/>
     <param name="queryName" type="GLchar *"/>
@@ -29,7 +29,7 @@
     <param name="capsMask" type="GLuint *"/>
   </function>
 
-  <function name="GetPerfCounterInfoINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="GetPerfCounterInfoINTEL" es2="2.0">
     <param name="queryId" type="GLuint"/>
     <param name="counterId" type="GLuint"/>
     <param name="counterNameLength" type="GLuint"/>
     <param name="rawCounterMaxValue" type="GLuint64 *"/>
   </function>
 
-  <function name="CreatePerfQueryINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="CreatePerfQueryINTEL" es2="2.0">
     <param name="queryId" type="GLuint"/>
     <param name="queryHandle" type="GLuint *"/>
   </function>
 
-  <function name="DeletePerfQueryINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="DeletePerfQueryINTEL" es2="2.0">
     <param name="queryHandle" type="GLuint"/>
   </function>
 
-  <function name="BeginPerfQueryINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="BeginPerfQueryINTEL" es2="2.0">
     <param name="queryHandle" type="GLuint"/>
   </function>
 
-  <function name="EndPerfQueryINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="EndPerfQueryINTEL" es2="2.0">
     <param name="queryHandle" type="GLuint"/>
   </function>
 
-  <function name="GetPerfQueryDataINTEL" offset="assign" static_dispatch="false" es2="2.0">
+  <function name="GetPerfQueryDataINTEL" es2="2.0">
     <param name="queryHandle" type="GLuint"/>
     <param name="flags" type="GLuint"/>
     <param name="dataSize" type="GLsizei"/>
index 48f7fa762bde4321fcf1784481fd7d37adbb3569..77956d61e385c45a40117518ec43b7db456920e1 100644 (file)
@@ -73,7 +73,7 @@
   <!-- Compatibility Profile -->
   <enum name="DISPLAY_LIST"                               value="0x82E7"/>
 
-  <function name="DebugMessageControl" offset="assign">
+  <function name="DebugMessageControl">
     <param name="source" type="GLenum"/>
     <param name="type" type="GLenum"/>
     <param name="severity" type="GLenum"/>
@@ -82,7 +82,7 @@
     <param name="enabled" type="GLboolean"/>
   </function>
 
-  <function name="DebugMessageInsert" offset="assign">
+  <function name="DebugMessageInsert">
     <param name="source" type="GLenum"/>
     <param name="type" type="GLenum"/>
     <param name="id" type="GLuint"/>
     <param name="buf" type="const GLchar *"/>
   </function>
 
-  <function name="DebugMessageCallback" offset="assign">
+  <function name="DebugMessageCallback">
     <param name="callback" type="GLDEBUGPROC"/>
     <param name="userParam" type="const GLvoid *"/>
   </function>
 
-  <function name="GetDebugMessageLog" offset="assign">
+  <function name="GetDebugMessageLog">
     <return type="GLuint"/>
     <param name="count" type="GLuint"/>
     <param name="bufsize" type="GLsizei"/>
     <param name="messageLog" type="GLchar *" output="true"/>
   </function>
 
-  <function name="PushDebugGroup" offset="assign">
+  <function name="PushDebugGroup">
     <param name="source" type="GLenum"/>
     <param name="id" type="GLuint"/>
     <param name="length" type="GLsizei"/>
     <param name="message" type="const GLchar *"/>
   </function>
 
-  <function name="PopDebugGroup" offset="assign"/>
+  <function name="PopDebugGroup" />
 
-  <function name="ObjectLabel" offset="assign">
+  <function name="ObjectLabel">
     <param name="identifier" type="GLenum"/>
     <param name="name" type="GLuint"/>
     <param name="length" type="GLsizei"/>
     <param name="label" type="const GLchar *"/>
   </function>
 
-  <function name="GetObjectLabel" offset="assign">
+  <function name="GetObjectLabel">
     <param name="identifier" type="GLenum"/>
     <param name="name" type="GLuint"/>
     <param name="bufSize" type="GLsizei"/>
     <param name="label" type="GLchar *"/>
   </function>
 
-  <function name="ObjectPtrLabel" offset="assign">
+  <function name="ObjectPtrLabel">
     <param name="ptr" type="const GLvoid *"/>
     <param name="length" type="GLsizei"/>
     <param name="label" type="const GLchar *"/>
   </function>
 
-  <function name="GetObjectPtrLabel" offset="assign">
+  <function name="GetObjectPtrLabel">
     <param name="ptr" type="const GLvoid *"/>
     <param name="bufSize" type="GLsizei"/>
     <param name="length" type="GLsizei *"/>
index c8d41746887c12dd4fd0c8a07cb17498db82122d..5b163b02e00bfb8124d67348bc6e38c07f4cd74d 100644 (file)
@@ -61,6 +61,7 @@ EXTRA_DIST= \
        $(MESA_GLAPI_DIR)/glapi_x86-64.S \
        $(MESA_GLAPI_DIR)/glapi_sparc.S \
        $(COMMON_GLX) \
+       apiexec.py \
        gl_apitemp.py \
        gl_enums.py \
        gl_genexec.py \
@@ -75,6 +76,7 @@ EXTRA_DIST= \
        glX_proto_size.py \
        glX_server_table.py \
        remap_helper.py \
+       static_data.py \
        SConscript \
        gl_API.dtd
 
@@ -129,6 +131,7 @@ API_XML = \
        ARB_draw_instanced.xml \
        ARB_ES2_compatibility.xml \
        ARB_ES3_compatibility.xml \
+       ARB_framebuffer_no_attachments.xml \
        ARB_framebuffer_object.xml \
        ARB_geometry_shader4.xml \
        ARB_get_program_binary.xml \
@@ -140,6 +143,7 @@ API_XML = \
        ARB_map_buffer_range.xml \
        ARB_multi_bind.xml \
        ARB_pipeline_statistics_query.xml \
+       ARB_program_interface_query.xml \
        ARB_robustness.xml \
        ARB_sample_shading.xml \
        ARB_sampler_objects.xml \
@@ -197,6 +201,7 @@ COMMON = $(API_XML) \
        gl_XML.py \
        glX_XML.py \
        license.py \
+       static_data.py \
        typeexpr.py
 
 COMMON_GLX = $(COMMON) glX_API.xml glX_XML.py glX_proto_common.py
@@ -264,7 +269,7 @@ $(MESA_GLAPI_DIR)/glapi_sparc.S: gl_SPARC_asm.py $(COMMON)
 $(MESA_DIR)/main/enums.c: gl_enums.py $(COMMON)
        $(PYTHON_GEN) $< -f $(srcdir)/gl_and_es_API.xml > $@
 
-$(MESA_DIR)/main/api_exec.c: gl_genexec.py $(COMMON)
+$(MESA_DIR)/main/api_exec.c: gl_genexec.py apiexec.py $(COMMON)
        $(PYTHON_GEN) $< -f $(srcdir)/gl_and_es_API.xml > $@
 
 $(MESA_DIR)/main/dispatch.h: gl_table.py $(COMMON)
@@ -287,7 +292,7 @@ $(MESA_GLX_DIR)/indirect_init.c: glX_proto_send.py $(COMMON_GLX)
 
 $(MESA_GLX_DIR)/indirect_size.h $(XORG_GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX)
        $(PYTHON_GEN) $< -f $(srcdir)/gl_API.xml -m size_h --only-set \
-           -h _INDIRECT_SIZE_H_ \
+           --header-tag _INDIRECT_SIZE_H_ \
          | $(INDENT) $(INDENT_FLAGS) > $@
 
 $(MESA_GLX_DIR)/indirect_size.c: glX_proto_size.py $(COMMON_GLX)
index 39edafe31c66b7065604feff0085997edcbd0c08..232665236b5473e81c5bb54d16a6832616804a9a 100644 (file)
@@ -11,9 +11,7 @@
     <enum name="PRIMITIVE_RESTART_NV"        value="0x8558"/>
     <enum name="PRIMITIVE_RESTART_INDEX_NV"  value="0x8559"/>
 
-    <function name="PrimitiveRestartNV" offset="assign" deprecated="3.1"
-              exec="dynamic">
-    </function>
+    <function name="PrimitiveRestartNV" deprecated="3.1" exec="dynamic"/>
 
     <function name="PrimitiveRestartIndexNV" alias="PrimitiveRestartIndex">
        <param name="index" type="GLuint"/>
index 52b1a3c08da3e2a58b57fd3c9cb829d56a207855..b4c361cc3e71178c0c47ac5df20a6343b78a9b96 100644 (file)
@@ -7,7 +7,7 @@
 <OpenGLAPI>
 
 <category name="GL_NV_texture_barrier" number="381">
-    <function name="TextureBarrierNV" offset="assign" />
+    <function name="TextureBarrierNV"/>
 </category>
 
 </OpenGLAPI>
index 0b19e1a85f6602e1578a871f2ff5ec5bbd1641a6..ceef7bdc9acb812208376c26564c69119de73579 100644 (file)
@@ -5,14 +5,14 @@
 
 <category name="GL_NV_vdpau_interop" number="396">
 
-    <function name="VDPAUInitNV" offset="assign">
+    <function name="VDPAUInitNV">
        <param name="vdpDevice" type="const GLvoid *"/>
        <param name="getProcAddress" type="const GLvoid *"/>
     </function>
 
-    <function name="VDPAUFiniNV" offset="assign"/>
+    <function name="VDPAUFiniNV"/>
 
-    <function name="VDPAURegisterVideoSurfaceNV" offset="assign">
+    <function name="VDPAURegisterVideoSurfaceNV">
         <return type="GLintptr"/>
        <param name="vdpSurface" type="const GLvoid *"/>
        <param name="target" type="GLenum"/>
@@ -20,7 +20,7 @@
        <param name="textureNames" type="const GLuint *"/>
     </function>
 
-    <function name="VDPAURegisterOutputSurfaceNV" offset="assign">
+    <function name="VDPAURegisterOutputSurfaceNV">
         <return type="GLintptr"/>
        <param name="vdpSurface" type="const GLvoid *"/>
        <param name="target" type="GLenum"/>
        <param name="textureNames" type="const GLuint *"/>
     </function>
 
-    <function name="VDPAUIsSurfaceNV" offset="assign">
+    <function name="VDPAUIsSurfaceNV">
         <return type="GLboolean"/>
        <param name="surface" type="GLintptr"/>
     </function>
 
-    <function name="VDPAUUnregisterSurfaceNV" offset="assign">
+    <function name="VDPAUUnregisterSurfaceNV">
        <param name="surface" type="GLintptr"/>
     </function>
 
-    <function name="VDPAUGetSurfaceivNV" offset="assign">
+    <function name="VDPAUGetSurfaceivNV">
        <param name="surface" type="GLintptr"/>
        <param name="pname" type="GLenum"/>
        <param name="bufSize" type="GLsizei"/>
        <param name="values" type="GLint *"/>
     </function>
 
-    <function name="VDPAUSurfaceAccessNV" offset="assign">
+    <function name="VDPAUSurfaceAccessNV">
        <param name="surface" type="GLintptr"/>
        <param name="access" type="GLenum"/>
     </function>
 
-    <function name="VDPAUMapSurfacesNV" offset="assign">
+    <function name="VDPAUMapSurfacesNV">
        <param name="numSurfaces" type="GLsizei"/>
        <param name="surfaces" type="const GLintptr *"/>
     </function>
 
-    <function name="VDPAUUnmapSurfacesNV" offset="assign">
+    <function name="VDPAUUnmapSurfacesNV">
        <param name="numSurfaces" type="GLsizei"/>
        <param name="surfaces" type="const GLintptr *"/>
     </function>
index a995cad6c95b65cdfbb68db6aa84e2481b5b8264..c483e91f1dfc65d36fbfae11817bb0754f9d59f6 100644 (file)
@@ -5,14 +5,12 @@
 
 <category name="GL_OES_EGL_image">
 
-    <function name="EGLImageTargetTexture2DOES" offset="assign" es1="1.0"
-              es2="2.0">
+    <function name="EGLImageTargetTexture2DOES" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="writeOffset" type="GLvoid *"/>
     </function>
 
-    <function name="EGLImageTargetRenderbufferStorageOES" offset="assign"
-              es1="1.0" es2="2.0">
+    <function name="EGLImageTargetRenderbufferStorageOES" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="writeOffset" type="GLvoid *"/>
     </function>
index d62d6e2ec51d37c01afc0c2f62e673411a537579..edd0acdba6f9aed866d716f840221df6bdc90eff 100644 (file)
     <type name="clampx"  size="4"                                    />
 
     <!-- OpenGL ES 1.0 -->
-    <function name="AlphaFuncxOES" static_dispatch="false"
-              es1="1.0" alias="AlphaFuncx">
+    <function name="AlphaFuncxOES" es1="1.0" alias="AlphaFuncx">
         <param name="func" type="GLenum"/>
         <param name="ref" type="GLclampx"/>
     </function>
 
-    <function name="ClearColorxOES" static_dispatch="false"
-              es1="1.0" alias="ClearColorx">
+    <function name="ClearColorxOES" es1="1.0" alias="ClearColorx">
         <param name="red" type="GLclampx"/>
         <param name="green" type="GLclampx"/>
         <param name="blue" type="GLclampx"/>
         <param name="alpha" type="GLclampx"/>
     </function>
 
-    <function name="ClearDepthxOES" static_dispatch="false"
-              es1="1.0" alias="ClearDepthx">
+    <function name="ClearDepthxOES" es1="1.0" alias="ClearDepthx">
         <param name="depth" type="GLclampx"/>
     </function>
 
-    <function name="Color4xOES" static_dispatch="false"
-              es1="1.0" alias="Color4x">
+    <function name="Color4xOES" es1="1.0" alias="Color4x">
         <param name="red" type="GLfixed"/>
         <param name="green" type="GLfixed"/>
         <param name="blue" type="GLfixed"/>
         <param name="alpha" type="GLfixed"/>
     </function>
 
-    <function name="DepthRangexOES" static_dispatch="false"
-              es1="1.0" alias="DepthRangex">
+    <function name="DepthRangexOES" es1="1.0" alias="DepthRangex">
         <param name="zNear" type="GLclampx"/>
         <param name="zFar" type="GLclampx"/>
     </function>
 
-    <function name="FogxOES" static_dispatch="false" es1="1.0" alias="Fogx">
+    <function name="FogxOES" es1="1.0" alias="Fogx">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="FogxvOES" static_dispatch="false"
-              es1="1.0" alias="Fogxv">
+    <function name="FogxvOES" es1="1.0" alias="Fogxv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="FrustumxOES" static_dispatch="false"
-              es1="1.0" alias="Frustumx">
+    <function name="FrustumxOES" es1="1.0" alias="Frustumx">
         <param name="left" type="GLfixed"/>
         <param name="right" type="GLfixed"/>
         <param name="bottom" type="GLfixed"/>
         <param name="zFar" type="GLfixed"/>
     </function>
 
-    <function name="LightModelxOES" static_dispatch="false"
-              es1="1.0" alias="LightModelx">
+    <function name="LightModelxOES" es1="1.0" alias="LightModelx">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="LightModelxvOES" static_dispatch="false"
-              es1="1.0" alias="LightModelxv">
+    <function name="LightModelxvOES" es1="1.0" alias="LightModelxv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="LightxOES" static_dispatch="false"
-              es1="1.0" alias="Lightx">
+    <function name="LightxOES" es1="1.0" alias="Lightx">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="LightxvOES" static_dispatch="false"
-              es1="1.0" alias="Lightxv">
+    <function name="LightxvOES" es1="1.0" alias="Lightxv">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="LineWidthxOES" static_dispatch="false"
-              es1="1.0" alias="LineWidthx">
+    <function name="LineWidthxOES" es1="1.0" alias="LineWidthx">
         <param name="width" type="GLfixed"/>
     </function>
 
-    <function name="LoadMatrixxOES" static_dispatch="false"
-              es1="1.0" alias="LoadMatrixx">
+    <function name="LoadMatrixxOES" es1="1.0" alias="LoadMatrixx">
         <param name="m" type="const GLfixed *"/>
     </function>
 
-    <function name="MaterialxOES" static_dispatch="false"
-              es1="1.0" alias="Materialx">
+    <function name="MaterialxOES" es1="1.0" alias="Materialx">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="MaterialxvOES" static_dispatch="false"
-              es1="1.0" alias="Materialxv">
+    <function name="MaterialxvOES" es1="1.0" alias="Materialxv">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="MultMatrixxOES" static_dispatch="false"
-              es1="1.0" alias="MultMatrixx">
+    <function name="MultMatrixxOES" es1="1.0" alias="MultMatrixx">
         <param name="m" type="const GLfixed *"/>
     </function>
 
-    <function name="MultiTexCoord4xOES" static_dispatch="false"
-              es1="1.0" alias="MultiTexCoord4x">
+    <function name="MultiTexCoord4xOES" es1="1.0" alias="MultiTexCoord4x">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfixed"/>
         <param name="t" type="GLfixed"/>
         <param name="q" type="GLfixed"/>
     </function>
 
-    <function name="Normal3xOES" static_dispatch="false"
-              es1="1.0" alias="Normal3x">
+    <function name="Normal3xOES" es1="1.0" alias="Normal3x">
         <param name="nx" type="GLfixed"/>
         <param name="ny" type="GLfixed"/>
         <param name="nz" type="GLfixed"/>
     </function>
 
-    <function name="OrthoxOES" static_dispatch="false"
-              es1="1.0" alias="Orthox">
+    <function name="OrthoxOES" es1="1.0" alias="Orthox">
         <param name="left" type="GLfixed"/>
         <param name="right" type="GLfixed"/>
         <param name="bottom" type="GLfixed"/>
         <param name="zFar" type="GLfixed"/>
     </function>
 
-    <function name="PointSizexOES" static_dispatch="false"
-              es1="1.0" alias="PointSizex">
+    <function name="PointSizexOES" es1="1.0" alias="PointSizex">
         <param name="size" type="GLfixed"/>
     </function>
 
-    <function name="PolygonOffsetxOES" static_dispatch="false"
-              es1="1.0" alias="PolygonOffsetx">
+    <function name="PolygonOffsetxOES" es1="1.0" alias="PolygonOffsetx">
         <param name="factor" type="GLfixed"/>
         <param name="units" type="GLfixed"/>
     </function>
 
-    <function name="RotatexOES" static_dispatch="false"
-              es1="1.0" alias="Rotatex">
+    <function name="RotatexOES" es1="1.0" alias="Rotatex">
         <param name="angle" type="GLfixed"/>
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
     </function>
 
-    <function name="SampleCoveragexOES" static_dispatch="false"
-              es1="1.0" alias="SampleCoveragex">
+    <function name="SampleCoveragexOES" es1="1.0" alias="SampleCoveragex">
         <param name="value" type="GLclampx"/>
         <param name="invert" type="GLboolean"/>
     </function>
 
-    <function name="ScalexOES" static_dispatch="false"
-              es1="1.0" alias="Scalex">
+    <function name="ScalexOES" es1="1.0" alias="Scalex">
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
     </function>
 
-    <function name="TexEnvxOES" static_dispatch="false"
-              es1="1.0" alias="TexEnvx">
+    <function name="TexEnvxOES" es1="1.0" alias="TexEnvx">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="TexEnvxvOES" static_dispatch="false"
-              es1="1.0" alias="TexEnvxv">
+    <function name="TexEnvxvOES" es1="1.0" alias="TexEnvxv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="TexParameterxOES" static_dispatch="false"
-              es1="1.0" alias="TexParameterx">
+    <function name="TexParameterxOES" es1="1.0" alias="TexParameterx">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="TranslatexOES" static_dispatch="false"
-              es1="1.0" alias="Translatex">
+    <function name="TranslatexOES" es1="1.0" alias="Translatex">
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
     </function>
 
     <!-- OpenGL ES 1.1 -->
-    <function name="ClipPlanexOES" static_dispatch="false"
-              es1="1.0" alias="ClipPlanex">
+    <function name="ClipPlanexOES" es1="1.0" alias="ClipPlanex">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="const GLfixed *"/>
     </function>
 
-    <function name="GetClipPlanexOES" static_dispatch="false"
+    <function name="GetClipPlanexOES"
               es1="1.0" desktop="false" alias="GetClipPlanex">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="GLfixed *"/>
     </function>
 
-    <function name="GetFixedvOES" static_dispatch="false"
-              es1="1.0" alias="GetFixedv">
+    <function name="GetFixedvOES" es1="1.0" alias="GetFixedv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *"/>
     </function>
 
-    <function name="GetLightxvOES" static_dispatch="false"
-              es1="1.0" alias="GetLightxv">
+    <function name="GetLightxvOES" es1="1.0" alias="GetLightxv">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *"/>
     </function>
 
-    <function name="GetMaterialxvOES" static_dispatch="false"
-              es1="1.0" alias="GetMaterialxv">
+    <function name="GetMaterialxvOES" es1="1.0" alias="GetMaterialxv">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *"/>
     </function>
 
-    <function name="GetTexEnvxvOES" static_dispatch="false"
-              es1="1.0" alias="GetTexEnvxv">
+    <function name="GetTexEnvxvOES" es1="1.0" alias="GetTexEnvxv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *"/>
     </function>
 
-    <function name="GetTexParameterxvOES"
-              static_dispatch="false" es1="1.0" alias="GetTexParameterxv">
+    <function name="GetTexParameterxvOES" es1="1.0" alias="GetTexParameterxv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *"/>
     </function>
 
-    <function name="PointParameterxOES" static_dispatch="false"
-              es1="1.0" alias="PointParameterx">
+    <function name="PointParameterxOES" es1="1.0" alias="PointParameterx">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="PointParameterxvOES"
-              static_dispatch="false" es1="1.0" alias="PointParameterxv">
+    <function name="PointParameterxvOES" es1="1.0" alias="PointParameterxv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="TexParameterxvOES" static_dispatch="false"
-              es1="1.0" alias="TexParameterxv">
+    <function name="TexParameterxvOES" es1="1.0" alias="TexParameterxv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
     <!-- texgen -->
-    <function name="GetTexGenxvOES" offset="assign" static_dispatch="false"
+    <function name="GetTexGenxvOES"
               es1="1.0" desktop="false">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="TexGenxOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="TexGenxOES" es1="1.0" desktop="false">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
     </function>
 
-    <function name="TexGenxvOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="TexGenxvOES" es1="1.0" desktop="false">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
index 8346b64ee83d8f836ed5dc0db826ff42be75faca..c6795042ee5dad1787f98b0502710b6112254090 100644 (file)
@@ -6,31 +6,27 @@
 <OpenGLAPI>
 
 <category name="GL_OES_single_precision" number="293">
-    <function name="ClearDepthfOES" alias="ClearDepthf" static_dispatch="false"
-              es1="1.0">
+    <function name="ClearDepthfOES" alias="ClearDepthf" es1="1.0">
         <param name="depth" type="GLclampf"/>
     </function>
 
-    <function name="ClipPlanefOES" static_dispatch="false"
-              es1="1.0" alias="ClipPlanef">
+    <function name="ClipPlanefOES" es1="1.0" alias="ClipPlanef">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="const GLfloat *"/>
     </function>
 
-    <function name="DepthRangefOES" alias="DepthRangef" static_dispatch="false"
-              es1="1.0">
+    <function name="DepthRangefOES" alias="DepthRangef" es1="1.0">
         <param name="zNear" type="GLclampf"/>
         <param name="zFar" type="GLclampf"/>
     </function>
 
-    <function name="GetClipPlanefOES" static_dispatch="false"
+    <function name="GetClipPlanefOES"
               es1="1.0" desktop="false" alias="GetClipPlanef">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="GLfloat *"/>
     </function>
 
-    <function name="FrustumfOES" static_dispatch="false"
-              es1="1.0" alias="Frustumf">
+    <function name="FrustumfOES" es1="1.0" alias="Frustumf">
         <param name="left" type="GLfloat"/>
         <param name="right" type="GLfloat"/>
         <param name="bottom" type="GLfloat"/>
@@ -39,8 +35,7 @@
         <param name="zFar" type="GLfloat"/>
     </function>
 
-    <function name="OrthofOES" static_dispatch="false"
-              es1="1.0" alias="Orthof">
+    <function name="OrthofOES" es1="1.0" alias="Orthof">
         <param name="left" type="GLfloat"/>
         <param name="right" type="GLfloat"/>
         <param name="bottom" type="GLfloat"/>
diff --git a/src/mapi/glapi/gen/apiexec.py b/src/mapi/glapi/gen/apiexec.py
new file mode 100644 (file)
index 0000000..b623b44
--- /dev/null
@@ -0,0 +1,245 @@
+# Copyright (C) 2015 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+class exec_info():
+    """Information relating GL APIs to a function.
+
+    Each of the four attributes of this class, compatibility, core, es1, and
+    es2, specify the minimum API version where a function can possibly exist
+    in Mesa.  The version is specified as an integer of (real GL version *
+    10).  For example, glCreateProgram was added in OpenGL 2.0, so
+    compatibility=20 and core=31.
+
+    If the attribute is None, then it cannot be supported by that
+    API.  For example, glNewList was removed from core profiles, so
+    compatibility=10 and core=None.
+
+    Each of the attributes that is not None must have a valid value.  The
+    valid ranges are:
+
+        compatiblity: [10, 30]
+        core: [31, )
+        es1: [10, 11]
+        es2: [20, )
+
+    These ranges are enforced by the constructor.
+    """
+    def __init__(self, compatibility=None, core=None, es1=None, es2=None):
+        if compatibility is not None:
+            assert isinstance(compatibility, int)
+            assert compatibility >= 10
+            assert compatibility <= 30
+
+        if core is not None:
+            assert isinstance(core, int)
+            assert core >= 31
+
+        if es1 is not None:
+            assert isinstance(es1, int)
+            assert es1 == 10 or es1 == 11
+
+        if es2 is not None:
+            assert isinstance(es2, int)
+            assert es2 >= 20
+
+        self.compatibility = compatibility
+        self.core = core
+        self.es1 = es1
+        self.es2 = es2
+
+functions = {
+    # OpenGL 3.1 / GL_ARB_texture_buffer_object.  Mesa only exposes this
+    # extension with core profile.
+    "TexBuffer": exec_info(core=31),
+
+    # OpenGL 3.2 / GL_ARB_geometry_shader4.  Mesa does not support
+    # GL_ARB_geometry_shader4, so OpenGL 3.2 is required.
+    "FramebufferTexture": exec_info(core=32),
+
+    # OpenGL 4.0 / GL_ARB_gpu_shader_fp64.  The extension spec says:
+    #
+    #     "OpenGL 3.2 and GLSL 1.50 are required."
+    "Uniform1d": exec_info(core=32),
+    "Uniform2d": exec_info(core=32),
+    "Uniform3d": exec_info(core=32),
+    "Uniform4d": exec_info(core=32),
+    "Uniform1dv": exec_info(core=32),
+    "Uniform2dv": exec_info(core=32),
+    "Uniform3dv": exec_info(core=32),
+    "Uniform4dv": exec_info(core=32),
+    "UniformMatrix2dv": exec_info(core=32),
+    "UniformMatrix3dv": exec_info(core=32),
+    "UniformMatrix4dv": exec_info(core=32),
+    "UniformMatrix2x3dv": exec_info(core=32),
+    "UniformMatrix2x4dv": exec_info(core=32),
+    "UniformMatrix3x2dv": exec_info(core=32),
+    "UniformMatrix3x4dv": exec_info(core=32),
+    "UniformMatrix4x2dv": exec_info(core=32),
+    "UniformMatrix4x3dv": exec_info(core=32),
+    "GetUniformdv": exec_info(core=32),
+
+    # OpenGL 4.1 / GL_ARB_vertex_attrib_64bit.  The extension spec says:
+    #
+    #     "OpenGL 3.0 and GLSL 1.30 are required.
+    #
+    #     ARB_gpu_shader_fp64 (or equivalent functionality) is required."
+    #
+    # For Mesa this effectively means OpenGL 3.2 is required.  It seems
+    # unlikely that Mesa will ever get support for any of the NV extensions
+    # that add "equivalent functionality."
+    "VertexAttribL1d": exec_info(core=32),
+    "VertexAttribL2d": exec_info(core=32),
+    "VertexAttribL3d": exec_info(core=32),
+    "VertexAttribL4d": exec_info(core=32),
+    "VertexAttribL1dv": exec_info(core=32),
+    "VertexAttribL2dv": exec_info(core=32),
+    "VertexAttribL3dv": exec_info(core=32),
+    "VertexAttribL4dv": exec_info(core=32),
+    "VertexAttribLPointer": exec_info(core=32),
+    "GetVertexAttribLdv": exec_info(core=32),
+
+    # OpenGL 4.1 / GL_ARB_viewport_array.  The extension spec says:
+    #
+    #     "OpenGL 3.2 or the EXT_geometry_shader4 or ARB_geometry_shader4
+    #     extensions are required."
+    #
+    # Mesa does not support either of the geometry shader extensions, so
+    # OpenGL 3.2 is required.
+    "ViewportArrayv": exec_info(core=32),
+    "ViewportIndexedf": exec_info(core=32),
+    "ViewportIndexedfv": exec_info(core=32),
+    "ScissorArrayv": exec_info(core=32),
+    "ScissorIndexed": exec_info(core=32),
+    "ScissorIndexedv": exec_info(core=32),
+    "DepthRangeArrayv": exec_info(core=32),
+    "DepthRangeIndexed": exec_info(core=32),
+    # GetFloati_v also GL_ARB_shader_atomic_counters
+    # GetDoublei_v also GL_ARB_shader_atomic_counters
+
+    # OpenGL 4.3 / GL_ARB_texture_buffer_range.  Mesa can expose the extension
+    # with OpenGL 3.1.
+    "TexBufferRange": exec_info(core=31),
+
+    # OpenGL 4.3 / GL_ARB_framebuffer_no_attachments.  Mesa can expose the
+    # extension with OpenGL 3.0.
+    "FramebufferParameteri": exec_info(compatibility=30, core=31),
+    "GetFramebufferParameteri": exec_info(compatibility=30, core=31),
+
+    # OpenGL 4.5 / GL_ARB_direct_state_access.   Mesa can expose the extension
+    # with core profile.
+    "CreateTransformFeedbacks": exec_info(core=31),
+    "TransformFeedbackBufferBase": exec_info(core=31),
+    "TransformFeedbackBufferRange": exec_info(core=31),
+    "GetTransformFeedbackiv": exec_info(core=31),
+    "GetTransformFeedbacki_v": exec_info(core=31),
+    "GetTransformFeedbacki64_v": exec_info(core=31),
+    "CreateBuffers": exec_info(core=31),
+    "NamedBufferStorage": exec_info(core=31),
+    "NamedBufferData": exec_info(core=31),
+    "NamedBufferSubData": exec_info(core=31),
+    "CopyNamedBufferSubData": exec_info(core=31),
+    "ClearNamedBufferData": exec_info(core=31),
+    "ClearNamedBufferSubData": exec_info(core=31),
+    "MapNamedBuffer": exec_info(core=31),
+    "MapNamedBufferRange": exec_info(core=31),
+    "UnmapNamedBuffer": exec_info(core=31),
+    "FlushMappedNamedBufferRange": exec_info(core=31),
+    "GetNamedBufferParameteriv": exec_info(core=31),
+    "GetNamedBufferParameteri64v": exec_info(core=31),
+    "GetNamedBufferPointerv": exec_info(core=31),
+    "GetNamedBufferSubData": exec_info(core=31),
+    "CreateFramebuffers": exec_info(core=31),
+    "NamedFramebufferRenderbuffer": exec_info(core=31),
+    "NamedFramebufferParameteri": exec_info(core=31),
+    "NamedFramebufferTexture": exec_info(core=31),
+    "NamedFramebufferTextureLayer": exec_info(core=31),
+    "NamedFramebufferDrawBuffer": exec_info(core=31),
+    "NamedFramebufferDrawBuffers": exec_info(core=31),
+    "NamedFramebufferReadBuffer": exec_info(core=31),
+    "InvalidateNamedFramebufferData": exec_info(core=31),
+    "InvalidateNamedFramebufferSubData": exec_info(core=31),
+    "ClearNamedFramebufferiv": exec_info(core=31),
+    "ClearNamedFramebufferuiv": exec_info(core=31),
+    "ClearNamedFramebufferfv": exec_info(core=31),
+    "ClearNamedFramebufferfi": exec_info(core=31),
+    "BlitNamedFramebuffer": exec_info(core=31),
+    "CheckNamedFramebufferStatus": exec_info(core=31),
+    "GetNamedFramebufferParameteriv": exec_info(core=31),
+    "GetNamedFramebufferAttachmentParameteriv": exec_info(core=31),
+    "CreateRenderbuffers": exec_info(core=31),
+    "NamedRenderbufferStorage": exec_info(core=31),
+    "NamedRenderbufferStorageMultisample": exec_info(core=31),
+    "GetNamedRenderbufferParameteriv": exec_info(core=31),
+    "CreateTextures": exec_info(core=31),
+    "TextureBuffer": exec_info(core=31),
+    "TextureBufferRange": exec_info(core=31),
+    "TextureStorage1D": exec_info(core=31),
+    "TextureStorage2D": exec_info(core=31),
+    "TextureStorage3D": exec_info(core=31),
+    "TextureStorage2DMultisample": exec_info(core=31),
+    "TextureStorage3DMultisample": exec_info(core=31),
+    "TextureSubImage1D": exec_info(core=31),
+    "TextureSubImage2D": exec_info(core=31),
+    "TextureSubImage3D": exec_info(core=31),
+    "CompressedTextureSubImage1D": exec_info(core=31),
+    "CompressedTextureSubImage2D": exec_info(core=31),
+    "CompressedTextureSubImage3D": exec_info(core=31),
+    "CopyTextureSubImage1D": exec_info(core=31),
+    "CopyTextureSubImage2D": exec_info(core=31),
+    "CopyTextureSubImage3D": exec_info(core=31),
+    "TextureParameterf": exec_info(core=31),
+    "TextureParameterfv": exec_info(core=31),
+    "TextureParameteri": exec_info(core=31),
+    "TextureParameterIiv": exec_info(core=31),
+    "TextureParameterIuiv": exec_info(core=31),
+    "TextureParameteriv": exec_info(core=31),
+    "GenerateTextureMipmap": exec_info(core=31),
+    "BindTextureUnit": exec_info(core=31),
+    "GetTextureImage": exec_info(core=31),
+    "GetCompressedTextureImage": exec_info(core=31),
+    "GetTextureLevelParameterfv": exec_info(core=31),
+    "GetTextureLevelParameteriv": exec_info(core=31),
+    "GetTextureParameterfv": exec_info(core=31),
+    "GetTextureParameterIiv": exec_info(core=31),
+    "GetTextureParameterIuiv": exec_info(core=31),
+    "GetTextureParameteriv": exec_info(core=31),
+    "CreateVertexArrays": exec_info(core=31),
+    "DisableVertexArrayAttrib": exec_info(core=31),
+    "EnableVertexArrayAttrib": exec_info(core=31),
+    "VertexArrayElementBuffer": exec_info(core=31),
+    "VertexArrayVertexBuffer": exec_info(core=31),
+    "VertexArrayVertexBuffers": exec_info(core=31),
+    "VertexArrayAttribFormat": exec_info(core=31),
+    "VertexArrayAttribIFormat": exec_info(core=31),
+    "VertexArrayAttribLFormat": exec_info(core=31),
+    "VertexArrayAttribBinding": exec_info(core=31),
+    "VertexArrayBindingDivisor": exec_info(core=31),
+    "GetVertexArrayiv": exec_info(core=31),
+    "GetVertexArrayIndexediv": exec_info(core=31),
+    "GetVertexArrayIndexed64iv": exec_info(core=31),
+    "CreateSamplers": exec_info(core=31),
+    "CreateProgramPipelines": exec_info(core=31),
+    "CreateQueries": exec_info(core=31),
+    "GetQueryBufferObjectiv": exec_info(core=31),
+    "GetQueryBufferObjectuiv": exec_info(core=31),
+    "GetQueryBufferObjecti64v": exec_info(core=31),
+    "GetQueryBufferObjectui64v": exec_info(core=31),
+}
index 3a2adeb0491631f2133ceac60a9308721bd89289..642e3b319bb8d3e50d7720494e2008b285afc60c 100644 (file)
@@ -11,7 +11,7 @@
     <enum name="BLEND_EQUATION_ALPHA_OES"                 value="0x883D"/>
 
     <function name="BlendEquationSeparateOES" alias="BlendEquationSeparate"
-              static_dispatch="false" es1="1.0">
+             es1="1.0">
         <param name="modeRGB" type="GLenum"/>
         <param name="modeA" type="GLenum"/>
     </function>
@@ -24,8 +24,7 @@
     <enum name="BLEND_DST_ALPHA_OES"                      value="0x80CA"/>
     <enum name="BLEND_SRC_ALPHA_OES"                      value="0x80CB"/>
 
-    <function name="BlendFuncSeparateOES" alias="BlendFuncSeparate"
-              static_dispatch="false" es1="1.0">
+    <function name="BlendFuncSeparateOES" alias="BlendFuncSeparate" es1="1.0">
         <param name="sfactorRGB" type="GLenum"/>
         <param name="dfactorRGB" type="GLenum"/>
         <param name="sfactorAlpha" type="GLenum"/>
@@ -40,8 +39,7 @@
     <enum name="FUNC_SUBTRACT_OES"                        value="0x800A"/>
     <enum name="FUNC_REVERSE_SUBTRACT_OES"                value="0x800B"/>
 
-    <function name="BlendEquationOES" alias="BlendEquation"
-              static_dispatch="false" es1="1.0">
+    <function name="BlendEquationOES" alias="BlendEquation" es1="1.0">
         <param name="mode" type="GLenum"/>
     </function>
 </category>
@@ -72,8 +70,7 @@
 <category name="GL_OES_draw_texture" number="7">
     <enum name="TEXTURE_CROP_RECT_OES"                    value="0x8B9D"/>
 
-    <function name="DrawTexiOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexiOES" es1="1.0" desktop="false">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
         <param name="height" type="GLint"/>
     </function>
 
-    <function name="DrawTexivOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexivOES" es1="1.0" desktop="false">
         <param name="coords" type="const GLint *" count="5"/>
     </function>
 
-    <function name="DrawTexfOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexfOES" es1="1.0" desktop="false">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
         <param name="height" type="GLfloat"/>
     </function>
 
-    <function name="DrawTexfvOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexfvOES" es1="1.0" desktop="false">
         <param name="coords" type="const GLfloat *" count="5"/>
     </function>
 
-    <function name="DrawTexsOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexsOES" es1="1.0" desktop="false">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
         <param name="height" type="GLshort"/>
     </function>
 
-    <function name="DrawTexsvOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexsvOES" es1="1.0" desktop="false">
         <param name="coords" type="const GLshort *" count="5"/>
     </function>
 
-    <function name="DrawTexxOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexxOES" es1="1.0" desktop="false">
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
         <param name="height" type="GLfixed"/>
     </function>
 
-    <function name="DrawTexxvOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="DrawTexxvOES" es1="1.0" desktop="false">
         <param name="coords" type="const GLfixed *" count="5"/>
     </function>
 
     <enum name="RENDERBUFFER_STENCIL_SIZE_OES"            value="0x8D55"/>
     <enum name="RGB565_OES"                               value="0x8D62"/>
 
-    <function name="BindFramebufferOES" alias="BindFramebuffer"
-              static_dispatch="false" es1="1.0">
+    <function name="BindFramebufferOES" alias="BindFramebuffer" es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="framebuffer" type="GLuint"/>
     </function>
 
-    <function name="BindRenderbufferOES" alias="BindRenderbuffer"
-              static_dispatch="false" es1="1.0">
+    <function name="BindRenderbufferOES" alias="BindRenderbuffer" es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="renderbuffer" type="GLuint"/>
     </function>
 
     <function name="CheckFramebufferStatusOES"
-              alias="CheckFramebufferStatus" static_dispatch="false"
-              es1="1.0">
+              alias="CheckFramebufferStatus" es1="1.0">
         <param name="target" type="GLenum"/>
        <return type="GLenum"/>
     </function>
 
-    <function name="DeleteFramebuffersOES" alias="DeleteFramebuffers"
-              static_dispatch="false" es1="1.0">
+    <function name="DeleteFramebuffersOES" alias="DeleteFramebuffers" es1="1.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="framebuffers" type="const GLuint *" count="n"/>
     </function>
 
     <function name="DeleteRenderbuffersOES" alias="DeleteRenderbuffers"
-              static_dispatch="false" es1="1.0">
+             es1="1.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="renderbuffers" type="const GLuint *" count="n"/>
     </function>
 
     <function name="FramebufferRenderbufferOES"
-              alias="FramebufferRenderbuffer" static_dispatch="false"
-              es1="1.0">
+              alias="FramebufferRenderbuffer" es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="renderbuffertarget" type="GLenum"/>
     </function>
 
     <function name="FramebufferTexture2DOES" alias="FramebufferTexture2D"
-              static_dispatch="false" es1="1.0">
+             es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="textarget" type="GLenum"/>
         <param name="level" type="GLint"/>
     </function>
 
-    <function name="GenerateMipmapOES" alias="GenerateMipmap"
-              static_dispatch="false" es1="1.0">
+    <function name="GenerateMipmapOES" alias="GenerateMipmap" es1="1.0">
         <param name="target" type="GLenum"/>
     </function>
 
-    <function name="GenFramebuffersOES" alias="GenFramebuffers"
-              static_dispatch="false" es1="1.0">
+    <function name="GenFramebuffersOES" alias="GenFramebuffers" es1="1.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="framebuffers" type="GLuint *" count="n" output="true"/>
     </function>
 
-    <function name="GenRenderbuffersOES" alias="GenRenderbuffers"
-              static_dispatch="false" es1="1.0">
+    <function name="GenRenderbuffersOES" alias="GenRenderbuffers" es1="1.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="renderbuffers" type="GLuint *" count="n" output="true"/>
     </function>
 
     <function name="GetFramebufferAttachmentParameterivOES"
-              alias="GetFramebufferAttachmentParameteriv"
-              static_dispatch="false" es1="1.0">
+              alias="GetFramebufferAttachmentParameteriv" es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="pname" type="GLenum"/>
     </function>
 
     <function name="GetRenderbufferParameterivOES"
-              alias="GetRenderbufferParameteriv" static_dispatch="false"
-              es1="1.0">
+              alias="GetRenderbufferParameteriv" es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true"/>
     </function>
 
-    <function name="IsFramebufferOES" alias="IsFramebuffer"
-              static_dispatch="false" es1="1.0">
+    <function name="IsFramebufferOES" alias="IsFramebuffer" es1="1.0">
         <param name="framebuffer" type="GLuint"/>
        <return type="GLboolean"/>
     </function>
 
-    <function name="IsRenderbufferOES" alias="IsRenderbuffer"
-              static_dispatch="false" es1="1.0">
+    <function name="IsRenderbufferOES" alias="IsRenderbuffer" es1="1.0">
         <param name="renderbuffer" type="GLuint"/>
        <return type="GLboolean"/>
     </function>
 
     <function name="RenderbufferStorageOES" alias="RenderbufferStorage"
-              static_dispatch="false" es1="1.0">
+             es1="1.0">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
     <enum name="MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES"    value="0x8B9E"/>
 
     <function name="CurrentPaletteMatrixOES" alias="CurrentPaletteMatrixARB"
-              static_dispatch="false" exec="skip">
+             exec="skip">
         <param name="matrixpaletteindex" type="GLuint"/>
     </function>
 
     <!-- no offset -->
-    <function name="LoadPaletteFromModelViewMatrixOES" static_dispatch="false"
-              exec="skip">
+    <function name="LoadPaletteFromModelViewMatrixOES" exec="skip">
     </function>
 
     <function name="MatrixIndexPointerOES" alias="MatrixIndexPointerARB"
-              static_dispatch="false" exec="skip">
+             exec="skip">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
     </function>
 
-    <function name="WeightPointerOES" alias="WeightPointerARB"
-              static_dispatch="false" exec="skip">
+    <function name="WeightPointerOES" alias="WeightPointerARB" exec="skip">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
     <enum name="POINT_SIZE_ARRAY_OES"                     value="0x8B9C"/>
     <enum name="POINT_SIZE_ARRAY_BUFFER_BINDING_OES"     value="0x8B9F"/>
 
-    <function name="PointSizePointerOES" offset="assign"
-              static_dispatch="true" es1="1.0" desktop="false">
+    <function name="PointSizePointerOES" es1="1.0" desktop="false">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
 
 <!-- optional for es1.0 -->
 <category name="GL_OES_query_matrix" number="16">
-    <function name="QueryMatrixxOES" offset="assign" static_dispatch="false"
-              es1="1.0" desktop="false">
+    <function name="QueryMatrixxOES" es1="1.0" desktop="false">
         <param name="mantissa" type="GLfixed *" count="16" />
         <param name="exponent" type="GLint *" count="16" />
        <return type="GLbitfield"/>
     <enum name="MAX_CUBE_MAP_TEXTURE_SIZE_OES"            value="0x851C"/>
     <enum name="TEXTURE_GEN_STR_OES"                      value="0x8D60"/>
 
-    <function name="GetTexGenfvOES" alias="GetTexGenfv" static_dispatch="false"
-              es1="1.0">
+    <function name="GetTexGenfvOES" alias="GetTexGenfv" es1="1.0">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="GetTexGenivOES" alias="GetTexGeniv" static_dispatch="false"
-              es1="1.0">
+    <function name="GetTexGenivOES" alias="GetTexGeniv" es1="1.0">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="TexGenfOES" alias="TexGenf" static_dispatch="false"
-              es1="1.0">
+    <function name="TexGenfOES" alias="TexGenf" es1="1.0">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
     </function>
 
-    <function name="TexGenfvOES" alias="TexGenfv" static_dispatch="false"
-              es1="1.0">
+    <function name="TexGenfvOES" alias="TexGenfv" es1="1.0">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
     </function>
 
-    <function name="TexGeniOES" alias="TexGeni" static_dispatch="false"
-              es1="1.0">
+    <function name="TexGeniOES" alias="TexGeni" es1="1.0">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
     </function>
 
-    <function name="TexGenivOES" alias="TexGeniv" static_dispatch="false"
-              es1="1.0">
+    <function name="TexGenivOES" alias="TexGeniv" es1="1.0">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
     <enum name="BUFFER_MAP_POINTER_OES"                   value="0x88BD"/>
 
     <function name="GetBufferPointervOES" alias="GetBufferPointerv"
-              static_dispatch="false" es1="1.0" es2="2.0">
+             es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLvoid **"/>
     </function>
 
-    <function name="MapBufferOES" alias="MapBuffer" static_dispatch="false"
-              es1="1.0" es2="2.0">
+    <function name="MapBufferOES" alias="MapBuffer" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="access" type="GLenum"/>
        <return type="GLvoid *"/>
     </function>
 
-    <function name="UnmapBufferOES" alias="UnmapBuffer"
-              static_dispatch="false" es1="1.0" es2="2.0">
+    <function name="UnmapBufferOES" alias="UnmapBuffer" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
        <return type="GLboolean"/>
     </function>
     <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES" value="0x8CD4"/>
 
     <function name="CompressedTexImage3DOES" alias="CompressedTexImage3D"
-              static_dispatch="false" es2="2.0">
+             es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
     </function>
 
     <function name="CompressedTexSubImage3DOES"
-              alias="CompressedTexSubImage3D" static_dispatch="false"
-              es2="2.0">
+              alias="CompressedTexSubImage3D" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <param name="data" type="const GLvoid *" count="imageSize"/>
     </function>
 
-    <function name="CopyTexSubImage3DOES" alias="CopyTexSubImage3D"
-              static_dispatch="false" es2="2.0">
+    <function name="CopyTexSubImage3DOES" alias="CopyTexSubImage3D" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
     </function>
 
     <function name="FramebufferTexture3DOES" alias="FramebufferTexture3D"
-              static_dispatch="false" es2="2.0">
+             es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="textarget" type="GLenum"/>
         <param name="zoffset" type="GLint"/>
     </function>
 
-    <function name="TexImage3DOES" alias="TexImage3D" static_dispatch="false"
-              es2="2.0">
+    <function name="TexImage3DOES" alias="TexImage3D" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
         <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type" img_target="target" img_null_flag="true" img_pad_dimensions="true"/>
     </function>
 
-    <function name="TexSubImage3DOES" alias="TexSubImage3D"
-              static_dispatch="false" es2="2.0">
+    <function name="TexSubImage3DOES" alias="TexSubImage3D" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
     <enum name="NUM_PROGRAM_BINARY_FORMATS_OES"           value="0x87FE"/>
     <enum name="PROGRAM_BINARY_FORMATS_OES"               value="0x87FF"/>
 
-    <function name="GetProgramBinaryOES" alias="GetProgramBinary"
-              static_dispatch="false" es2="2.0">
+    <function name="GetProgramBinaryOES" alias="GetProgramBinary" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *"/>
         <param name="binary" type="GLvoid *"/>
     </function>
 
-    <function name="ProgramBinaryOES" alias="ProgramBinary"
-              static_dispatch="false" es2="2.0">
+    <function name="ProgramBinaryOES" alias="ProgramBinary" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="binaryFormat" type="GLenum"/>
         <param name="binary" type="const GLvoid *"/>
 <!-- 64. GL_EXT_discard_framebuffer -->
 
 <category name="GL_EXT_discard_framebuffer" number="64">
-    <function name="DiscardFramebufferEXT" es1="1.0" es2="2.0"
-              offset="assign" static_dispatch="false" desktop="false">
+    <function name="DiscardFramebufferEXT" es1="1.0" es2="2.0" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="numAttachments" type="GLsizei"/>
         <param name="attachments" type="const GLenum *" count="numAttachments"/>
 
 <!-- 71. GL_OES_vertex_array_object -->
 <category name="GL_OES_vertex_array_object" number="71">
-    <function name="BindVertexArrayOES" alias="BindVertexArray"
-              static_dispatch="false" es2="2.0">
+    <function name="BindVertexArrayOES" alias="BindVertexArray" es2="2.0">
         <param name="array" type="GLuint"/>
     </function>
 
-    <function name="DeleteVertexArraysOES" alias="DeleteVertexArrays"
-              static_dispatch="false" es2="2.0">
+    <function name="DeleteVertexArraysOES" alias="DeleteVertexArrays" es2="2.0">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="const GLuint *" count="n"/>
     </function>
 
-    <function name="GenVertexArraysOES" alias="GenVertexArrays"
-              static_dispatch="false" es2="2.0">
+    <function name="GenVertexArraysOES" alias="GenVertexArrays" es2="2.0">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="GLuint *" output="true" count="n"/>
     </function>
 
-    <function name="IsVertexArrayOES" alias="IsVertexArray"
-              static_dispatch="false" es2="2.0">
+    <function name="IsVertexArrayOES" alias="IsVertexArray" es2="2.0">
         <param name="array" type="GLuint"/>
         <return type="GLboolean"/>
     </function>
         <size name="Get" mode="get"/>
     </enum>
 
-    <function name="DrawBuffersNV" alias="DrawBuffers"
-              static_dispatch="false" es2="2.0">
+    <function name="DrawBuffersNV" alias="DrawBuffers" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="bufs" type="const GLenum *" count="n"/>
     </function>
 
 <!-- 93. GL_NV_read_buffer -->
 <category name="GL_NV_read_buffer">
-    <function name="ReadBufferNV" alias="ReadBuffer"
-              static_dispatch="false" es2="2.0">
+    <function name="ReadBufferNV" alias="ReadBuffer" es2="2.0">
         <param name="mode" type="GLenum"/>
     </function>
 </category>
     <enum name="MAP_UNSYNCHRONIZED_BIT_EXT"               value="0x0020"/>
 
     <function name="MapBufferRangeEXT" alias="MapBufferRange"
-              static_dispatch="false" es1="1.0" es2="2.0">
+             es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="size" type="GLsizeiptr"/>
     </function>
 
     <function name="FlushMappedBufferRangeEXT" alias="FlushMappedBufferRange"
-              static_dispatch="false" es1="1.0" es2="2.0">
+             es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="length" type="GLsizeiptr"/>
 
 <!-- 151. GL_EXT_draw_buffers -->
 <category name="GL_EXT_draw_buffers" number="151">
-    <function name="DrawBuffersEXT" alias="DrawBuffers"
-              static_dispatch="false" es2="2.0">
+    <function name="DrawBuffersEXT" alias="DrawBuffers" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="bufs" type="const GLenum *" count="n"/>
     </function>
index d076409c2faccd8083bff9131b10f1d3d31ce19b..da468dc587665e4bfaa620a0b1ce278044480da0 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+import string
+
 import gl_XML, glX_XML, glX_proto_common, license
-import sys, getopt, string
 
 
 class PrintGlxDispatch_h(gl_XML.gl_print_base):
@@ -524,31 +526,39 @@ class PrintGlxDispatchFunctions(glX_proto_common.glx_print_proto):
         return
 
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:m:s")
-    except Exception,e:
-        show_usage()
-
-    mode = "dispatch_c"
-    do_swap = 0
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-m":
-            mode = val
-        elif arg == "-s":
-            do_swap = 1
-
-    if mode == "dispatch_c":
-        printer = PrintGlxDispatchFunctions(do_swap)
-    elif mode == "dispatch_h":
+def _parser():
+    """Parse any arguments passed and return a namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='an xml file describing an OpenGL API')
+    parser.add_argument('-m',
+                        dest='mode',
+                        default='dispatch_c',
+                        choices=['dispatch_c', 'dispatch_h'],
+                        help='what file to generate')
+    parser.add_argument('-s',
+                        dest='swap',
+                        action='store_true',
+                        help='emit swap in GlXDispatchFunctions')
+    return parser.parse_args()
+
+
+def main():
+    """Main function."""
+    args = _parser()
+
+    if args._mode == "dispatch_c":
+        printer = PrintGlxDispatchFunctions(args.swap)
+    elif args._mode == "dispatch_h":
         printer = PrintGlxDispatch_h()
-    else:
-        show_usage()
 
-    api = gl_XML.parse_GL_API( file_name, glX_proto_common.glx_proto_item_factory() )
+    api = gl_XML.parse_GL_API(
+        args.filename, glX_proto_common.glx_proto_item_factory())
+
+    printer.Print(api)
 
-    printer.Print( api )
+
+if __name__ == '__main__':
+    main()
index b93989f753a5c6c0398ebbb436496360a5d3adef..2b3303078a21c6517d93cab4c6c1ab142c28d2d5 100644 (file)
@@ -2,6 +2,7 @@
 
 # (C) Copyright IBM Corporation 2004, 2005
 # All Rights Reserved.
+# Copyright (c) 2015 Intel Corporation
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
 #    Ian Romanick <idr@us.ibm.com>
 #    Jeremy Kolb <jkolb@brandeis.edu>
 
+import argparse
+
 import gl_XML, glX_XML, glX_proto_common, license
-import sys, getopt, copy, string
+import copy, string
 
 def convertStringForXCB(str):
     tmp = ""
@@ -1085,42 +1088,41 @@ extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
         print '#endif'
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
-    print "    -m output_mode   Output mode can be one of 'proto', 'init_c' or 'init_h'."
-    print "    -d               Enable extra debug information in the generated code."
-    sys.exit(1)
-
-
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
-    except Exception,e:
-        show_usage()
-
-    debug = 0
-    mode = "proto"
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-m":
-            mode = val
-        elif arg == "-d":
-            debug = 1
-
-    if mode == "proto":
+def _parser():
+    """Parse input and returned a parsed namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        default='gl_API.xml',
+                        dest='filename',
+                        help='An XML file describing an API')
+    parser.add_argument('-m',
+                        required=True,
+                        dest='mode',
+                        choices=frozenset(['proto', 'init_c', 'init_h']),
+                        help='which file to generate')
+    parser.add_argument('-d',
+                        action='store_true',
+                        dest='debug',
+                        help='turn debug mode on.')
+    return parser.parse_args()
+
+
+def main():
+    """Main function."""
+    args = _parser()
+
+    if args.mode == "proto":
         printer = PrintGlxProtoStubs()
-    elif mode == "init_c":
+    elif args.mode == "init_c":
         printer = PrintGlxProtoInit_c()
-    elif mode == "init_h":
+    elif args.mode == "init_h":
         printer = PrintGlxProtoInit_h()
-    else:
-        show_usage()
 
-
-    printer.debug = debug
-    api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
+    printer.debug = args.debug
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
 
     printer.Print( api )
+
+
+if __name__ == '__main__':
+    main()
index 4737fbf717dc52e842da7163594fa374cf49c2fa..75fc26f5db0eb71036bbaaad1abe0f21cf251047 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+import sys, string
+
 import gl_XML, glX_XML
 import license
-import sys, getopt, copy, string
 
 
 class glx_enum_function(object):
@@ -650,54 +652,57 @@ class PrintGlxReqSize_c(PrintGlxReqSize_common):
         return alias
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] -m output_mode [--only-get | --only-set] [--get-alias-set]" % sys.argv[0]
-    print "    -m output_mode   Output mode can be one of 'size_c' or 'size_h'."
-    print "    --only-get       Only emit 'get'-type functions."
-    print "    --only-set       Only emit 'set'-type functions."
-    print ""
-    print "By default, both 'get' and 'set'-type functions are emitted."
-    sys.exit(1)
-
-
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:m:h:", ["only-get", "only-set", "header-tag"])
-    except Exception,e:
-        show_usage()
-
-    mode = None
-    header_tag = None
-    which_functions = PrintGlxSizeStubs_common.do_get | PrintGlxSizeStubs_common.do_set
-
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-m":
-            mode = val
-        elif arg == "--only-get":
-            which_functions = PrintGlxSizeStubs_common.do_get
-        elif arg == "--only-set":
-            which_functions = PrintGlxSizeStubs_common.do_set
-        elif (arg == '-h') or (arg == "--header-tag"):
-            header_tag = val
-
-    if mode == "size_c":
-        printer = PrintGlxSizeStubs_c( which_functions )
-    elif mode == "size_h":
-        printer = PrintGlxSizeStubs_h( which_functions )
-        if header_tag:
-            printer.header_tag = header_tag
-    elif mode == "reqsize_c":
+def _parser():
+    """Parse arguments and return a namespace."""
+    parser = argparse.ArgumentParser()
+    parser.set_defaults(which_functions=(PrintGlxSizeStubs_common.do_get |
+                                         PrintGlxSizeStubs_common.do_set))
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='an XML file describing an OpenGL API.')
+    parser.add_argument('-m',
+                        dest='mode',
+                        choices=['size_c', 'size_h', 'reqsize_c', 'reqsize_h'],
+                        help='Which file to generate')
+    getset = parser.add_mutually_exclusive_group()
+    getset.add_argument('--only-get',
+                        dest='which_functions',
+                        action='store_const',
+                        const=PrintGlxSizeStubs_common.do_get,
+                        help='only emit "get-type" functions')
+    getset.add_argument('--only-set',
+                        dest='which_functions',
+                        action='store_const',
+                        const=PrintGlxSizeStubs_common.do_set,
+                        help='only emit "set-type" functions')
+    parser.add_argument('--header-tag',
+                        dest='header_tag',
+                        action='store',
+                        default=None,
+                        help='set header tag value')
+    return parser.parse_args()
+
+
+def main():
+    """Main function."""
+    args = _parser()
+
+    if args.mode == "size_c":
+        printer = PrintGlxSizeStubs_c(args.which_functions)
+    elif args.mode == "size_h":
+        printer = PrintGlxSizeStubs_h(args.which_functions)
+        if args.header_tag is not None:
+            printer.header_tag = args.header_tag
+    elif args.mode == "reqsize_c":
         printer = PrintGlxReqSize_c()
-    elif mode == "reqsize_h":
+    elif args.mode == "reqsize_h":
         printer = PrintGlxReqSize_h()
-    else:
-        show_usage()
 
-    api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
+
+    printer.Print(api)
 
 
-    printer.Print( api )
+if __name__ == '__main__':
+    main()
index 47aa11116be923c3071baa4a2380938f7158ae42..2d21f4e4ee11a03a5d905606073cb70789d4d07b 100644 (file)
@@ -25,8 +25,9 @@
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import gl_XML, glX_XML, glX_proto_common, license
-import sys, getopt
 
 
 def log2(value):
@@ -383,28 +384,19 @@ class PrintGlxDispatchTables(glX_proto_common.glx_print_proto):
         return
 
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:m")
-    except Exception,e:
-        show_usage()
-
-    mode = "table_c"
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-m":
-            mode = val
+def _parser():
+    """Parse arguments and return namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='An XML file describing an API.')
+    return parser.parse_args()
 
-    if mode == "table_c":
-        printer = PrintGlxDispatchTables()
-    else:
-        show_usage()
-
-
-    api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
 
+if __name__ == '__main__':
+    args = _parser()
+    printer = PrintGlxDispatchTables()
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
 
-    printer.Print( api )
+    printer.Print(api)
index ab321fad0f81b93fa008733e76b07500929f0b82..bdc62f1c835abaaf29accfba1a84f0df4a569985 100644 (file)
@@ -33,8 +33,6 @@
                    value               NMTOKEN #REQUIRED>
 <!ATTLIST function name                NMTOKEN #REQUIRED
                    alias               NMTOKEN #IMPLIED
-                   offset              CDATA   #IMPLIED
-                   static_dispatch     (true | false) "true"
                    vectorequiv         NMTOKEN #IMPLIED
                    es1                 CDATA   "none"
                    es2                 CDATA   "none"
index d1565989c2e2777b366f117182a267bd73fb21fb..2f330756f2270998f8ce6a1359ebeb1ae62848ca 100644 (file)
     <type name="DEBUGPROCARB" size="4" pointer="true"/>
     <type name="DEBUGPROC" size="4" pointer="true"/>
 
-    <function name="NewList" offset="0" deprecated="3.1">
+    <function name="NewList" deprecated="3.1">
         <param name="list" type="GLuint"/>
         <param name="mode" type="GLenum"/>
         <glx sop="101"/>
     </function>
 
-    <function name="EndList" offset="1" deprecated="3.1">
+    <function name="EndList" deprecated="3.1">
         <glx sop="102"/>
     </function>
 
-    <function name="CallList" offset="2" deprecated="3.1">
+    <function name="CallList" deprecated="3.1">
         <param name="list" type="GLuint"/>
         <glx rop="1"/>
     </function>
 
-    <function name="CallLists" offset="3" deprecated="3.1">
+    <function name="CallLists" deprecated="3.1">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="type" type="GLenum"/>
         <param name="lists" type="const GLvoid *" variable_param="type" count="n"/>
         <glx rop="2" large="true"/>
     </function>
 
-    <function name="DeleteLists" offset="4" deprecated="3.1">
+    <function name="DeleteLists" deprecated="3.1">
         <param name="list" type="GLuint"/>
         <param name="range" type="GLsizei"/>
         <glx sop="103"/>
     </function>
 
-    <function name="GenLists" offset="5" deprecated="3.1">
+    <function name="GenLists" deprecated="3.1">
         <param name="range" type="GLsizei"/>
         <return type="GLuint"/>
         <glx sop="104"/>
     </function>
 
-    <function name="ListBase" offset="6" deprecated="3.1">
+    <function name="ListBase" deprecated="3.1">
         <param name="base" type="GLuint"/>
         <glx rop="3"/>
     </function>
 
-    <function name="Begin" offset="7" deprecated="3.1" exec="dynamic">
+    <function name="Begin" deprecated="3.1" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <glx rop="4"/>
     </function>
 
-    <function name="Bitmap" offset="8" deprecated="3.1">
+    <function name="Bitmap" deprecated="3.1">
         <param name="width" type="GLsizei"/>
         <param name="height" type="GLsizei"/>
         <param name="xorig" type="GLfloat"/>
         <glx rop="5" large="true"/>
     </function>
 
-    <function name="Color3b" offset="9" vectorequiv="Color3bv"
-              deprecated="3.1">
+    <function name="Color3b" vectorequiv="Color3bv" deprecated="3.1">
         <param name="red" type="GLbyte"/>
         <param name="green" type="GLbyte"/>
         <param name="blue" type="GLbyte"/>
     </function>
 
-    <function name="Color3bv" offset="10" deprecated="3.1">
+    <function name="Color3bv" deprecated="3.1">
         <param name="v" type="const GLbyte *" count="3"/>
         <glx rop="6"/>
     </function>
 
-    <function name="Color3d" offset="11" vectorequiv="Color3dv"
-              deprecated="3.1">
+    <function name="Color3d" vectorequiv="Color3dv" deprecated="3.1">
         <param name="red" type="GLdouble"/>
         <param name="green" type="GLdouble"/>
         <param name="blue" type="GLdouble"/>
     </function>
 
-    <function name="Color3dv" offset="12" deprecated="3.1">
+    <function name="Color3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="7"/>
     </function>
 
-    <function name="Color3f" offset="13" vectorequiv="Color3fv"
-              deprecated="3.1" exec="dynamic">
+    <function name="Color3f" vectorequiv="Color3fv"
+             deprecated="3.1" exec="dynamic">
         <param name="red" type="GLfloat"/>
         <param name="green" type="GLfloat"/>
         <param name="blue" type="GLfloat"/>
     </function>
 
-    <function name="Color3fv" offset="14" deprecated="3.1" exec="dynamic">
+    <function name="Color3fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="8"/>
     </function>
 
-    <function name="Color3i" offset="15" vectorequiv="Color3iv"
-              deprecated="3.1">
+    <function name="Color3i" vectorequiv="Color3iv" deprecated="3.1">
         <param name="red" type="GLint"/>
         <param name="green" type="GLint"/>
         <param name="blue" type="GLint"/>
     </function>
 
-    <function name="Color3iv" offset="16" deprecated="3.1">
+    <function name="Color3iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="9"/>
     </function>
 
-    <function name="Color3s" offset="17" vectorequiv="Color3sv"
-              deprecated="3.1">
+    <function name="Color3s" vectorequiv="Color3sv" deprecated="3.1">
         <param name="red" type="GLshort"/>
         <param name="green" type="GLshort"/>
         <param name="blue" type="GLshort"/>
     </function>
 
-    <function name="Color3sv" offset="18" deprecated="3.1">
+    <function name="Color3sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="10"/>
     </function>
 
-    <function name="Color3ub" offset="19" vectorequiv="Color3ubv"
-              deprecated="3.1">
+    <function name="Color3ub" vectorequiv="Color3ubv" deprecated="3.1">
         <param name="red" type="GLubyte"/>
         <param name="green" type="GLubyte"/>
         <param name="blue" type="GLubyte"/>
     </function>
 
-    <function name="Color3ubv" offset="20" deprecated="3.1">
+    <function name="Color3ubv" deprecated="3.1">
         <param name="v" type="const GLubyte *" count="3"/>
         <glx rop="11"/>
     </function>
 
-    <function name="Color3ui" offset="21" vectorequiv="Color3uiv"
-              deprecated="3.1">
+    <function name="Color3ui" vectorequiv="Color3uiv" deprecated="3.1">
         <param name="red" type="GLuint"/>
         <param name="green" type="GLuint"/>
         <param name="blue" type="GLuint"/>
     </function>
 
-    <function name="Color3uiv" offset="22" deprecated="3.1">
+    <function name="Color3uiv" deprecated="3.1">
         <param name="v" type="const GLuint *" count="3"/>
         <glx rop="12"/>
     </function>
 
-    <function name="Color3us" offset="23" vectorequiv="Color3usv"
-              deprecated="3.1">
+    <function name="Color3us" vectorequiv="Color3usv" deprecated="3.1">
         <param name="red" type="GLushort"/>
         <param name="green" type="GLushort"/>
         <param name="blue" type="GLushort"/>
     </function>
 
-    <function name="Color3usv" offset="24" deprecated="3.1">
+    <function name="Color3usv" deprecated="3.1">
         <param name="v" type="const GLushort *" count="3"/>
         <glx rop="13"/>
     </function>
 
-    <function name="Color4b" offset="25" vectorequiv="Color4bv"
-              deprecated="3.1">
+    <function name="Color4b" vectorequiv="Color4bv" deprecated="3.1">
         <param name="red" type="GLbyte"/>
         <param name="green" type="GLbyte"/>
         <param name="blue" type="GLbyte"/>
         <param name="alpha" type="GLbyte"/>
     </function>
 
-    <function name="Color4bv" offset="26" deprecated="3.1">
+    <function name="Color4bv" deprecated="3.1">
         <param name="v" type="const GLbyte *" count="4"/>
         <glx rop="14"/>
     </function>
 
-    <function name="Color4d" offset="27" vectorequiv="Color4dv"
-              deprecated="3.1">
+    <function name="Color4d" vectorequiv="Color4dv" deprecated="3.1">
         <param name="red" type="GLdouble"/>
         <param name="green" type="GLdouble"/>
         <param name="blue" type="GLdouble"/>
         <param name="alpha" type="GLdouble"/>
     </function>
 
-    <function name="Color4dv" offset="28" deprecated="3.1">
+    <function name="Color4dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="15"/>
     </function>
 
-    <function name="Color4f" offset="29" vectorequiv="Color4fv" es1="1.0"
+    <function name="Color4f" vectorequiv="Color4fv" es1="1.0"
               deprecated="3.1" exec="dynamic">
         <param name="red" type="GLfloat"/>
         <param name="green" type="GLfloat"/>
         <param name="alpha" type="GLfloat"/>
     </function>
 
-    <function name="Color4fv" offset="30" deprecated="3.1" exec="dynamic">
+    <function name="Color4fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="16"/>
     </function>
 
-    <function name="Color4i" offset="31" vectorequiv="Color4iv"
-              deprecated="3.1">
+    <function name="Color4i" vectorequiv="Color4iv" deprecated="3.1">
         <param name="red" type="GLint"/>
         <param name="green" type="GLint"/>
         <param name="blue" type="GLint"/>
         <param name="alpha" type="GLint"/>
     </function>
 
-    <function name="Color4iv" offset="32" deprecated="3.1">
+    <function name="Color4iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="17"/>
     </function>
 
-    <function name="Color4s" offset="33" vectorequiv="Color4sv"
-              deprecated="3.1">
+    <function name="Color4s" vectorequiv="Color4sv" deprecated="3.1">
         <param name="red" type="GLshort"/>
         <param name="green" type="GLshort"/>
         <param name="blue" type="GLshort"/>
         <param name="alpha" type="GLshort"/>
     </function>
 
-    <function name="Color4sv" offset="34" deprecated="3.1">
+    <function name="Color4sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="18"/>
     </function>
 
-    <function name="Color4ub" offset="35" vectorequiv="Color4ubv" es1="1.1"
+    <function name="Color4ub" vectorequiv="Color4ubv" es1="1.1"
               deprecated="3.1">
         <param name="red" type="GLubyte"/>
         <param name="green" type="GLubyte"/>
         <param name="alpha" type="GLubyte"/>
     </function>
 
-    <function name="Color4ubv" offset="36" deprecated="3.1">
+    <function name="Color4ubv" deprecated="3.1">
         <param name="v" type="const GLubyte *" count="4"/>
         <glx rop="19"/>
     </function>
 
-    <function name="Color4ui" offset="37" vectorequiv="Color4uiv"
-              deprecated="3.1">
+    <function name="Color4ui" vectorequiv="Color4uiv" deprecated="3.1">
         <param name="red" type="GLuint"/>
         <param name="green" type="GLuint"/>
         <param name="blue" type="GLuint"/>
         <param name="alpha" type="GLuint"/>
     </function>
 
-    <function name="Color4uiv" offset="38" deprecated="3.1">
+    <function name="Color4uiv" deprecated="3.1">
         <param name="v" type="const GLuint *" count="4"/>
         <glx rop="20"/>
     </function>
 
-    <function name="Color4us" offset="39" vectorequiv="Color4usv"
-              deprecated="3.1">
+    <function name="Color4us" vectorequiv="Color4usv" deprecated="3.1">
         <param name="red" type="GLushort"/>
         <param name="green" type="GLushort"/>
         <param name="blue" type="GLushort"/>
         <param name="alpha" type="GLushort"/>
     </function>
 
-    <function name="Color4usv" offset="40" deprecated="3.1">
+    <function name="Color4usv" deprecated="3.1">
         <param name="v" type="const GLushort *" count="4"/>
         <glx rop="21"/>
     </function>
 
-    <function name="EdgeFlag" offset="41" vectorequiv="EdgeFlagv"
+    <function name="EdgeFlag" vectorequiv="EdgeFlagv"
               deprecated="3.1" exec="dynamic">
         <param name="flag" type="GLboolean"/>
     </function>
 
-    <function name="EdgeFlagv" offset="42" deprecated="3.1">
+    <function name="EdgeFlagv" deprecated="3.1">
         <param name="flag" type="const GLboolean *" count="1"/>
         <glx rop="22"/>
     </function>
 
-    <function name="End" offset="43" deprecated="3.1" exec="dynamic">
+    <function name="End" deprecated="3.1" exec="dynamic">
         <glx rop="23"/>
     </function>
 
-    <function name="Indexd" offset="44" vectorequiv="Indexdv" deprecated="3.1">
+    <function name="Indexd" vectorequiv="Indexdv" deprecated="3.1">
         <param name="c" type="GLdouble"/>
     </function>
 
-    <function name="Indexdv" offset="45" deprecated="3.1">
+    <function name="Indexdv" deprecated="3.1">
         <param name="c" type="const GLdouble *" count="1"/>
         <glx rop="24"/>
     </function>
 
-    <function name="Indexf" offset="46" vectorequiv="Indexfv" deprecated="3.1"
+    <function name="Indexf" vectorequiv="Indexfv" deprecated="3.1"
               exec="dynamic">
         <param name="c" type="GLfloat"/>
     </function>
 
-    <function name="Indexfv" offset="47" deprecated="3.1" exec="dynamic">
+    <function name="Indexfv" deprecated="3.1" exec="dynamic">
         <param name="c" type="const GLfloat *" count="1"/>
         <glx rop="25"/>
     </function>
 
-    <function name="Indexi" offset="48" vectorequiv="Indexiv" deprecated="3.1">
+    <function name="Indexi" vectorequiv="Indexiv" deprecated="3.1">
         <param name="c" type="GLint"/>
     </function>
 
-    <function name="Indexiv" offset="49" deprecated="3.1">
+    <function name="Indexiv" deprecated="3.1">
         <param name="c" type="const GLint *" count="1"/>
         <glx rop="26"/>
     </function>
 
-    <function name="Indexs" offset="50" vectorequiv="Indexsv" deprecated="3.1">
+    <function name="Indexs" vectorequiv="Indexsv" deprecated="3.1">
         <param name="c" type="GLshort"/>
     </function>
 
-    <function name="Indexsv" offset="51" deprecated="3.1">
+    <function name="Indexsv" deprecated="3.1">
         <param name="c" type="const GLshort *" count="1"/>
         <glx rop="27"/>
     </function>
 
-    <function name="Normal3b" offset="52" vectorequiv="Normal3bv"
-              deprecated="3.1">
+    <function name="Normal3b" vectorequiv="Normal3bv" deprecated="3.1">
         <param name="nx" type="GLbyte"/>
         <param name="ny" type="GLbyte"/>
         <param name="nz" type="GLbyte"/>
     </function>
 
-    <function name="Normal3bv" offset="53" deprecated="3.1">
+    <function name="Normal3bv" deprecated="3.1">
         <param name="v" type="const GLbyte *" count="3"/>
         <glx rop="28"/>
     </function>
 
-    <function name="Normal3d" offset="54" vectorequiv="Normal3dv"
-              deprecated="3.1">
+    <function name="Normal3d" vectorequiv="Normal3dv" deprecated="3.1">
         <param name="nx" type="GLdouble"/>
         <param name="ny" type="GLdouble"/>
         <param name="nz" type="GLdouble"/>
     </function>
 
-    <function name="Normal3dv" offset="55" deprecated="3.1">
+    <function name="Normal3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="29"/>
     </function>
 
-    <function name="Normal3f" offset="56" vectorequiv="Normal3fv" es1="1.0"
+    <function name="Normal3f" vectorequiv="Normal3fv" es1="1.0"
               deprecated="3.1" exec="dynamic">
         <param name="nx" type="GLfloat"/>
         <param name="ny" type="GLfloat"/>
         <param name="nz" type="GLfloat"/>
     </function>
 
-    <function name="Normal3fv" offset="57" deprecated="3.1" exec="dynamic">
+    <function name="Normal3fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="30"/>
     </function>
 
-    <function name="Normal3i" offset="58" vectorequiv="Normal3iv"
-              deprecated="3.1">
+    <function name="Normal3i" vectorequiv="Normal3iv" deprecated="3.1">
         <param name="nx" type="GLint"/>
         <param name="ny" type="GLint"/>
         <param name="nz" type="GLint"/>
     </function>
 
-    <function name="Normal3iv" offset="59" deprecated="3.1">
+    <function name="Normal3iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="31"/>
     </function>
 
-    <function name="Normal3s" offset="60" vectorequiv="Normal3sv"
-              deprecated="3.1">
+    <function name="Normal3s" vectorequiv="Normal3sv" deprecated="3.1">
         <param name="nx" type="GLshort"/>
         <param name="ny" type="GLshort"/>
         <param name="nz" type="GLshort"/>
     </function>
 
-    <function name="Normal3sv" offset="61" deprecated="3.1">
+    <function name="Normal3sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="32"/>
     </function>
 
-    <function name="RasterPos2d" offset="62" vectorequiv="RasterPos2dv"
-              deprecated="3.1">
+    <function name="RasterPos2d" vectorequiv="RasterPos2dv" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
     </function>
 
-    <function name="RasterPos2dv" offset="63" deprecated="3.1">
+    <function name="RasterPos2dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="2"/>
         <glx rop="33"/>
     </function>
 
-    <function name="RasterPos2f" offset="64" vectorequiv="RasterPos2fv"
-              deprecated="3.1">
+    <function name="RasterPos2f" vectorequiv="RasterPos2fv" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
     </function>
 
-    <function name="RasterPos2fv" offset="65" deprecated="3.1">
+    <function name="RasterPos2fv" deprecated="3.1">
         <param name="v" type="const GLfloat *" count="2"/>
         <glx rop="34"/>
     </function>
 
-    <function name="RasterPos2i" offset="66" vectorequiv="RasterPos2iv"
-              deprecated="3.1">
+    <function name="RasterPos2i" vectorequiv="RasterPos2iv" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
     </function>
 
-    <function name="RasterPos2iv" offset="67" deprecated="3.1">
+    <function name="RasterPos2iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="2"/>
         <glx rop="35"/>
     </function>
 
-    <function name="RasterPos2s" offset="68" vectorequiv="RasterPos2sv"
-              deprecated="3.1">
+    <function name="RasterPos2s" vectorequiv="RasterPos2sv" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
     </function>
 
-    <function name="RasterPos2sv" offset="69" deprecated="3.1">
+    <function name="RasterPos2sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="2"/>
         <glx rop="36"/>
     </function>
 
-    <function name="RasterPos3d" offset="70" vectorequiv="RasterPos3dv"
-              deprecated="3.1">
+    <function name="RasterPos3d" vectorequiv="RasterPos3dv" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
     </function>
 
-    <function name="RasterPos3dv" offset="71" deprecated="3.1">
+    <function name="RasterPos3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="37"/>
     </function>
 
-    <function name="RasterPos3f" offset="72" vectorequiv="RasterPos3fv"
-              deprecated="3.1">
+    <function name="RasterPos3f" vectorequiv="RasterPos3fv" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
     </function>
 
-    <function name="RasterPos3fv" offset="73" deprecated="3.1">
+    <function name="RasterPos3fv" deprecated="3.1">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="38"/>
     </function>
 
-    <function name="RasterPos3i" offset="74" vectorequiv="RasterPos3iv"
-              deprecated="3.1">
+    <function name="RasterPos3i" vectorequiv="RasterPos3iv" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
     </function>
 
-    <function name="RasterPos3iv" offset="75" deprecated="3.1">
+    <function name="RasterPos3iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="39"/>
     </function>
 
-    <function name="RasterPos3s" offset="76" vectorequiv="RasterPos3sv"
-              deprecated="3.1">
+    <function name="RasterPos3s" vectorequiv="RasterPos3sv" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
     </function>
 
-    <function name="RasterPos3sv" offset="77" deprecated="3.1">
+    <function name="RasterPos3sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="40"/>
     </function>
 
-    <function name="RasterPos4d" offset="78" vectorequiv="RasterPos4dv"
-              deprecated="3.1">
+    <function name="RasterPos4d" vectorequiv="RasterPos4dv" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="RasterPos4dv" offset="79" deprecated="3.1">
+    <function name="RasterPos4dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="41"/>
     </function>
 
-    <function name="RasterPos4f" offset="80" vectorequiv="RasterPos4fv"
-              deprecated="3.1">
+    <function name="RasterPos4f" vectorequiv="RasterPos4fv" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="RasterPos4fv" offset="81" deprecated="3.1">
+    <function name="RasterPos4fv" deprecated="3.1">
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="42"/>
     </function>
 
-    <function name="RasterPos4i" offset="82" vectorequiv="RasterPos4iv"
-              deprecated="3.1">
+    <function name="RasterPos4i" vectorequiv="RasterPos4iv" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
         <param name="w" type="GLint"/>
     </function>
 
-    <function name="RasterPos4iv" offset="83" deprecated="3.1">
+    <function name="RasterPos4iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="43"/>
     </function>
 
-    <function name="RasterPos4s" offset="84" vectorequiv="RasterPos4sv"
-              deprecated="3.1">
+    <function name="RasterPos4s" vectorequiv="RasterPos4sv" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
         <param name="w" type="GLshort"/>
     </function>
 
-    <function name="RasterPos4sv" offset="85" deprecated="3.1">
+    <function name="RasterPos4sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="44"/>
     </function>
 
-    <function name="Rectd" offset="86" vectorequiv="Rectdv" deprecated="3.1">
+    <function name="Rectd" vectorequiv="Rectdv" deprecated="3.1">
         <param name="x1" type="GLdouble"/>
         <param name="y1" type="GLdouble"/>
         <param name="x2" type="GLdouble"/>
         <param name="y2" type="GLdouble"/>
     </function>
 
-    <function name="Rectdv" offset="87" deprecated="3.1">
+    <function name="Rectdv" deprecated="3.1">
         <param name="v1" type="const GLdouble *" count="2"/>
         <param name="v2" type="const GLdouble *" count="2"/>
         <glx rop="45"/>
     </function>
 
-    <function name="Rectf" offset="88" vectorequiv="Rectfv" deprecated="3.1"
-              exec="dynamic">
+    <function name="Rectf" vectorequiv="Rectfv" deprecated="3.1" exec="dynamic">
         <param name="x1" type="GLfloat"/>
         <param name="y1" type="GLfloat"/>
         <param name="x2" type="GLfloat"/>
         <param name="y2" type="GLfloat"/>
     </function>
 
-    <function name="Rectfv" offset="89" deprecated="3.1">
+    <function name="Rectfv" deprecated="3.1">
         <param name="v1" type="const GLfloat *" count="2"/>
         <param name="v2" type="const GLfloat *" count="2"/>
         <glx rop="46"/>
     </function>
 
-    <function name="Recti" offset="90" vectorequiv="Rectiv" deprecated="3.1">
+    <function name="Recti" vectorequiv="Rectiv" deprecated="3.1">
         <param name="x1" type="GLint"/>
         <param name="y1" type="GLint"/>
         <param name="x2" type="GLint"/>
         <param name="y2" type="GLint"/>
     </function>
 
-    <function name="Rectiv" offset="91" deprecated="3.1">
+    <function name="Rectiv" deprecated="3.1">
         <param name="v1" type="const GLint *" count="2"/>
         <param name="v2" type="const GLint *" count="2"/>
         <glx rop="47"/>
     </function>
 
-    <function name="Rects" offset="92" vectorequiv="Rectsv" deprecated="3.1">
+    <function name="Rects" vectorequiv="Rectsv" deprecated="3.1">
         <param name="x1" type="GLshort"/>
         <param name="y1" type="GLshort"/>
         <param name="x2" type="GLshort"/>
         <param name="y2" type="GLshort"/>
     </function>
 
-    <function name="Rectsv" offset="93" deprecated="3.1">
+    <function name="Rectsv" deprecated="3.1">
         <param name="v1" type="const GLshort *" count="2"/>
         <param name="v2" type="const GLshort *" count="2"/>
         <glx rop="48"/>
     </function>
 
-    <function name="TexCoord1d" offset="94" vectorequiv="TexCoord1dv"
-              deprecated="3.1">
+    <function name="TexCoord1d" vectorequiv="TexCoord1dv" deprecated="3.1">
         <param name="s" type="GLdouble"/>
     </function>
 
-    <function name="TexCoord1dv" offset="95" deprecated="3.1">
+    <function name="TexCoord1dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="1"/>
         <glx rop="49"/>
     </function>
 
-    <function name="TexCoord1f" offset="96" vectorequiv="TexCoord1fv"
+    <function name="TexCoord1f" vectorequiv="TexCoord1fv"
               deprecated="3.1" exec="dynamic">
         <param name="s" type="GLfloat"/>
     </function>
 
-    <function name="TexCoord1fv" offset="97" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoord1fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="1"/>
         <glx rop="50"/>
     </function>
 
-    <function name="TexCoord1i" offset="98" vectorequiv="TexCoord1iv"
-              deprecated="3.1">
+    <function name="TexCoord1i" vectorequiv="TexCoord1iv" deprecated="3.1">
         <param name="s" type="GLint"/>
     </function>
 
-    <function name="TexCoord1iv" offset="99" deprecated="3.1">
+    <function name="TexCoord1iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="1"/>
         <glx rop="51"/>
     </function>
 
-    <function name="TexCoord1s" offset="100" vectorequiv="TexCoord1sv"
-              deprecated="3.1">
+    <function name="TexCoord1s" vectorequiv="TexCoord1sv" deprecated="3.1">
         <param name="s" type="GLshort"/>
     </function>
 
-    <function name="TexCoord1sv" offset="101" deprecated="3.1">
+    <function name="TexCoord1sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="1"/>
         <glx rop="52"/>
     </function>
 
-    <function name="TexCoord2d" offset="102" vectorequiv="TexCoord2dv"
-              deprecated="3.1">
+    <function name="TexCoord2d" vectorequiv="TexCoord2dv" deprecated="3.1">
         <param name="s" type="GLdouble"/>
         <param name="t" type="GLdouble"/>
     </function>
 
-    <function name="TexCoord2dv" offset="103" deprecated="3.1">
+    <function name="TexCoord2dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="2"/>
         <glx rop="53"/>
     </function>
 
-    <function name="TexCoord2f" offset="104" vectorequiv="TexCoord2fv"
+    <function name="TexCoord2f" vectorequiv="TexCoord2fv"
               deprecated="3.1" exec="dynamic">
         <param name="s" type="GLfloat"/>
         <param name="t" type="GLfloat"/>
     </function>
 
-    <function name="TexCoord2fv" offset="105" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoord2fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="2"/>
         <glx rop="54"/>
     </function>
 
-    <function name="TexCoord2i" offset="106" vectorequiv="TexCoord2iv"
-              deprecated="3.1">
+    <function name="TexCoord2i" vectorequiv="TexCoord2iv" deprecated="3.1">
         <param name="s" type="GLint"/>
         <param name="t" type="GLint"/>
     </function>
 
-    <function name="TexCoord2iv" offset="107" deprecated="3.1">
+    <function name="TexCoord2iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="2"/>
         <glx rop="55"/>
     </function>
 
-    <function name="TexCoord2s" offset="108" vectorequiv="TexCoord2sv"
-              deprecated="3.1">
+    <function name="TexCoord2s" vectorequiv="TexCoord2sv" deprecated="3.1">
         <param name="s" type="GLshort"/>
         <param name="t" type="GLshort"/>
     </function>
 
-    <function name="TexCoord2sv" offset="109" deprecated="3.1">
+    <function name="TexCoord2sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="2"/>
         <glx rop="56"/>
     </function>
 
-    <function name="TexCoord3d" offset="110" vectorequiv="TexCoord3dv"
-              deprecated="3.1">
+    <function name="TexCoord3d" vectorequiv="TexCoord3dv" deprecated="3.1">
         <param name="s" type="GLdouble"/>
         <param name="t" type="GLdouble"/>
         <param name="r" type="GLdouble"/>
     </function>
 
-    <function name="TexCoord3dv" offset="111" deprecated="3.1">
+    <function name="TexCoord3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="57"/>
     </function>
 
-    <function name="TexCoord3f" offset="112" vectorequiv="TexCoord3fv"
+    <function name="TexCoord3f" vectorequiv="TexCoord3fv"
               deprecated="3.1" exec="dynamic">
         <param name="s" type="GLfloat"/>
         <param name="t" type="GLfloat"/>
         <param name="r" type="GLfloat"/>
     </function>
 
-    <function name="TexCoord3fv" offset="113" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoord3fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="58"/>
     </function>
 
-    <function name="TexCoord3i" offset="114" vectorequiv="TexCoord3iv"
-              deprecated="3.1">
+    <function name="TexCoord3i" vectorequiv="TexCoord3iv" deprecated="3.1">
         <param name="s" type="GLint"/>
         <param name="t" type="GLint"/>
         <param name="r" type="GLint"/>
     </function>
 
-    <function name="TexCoord3iv" offset="115" deprecated="3.1">
+    <function name="TexCoord3iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="59"/>
     </function>
 
-    <function name="TexCoord3s" offset="116" vectorequiv="TexCoord3sv"
-              deprecated="3.1">
+    <function name="TexCoord3s" vectorequiv="TexCoord3sv" deprecated="3.1">
         <param name="s" type="GLshort"/>
         <param name="t" type="GLshort"/>
         <param name="r" type="GLshort"/>
     </function>
 
-    <function name="TexCoord3sv" offset="117" deprecated="3.1">
+    <function name="TexCoord3sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="60"/>
     </function>
 
-    <function name="TexCoord4d" offset="118" vectorequiv="TexCoord4dv"
-              deprecated="3.1">
+    <function name="TexCoord4d" vectorequiv="TexCoord4dv" deprecated="3.1">
         <param name="s" type="GLdouble"/>
         <param name="t" type="GLdouble"/>
         <param name="r" type="GLdouble"/>
         <param name="q" type="GLdouble"/>
     </function>
 
-    <function name="TexCoord4dv" offset="119" deprecated="3.1">
+    <function name="TexCoord4dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="61"/>
     </function>
 
-    <function name="TexCoord4f" offset="120" vectorequiv="TexCoord4fv"
+    <function name="TexCoord4f" vectorequiv="TexCoord4fv"
               deprecated="3.1" exec="dynamic">
         <param name="s" type="GLfloat"/>
         <param name="t" type="GLfloat"/>
         <param name="q" type="GLfloat"/>
     </function>
 
-    <function name="TexCoord4fv" offset="121" deprecated="3.1"
-              exec="dynamic">
+    <function name="TexCoord4fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="62"/>
     </function>
 
-    <function name="TexCoord4i" offset="122" vectorequiv="TexCoord4iv"
-              deprecated="3.1">
+    <function name="TexCoord4i" vectorequiv="TexCoord4iv" deprecated="3.1">
         <param name="s" type="GLint"/>
         <param name="t" type="GLint"/>
         <param name="r" type="GLint"/>
         <param name="q" type="GLint"/>
     </function>
 
-    <function name="TexCoord4iv" offset="123" deprecated="3.1">
+    <function name="TexCoord4iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="63"/>
     </function>
 
-    <function name="TexCoord4s" offset="124" vectorequiv="TexCoord4sv"
-              deprecated="3.1">
+    <function name="TexCoord4s" vectorequiv="TexCoord4sv" deprecated="3.1">
         <param name="s" type="GLshort"/>
         <param name="t" type="GLshort"/>
         <param name="r" type="GLshort"/>
         <param name="q" type="GLshort"/>
     </function>
 
-    <function name="TexCoord4sv" offset="125" deprecated="3.1">
+    <function name="TexCoord4sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="64"/>
     </function>
 
-    <function name="Vertex2d" offset="126" vectorequiv="Vertex2dv"
-              deprecated="3.1">
+    <function name="Vertex2d" vectorequiv="Vertex2dv" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
     </function>
 
-    <function name="Vertex2dv" offset="127" deprecated="3.1">
+    <function name="Vertex2dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="2"/>
         <glx rop="65"/>
     </function>
 
-    <function name="Vertex2f" offset="128" vectorequiv="Vertex2fv"
+    <function name="Vertex2f" vectorequiv="Vertex2fv"
               deprecated="3.1" exec="dynamic">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
     </function>
 
-    <function name="Vertex2fv" offset="129" deprecated="3.1"
-              exec="dynamic">
+    <function name="Vertex2fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="2"/>
         <glx rop="66"/>
     </function>
 
-    <function name="Vertex2i" offset="130" vectorequiv="Vertex2iv"
-              deprecated="3.1">
+    <function name="Vertex2i" vectorequiv="Vertex2iv" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
     </function>
 
-    <function name="Vertex2iv" offset="131" deprecated="3.1">
+    <function name="Vertex2iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="2"/>
         <glx rop="67"/>
     </function>
 
-    <function name="Vertex2s" offset="132" vectorequiv="Vertex2sv"
-              deprecated="3.1">
+    <function name="Vertex2s" vectorequiv="Vertex2sv" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
     </function>
 
-    <function name="Vertex2sv" offset="133" deprecated="3.1">
+    <function name="Vertex2sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="2"/>
         <glx rop="68"/>
     </function>
 
-    <function name="Vertex3d" offset="134" vectorequiv="Vertex3dv"
-              deprecated="3.1">
+    <function name="Vertex3d" vectorequiv="Vertex3dv" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
     </function>
 
-    <function name="Vertex3dv" offset="135" deprecated="3.1">
+    <function name="Vertex3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="69"/>
     </function>
 
-    <function name="Vertex3f" offset="136" vectorequiv="Vertex3fv"
+    <function name="Vertex3f" vectorequiv="Vertex3fv"
               deprecated="3.1" exec="dynamic">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
     </function>
 
-    <function name="Vertex3fv" offset="137" deprecated="3.1"
-              exec="dynamic">
+    <function name="Vertex3fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="70"/>
     </function>
 
-    <function name="Vertex3i" offset="138" vectorequiv="Vertex3iv"
-              deprecated="3.1">
+    <function name="Vertex3i" vectorequiv="Vertex3iv" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
     </function>
 
-    <function name="Vertex3iv" offset="139" deprecated="3.1">
+    <function name="Vertex3iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="71"/>
     </function>
 
-    <function name="Vertex3s" offset="140" vectorequiv="Vertex3sv"
-              deprecated="3.1">
+    <function name="Vertex3s" vectorequiv="Vertex3sv" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
     </function>
 
-    <function name="Vertex3sv" offset="141" deprecated="3.1">
+    <function name="Vertex3sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="72"/>
     </function>
 
-    <function name="Vertex4d" offset="142" vectorequiv="Vertex4dv"
-              deprecated="3.1">
+    <function name="Vertex4d" vectorequiv="Vertex4dv" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="Vertex4dv" offset="143" deprecated="3.1">
+    <function name="Vertex4dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="73"/>
     </function>
 
-    <function name="Vertex4f" offset="144" vectorequiv="Vertex4fv"
+    <function name="Vertex4f" vectorequiv="Vertex4fv"
               deprecated="3.1" exec="dynamic">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="Vertex4fv" offset="145" deprecated="3.1"
-              exec="dynamic">
+    <function name="Vertex4fv" deprecated="3.1" exec="dynamic">
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="74"/>
     </function>
 
-    <function name="Vertex4i" offset="146" vectorequiv="Vertex4iv"
-              deprecated="3.1">
+    <function name="Vertex4i" vectorequiv="Vertex4iv" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
         <param name="w" type="GLint"/>
     </function>
 
-    <function name="Vertex4iv" offset="147" deprecated="3.1">
+    <function name="Vertex4iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="75"/>
     </function>
 
-    <function name="Vertex4s" offset="148" vectorequiv="Vertex4sv"
-              deprecated="3.1">
+    <function name="Vertex4s" vectorequiv="Vertex4sv" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
         <param name="w" type="GLshort"/>
     </function>
 
-    <function name="Vertex4sv" offset="149" deprecated="3.1">
+    <function name="Vertex4sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="76"/>
     </function>
 
-    <function name="ClipPlane" offset="150" deprecated="3.1">
+    <function name="ClipPlane" deprecated="3.1">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="const GLdouble *" count="4"/>
         <glx rop="77"/>
     </function>
 
-    <function name="ColorMaterial" offset="151" deprecated="3.1">
+    <function name="ColorMaterial" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <param name="mode" type="GLenum"/>
         <glx rop="78"/>
     </function>
 
-    <function name="CullFace" offset="152" es1="1.0" es2="2.0">
+    <function name="CullFace" es1="1.0" es2="2.0">
         <param name="mode" type="GLenum"/>
         <glx rop="79"/>
     </function>
 
-    <function name="Fogf" offset="153" es1="1.0" deprecated="3.1">
+    <function name="Fogf" es1="1.0" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="80"/>
     </function>
 
-    <function name="Fogfv" offset="154" es1="1.0" deprecated="3.1">
+    <function name="Fogfv" es1="1.0" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="81"/>
     </function>
 
-    <function name="Fogi" offset="155" deprecated="3.1">
+    <function name="Fogi" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="82"/>
     </function>
 
-    <function name="Fogiv" offset="156" deprecated="3.1">
+    <function name="Fogiv" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="83"/>
     </function>
 
-    <function name="FrontFace" offset="157" es1="1.0" es2="2.0">
+    <function name="FrontFace" es1="1.0" es2="2.0">
         <param name="mode" type="GLenum"/>
         <glx rop="84"/>
     </function>
 
-    <function name="Hint" offset="158" es1="1.0" es2="2.0">
+    <function name="Hint" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="mode" type="GLenum"/>
         <glx rop="85"/>
     </function>
 
-    <function name="Lightf" offset="159" es1="1.0" deprecated="3.1">
+    <function name="Lightf" es1="1.0" deprecated="3.1">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="86"/>
     </function>
 
-    <function name="Lightfv" offset="160" es1="1.0" deprecated="3.1">
+    <function name="Lightfv" es1="1.0" deprecated="3.1">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="87"/>
     </function>
 
-    <function name="Lighti" offset="161" deprecated="3.1">
+    <function name="Lighti" deprecated="3.1">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="88"/>
     </function>
 
-    <function name="Lightiv" offset="162" deprecated="3.1">
+    <function name="Lightiv" deprecated="3.1">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="89"/>
     </function>
 
-    <function name="LightModelf" offset="163" es1="1.0" deprecated="3.1">
+    <function name="LightModelf" es1="1.0" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="90"/>
     </function>
 
-    <function name="LightModelfv" offset="164" es1="1.0" deprecated="3.1">
+    <function name="LightModelfv" es1="1.0" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="91"/>
     </function>
 
-    <function name="LightModeli" offset="165" deprecated="3.1">
+    <function name="LightModeli" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="92"/>
     </function>
 
-    <function name="LightModeliv" offset="166" deprecated="3.1">
+    <function name="LightModeliv" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="93"/>
     </function>
 
-    <function name="LineStipple" offset="167" deprecated="3.1">
+    <function name="LineStipple" deprecated="3.1">
         <param name="factor" type="GLint"/>
         <param name="pattern" type="GLushort"/>
         <glx rop="94"/>
     </function>
 
-    <function name="LineWidth" offset="168" es1="1.0" es2="2.0">
+    <function name="LineWidth" es1="1.0" es2="2.0">
         <param name="width" type="GLfloat"/>
         <glx rop="95"/>
     </function>
 
-    <function name="Materialf" offset="169" es1="1.0" deprecated="3.1">
+    <function name="Materialf" es1="1.0" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="96"/>
     </function>
 
-    <function name="Materialfv" offset="170" es1="1.0" deprecated="3.1"
-              exec="dynamic">
+    <function name="Materialfv" es1="1.0" deprecated="3.1" exec="dynamic">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="97"/>
     </function>
 
-    <function name="Materiali" offset="171" deprecated="3.1">
+    <function name="Materiali" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="98"/>
     </function>
 
-    <function name="Materialiv" offset="172" deprecated="3.1">
+    <function name="Materialiv" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="99"/>
     </function>
 
-    <function name="PointSize" offset="173" es1="1.0">
+    <function name="PointSize" es1="1.0">
         <param name="size" type="GLfloat"/>
         <glx rop="100"/>
     </function>
 
-    <function name="PolygonMode" offset="174">
+    <function name="PolygonMode">
         <param name="face" type="GLenum"/>
         <param name="mode" type="GLenum"/>
         <glx rop="101"/>
     </function>
 
-    <function name="PolygonStipple" offset="175" deprecated="3.1">
+    <function name="PolygonStipple" deprecated="3.1">
         <param name="mask" type="const GLubyte *" img_width="32" img_height="32" img_format="GL_COLOR_INDEX" img_type="GL_BITMAP" img_target="0" img_pad_dimensions="false"/>
         <glx rop="102"/>
     </function>
 
-    <function name="Scissor" offset="176" es1="1.0" es2="2.0">
+    <function name="Scissor" es1="1.0" es2="2.0">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="width" type="GLsizei"/>
         <glx rop="103"/>
     </function>
 
-    <function name="ShadeModel" offset="177" es1="1.0" deprecated="3.1">
+    <function name="ShadeModel" es1="1.0" deprecated="3.1">
         <param name="mode" type="GLenum"/>
         <glx rop="104"/>
     </function>
 
-    <function name="TexParameterf" offset="178" es1="1.0" es2="2.0">
+    <function name="TexParameterf" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="105"/>
     </function>
 
-    <function name="TexParameterfv" offset="179" es1="1.1" es2="2.0">
+    <function name="TexParameterfv" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="106"/>
     </function>
 
-    <function name="TexParameteri" offset="180" es1="1.1" es2="2.0">
+    <function name="TexParameteri" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="107"/>
     </function>
 
-    <function name="TexParameteriv" offset="181" es1="1.1" es2="2.0">
+    <function name="TexParameteriv" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="108"/>
     </function>
 
-    <function name="TexImage1D" offset="182">
+    <function name="TexImage1D">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLint"/>
         <glx rop="109" large="true"/>
     </function>
 
-    <function name="TexImage2D" offset="183" es1="1.0" es2="2.0">
+    <function name="TexImage2D" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLint"/>
         <glx rop="110" large="true"/>
     </function>
 
-    <function name="TexEnvf" offset="184" es1="1.0" deprecated="3.1">
+    <function name="TexEnvf" es1="1.0" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="111"/>
     </function>
 
-    <function name="TexEnvfv" offset="185" es1="1.0" deprecated="3.1">
+    <function name="TexEnvfv" es1="1.0" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="112"/>
     </function>
 
-    <function name="TexEnvi" offset="186" es1="1.1" deprecated="3.1">
+    <function name="TexEnvi" es1="1.1" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="113"/>
     </function>
 
-    <function name="TexEnviv" offset="187" es1="1.1" deprecated="3.1">
+    <function name="TexEnviv" es1="1.1" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="114"/>
     </function>
 
-    <function name="TexGend" offset="188" deprecated="3.1">
+    <function name="TexGend" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLdouble"/>
         <glx rop="115"/>
     </function>
 
-    <function name="TexGendv" offset="189" deprecated="3.1">
+    <function name="TexGendv" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLdouble *" variable_param="pname"/>
         <glx rop="116"/>
     </function>
 
-    <function name="TexGenf" offset="190" deprecated="3.1">
+    <function name="TexGenf" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="117"/>
     </function>
 
-    <function name="TexGenfv" offset="191" deprecated="3.1">
+    <function name="TexGenfv" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="118"/>
     </function>
 
-    <function name="TexGeni" offset="192" deprecated="3.1">
+    <function name="TexGeni" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="119"/>
     </function>
 
-    <function name="TexGeniv" offset="193" deprecated="3.1">
+    <function name="TexGeniv" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="120"/>
     </function>
 
-    <function name="FeedbackBuffer" offset="194" deprecated="3.1">
+    <function name="FeedbackBuffer" deprecated="3.1">
         <param name="size" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <param name="buffer" type="GLfloat *" output="true"/>
         <glx sop="105" handcode="true"/>
     </function>
 
-    <function name="SelectBuffer" offset="195" deprecated="3.1">
+    <function name="SelectBuffer" deprecated="3.1">
         <param name="size" type="GLsizei"/>
         <param name="buffer" type="GLuint *" output="true"/>
         <glx sop="106" handcode="true"/>
     </function>
 
-    <function name="RenderMode" offset="196" deprecated="3.1">
+    <function name="RenderMode" deprecated="3.1">
         <param name="mode" type="GLenum"/>
         <return type="GLint"/>
         <glx sop="107" handcode="true"/>
     </function>
 
-    <function name="InitNames" offset="197" deprecated="3.1">
+    <function name="InitNames" deprecated="3.1">
         <glx rop="121"/>
     </function>
 
-    <function name="LoadName" offset="198" deprecated="3.1">
+    <function name="LoadName" deprecated="3.1">
         <param name="name" type="GLuint"/>
         <glx rop="122"/>
     </function>
 
-    <function name="PassThrough" offset="199" deprecated="3.1">
+    <function name="PassThrough" deprecated="3.1">
         <param name="token" type="GLfloat"/>
         <glx rop="123"/>
     </function>
 
-    <function name="PopName" offset="200" deprecated="3.1">
+    <function name="PopName" deprecated="3.1">
         <glx rop="124"/>
     </function>
 
-    <function name="PushName" offset="201" deprecated="3.1">
+    <function name="PushName" deprecated="3.1">
         <param name="name" type="GLuint"/>
         <glx rop="125"/>
     </function>
 
-    <function name="DrawBuffer" offset="202">
+    <function name="DrawBuffer">
         <param name="mode" type="GLenum"/>
         <glx rop="126"/>
     </function>
 
-    <function name="Clear" offset="203" es1="1.0" es2="2.0">
+    <function name="Clear" es1="1.0" es2="2.0">
         <param name="mask" type="GLbitfield"/>
         <glx rop="127"/>
     </function>
 
-    <function name="ClearAccum" offset="204" deprecated="3.1">
+    <function name="ClearAccum" deprecated="3.1">
         <param name="red" type="GLfloat"/>
         <param name="green" type="GLfloat"/>
         <param name="blue" type="GLfloat"/>
         <glx rop="128"/>
     </function>
 
-    <function name="ClearIndex" offset="205" deprecated="3.1">
+    <function name="ClearIndex" deprecated="3.1">
         <param name="c" type="GLfloat"/>
         <glx rop="129"/>
     </function>
 
-    <function name="ClearColor" offset="206" es1="1.0" es2="2.0">
+    <function name="ClearColor" es1="1.0" es2="2.0">
         <param name="red" type="GLclampf"/>
         <param name="green" type="GLclampf"/>
         <param name="blue" type="GLclampf"/>
         <glx rop="130"/>
     </function>
 
-    <function name="ClearStencil" offset="207" es1="1.0" es2="2.0">
+    <function name="ClearStencil" es1="1.0" es2="2.0">
         <param name="s" type="GLint"/>
         <glx rop="131"/>
     </function>
 
-    <function name="ClearDepth" offset="208">
+    <function name="ClearDepth">
         <param name="depth" type="GLclampd"/>
         <glx rop="132"/>
     </function>
 
-    <function name="StencilMask" offset="209" es1="1.0" es2="2.0">
+    <function name="StencilMask" es1="1.0" es2="2.0">
         <param name="mask" type="GLuint"/>
         <glx rop="133"/>
     </function>
 
-    <function name="ColorMask" offset="210" es1="1.0" es2="2.0">
+    <function name="ColorMask" es1="1.0" es2="2.0">
         <param name="red" type="GLboolean"/>
         <param name="green" type="GLboolean"/>
         <param name="blue" type="GLboolean"/>
         <glx rop="134"/>
     </function>
 
-    <function name="DepthMask" offset="211" es1="1.0" es2="2.0">
+    <function name="DepthMask" es1="1.0" es2="2.0">
         <param name="flag" type="GLboolean"/>
         <glx rop="135"/>
     </function>
 
-    <function name="IndexMask" offset="212" deprecated="3.1">
+    <function name="IndexMask" deprecated="3.1">
         <param name="mask" type="GLuint"/>
         <glx rop="136"/>
     </function>
 
-    <function name="Accum" offset="213" deprecated="3.1">
+    <function name="Accum" deprecated="3.1">
         <param name="op" type="GLenum"/>
         <param name="value" type="GLfloat"/>
         <glx rop="137"/>
     </function>
 
-    <function name="Disable" offset="214" es1="1.0" es2="2.0">
+    <function name="Disable" es1="1.0" es2="2.0">
         <param name="cap" type="GLenum"/>
         <glx rop="138" handcode="client"/>
     </function>
 
-    <function name="Enable" offset="215" es1="1.0" es2="2.0">
+    <function name="Enable" es1="1.0" es2="2.0">
         <param name="cap" type="GLenum"/>
         <glx rop="139" handcode="client"/>
     </function>
 
-    <function name="Finish" offset="216" es1="1.0" es2="2.0">
+    <function name="Finish" es1="1.0" es2="2.0">
         <glx sop="108" handcode="true"/>
     </function>
 
-    <function name="Flush" offset="217" es1="1.0" es2="2.0">
+    <function name="Flush" es1="1.0" es2="2.0">
         <glx sop="142" handcode="true"/>
     </function>
 
-    <function name="PopAttrib" offset="218" deprecated="3.1">
+    <function name="PopAttrib" deprecated="3.1">
         <glx rop="141"/>
     </function>
 
-    <function name="PushAttrib" offset="219" deprecated="3.1">
+    <function name="PushAttrib" deprecated="3.1">
         <param name="mask" type="GLbitfield"/>
         <glx rop="142"/>
     </function>
 
-    <function name="Map1d" offset="220" deprecated="3.1">
+    <function name="Map1d" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="u1" type="GLdouble"/>
         <param name="u2" type="GLdouble"/>
         <glx rop="143" handcode="true"/>
     </function>
 
-    <function name="Map1f" offset="221" deprecated="3.1">
+    <function name="Map1f" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="u1" type="GLfloat"/>
         <param name="u2" type="GLfloat"/>
         <glx rop="144" handcode="true"/>
     </function>
 
-    <function name="Map2d" offset="222" deprecated="3.1">
+    <function name="Map2d" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="u1" type="GLdouble"/>
         <param name="u2" type="GLdouble"/>
         <glx rop="145" handcode="true"/>
     </function>
 
-    <function name="Map2f" offset="223" deprecated="3.1">
+    <function name="Map2f" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="u1" type="GLfloat"/>
         <param name="u2" type="GLfloat"/>
         <glx rop="146" handcode="true"/>
     </function>
 
-    <function name="MapGrid1d" offset="224" deprecated="3.1">
+    <function name="MapGrid1d" deprecated="3.1">
         <param name="un" type="GLint"/>
         <param name="u1" type="GLdouble"/>
         <param name="u2" type="GLdouble"/>
         <glx rop="147"/>
     </function>
 
-    <function name="MapGrid1f" offset="225" deprecated="3.1">
+    <function name="MapGrid1f" deprecated="3.1">
         <param name="un" type="GLint"/>
         <param name="u1" type="GLfloat"/>
         <param name="u2" type="GLfloat"/>
         <glx rop="148"/>
     </function>
 
-    <function name="MapGrid2d" offset="226" deprecated="3.1">
+    <function name="MapGrid2d" deprecated="3.1">
         <param name="un" type="GLint"/>
         <param name="u1" type="GLdouble"/>
         <param name="u2" type="GLdouble"/>
         <glx rop="149"/>
     </function>
 
-    <function name="MapGrid2f" offset="227" deprecated="3.1">
+    <function name="MapGrid2f" deprecated="3.1">
         <param name="un" type="GLint"/>
         <param name="u1" type="GLfloat"/>
         <param name="u2" type="GLfloat"/>
         <glx rop="150"/>
     </function>
 
-    <function name="EvalCoord1d" offset="228" vectorequiv="EvalCoord1dv"
-              deprecated="3.1">
+    <function name="EvalCoord1d" vectorequiv="EvalCoord1dv" deprecated="3.1">
         <param name="u" type="GLdouble"/>
     </function>
 
-    <function name="EvalCoord1dv" offset="229" deprecated="3.1">
+    <function name="EvalCoord1dv" deprecated="3.1">
         <param name="u" type="const GLdouble *" count="1"/>
         <glx rop="151"/>
     </function>
 
-    <function name="EvalCoord1f" offset="230" vectorequiv="EvalCoord1fv"
+    <function name="EvalCoord1f" vectorequiv="EvalCoord1fv"
               deprecated="3.1" exec="dynamic">
         <param name="u" type="GLfloat"/>
     </function>
 
-    <function name="EvalCoord1fv" offset="231" deprecated="3.1">
+    <function name="EvalCoord1fv" deprecated="3.1">
         <param name="u" type="const GLfloat *" count="1"/>
         <glx rop="152"/>
     </function>
 
-    <function name="EvalCoord2d" offset="232" vectorequiv="EvalCoord2dv"
-              deprecated="3.1">
+    <function name="EvalCoord2d" vectorequiv="EvalCoord2dv" deprecated="3.1">
         <param name="u" type="GLdouble"/>
         <param name="v" type="GLdouble"/>
     </function>
 
-    <function name="EvalCoord2dv" offset="233" deprecated="3.1">
+    <function name="EvalCoord2dv" deprecated="3.1">
         <param name="u" type="const GLdouble *" count="2"/>
         <glx rop="153"/>
     </function>
 
-    <function name="EvalCoord2f" offset="234" vectorequiv="EvalCoord2fv"
+    <function name="EvalCoord2f" vectorequiv="EvalCoord2fv"
               deprecated="3.1" exec="dynamic">
         <param name="u" type="GLfloat"/>
         <param name="v" type="GLfloat"/>
     </function>
 
-    <function name="EvalCoord2fv" offset="235" deprecated="3.1">
+    <function name="EvalCoord2fv" deprecated="3.1">
         <param name="u" type="const GLfloat *" count="2"/>
         <glx rop="154"/>
     </function>
 
-    <function name="EvalMesh1" offset="236" deprecated="3.1"
-              exec="dynamic">
+    <function name="EvalMesh1" deprecated="3.1" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="i1" type="GLint"/>
         <param name="i2" type="GLint"/>
         <glx rop="155"/>
     </function>
 
-    <function name="EvalPoint1" offset="237" deprecated="3.1"
-              exec="dynamic">
+    <function name="EvalPoint1" deprecated="3.1" exec="dynamic">
         <param name="i" type="GLint"/>
         <glx rop="156"/>
     </function>
 
-    <function name="EvalMesh2" offset="238" deprecated="3.1"
-              exec="dynamic">
+    <function name="EvalMesh2" deprecated="3.1" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="i1" type="GLint"/>
         <param name="i2" type="GLint"/>
         <glx rop="157"/>
     </function>
 
-    <function name="EvalPoint2" offset="239" deprecated="3.1"
-              exec="dynamic">
+    <function name="EvalPoint2" deprecated="3.1" exec="dynamic">
         <param name="i" type="GLint"/>
         <param name="j" type="GLint"/>
         <glx rop="158"/>
     </function>
 
-    <function name="AlphaFunc" offset="240" es1="1.0" deprecated="3.1">
+    <function name="AlphaFunc" es1="1.0" deprecated="3.1">
         <param name="func" type="GLenum"/>
         <param name="ref" type="GLclampf"/>
         <glx rop="159"/>
     </function>
 
-    <function name="BlendFunc" offset="241" es1="1.0" es2="2.0">
+    <function name="BlendFunc" es1="1.0" es2="2.0">
         <param name="sfactor" type="GLenum"/>
         <param name="dfactor" type="GLenum"/>
         <glx rop="160"/>
     </function>
 
-    <function name="LogicOp" offset="242" es1="1.0">
+    <function name="LogicOp" es1="1.0">
         <param name="opcode" type="GLenum"/>
         <glx rop="161"/>
     </function>
 
-    <function name="StencilFunc" offset="243" es1="1.0" es2="2.0">
+    <function name="StencilFunc" es1="1.0" es2="2.0">
         <param name="func" type="GLenum"/>
         <param name="ref" type="GLint"/>
         <param name="mask" type="GLuint"/>
         <glx rop="162"/>
     </function>
 
-    <function name="StencilOp" offset="244" es1="1.0" es2="2.0">
+    <function name="StencilOp" es1="1.0" es2="2.0">
         <param name="fail" type="GLenum"/>
         <param name="zfail" type="GLenum"/>
         <param name="zpass" type="GLenum"/>
         <glx rop="163"/>
     </function>
 
-    <function name="DepthFunc" offset="245" es1="1.0" es2="2.0">
+    <function name="DepthFunc" es1="1.0" es2="2.0">
         <param name="func" type="GLenum"/>
         <glx rop="164"/>
     </function>
 
-    <function name="PixelZoom" offset="246" deprecated="3.1">
+    <function name="PixelZoom" deprecated="3.1">
         <param name="xfactor" type="GLfloat"/>
         <param name="yfactor" type="GLfloat"/>
         <glx rop="165"/>
     </function>
 
-    <function name="PixelTransferf" offset="247" deprecated="3.1">
+    <function name="PixelTransferf" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="166"/>
     </function>
 
-    <function name="PixelTransferi" offset="248" deprecated="3.1">
+    <function name="PixelTransferi" deprecated="3.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="167"/>
     </function>
 
-    <function name="PixelStoref" offset="249">
+    <function name="PixelStoref">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx sop="109" handcode="client"/>
     </function>
 
-    <function name="PixelStorei" offset="250" es1="1.0" es2="2.0">
+    <function name="PixelStorei" es1="1.0" es2="2.0">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx sop="110" handcode="client"/>
     </function>
 
-    <function name="PixelMapfv" offset="251" deprecated="3.1">
+    <function name="PixelMapfv" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="mapsize" type="GLsizei" counter="true"/>
         <param name="values" type="const GLfloat *" count="mapsize"/>
         <glx rop="168" large="true"/>
     </function>
 
-    <function name="PixelMapuiv" offset="252" deprecated="3.1">
+    <function name="PixelMapuiv" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="mapsize" type="GLsizei" counter="true"/>
         <param name="values" type="const GLuint *" count="mapsize"/>
         <glx rop="169" large="true"/>
     </function>
 
-    <function name="PixelMapusv" offset="253" deprecated="3.1">
+    <function name="PixelMapusv" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="mapsize" type="GLsizei" counter="true"/>
         <param name="values" type="const GLushort *" count="mapsize"/>
         <glx rop="170" large="true"/>
     </function>
 
-    <function name="ReadBuffer" offset="254" es2="3.0">
+    <function name="ReadBuffer" es2="3.0">
         <param name="mode" type="GLenum"/>
         <glx rop="171"/>
     </function>
 
-    <function name="CopyPixels" offset="255" deprecated="3.1">
+    <function name="CopyPixels" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="width" type="GLsizei"/>
         <glx rop="172"/>
     </function>
 
-    <function name="ReadPixels" offset="256" es1="1.0" es2="2.0">
+    <function name="ReadPixels" es1="1.0" es2="2.0">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="width" type="GLsizei"/>
         <glx sop="111"/>
     </function>
 
-    <function name="DrawPixels" offset="257" deprecated="3.1">
+    <function name="DrawPixels" deprecated="3.1">
         <param name="width" type="GLsizei"/>
         <param name="height" type="GLsizei"/>
         <param name="format" type="GLenum"/>
         <glx rop="173" large="true"/>
     </function>
 
-    <function name="GetBooleanv" offset="258" es1="1.1" es2="2.0">
+    <function name="GetBooleanv" es1="1.1" es2="2.0">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLboolean *" output="true" variable_param="pname"/>
         <glx sop="112" handcode="client"/>
     </function>
 
-    <function name="GetClipPlane" offset="259" deprecated="3.1">
+    <function name="GetClipPlane" deprecated="3.1">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="GLdouble *" output="true" count="4"/>
         <glx sop="113" always_array="true"/>
     </function>
 
-    <function name="GetDoublev" offset="260">
+    <function name="GetDoublev">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLdouble *" output="true" variable_param="pname"/>
         <glx sop="114" handcode="client"/>
     </function>
 
-    <function name="GetError" offset="261" es1="1.0" es2="2.0">
+    <function name="GetError" es1="1.0" es2="2.0">
         <return type="GLenum"/>
         <glx sop="115" handcode="client"/>
     </function>
 
-    <function name="GetFloatv" offset="262" es1="1.1" es2="2.0">
+    <function name="GetFloatv" es1="1.1" es2="2.0">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="116" handcode="client"/>
     </function>
 
-    <function name="GetIntegerv" offset="263" es1="1.0" es2="2.0">
+    <function name="GetIntegerv" es1="1.0" es2="2.0">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="117" handcode="client"/>
     </function>
 
-    <function name="GetLightfv" offset="264" es1="1.1" deprecated="3.1">
+    <function name="GetLightfv" es1="1.1" deprecated="3.1">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="118"/>
     </function>
 
-    <function name="GetLightiv" offset="265" deprecated="3.1">
+    <function name="GetLightiv" deprecated="3.1">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="119"/>
     </function>
 
-    <function name="GetMapdv" offset="266" deprecated="3.1">
+    <function name="GetMapdv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="query" type="GLenum"/>
         <param name="v" type="GLdouble *" output="true" variable_param="target query"/>
         <glx sop="120"/>
     </function>
 
-    <function name="GetMapfv" offset="267" deprecated="3.1">
+    <function name="GetMapfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="query" type="GLenum"/>
         <param name="v" type="GLfloat *" output="true" variable_param="target query"/>
         <glx sop="121"/>
     </function>
 
-    <function name="GetMapiv" offset="268" deprecated="3.1">
+    <function name="GetMapiv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="query" type="GLenum"/>
         <param name="v" type="GLint *" output="true" variable_param="target query"/>
         <glx sop="122"/>
     </function>
 
-    <function name="GetMaterialfv" offset="269" es1="1.1" deprecated="3.1">
+    <function name="GetMaterialfv" es1="1.1" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="123"/>
     </function>
 
-    <function name="GetMaterialiv" offset="270" deprecated="3.1">
+    <function name="GetMaterialiv" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="124"/>
     </function>
 
-    <function name="GetPixelMapfv" offset="271" deprecated="3.1">
+    <function name="GetPixelMapfv" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="values" type="GLfloat *" output="true" variable_param="map"/>
         <glx sop="125"/>
     </function>
 
-    <function name="GetPixelMapuiv" offset="272" deprecated="3.1">
+    <function name="GetPixelMapuiv" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="values" type="GLuint *" output="true" variable_param="map"/>
         <glx sop="126"/>
     </function>
 
-    <function name="GetPixelMapusv" offset="273" deprecated="3.1">
+    <function name="GetPixelMapusv" deprecated="3.1">
         <param name="map" type="GLenum"/>
         <param name="values" type="GLushort *" output="true" variable_param="map"/>
         <glx sop="127"/>
     </function>
 
-    <function name="GetPolygonStipple" offset="274" deprecated="3.1">
+    <function name="GetPolygonStipple" deprecated="3.1">
         <param name="mask" type="GLubyte *" output="true" img_width="32" img_height="32" img_format="GL_COLOR_INDEX" img_type="GL_BITMAP"/>
         <glx sop="128"/>
     </function>
 
-    <function name="GetString" offset="275" es1="1.0" es2="2.0">
+    <function name="GetString" es1="1.0" es2="2.0">
         <param name="name" type="GLenum"/>
         <return type="const GLubyte *"/>
         <glx sop="129" handcode="true"/>
     </function>
 
-    <function name="GetTexEnvfv" offset="276" es1="1.1" deprecated="3.1">
+    <function name="GetTexEnvfv" es1="1.1" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="130"/>
     </function>
 
-    <function name="GetTexEnviv" offset="277" es1="1.1" deprecated="3.1">
+    <function name="GetTexEnviv" es1="1.1" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="131"/>
     </function>
 
-    <function name="GetTexGendv" offset="278" deprecated="3.1">
+    <function name="GetTexGendv" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLdouble *" output="true" variable_param="pname"/>
         <glx sop="132"/>
     </function>
 
-    <function name="GetTexGenfv" offset="279" deprecated="3.1">
+    <function name="GetTexGenfv" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="133"/>
     </function>
 
-    <function name="GetTexGeniv" offset="280" deprecated="3.1">
+    <function name="GetTexGeniv" deprecated="3.1">
         <param name="coord" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="134"/>
     </function>
 
-    <function name="GetTexImage" offset="281">
+    <function name="GetTexImage">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="format" type="GLenum"/>
         <glx sop="135" dimensions_in_reply="true"/>
     </function>
 
-    <function name="GetTexParameterfv" offset="282" es1="1.1" es2="2.0">
+    <function name="GetTexParameterfv" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="136"/>
     </function>
 
-    <function name="GetTexParameteriv" offset="283" es1="1.1" es2="2.0">
+    <function name="GetTexParameteriv" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="137"/>
     </function>
 
-    <function name="GetTexLevelParameterfv" offset="284">
+    <function name="GetTexLevelParameterfv" es2="3.1">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="pname" type="GLenum"/>
         <glx sop="138"/>
     </function>
 
-    <function name="GetTexLevelParameteriv" offset="285">
+    <function name="GetTexLevelParameteriv" es2="3.1">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="pname" type="GLenum"/>
         <glx sop="139"/>
     </function>
 
-    <function name="IsEnabled" offset="286" es1="1.1" es2="2.0">
+    <function name="IsEnabled" es1="1.1" es2="2.0">
         <param name="cap" type="GLenum"/>
         <return type="GLboolean"/>
         <glx sop="140" handcode="client"/>
     </function>
 
-    <function name="IsList" offset="287" deprecated="3.1">
+    <function name="IsList" deprecated="3.1">
         <param name="list" type="GLuint"/>
         <return type="GLboolean"/>
         <glx sop="141"/>
     </function>
 
-    <function name="DepthRange" offset="288">
+    <function name="DepthRange">
         <param name="zNear" type="GLclampd"/>
         <param name="zFar" type="GLclampd"/>
         <glx rop="174"/>
     </function>
 
-    <function name="Frustum" offset="289" deprecated="3.1">
+    <function name="Frustum" deprecated="3.1">
         <param name="left" type="GLdouble"/>
         <param name="right" type="GLdouble"/>
         <param name="bottom" type="GLdouble"/>
         <glx rop="175"/>
     </function>
 
-    <function name="LoadIdentity" offset="290" es1="1.0" deprecated="3.1">
+    <function name="LoadIdentity" es1="1.0" deprecated="3.1">
         <glx rop="176"/>
     </function>
 
-    <function name="LoadMatrixf" offset="291" es1="1.0" deprecated="3.1">
+    <function name="LoadMatrixf" es1="1.0" deprecated="3.1">
         <param name="m" type="const GLfloat *" count="16"/>
         <glx rop="177"/>
     </function>
 
-    <function name="LoadMatrixd" offset="292" deprecated="3.1">
+    <function name="LoadMatrixd" deprecated="3.1">
         <param name="m" type="const GLdouble *" count="16"/>
         <glx rop="178"/>
     </function>
 
-    <function name="MatrixMode" offset="293" es1="1.0" deprecated="3.1">
+    <function name="MatrixMode" es1="1.0" deprecated="3.1">
         <param name="mode" type="GLenum"/>
         <glx rop="179"/>
     </function>
 
-    <function name="MultMatrixf" offset="294" es1="1.0" deprecated="3.1">
+    <function name="MultMatrixf" es1="1.0" deprecated="3.1">
         <param name="m" type="const GLfloat *" count="16"/>
         <glx rop="180"/>
     </function>
 
-    <function name="MultMatrixd" offset="295" deprecated="3.1">
+    <function name="MultMatrixd" deprecated="3.1">
         <param name="m" type="const GLdouble *" count="16"/>
         <glx rop="181"/>
     </function>
 
-    <function name="Ortho" offset="296" deprecated="3.1">
+    <function name="Ortho" deprecated="3.1">
         <param name="left" type="GLdouble"/>
         <param name="right" type="GLdouble"/>
         <param name="bottom" type="GLdouble"/>
         <glx rop="182"/>
     </function>
 
-    <function name="PopMatrix" offset="297" es1="1.0" deprecated="3.1">
+    <function name="PopMatrix" es1="1.0" deprecated="3.1">
         <glx rop="183"/>
     </function>
 
-    <function name="PushMatrix" offset="298" es1="1.0" deprecated="3.1">
+    <function name="PushMatrix" es1="1.0" deprecated="3.1">
         <glx rop="184"/>
     </function>
 
-    <function name="Rotated" offset="299" deprecated="3.1">
+    <function name="Rotated" deprecated="3.1">
         <param name="angle" type="GLdouble"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <glx rop="185"/>
     </function>
 
-    <function name="Rotatef" offset="300" es1="1.0" deprecated="3.1">
+    <function name="Rotatef" es1="1.0" deprecated="3.1">
         <param name="angle" type="GLfloat"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <glx rop="186"/>
     </function>
 
-    <function name="Scaled" offset="301" deprecated="3.1">
+    <function name="Scaled" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <glx rop="187"/>
     </function>
 
-    <function name="Scalef" offset="302" es1="1.0" deprecated="3.1">
+    <function name="Scalef" es1="1.0" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
         <glx rop="188"/>
     </function>
 
-    <function name="Translated" offset="303" deprecated="3.1">
+    <function name="Translated" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <glx rop="189"/>
     </function>
 
-    <function name="Translatef" offset="304" es1="1.0" deprecated="3.1">
+    <function name="Translatef" es1="1.0" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
         <glx rop="190"/>
     </function>
 
-    <function name="Viewport" offset="305" es1="1.0" es2="2.0">
+    <function name="Viewport" es1="1.0" es2="2.0">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="width" type="GLsizei"/>
     <enum name="ALL_CLIENT_ATTRIB_BITS"                   value="0xFFFFFFFF"/>
     <enum name="CLIENT_ALL_ATTRIB_BITS"                   value="0xFFFFFFFF"/>
 
-    <function name="ArrayElement" offset="306" deprecated="3.1"
-              exec="dynamic">
+    <function name="ArrayElement" deprecated="3.1" exec="dynamic">
         <param name="i" type="GLint"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="ColorPointer" offset="308" es1="1.0" deprecated="3.1">
+    <function name="ColorPointer" es1="1.0" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="DisableClientState" offset="309" es1="1.0"
-              deprecated="3.1">
+    <function name="DisableClientState" es1="1.0" deprecated="3.1">
         <param name="array" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="DrawArrays" offset="310" es1="1.0" es2="2.0"
-              exec="dynamic">
+    <function name="DrawArrays" es1="1.0" es2="2.0" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="first" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <glx rop="193" handcode="true"/>
     </function>
 
-    <function name="DrawElements" offset="311" es1="1.0" es2="2.0"
-              exec="dynamic">
+    <function name="DrawElements" es1="1.0" es2="2.0" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="EdgeFlagPointer" offset="312" deprecated="3.1">
+    <function name="EdgeFlagPointer" deprecated="3.1">
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="EnableClientState" offset="313" es1="1.0" deprecated="3.1">
+    <function name="EnableClientState" es1="1.0" deprecated="3.1">
         <param name="array" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="GetPointerv" offset="329" es1="1.1">
+    <function name="GetPointerv" es1="1.1">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLvoid **" output="true"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="IndexPointer" offset="314" deprecated="3.1">
+    <function name="IndexPointer" deprecated="3.1">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="InterleavedArrays" offset="317" deprecated="3.1">
+    <function name="InterleavedArrays" deprecated="3.1">
         <param name="format" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="NormalPointer" offset="318" es1="1.0" deprecated="3.1">
+    <function name="NormalPointer" es1="1.0" deprecated="3.1">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="TexCoordPointer" offset="320" es1="1.0" deprecated="3.1">
+    <function name="TexCoordPointer" es1="1.0" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="VertexPointer" offset="321" es1="1.0" deprecated="3.1">
+    <function name="VertexPointer" es1="1.0" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="PolygonOffset" offset="319" es1="1.0" es2="2.0">
+    <function name="PolygonOffset" es1="1.0" es2="2.0">
         <param name="factor" type="GLfloat"/>
         <param name="units" type="GLfloat"/>
         <glx rop="192"/>
     </function>
 
-    <function name="CopyTexImage1D" offset="323">
+    <function name="CopyTexImage1D">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="4119"/>
     </function>
 
-    <function name="CopyTexImage2D" offset="324" es1="1.0" es2="2.0">
+    <function name="CopyTexImage2D" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="4120"/>
     </function>
 
-    <function name="CopyTexSubImage1D" offset="325">
+    <function name="CopyTexSubImage1D">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="4121"/>
     </function>
 
-    <function name="CopyTexSubImage2D" offset="326" es1="1.0" es2="2.0">
+    <function name="CopyTexSubImage2D" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="4122"/>
     </function>
 
-    <function name="TexSubImage1D" offset="332">
+    <function name="TexSubImage1D">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="4099" large="true"/>
     </function>
 
-    <function name="TexSubImage2D" offset="333" es1="1.0" es2="2.0">
+    <function name="TexSubImage2D" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="4100" large="true"/>
     </function>
 
-    <function name="AreTexturesResident" offset="322" deprecated="3.1">
+    <function name="AreTexturesResident" deprecated="3.1">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="textures" type="const GLuint *" count="n"/>
         <param name="residences" type="GLboolean *" output="true" count="n"/>
         <glx sop="143" handcode="client" always_array="true"/>
     </function>
 
-    <function name="BindTexture" offset="307" es1="1.0" es2="2.0">
+    <function name="BindTexture" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="texture" type="GLuint"/>
         <glx rop="4117"/>
     </function>
 
-    <function name="DeleteTextures" offset="327" es1="1.0" es2="2.0">
+    <function name="DeleteTextures" es1="1.0" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="textures" type="const GLuint *" count="n"/>
         <glx sop="144"/>
     </function>
 
-    <function name="GenTextures" offset="328" es1="1.0" es2="2.0">
+    <function name="GenTextures" es1="1.0" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="textures" type="GLuint *" output="true" count="n"/>
         <glx sop="145" always_array="true"/>
     </function>
 
-    <function name="IsTexture" offset="330" es1="1.1" es2="2.0">
+    <function name="IsTexture" es1="1.1" es2="2.0">
         <param name="texture" type="GLuint"/>
         <return type="GLboolean"/>
         <glx sop="146"/>
     </function>
 
-    <function name="PrioritizeTextures" offset="331" deprecated="3.1">
+    <function name="PrioritizeTextures" deprecated="3.1">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="textures" type="const GLuint *" count="n"/>
         <param name="priorities" type="const GLclampf *" count="n"/>
         <glx rop="4118"/>
     </function>
 
-    <function name="Indexub" offset="315" vectorequiv="Indexubv"
-              deprecated="3.1">
+    <function name="Indexub" vectorequiv="Indexubv" deprecated="3.1">
         <param name="c" type="GLubyte"/>
     </function>
 
-    <function name="Indexubv" offset="316" deprecated="3.1">
+    <function name="Indexubv" deprecated="3.1">
         <param name="c" type="const GLubyte *" count="1"/>
         <glx rop="194"/>
     </function>
 
-    <function name="PopClientAttrib" offset="334" deprecated="3.1">
+    <function name="PopClientAttrib" deprecated="3.1">
         <glx handcode="true"/>
     </function>
 
-    <function name="PushClientAttrib" offset="335" deprecated="3.1">
+    <function name="PushClientAttrib" deprecated="3.1">
         <param name="mask" type="GLbitfield"/>
         <glx handcode="true"/>
     </function>
     </enum>
 
 
-    <function name="BlendColor" offset="336" es2="2.0">
+    <function name="BlendColor" es2="2.0">
         <param name="red" type="GLclampf"/>
         <param name="green" type="GLclampf"/>
         <param name="blue" type="GLclampf"/>
         <glx rop="4096"/>
     </function>
 
-    <function name="BlendEquation" offset="337" es2="2.0">
+    <function name="BlendEquation" es2="2.0">
         <param name="mode" type="GLenum"/>
         <glx rop="4097"/>
     </function>
 
-    <function name="DrawRangeElements" offset="338" es2="3.0"
-              exec="dynamic">
+    <function name="DrawRangeElements" es2="3.0" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="start" type="GLuint"/>
         <param name="end" type="GLuint"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="ColorTable" offset="339" deprecated="3.1">
+    <function name="ColorTable" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <glx rop="2053" large="true"/>
     </function>
 
-    <function name="ColorTableParameterfv" offset="340" deprecated="3.1">
+    <function name="ColorTableParameterfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="2054"/>
     </function>
 
-    <function name="ColorTableParameteriv" offset="341" deprecated="3.1">
+    <function name="ColorTableParameteriv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="2055"/>
     </function>
 
-    <function name="CopyColorTable" offset="342" deprecated="3.1">
+    <function name="CopyColorTable" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="x" type="GLint"/>
         <glx rop="2056"/>
     </function>
 
-    <function name="GetColorTable" offset="343" deprecated="3.1">
+    <function name="GetColorTable" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <glx sop="147" dimensions_in_reply="true"/>
     </function>
 
-    <function name="GetColorTableParameterfv" offset="344" deprecated="3.1">
+    <function name="GetColorTableParameterfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="148"/>
     </function>
 
-    <function name="GetColorTableParameteriv" offset="345" deprecated="3.1">
+    <function name="GetColorTableParameteriv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="149"/>
     </function>
 
-    <function name="ColorSubTable" offset="346" deprecated="3.1">
+    <function name="ColorSubTable" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="start" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <glx rop="195" large="true"/>
     </function>
 
-    <function name="CopyColorSubTable" offset="347" deprecated="3.1">
+    <function name="CopyColorSubTable" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="start" type="GLsizei"/>
         <param name="x" type="GLint"/>
         <glx rop="196"/>
     </function>
 
-    <function name="ConvolutionFilter1D" offset="348" deprecated="3.1">
+    <function name="ConvolutionFilter1D" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <glx rop="4101" large="true"/>
     </function>
 
-    <function name="ConvolutionFilter2D" offset="349" deprecated="3.1">
+    <function name="ConvolutionFilter2D" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <glx rop="4102" large="true"/>
     </function>
 
-    <function name="ConvolutionParameterf" offset="350" deprecated="3.1">
+    <function name="ConvolutionParameterf" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat"/>
         <glx rop="4103"/>
     </function>
 
-    <function name="ConvolutionParameterfv" offset="351" deprecated="3.1">
+    <function name="ConvolutionParameterfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="4104"/>
     </function>
 
-    <function name="ConvolutionParameteri" offset="352" deprecated="3.1">
+    <function name="ConvolutionParameteri" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint"/>
         <glx rop="4105"/>
     </function>
 
-    <function name="ConvolutionParameteriv" offset="353" deprecated="3.1">
+    <function name="ConvolutionParameteriv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="4106"/>
     </function>
 
-    <function name="CopyConvolutionFilter1D" offset="354" deprecated="3.1">
+    <function name="CopyConvolutionFilter1D" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="x" type="GLint"/>
         <glx rop="4107"/>
     </function>
 
-    <function name="CopyConvolutionFilter2D" offset="355" deprecated="3.1">
+    <function name="CopyConvolutionFilter2D" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="x" type="GLint"/>
         <glx rop="4108"/>
     </function>
 
-    <function name="GetConvolutionFilter" offset="356" deprecated="3.1">
+    <function name="GetConvolutionFilter" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <glx sop="150" dimensions_in_reply="true"/>
     </function>
 
-    <function name="GetConvolutionParameterfv" offset="357" deprecated="3.1">
+    <function name="GetConvolutionParameterfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="151"/>
     </function>
 
-    <function name="GetConvolutionParameteriv" offset="358" deprecated="3.1">
+    <function name="GetConvolutionParameteriv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="152"/>
     </function>
 
-    <function name="GetSeparableFilter" offset="359" deprecated="3.1">
+    <function name="GetSeparableFilter" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <glx sop="153" handcode="true"/>
     </function>
 
-    <function name="SeparableFilter2D" offset="360" deprecated="3.1">
+    <function name="SeparableFilter2D" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <glx rop="4109" handcode="true"/>
     </function>
 
-    <function name="GetHistogram" offset="361" deprecated="3.1">
+    <function name="GetHistogram" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="reset" type="GLboolean"/>
         <param name="format" type="GLenum"/>
         <glx sop="154" dimensions_in_reply="true" img_reset="reset"/>
     </function>
 
-    <function name="GetHistogramParameterfv" offset="362" deprecated="3.1">
+    <function name="GetHistogramParameterfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="155"/>
     </function>
 
-    <function name="GetHistogramParameteriv" offset="363" deprecated="3.1">
+    <function name="GetHistogramParameteriv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="156"/>
     </function>
 
-    <function name="GetMinmax" offset="364" deprecated="3.1">
+    <function name="GetMinmax" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="reset" type="GLboolean"/>
         <param name="format" type="GLenum"/>
         <glx sop="157" img_reset="reset"/>
     </function>
 
-    <function name="GetMinmaxParameterfv" offset="365" deprecated="3.1">
+    <function name="GetMinmaxParameterfv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx sop="158"/>
     </function>
 
-    <function name="GetMinmaxParameteriv" offset="366" deprecated="3.1">
+    <function name="GetMinmaxParameteriv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="159"/>
     </function>
 
-    <function name="Histogram" offset="367" deprecated="3.1">
+    <function name="Histogram" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="4110"/>
     </function>
 
-    <function name="Minmax" offset="368" deprecated="3.1">
+    <function name="Minmax" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="sink" type="GLboolean"/>
         <glx rop="4111"/>
     </function>
 
-    <function name="ResetHistogram" offset="369" deprecated="3.1">
+    <function name="ResetHistogram" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <glx rop="4112"/>
     </function>
 
-    <function name="ResetMinmax" offset="370" deprecated="3.1">
+    <function name="ResetMinmax" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <glx rop="4113"/>
     </function>
 
-    <function name="TexImage3D" offset="371" es2="3.0">
+    <function name="TexImage3D" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLint"/>
         <glx rop="4114" large="true"/>
     </function>
 
-    <function name="TexSubImage3D" offset="372" es2="3.0">
+    <function name="TexSubImage3D" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="4115" large="true"/>
     </function>
 
-    <function name="CopyTexSubImage3D" offset="373" es2="3.0">
+    <function name="CopyTexSubImage3D" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
     <enum name="DOT3_RGB"                                 value="0x86AE"/>
     <enum name="DOT3_RGBA"                                value="0x86AF"/>
 
-    <function name="ActiveTexture" es1="1.0"
-              es2="2.0" offset="374">
+    <function name="ActiveTexture" es1="1.0" es2="2.0">
         <param name="texture" type="GLenum"/>
         <glx rop="197"/>
     </function>
 
-    <function name="ClientActiveTexture"
-              es1="1.0" deprecated="3.1" offset="375">
+    <function name="ClientActiveTexture" es1="1.0" deprecated="3.1">
         <param name="texture" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="MultiTexCoord1d"
-              deprecated="3.1" offset="376">
+    <function name="MultiTexCoord1d" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLdouble"/>
     </function>
 
-    <function name="MultiTexCoord1dv"
-              deprecated="3.1" offset="377">
+    <function name="MultiTexCoord1dv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLdouble *" count="1"/>
         <glx rop="198"/>
     </function>
 
-    <function name="MultiTexCoord1f" alias="MultiTexCoord1fARB"
-              deprecated="3.1">
+    <function name="MultiTexCoord1f" alias="MultiTexCoord1fARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfloat"/>
     </function>
         <param name="v" type="const GLfloat *"/>
     </function>
 
-    <function name="MultiTexCoord1i"
-              deprecated="3.1" offset="380">
+    <function name="MultiTexCoord1i" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLint"/>
     </function>
 
-    <function name="MultiTexCoord1iv"
-              deprecated="3.1" offset="381">
+    <function name="MultiTexCoord1iv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLint *" count="1"/>
         <glx rop="200"/>
     </function>
 
-    <function name="MultiTexCoord1s"
-              deprecated="3.1" offset="382">
+    <function name="MultiTexCoord1s" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLshort"/>
     </function>
 
-    <function name="MultiTexCoord1sv"
-              deprecated="3.1" offset="383">
+    <function name="MultiTexCoord1sv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLshort *" count="1"/>
         <glx rop="201"/>
     </function>
 
-    <function name="MultiTexCoord2d"
-              deprecated="3.1" offset="384">
+    <function name="MultiTexCoord2d" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLdouble"/>
         <param name="t" type="GLdouble"/>
     </function>
 
-    <function name="MultiTexCoord2dv"
-              deprecated="3.1" offset="385">
+    <function name="MultiTexCoord2dv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLdouble *" count="2"/>
         <glx rop="202"/>
         <param name="v" type="const GLfloat *"/>
     </function>
 
-    <function name="MultiTexCoord2i"
-              deprecated="3.1" offset="388">
+    <function name="MultiTexCoord2i" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLint"/>
         <param name="t" type="GLint"/>
     </function>
 
-    <function name="MultiTexCoord2iv"
-              deprecated="3.1" offset="389">
+    <function name="MultiTexCoord2iv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLint *" count="2"/>
         <glx rop="204"/>
     </function>
 
-    <function name="MultiTexCoord2s"
-              deprecated="3.1" offset="390">
+    <function name="MultiTexCoord2s" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLshort"/>
         <param name="t" type="GLshort"/>
     </function>
 
-    <function name="MultiTexCoord2sv"
-              deprecated="3.1" offset="391">
+    <function name="MultiTexCoord2sv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLshort *" count="2"/>
         <glx rop="205"/>
     </function>
 
-    <function name="MultiTexCoord3d"
-              deprecated="3.1" offset="392">
+    <function name="MultiTexCoord3d" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLdouble"/>
         <param name="t" type="GLdouble"/>
         <param name="r" type="GLdouble"/>
     </function>
 
-    <function name="MultiTexCoord3dv"
-              deprecated="3.1" offset="393">
+    <function name="MultiTexCoord3dv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="206"/>
         <param name="v" type="const GLfloat *"/>
     </function>
 
-    <function name="MultiTexCoord3i"
-              deprecated="3.1" offset="396">
+    <function name="MultiTexCoord3i" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLint"/>
         <param name="t" type="GLint"/>
         <param name="r" type="GLint"/>
     </function>
 
-    <function name="MultiTexCoord3iv"
-              deprecated="3.1" offset="397">
+    <function name="MultiTexCoord3iv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="208"/>
     </function>
 
-    <function name="MultiTexCoord3s"
-              deprecated="3.1" offset="398">
+    <function name="MultiTexCoord3s" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLshort"/>
         <param name="t" type="GLshort"/>
         <param name="r" type="GLshort"/>
     </function>
 
-    <function name="MultiTexCoord3sv"
-              deprecated="3.1" offset="399">
+    <function name="MultiTexCoord3sv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="209"/>
     </function>
 
-    <function name="MultiTexCoord4d"
-              deprecated="3.1" offset="400">
+    <function name="MultiTexCoord4d" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLdouble"/>
         <param name="t" type="GLdouble"/>
         <param name="q" type="GLdouble"/>
     </function>
 
-    <function name="MultiTexCoord4dv"
-              deprecated="3.1" offset="401">
+    <function name="MultiTexCoord4dv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="210"/>
         <param name="v" type="const GLfloat *"/>
     </function>
 
-    <function name="MultiTexCoord4i"
-              deprecated="3.1" offset="404">
+    <function name="MultiTexCoord4i" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLint"/>
         <param name="t" type="GLint"/>
         <param name="q" type="GLint"/>
     </function>
 
-    <function name="MultiTexCoord4iv"
-              deprecated="3.1" offset="405">
+    <function name="MultiTexCoord4iv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="212"/>
     </function>
 
-    <function name="MultiTexCoord4s"
-              deprecated="3.1" offset="406">
+    <function name="MultiTexCoord4s" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLshort"/>
         <param name="t" type="GLshort"/>
         <param name="q" type="GLshort"/>
     </function>
 
-    <function name="MultiTexCoord4sv"
-              deprecated="3.1" offset="407">
+    <function name="MultiTexCoord4sv" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="213"/>
     </function>
 
-    <function name="LoadTransposeMatrixf"
-              deprecated="3.1" offset="assign">
+    <function name="LoadTransposeMatrixf" deprecated="3.1">
         <param name="m" type="const GLfloat *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="LoadTransposeMatrixd"
-              deprecated="3.1" offset="assign">
+    <function name="LoadTransposeMatrixd" deprecated="3.1">
         <param name="m" type="const GLdouble *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="MultTransposeMatrixf"
-              deprecated="3.1" offset="assign">
+    <function name="MultTransposeMatrixf" deprecated="3.1">
         <param name="m" type="const GLfloat *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="MultTransposeMatrixd"
-              deprecated="3.1" offset="assign">
+    <function name="MultTransposeMatrixd" deprecated="3.1">
         <param name="m" type="const GLdouble *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="SampleCoverage" es1="1.0"
-              es2="2.0" offset="assign">
+    <function name="SampleCoverage" es1="1.0" es2="2.0">
         <param name="value" type="GLclampf"/>
         <param name="invert" type="GLboolean"/>
         <glx rop="229"/>
     </function>
 
-    <function name="CompressedTexImage3D" es2="3.0" offset="assign">
+    <function name="CompressedTexImage3D" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="216" handcode="client"/>
     </function>
 
-    <function name="CompressedTexImage2D"
-              es1="1.0" es2="2.0" offset="assign">
+    <function name="CompressedTexImage2D" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="215" handcode="client"/>
     </function>
 
-    <function name="CompressedTexImage1D" offset="assign">
+    <function name="CompressedTexImage1D">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="internalformat" type="GLenum"/>
         <glx rop="214" handcode="client"/>
     </function>
 
-    <function name="CompressedTexSubImage3D" es2="3.0" offset="assign">
+    <function name="CompressedTexSubImage3D" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="219" handcode="client"/>
     </function>
 
-    <function name="CompressedTexSubImage2D"
-              es1="1.0" es2="2.0" offset="assign">
+    <function name="CompressedTexSubImage2D" es1="1.0" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="218" handcode="client"/>
     </function>
 
-    <function name="CompressedTexSubImage1D" offset="assign">
+    <function name="CompressedTexSubImage1D">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="xoffset" type="GLint"/>
         <glx rop="217" handcode="client"/>
     </function>
 
-    <function name="GetCompressedTexImage" offset="assign">
+    <function name="GetCompressedTexImage">
         <param name="target" type="GLenum"/>
         <param name="level" type="GLint"/>
         <param name="img" type="GLvoid *" output="true"/>
     </enum>
     <enum name="COMPARE_R_TO_TEXTURE"                     value="0x884E"/>
 
-    <function name="BlendFuncSeparate" es2="2.0" offset="assign">
+    <function name="BlendFuncSeparate" es2="2.0">
         <param name="sfactorRGB" type="GLenum"/>
         <param name="dfactorRGB" type="GLenum"/>
         <param name="sfactorAlpha" type="GLenum"/>
         <param name="coord" type="const GLfloat *"/>
     </function>
 
-    <function name="FogCoordd" deprecated="3.1" offset="assign">
+    <function name="FogCoordd" deprecated="3.1">
         <param name="coord" type="GLdouble"/>
     </function>
 
-    <function name="FogCoorddv" deprecated="3.1" offset="assign">
+    <function name="FogCoorddv" deprecated="3.1">
         <param name="coord" type="const GLdouble *" count="1"/>
         <glx rop="4125"/>
     </function>
 
-    <function name="FogCoordPointer"
-              deprecated="3.1" offset="assign">
+    <function name="FogCoordPointer" deprecated="3.1">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="MultiDrawArrays" offset="assign">
+    <function name="MultiDrawArrays">
         <param name="mode" type="GLenum"/>
         <param name="first" type="const GLint *"/>
         <param name="count" type="const GLsizei *"/>
         <param name="primcount" type="GLsizei"/>
     </function>
 
-    <function name="PointParameterf" es1="1.1" offset="assign">
+    <function name="PointParameterf" es1="1.1">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
         <glx rop="2065"/>
     </function>
 
-    <function name="PointParameterfv" es1="1.1" offset="assign">
+    <function name="PointParameterfv" es1="1.1">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *" variable_param="pname"/>
         <glx rop="2066"/>
     </function>
 
-    <function name="PointParameteri" offset="assign">
+    <function name="PointParameteri">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
         <glx rop="4221"/>
     </function>
 
-    <function name="PointParameteriv" offset="assign">
+    <function name="PointParameteriv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *" variable_param="pname"/>
         <glx rop="4222"/>
     </function>
 
-    <function name="SecondaryColor3b"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3b" deprecated="3.1">
         <param name="red" type="GLbyte"/>
         <param name="green" type="GLbyte"/>
         <param name="blue" type="GLbyte"/>
     </function>
 
-    <function name="SecondaryColor3bv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3bv" deprecated="3.1">
         <param name="v" type="const GLbyte *" count="3"/>
         <glx rop="4126"/>
     </function>
 
-    <function name="SecondaryColor3d"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3d" deprecated="3.1">
         <param name="red" type="GLdouble"/>
         <param name="green" type="GLdouble"/>
         <param name="blue" type="GLdouble"/>
     </function>
 
-    <function name="SecondaryColor3dv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="4130"/>
     </function>
         <param name="v" type="const GLfloat *"/>
     </function>
 
-    <function name="SecondaryColor3i"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3i" deprecated="3.1">
         <param name="red" type="GLint"/>
         <param name="green" type="GLint"/>
         <param name="blue" type="GLint"/>
     </function>
 
-    <function name="SecondaryColor3iv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3iv" deprecated="3.1">
         <param name="v" type="const GLint *" count="3"/>
         <glx rop="4128"/>
     </function>
 
-    <function name="SecondaryColor3s"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3s" deprecated="3.1">
         <param name="red" type="GLshort"/>
         <param name="green" type="GLshort"/>
         <param name="blue" type="GLshort"/>
     </function>
 
-    <function name="SecondaryColor3sv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3sv" deprecated="3.1">
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="4127"/>
     </function>
 
-    <function name="SecondaryColor3ub"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3ub" deprecated="3.1">
         <param name="red" type="GLubyte"/>
         <param name="green" type="GLubyte"/>
         <param name="blue" type="GLubyte"/>
     </function>
 
-    <function name="SecondaryColor3ubv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3ubv" deprecated="3.1">
         <param name="v" type="const GLubyte *" count="3"/>
         <glx rop="4131"/>
     </function>
 
-    <function name="SecondaryColor3ui"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3ui" deprecated="3.1">
         <param name="red" type="GLuint"/>
         <param name="green" type="GLuint"/>
         <param name="blue" type="GLuint"/>
     </function>
 
-    <function name="SecondaryColor3uiv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3uiv" deprecated="3.1">
         <param name="v" type="const GLuint *" count="3"/>
         <glx rop="4133"/>
     </function>
 
-    <function name="SecondaryColor3us"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3us" deprecated="3.1">
         <param name="red" type="GLushort"/>
         <param name="green" type="GLushort"/>
         <param name="blue" type="GLushort"/>
     </function>
 
-    <function name="SecondaryColor3usv"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColor3usv" deprecated="3.1">
         <param name="v" type="const GLushort *" count="3"/>
         <glx rop="4132"/>
     </function>
 
-    <function name="SecondaryColorPointer"
-              deprecated="3.1" offset="assign">
+    <function name="SecondaryColorPointer" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2d" deprecated="3.1" offset="assign">
+    <function name="WindowPos2d" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2dv" deprecated="3.1" offset="assign">
+    <function name="WindowPos2dv" deprecated="3.1">
         <param name="v" type="const GLdouble *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2f" deprecated="3.1" offset="assign">
+    <function name="WindowPos2f" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2fv" deprecated="3.1" offset="assign">
+    <function name="WindowPos2fv" deprecated="3.1">
         <param name="v" type="const GLfloat *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2i" deprecated="3.1" offset="assign">
+    <function name="WindowPos2i" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2iv" deprecated="3.1" offset="assign">
+    <function name="WindowPos2iv" deprecated="3.1">
         <param name="v" type="const GLint *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2s" deprecated="3.1" offset="assign">
+    <function name="WindowPos2s" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos2sv" deprecated="3.1" offset="assign">
+    <function name="WindowPos2sv" deprecated="3.1">
         <param name="v" type="const GLshort *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos3d" deprecated="3.1" offset="assign">
+    <function name="WindowPos3d" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos3dv" deprecated="3.1" offset="assign">
+    <function name="WindowPos3dv" deprecated="3.1">
         <param name="v" type="const GLdouble *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos3f" deprecated="3.1" offset="assign">
+    <function name="WindowPos3f" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
     </function>
 
-    <function name="WindowPos3fv" deprecated="3.1" offset="assign">
+    <function name="WindowPos3fv" deprecated="3.1">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="230"/>
     </function>
 
-    <function name="WindowPos3i" deprecated="3.1" offset="assign">
+    <function name="WindowPos3i" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos3iv" deprecated="3.1" offset="assign">
+    <function name="WindowPos3iv" deprecated="3.1">
         <param name="v" type="const GLint *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos3s" deprecated="3.1" offset="assign">
+    <function name="WindowPos3s" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="WindowPos3sv" deprecated="3.1" offset="assign">
+    <function name="WindowPos3sv" deprecated="3.1">
         <param name="v" type="const GLshort *"/>
         <glx handcode="true"/>
     </function>
     <type name="intptr"   size="4"                  glx_name="CARD32"/>
     <type name="sizeiptr" size="4"  unsigned="true" glx_name="CARD32"/>
 
-    <function name="BindBuffer" es1="1.1" es2="2.0" offset="assign">
+    <function name="BindBuffer" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="buffer" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="BufferData" es1="1.1" es2="2.0" offset="assign">
+    <function name="BufferData" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="size" type="GLsizeiptr" counter="true"/>
         <param name="data" type="const GLvoid *" count="size" img_null_flag="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="BufferSubData" es1="1.1"
-              es2="2.0" offset="assign">
+    <function name="BufferSubData" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="size" type="GLsizeiptr" counter="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DeleteBuffers" es1="1.1"
-              es2="2.0" offset="assign">
+    <function name="DeleteBuffers" es1="1.1" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="buffer" type="const GLuint *" count="n"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GenBuffers" es1="1.1" es2="2.0" offset="assign">
+    <function name="GenBuffers" es1="1.1" es2="2.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="buffer" type="GLuint *" output="true" count="n"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetBufferParameteriv"
-              es1="1.1" es2="2.0" offset="assign">
+    <function name="GetBufferParameteriv" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetBufferPointerv" es2="3.0" offset="assign">
+    <function name="GetBufferPointerv" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLvoid **" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetBufferSubData" offset="assign">
+    <function name="GetBufferSubData">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="size" type="GLsizeiptr" counter="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="IsBuffer" es1="1.1" es2="2.0" offset="assign">
+    <function name="IsBuffer" es1="1.1" es2="2.0">
         <param name="buffer" type="GLuint"/>
         <return type="GLboolean"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="MapBuffer" offset="assign">
+    <function name="MapBuffer">
         <param name="target" type="GLenum"/>
         <param name="access" type="GLenum"/>
         <return type="GLvoid *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="UnmapBuffer" es2="3.0" offset="assign">
+    <function name="UnmapBuffer" es2="3.0">
         <param name="target" type="GLenum"/>
         <return type="GLboolean"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GenQueries" es2="3.0" offset="assign">
+    <function name="GenQueries" es2="3.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="ids" type="GLuint *" output="true" count="n"/>
         <glx sop="162" always_array="true"/>
     </function>
 
-    <function name="DeleteQueries" es2="3.0" offset="assign">
+    <function name="DeleteQueries" es2="3.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="ids" type="const GLuint *" count="n"/>
         <glx sop="161"/>
     </function>
 
-    <function name="IsQuery" es2="3.0" offset="assign">
+    <function name="IsQuery" es2="3.0">
         <param name="id" type="GLuint"/>
         <return type="GLboolean"/>
         <glx sop="163"/>
     </function>
 
-    <function name="BeginQuery" es2="3.0" offset="assign">
+    <function name="BeginQuery" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="id" type="GLuint"/>
         <glx rop="231"/>
     </function>
 
-    <function name="EndQuery" es2="3.0" offset="assign">
+    <function name="EndQuery" es2="3.0">
         <param name="target" type="GLenum"/>
         <glx rop="232"/>
     </function>
 
-    <function name="GetQueryiv" es2="3.0" offset="assign">
+    <function name="GetQueryiv" es2="3.0">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="164"/>
     </function>
 
-    <function name="GetQueryObjectiv" offset="assign">
+    <function name="GetQueryObjectiv">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx sop="165"/>
     </function>
 
-    <function name="GetQueryObjectuiv" es2="3.0" offset="assign">
+    <function name="GetQueryObjectuiv" es2="3.0">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLuint *" output="true" variable_param="pname"/>
     <enum name="STENCIL_BACK_VALUE_MASK"          value="0x8CA4"/>
     <enum name="STENCIL_BACK_WRITEMASK"           value="0x8CA5"/>
 
-    <function name="BlendEquationSeparate"
-              es2="2.0" offset="assign">
+    <function name="BlendEquationSeparate" es2="2.0">
         <param name="modeRGB" type="GLenum"/>
         <param name="modeA" type="GLenum"/>
         <glx rop="4228"/>
     </function>
 
-    <function name="DrawBuffers" es2="3.0" offset="assign">
+    <function name="DrawBuffers" es2="3.0">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="bufs" type="const GLenum *" count="n"/>
         <glx rop="233" large="true"/>
     </function>
 
-    <function name="StencilFuncSeparate" offset="assign" es2="2.0">
+    <function name="StencilFuncSeparate" es2="2.0">
         <param name="face" type="GLenum"/>
         <param name="func" type="GLenum"/>
         <param name="ref" type="GLint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="StencilOpSeparate" offset="assign" es2="2.0">
+    <function name="StencilOpSeparate" es2="2.0">
         <param name="face" type="GLenum"/>
         <param name="sfail" type="GLenum"/>
         <param name="zfail" type="GLenum"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="StencilMaskSeparate" offset="assign" es2="2.0">
+    <function name="StencilMaskSeparate" es2="2.0">
         <param name="face" type="GLenum"/>
         <param name="mask" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="AttachShader" offset="assign" es2="2.0">
+    <function name="AttachShader" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="shader" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="BindAttribLocation"
-              es2="2.0" offset="assign">
+    <function name="BindAttribLocation" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="index" type="GLuint"/>
         <param name="name" type="const GLchar *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="CompileShader" es2="2.0" offset="assign">
+    <function name="CompileShader" es2="2.0">
         <param name="shader" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="CreateProgram" offset="assign" es2="2.0">
+    <function name="CreateProgram" es2="2.0">
         <return type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="CreateShader" offset="assign" es2="2.0">
+    <function name="CreateShader" es2="2.0">
         <param name="type" type="GLenum"/>
         <return type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DeleteProgram" offset="assign" es2="2.0">
+    <function name="DeleteProgram" es2="2.0">
         <param name="program" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DeleteShader" offset="assign" es2="2.0">
+    <function name="DeleteShader" es2="2.0">
         <param name="program" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DetachShader" offset="assign" es2="2.0">
+    <function name="DetachShader" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="shader" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DisableVertexAttribArray" es2="2.0" offset="assign">
+    <function name="DisableVertexAttribArray" es2="2.0">
         <param name="index" type="GLuint"/>
         <glx ignore="true"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="EnableVertexAttribArray"
-              es2="2.0" offset="assign">
+    <function name="EnableVertexAttribArray" es2="2.0">
         <param name="index" type="GLuint"/>
         <glx ignore="true"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="GetActiveAttrib" es2="2.0" offset="assign">
+    <function name="GetActiveAttrib" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="index" type="GLuint"/>
         <param name="bufSize" type="GLsizei "/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetActiveUniform" es2="2.0" offset="assign">
+    <function name="GetActiveUniform" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="index" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetAttachedShaders" offset="assign" es2="2.0">
+    <function name="GetAttachedShaders" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="maxCount" type="GLsizei"/>
         <param name="count" type="GLsizei *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetAttribLocation" es2="2.0" offset="assign">
+    <function name="GetAttribLocation" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="name" type="const GLchar *"/>
         <return type="GLint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetProgramiv" offset="assign" es2="2.0">
+    <function name="GetProgramiv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetProgramInfoLog" offset="assign" es2="2.0">
+    <function name="GetProgramInfoLog" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetShaderiv" offset="assign" es2="2.0">
+    <function name="GetShaderiv" es2="2.0">
         <param name="shader" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetShaderInfoLog" offset="assign" es2="2.0">
+    <function name="GetShaderInfoLog" es2="2.0">
         <param name="shader" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetShaderSource" es2="2.0" offset="assign">
+    <function name="GetShaderSource" es2="2.0">
         <param name="shader" type="GLuint"/>
         <param name="bufSize" type="GLsizei"/>
         <param name="length" type="GLsizei *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetUniformLocation"
-              es2="2.0" offset="assign">
+    <function name="GetUniformLocation" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="name" type="const GLchar *"/>
         <return type="GLint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetUniformfv" es2="2.0" offset="assign">
+    <function name="GetUniformfv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="params" type="GLfloat *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetUniformiv" es2="2.0" offset="assign">
+    <function name="GetUniformiv" es2="2.0">
         <param name="program" type="GLuint"/>
         <param name="location" type="GLint"/>
         <param name="params" type="GLint *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetVertexAttribdv" offset="assign">
+    <function name="GetVertexAttribdv">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLdouble *" output="true" variable_param="pname"/>
         <glx handcode="client" vendorpriv="1301"/>
     </function>
 
-    <function name="GetVertexAttribfv" es2="2.0" offset="assign">
+    <function name="GetVertexAttribfv" es2="2.0">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx handcode="client" vendorpriv="1302"/>
     </function>
 
-    <function name="GetVertexAttribiv" es2="2.0" offset="assign">
+    <function name="GetVertexAttribiv" es2="2.0">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx handcode="client" vendorpriv="1303"/>
     </function>
 
-    <function name="GetVertexAttribPointerv"
-              es2="2.0" offset="assign">
+    <function name="GetVertexAttribPointerv" es2="2.0">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="pointer" type="GLvoid **" output="true"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="IsProgram" offset="assign" es2="2.0">
+    <function name="IsProgram" es2="2.0">
         <param name="program" type="GLuint"/>
         <return type="GLboolean"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="IsShader" offset="assign" es2="2.0">
+    <function name="IsShader" es2="2.0">
         <param name="shader" type="GLuint"/>
         <return type="GLboolean"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="LinkProgram" es2="2.0" offset="assign">
+    <function name="LinkProgram" es2="2.0">
         <param name="program" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="ShaderSource" es2="2.0" offset="assign">
+    <function name="ShaderSource" es2="2.0">
         <param name="shader" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="string" type="const GLchar * const *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="UseProgram" es2="2.0" offset="assign">
+    <function name="UseProgram" es2="2.0">
         <param name="program" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="Uniform1f" es2="2.0" offset="assign">
+    <function name="Uniform1f" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLfloat"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform2f" es2="2.0" offset="assign">
+    <function name="Uniform2f" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLfloat"/>
         <param name="v1" type="GLfloat"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform3f" es2="2.0" offset="assign">
+    <function name="Uniform3f" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLfloat"/>
         <param name="v1" type="GLfloat"/>
         <param name="v2" type="GLfloat"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform4f" es2="2.0" offset="assign">
+    <function name="Uniform4f" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLfloat"/>
         <param name="v1" type="GLfloat"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="Uniform1i" es2="2.0" offset="assign">
+    <function name="Uniform1i" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLint"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform2i" es2="2.0" offset="assign">
+    <function name="Uniform2i" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLint"/>
         <param name="v1" type="GLint"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform3i" es2="2.0" offset="assign">
+    <function name="Uniform3i" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLint"/>
         <param name="v1" type="GLint"/>
         <param name="v2" type="GLint"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform4i" es2="2.0" offset="assign">
+    <function name="Uniform4i" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLint"/>
         <param name="v1" type="GLint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="Uniform1fv" es2="2.0" offset="assign">
+    <function name="Uniform1fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLfloat *" count="count"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform2fv" es2="2.0" offset="assign">
+    <function name="Uniform2fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="2"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform3fv" es2="2.0" offset="assign">
+    <function name="Uniform3fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="3"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform4fv" es2="2.0" offset="assign">
+    <function name="Uniform4fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="4"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="Uniform1iv" es2="2.0" offset="assign">
+    <function name="Uniform1iv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLint *" count="count"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform2iv" es2="2.0" offset="assign">
+    <function name="Uniform2iv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLint *" count="count" count_scale="2"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform3iv" es2="2.0" offset="assign">
+    <function name="Uniform3iv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLint *" count="count" count_scale="3"/>
         <glx ignore="true"/>
     </function>
-    <function name="Uniform4iv" es2="2.0" offset="assign">
+    <function name="Uniform4iv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="value" type="const GLint *" count="count" count_scale="4"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="UniformMatrix2fv" es2="2.0" offset="assign">
+    <function name="UniformMatrix2fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="4"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix3fv" es2="2.0" offset="assign">
+    <function name="UniformMatrix3fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="9"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix4fv" es2="2.0" offset="assign">
+    <function name="UniformMatrix4fv" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="ValidateProgram" es2="2.0" offset="assign">
+    <function name="ValidateProgram" es2="2.0">
         <param name="program" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="VertexAttrib1d" offset="assign">
+    <function name="VertexAttrib1d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
     </function>
-    <function name="VertexAttrib1dv" offset="assign">
+    <function name="VertexAttrib1dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="1"/>
         <glx rop="4197" doubles_in_order="true"/>
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *"/>
     </function>
-    <function name="VertexAttrib1s" offset="assign">
+    <function name="VertexAttrib1s">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
     </function>
-    <function name="VertexAttrib1sv" offset="assign">
+    <function name="VertexAttrib1sv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="1"/>
         <glx rop="4189"/>
     </function>
 
-    <function name="VertexAttrib2d" offset="assign">
+    <function name="VertexAttrib2d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
     </function>
-    <function name="VertexAttrib2dv" offset="assign">
+    <function name="VertexAttrib2dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="2"/>
         <glx rop="4198" doubles_in_order="true"/>
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *"/>
     </function>
-    <function name="VertexAttrib2s" offset="assign">
+    <function name="VertexAttrib2s">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
     </function>
-    <function name="VertexAttrib2sv" offset="assign">
+    <function name="VertexAttrib2sv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="2"/>
         <glx rop="4190"/>
     </function>
 
-    <function name="VertexAttrib3d" offset="assign">
+    <function name="VertexAttrib3d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
     </function>
-    <function name="VertexAttrib3dv" offset="assign">
+    <function name="VertexAttrib3dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="4199" doubles_in_order="true"/>
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *"/>
     </function>
-    <function name="VertexAttrib3s" offset="assign">
+    <function name="VertexAttrib3s">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
     </function>
-    <function name="VertexAttrib3sv" offset="assign">
+    <function name="VertexAttrib3sv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="4191"/>
     </function>
 
-    <function name="VertexAttrib4Nbv" offset="assign">
+    <function name="VertexAttrib4Nbv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLbyte *" count="4"/>
         <glx rop="4235"/>
     </function>
-    <function name="VertexAttrib4Niv" offset="assign">
+    <function name="VertexAttrib4Niv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="4237"/>
     </function>
-    <function name="VertexAttrib4Nsv" offset="assign">
+    <function name="VertexAttrib4Nsv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="4236"/>
     </function>
-    <function name="VertexAttrib4Nub" offset="assign">
+    <function name="VertexAttrib4Nub">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLubyte"/>
         <param name="y" type="GLubyte"/>
         <param name="z" type="GLubyte"/>
         <param name="w" type="GLubyte"/>
     </function>
-    <function name="VertexAttrib4Nubv" offset="assign">
+    <function name="VertexAttrib4Nubv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLubyte *" count="4"/>
         <glx rop="4201"/>
     </function>
-    <function name="VertexAttrib4Nuiv" offset="assign">
+    <function name="VertexAttrib4Nuiv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLuint *" count="4"/>
         <glx rop="4239"/>
     </function>
-    <function name="VertexAttrib4Nusv" offset="assign">
+    <function name="VertexAttrib4Nusv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLushort *" count="4"/>
         <glx rop="4238"/>
     </function>
-    <function name="VertexAttrib4bv" offset="assign">
+    <function name="VertexAttrib4bv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLbyte *" count="4"/>
         <glx rop="4230"/>
     </function>
-    <function name="VertexAttrib4d" offset="assign">
+    <function name="VertexAttrib4d">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <param name="w" type="GLdouble"/>
     </function>
-    <function name="VertexAttrib4dv" offset="assign">
+    <function name="VertexAttrib4dv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="4200" doubles_in_order="true"/>
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *"/>
     </function>
-    <function name="VertexAttrib4iv" offset="assign">
+    <function name="VertexAttrib4iv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLint *" count="4"/>
         <glx rop="4231"/>
     </function>
-    <function name="VertexAttrib4s" offset="assign">
+    <function name="VertexAttrib4s">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
         <param name="w" type="GLshort"/>
     </function>
-    <function name="VertexAttrib4sv" offset="assign">
+    <function name="VertexAttrib4sv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="4192"/>
     </function>
-    <function name="VertexAttrib4ubv" offset="assign">
+    <function name="VertexAttrib4ubv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLubyte *" count="4"/>
         <glx rop="4232"/>
     </function>
-    <function name="VertexAttrib4uiv" offset="assign">
+    <function name="VertexAttrib4uiv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLuint *" count="4"/>
         <glx rop="4234"/>
     </function>
-    <function name="VertexAttrib4usv" offset="assign">
+    <function name="VertexAttrib4usv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLushort *" count="4"/>
         <glx rop="4233"/>
     </function>
 
-    <function name="VertexAttribPointer"
-              es2="2.0" offset="assign">
+    <function name="VertexAttribPointer" es2="2.0">
         <param name="index" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
     <enum name="COMPRESSED_SLUMINANCE"          value="0x8C4A"/>
     <enum name="COMPRESSED_SLUMINANCE_ALPHA"    value="0x8C4B"/>
 
-    <function name="UniformMatrix2x3fv" offset="assign" es2="3.0">
+    <function name="UniformMatrix2x3fv" es2="3.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="6"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix3x2fv" offset="assign" es2="3.0">
+    <function name="UniformMatrix3x2fv" es2="3.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="6"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix2x4fv" offset="assign" es2="3.0">
+    <function name="UniformMatrix2x4fv" es2="3.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="6"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix4x2fv" offset="assign" es2="3.0">
+    <function name="UniformMatrix4x2fv" es2="3.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="8"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix3x4fv" offset="assign" es2="3.0">
+    <function name="UniformMatrix3x4fv" es2="3.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="value" type="const GLfloat *" count="count" count_scale="12"/>
         <glx ignore="true"/>
     </function>
-    <function name="UniformMatrix4x3fv" offset="assign" es2="3.0">
+    <function name="UniformMatrix4x3fv" es2="3.0">
         <param name="location" type="GLint"/>
         <param name="count" type="GLsizei" counter="true"/>
         <param name="transpose" type="GLboolean"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="MultiTexCoord1fARB" offset="378"
+    <function name="MultiTexCoord1fARB"
               vectorequiv="MultiTexCoord1fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfloat"/>
     </function>
 
-    <function name="MultiTexCoord1fvARB" offset="379" exec="dynamic">
+    <function name="MultiTexCoord1fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLfloat *" count="1"/>
         <glx rop="199"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="MultiTexCoord2fARB" offset="386"
+    <function name="MultiTexCoord2fARB"
               vectorequiv="MultiTexCoord2fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfloat"/>
         <param name="t" type="GLfloat"/>
     </function>
 
-    <function name="MultiTexCoord2fvARB" offset="387" exec="dynamic">
+    <function name="MultiTexCoord2fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLfloat *" count="2"/>
         <glx rop="203"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="MultiTexCoord3fARB" offset="394"
+    <function name="MultiTexCoord3fARB"
               vectorequiv="MultiTexCoord3fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfloat"/>
         <param name="r" type="GLfloat"/>
     </function>
 
-    <function name="MultiTexCoord3fvARB" offset="395" exec="dynamic">
+    <function name="MultiTexCoord3fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="207"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="MultiTexCoord4fARB" offset="402"
+    <function name="MultiTexCoord4fARB"
               vectorequiv="MultiTexCoord4fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfloat"/>
         <param name="q" type="GLfloat"/>
     </function>
 
-    <function name="MultiTexCoord4fvARB" offset="403" exec="dynamic">
+    <function name="MultiTexCoord4fvARB" exec="dynamic">
         <param name="target" type="GLenum"/>
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="211"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
-        <glx handcode="true"/>
+        <glx ignore="true" handcode="true"/>
     </function>
 
     <function name="VertexBlendARB" exec="skip">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
-        <glx handcode="true"/>
+        <glx ignore="true" handcode="true"/>
     </function>
 </category>
 
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttrib1fARB" offset="assign"
-              vectorequiv="VertexAttrib1fvARB" exec="dynamic">
+    <function name="VertexAttrib1fARB"
+             vectorequiv="VertexAttrib1fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib1fvARB" offset="assign" exec="dynamic">
+    <function name="VertexAttrib1fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="1"/>
         <glx rop="4193"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttrib2fARB" offset="assign"
+    <function name="VertexAttrib2fARB"
               vectorequiv="VertexAttrib2fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib2fvARB" offset="assign" exec="dynamic">
+    <function name="VertexAttrib2fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="2"/>
         <glx rop="4194"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttrib3fARB" offset="assign"
+    <function name="VertexAttrib3fARB"
               vectorequiv="VertexAttrib3fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib3fvARB" offset="assign" exec="dynamic">
+    <function name="VertexAttrib3fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="4195"/>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="VertexAttrib4fARB" offset="assign"
+    <function name="VertexAttrib4fARB"
               vectorequiv="VertexAttrib4fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib4fvARB" offset="assign" exec="dynamic">
+    <function name="VertexAttrib4fvARB" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="4196"/>
         <param name="index" type="GLuint"/>
     </function>
 
-    <function name="ProgramStringARB" offset="assign" deprecated="3.1">
+    <function name="ProgramStringARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="len" type="GLsizei" counter="true"/>
         <glx rop="4217" large="true"/>
     </function>
 
-    <function name="BindProgramARB" offset="assign">
+    <function name="BindProgramARB">
         <param name="target" type="GLenum"/>
         <param name="program" type="GLuint"/>
         <glx rop="4180"/>
     </function>
 
-    <function name="DeleteProgramsARB" offset="assign">
+    <function name="DeleteProgramsARB">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="programs" type="const GLuint *" count="n"/>
         <glx vendorpriv="1294"/>
     </function>
 
-    <function name="GenProgramsARB" offset="assign">
+    <function name="GenProgramsARB">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="programs" type="GLuint *" output="true" count="n"/>
         <glx vendorpriv="1295" always_array="true"/>
     </function>
 
-    <function name="IsProgramARB" offset="assign">
+    <function name="IsProgramARB">
         <param name="program" type="GLuint"/>
         <return type="GLboolean"/>
         <glx vendorpriv="1304"/>
     </function>
 
-    <function name="ProgramEnvParameter4dARB" offset="assign"
+    <function name="ProgramEnvParameter4dARB"
               vectorequiv="ProgramEnvParameter4dvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="ProgramEnvParameter4dvARB" offset="assign"
+    <function name="ProgramEnvParameter4dvARB"
               deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <glx rop="4185" doubles_in_order="true"/>
     </function>
 
-    <function name="ProgramEnvParameter4fARB" offset="assign"
+    <function name="ProgramEnvParameter4fARB"
               vectorequiv="ProgramEnvParameter4fvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="ProgramEnvParameter4fvARB" offset="assign"
+    <function name="ProgramEnvParameter4fvARB"
               deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <glx rop="4184"/>
     </function>
 
-    <function name="ProgramLocalParameter4dARB" offset="assign"
+    <function name="ProgramLocalParameter4dARB"
               vectorequiv="ProgramLocalParameter4dvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="ProgramLocalParameter4dvARB" offset="assign"
+    <function name="ProgramLocalParameter4dvARB"
               deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <glx rop="4216" doubles_in_order="true"/>
     </function>
 
-    <function name="ProgramLocalParameter4fARB" offset="assign"
+    <function name="ProgramLocalParameter4fARB"
               vectorequiv="ProgramLocalParameter4fvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="ProgramLocalParameter4fvARB" offset="assign"
-              deprecated="3.1">
+    <function name="ProgramLocalParameter4fvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="params" type="const GLfloat *" count="4"/>
          the ARB_vertex_program protocol to unused padding.
       -->
 
-    <function name="GetProgramEnvParameterdvARB" offset="assign"
-              deprecated="3.1">
+    <function name="GetProgramEnvParameterdvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="params" type="GLdouble *" output="true" count="4"/>
         <glx vendorpriv="1297" handcode="client" doubles_in_order="true"/>
     </function>
 
-    <function name="GetProgramEnvParameterfvARB" offset="assign"
-              deprecated="3.1">
+    <function name="GetProgramEnvParameterfvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="params" type="GLfloat *" output="true" count="4"/>
         <glx vendorpriv="1296" handcode="client"/>
     </function>
 
-    <function name="GetProgramLocalParameterdvARB" offset="assign"
-              deprecated="3.1">
+    <function name="GetProgramLocalParameterdvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="params" type="GLdouble *" output="true" count="4"/>
         <glx vendorpriv="1306" handcode="client" doubles_in_order="true"/>
     </function>
 
-    <function name="GetProgramLocalParameterfvARB" offset="assign"
-              deprecated="3.1">
+    <function name="GetProgramLocalParameterfvARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="params" type="GLfloat *" output="true" count="4"/>
     </function>
 
 
-    <function name="GetProgramivARB" offset="assign" deprecated="3.1">
+    <function name="GetProgramivARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx vendorpriv="1307"/>
     </function>
 
-    <function name="GetProgramStringARB" offset="assign" deprecated="3.1">
+    <function name="GetProgramStringARB" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="string" type="GLvoid *" output="true"/>
     <type name="charARB"   size="1" glx_name="CARD8"/>
     <type name="handleARB" size="4" glx_name="CARD32"/>
 
-    <function name="DeleteObjectARB" offset="assign">
+    <function name="DeleteObjectARB">
         <param name="obj" type="GLhandleARB"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetHandleARB" offset="assign">
+    <function name="GetHandleARB">
         <param name="pname" type="GLenum"/>
         <return type="GLhandleARB"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DetachObjectARB" offset="assign">
+    <function name="DetachObjectARB">
         <param name="containerObj" type="GLhandleARB"/>
         <param name="attachedObj" type="GLhandleARB"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="CreateShaderObjectARB" offset="assign">
+    <function name="CreateShaderObjectARB">
         <param name="shaderType" type="GLenum"/>
         <return type="GLhandleARB"/>
         <glx ignore="true"/>
         <param name="shader" type="GLhandleARB"/>
     </function>
 
-    <function name="CreateProgramObjectARB" offset="assign">
+    <function name="CreateProgramObjectARB">
         <return type="GLhandleARB"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="AttachObjectARB" offset="assign">
+    <function name="AttachObjectARB">
         <param name="containerObj" type="GLhandleARB"/>
         <param name="obj" type="GLhandleARB"/>
         <glx ignore="true"/>
         <param name="value" type="const GLfloat *"/>
     </function>
 
-    <function name="GetObjectParameterfvARB" offset="assign">
+    <function name="GetObjectParameterfvARB">
         <param name="obj" type="GLhandleARB"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetObjectParameterivARB" offset="assign">
+    <function name="GetObjectParameterivARB">
         <param name="obj" type="GLhandleARB"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetInfoLogARB" offset="assign">
+    <function name="GetInfoLogARB">
         <param name="obj" type="GLhandleARB"/>
         <param name="maxLength" type="GLsizei"/>
         <param name="length" type="GLsizei *" output="true"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="GetAttachedObjectsARB" offset="assign">
+    <function name="GetAttachedObjectsARB">
         <param name="containerObj" type="GLhandleARB"/>
         <param name="maxLength" type="GLsizei"/>
         <param name="length" type="GLsizei *" output="true"/>
     <enum name="TIMESTAMP" value="0x8E28"/>
     <type name="int64"                  size="8"/>
     <type name="uint64" unsigned="true" size="8"/>
-    <function name="GetQueryObjecti64v" static_dispatch="false" offset="assign">
+    <function name="GetQueryObjecti64v">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint64 *"/>
     </function>
-    <function name="GetQueryObjectui64v" static_dispatch="false" offset="assign">
+    <function name="GetQueryObjectui64v">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLuint64 *"/>
     </function>
-    <function name="QueryCounter" offset="assign" static_dispatch="false">
+    <function name="QueryCounter">
         <param name="id" type="GLuint"/>
         <param name="target" type="GLenum"/>
     </function>
   <enum name="MAX_TRANSFORM_FEEDBACK_BUFFERS" value="0x8E70"/>
   <enum name="MAX_VERTEX_STREAMS"             value="0x8E71"/>
 
-  <function name="DrawTransformFeedbackStream" offset="assign"
-            exec="dynamic">
+  <function name="DrawTransformFeedbackStream" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="id" type="GLuint"/>
     <param name="stream" type="GLuint"/>
   </function>
 
-  <function name="BeginQueryIndexed" offset="assign">
+  <function name="BeginQueryIndexed">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="id" type="GLuint"/>
   </function>
 
-  <function name="EndQueryIndexed" offset="assign">
+  <function name="EndQueryIndexed">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
   </function>
 
-  <function name="GetQueryIndexediv" offset="assign">
+  <function name="GetQueryIndexediv">
     <param name="target" type="GLenum"/>
     <param name="index" type="GLuint"/>
     <param name="pname" type="GLenum"/>
 <xi:include href="ARB_base_instance.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
 <category name="GL_ARB_transform_feedback_instanced" number="109">
-  <function name="DrawTransformFeedbackInstanced" offset="assign"
-            exec="dynamic">
+  <function name="DrawTransformFeedbackInstanced" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="id" type="GLuint"/>
     <param name="primcount" type="GLsizei"/>
   </function>
 
-  <function name="DrawTransformFeedbackStreamInstanced" offset="assign"
-            exec="dynamic">
+  <function name="DrawTransformFeedbackStreamInstanced" exec="dynamic">
     <param name="mode" type="GLenum"/>
     <param name="id" type="GLuint"/>
     <param name="stream" type="GLuint"/>
     <!-- No new functions, types, enums. -->
 </category>
 
-<!-- ARB extensions #130..#131 -->
+<xi:include href="ARB_framebuffer_no_attachments.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<!-- ARB extensions #131 -->
 
 <category name="GL_ARB_explicit_uniform_location" number="128">
     <enum name="MAX_UNIFORM_LOCATIONS" count="1" value="0x826E" >
     <enum name="BUFFER_STORAGE_FLAGS" value="0x8220" />
     <enum name="CLIENT_MAPPED_BUFFER_BARRIER_BIT" value="0x4000" />
 
-    <function name="BufferStorage" offset="assign">
+    <function name="BufferStorage">
         <param name="target" type="GLenum"/>
         <param name="size" type="GLsizeiptr"/>
         <param name="data" type="const GLvoid *"/>
 <category name="GL_EXT_polygon_offset" number="3">
     <enum name="POLYGON_OFFSET_BIAS_EXT"                  value="0x8039"/>
 
-    <function name="PolygonOffsetEXT" offset="assign" deprecated="3.1">
+    <function name="PolygonOffsetEXT" deprecated="3.1">
         <param name="factor" type="GLfloat"/>
         <param name="bias" type="GLfloat"/>
         <glx rop="4098" ignore="true"/>
     </enum>
     <enum name="TABLE_TOO_LARGE_EXT"                      value="0x8031"/>
 
-    <function name="GetHistogramEXT" alias="GetHistogram" static_dispatch="false">
+    <function name="GetHistogramEXT" alias="GetHistogram">
         <param name="target" type="GLenum"/>
         <param name="reset" type="GLboolean"/>
         <param name="format" type="GLenum"/>
         <glx vendorpriv="5" dimensions_in_reply="true" img_reset="reset"/>
     </function>
 
-    <function name="GetHistogramParameterfvEXT" alias="GetHistogramParameterfv" static_dispatch="false">
+    <function name="GetHistogramParameterfvEXT" alias="GetHistogramParameterfv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx vendorpriv="6"/>
     </function>
 
-    <function name="GetHistogramParameterivEXT" alias="GetHistogramParameteriv" static_dispatch="false">
+    <function name="GetHistogramParameterivEXT" alias="GetHistogramParameteriv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx vendorpriv="7"/>
     </function>
 
-    <function name="GetMinmaxEXT" alias="GetMinmax" static_dispatch="false">
+    <function name="GetMinmaxEXT" alias="GetMinmax">
         <param name="target" type="GLenum"/>
         <param name="reset" type="GLboolean"/>
         <param name="format" type="GLenum"/>
         <glx vendorpriv="8" img_reset="reset"/>
     </function>
 
-    <function name="GetMinmaxParameterfvEXT" alias="GetMinmaxParameterfv" static_dispatch="false">
+    <function name="GetMinmaxParameterfvEXT" alias="GetMinmaxParameterfv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx vendorpriv="9"/>
     </function>
 
-    <function name="GetMinmaxParameterivEXT" alias="GetMinmaxParameteriv" static_dispatch="false">
+    <function name="GetMinmaxParameterivEXT" alias="GetMinmaxParameteriv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx vendorpriv="10"/>
     </function>
 
-    <function name="HistogramEXT" alias="Histogram" static_dispatch="false">
+    <function name="HistogramEXT" alias="Histogram">
         <param name="target" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <param name="internalformat" type="GLenum"/>
         <param name="sink" type="GLboolean"/>
     </function>
 
-    <function name="MinmaxEXT" alias="Minmax" static_dispatch="false">
+    <function name="MinmaxEXT" alias="Minmax">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="sink" type="GLboolean"/>
     </function>
 
-    <function name="ResetHistogramEXT" alias="ResetHistogram" static_dispatch="false">
+    <function name="ResetHistogramEXT" alias="ResetHistogram">
         <param name="target" type="GLenum"/>
     </function>
 
-    <function name="ResetMinmaxEXT" alias="ResetMinmax" static_dispatch="false">
+    <function name="ResetMinmaxEXT" alias="ResetMinmax">
         <param name="target" type="GLenum"/>
     </function>
 </category>
         <size name="Get" mode="get"/>
     </enum>
 
-    <function name="ConvolutionFilter1DEXT" alias="ConvolutionFilter1D" static_dispatch="false">
+    <function name="ConvolutionFilter1DEXT" alias="ConvolutionFilter1D">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <param name="image" type="const GLvoid *"/>
     </function>
 
-    <function name="ConvolutionFilter2DEXT" alias="ConvolutionFilter2D" static_dispatch="false">
+    <function name="ConvolutionFilter2DEXT" alias="ConvolutionFilter2D">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <param name="image" type="const GLvoid *"/>
     </function>
 
-    <function name="ConvolutionParameterfEXT" alias="ConvolutionParameterf" static_dispatch="false">
+    <function name="ConvolutionParameterfEXT" alias="ConvolutionParameterf">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat"/>
     </function>
 
-    <function name="ConvolutionParameterfvEXT" alias="ConvolutionParameterfv" static_dispatch="false">
+    <function name="ConvolutionParameterfvEXT" alias="ConvolutionParameterfv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *"/>
     </function>
 
-    <function name="ConvolutionParameteriEXT" alias="ConvolutionParameteri" static_dispatch="false">
+    <function name="ConvolutionParameteriEXT" alias="ConvolutionParameteri">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint"/>
     </function>
 
-    <function name="ConvolutionParameterivEXT" alias="ConvolutionParameteriv" static_dispatch="false">
+    <function name="ConvolutionParameterivEXT" alias="ConvolutionParameteriv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *"/>
     </function>
 
-    <function name="CopyConvolutionFilter1DEXT" alias="CopyConvolutionFilter1D" static_dispatch="false">
+    <function name="CopyConvolutionFilter1DEXT" alias="CopyConvolutionFilter1D">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="x" type="GLint"/>
         <param name="width" type="GLsizei"/>
     </function>
 
-    <function name="CopyConvolutionFilter2DEXT" alias="CopyConvolutionFilter2D" static_dispatch="false">
+    <function name="CopyConvolutionFilter2DEXT" alias="CopyConvolutionFilter2D">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="x" type="GLint"/>
         <param name="height" type="GLsizei"/>
     </function>
 
-    <function name="GetConvolutionFilterEXT" alias="GetConvolutionFilter" static_dispatch="false">
+    <function name="GetConvolutionFilterEXT" alias="GetConvolutionFilter">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <glx vendorpriv="1" dimensions_in_reply="true"/>
     </function>
 
-    <function name="GetConvolutionParameterfvEXT" alias="GetConvolutionParameterfv" static_dispatch="false">
+    <function name="GetConvolutionParameterfvEXT" alias="GetConvolutionParameterfv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx vendorpriv="2"/>
     </function>
 
-    <function name="GetConvolutionParameterivEXT" alias="GetConvolutionParameteriv" static_dispatch="false">
+    <function name="GetConvolutionParameterivEXT" alias="GetConvolutionParameteriv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx vendorpriv="3"/>
     </function>
 
-    <function name="GetSeparableFilterEXT" alias="GetSeparableFilter" static_dispatch="false">
+    <function name="GetSeparableFilterEXT" alias="GetSeparableFilter">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <glx vendorpriv="4" handcode="true"/>
     </function>
 
-    <function name="SeparableFilter2DEXT" alias="SeparableFilter2D" static_dispatch="false">
+    <function name="SeparableFilter2DEXT" alias="SeparableFilter2D">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <size name="GetColorTableParameterivSGI" mode="get"/>
     </enum>
 
-    <function name="ColorTableSGI" alias="ColorTable" static_dispatch="false">
+    <function name="ColorTableSGI" alias="ColorTable">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <param name="table" type="const GLvoid *"/>
     </function>
 
-    <function name="ColorTableParameterfvSGI" alias="ColorTableParameterfv" static_dispatch="false">
+    <function name="ColorTableParameterfvSGI" alias="ColorTableParameterfv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *"/>
     </function>
 
-    <function name="ColorTableParameterivSGI" alias="ColorTableParameteriv" static_dispatch="false">
+    <function name="ColorTableParameterivSGI" alias="ColorTableParameteriv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLint *"/>
     </function>
 
-    <function name="CopyColorTableSGI" alias="CopyColorTable" static_dispatch="false">
+    <function name="CopyColorTableSGI" alias="CopyColorTable">
         <param name="target" type="GLenum"/>
         <param name="internalformat" type="GLenum"/>
         <param name="x" type="GLint"/>
         <param name="width" type="GLsizei"/>
     </function>
 
-    <function name="GetColorTableSGI" alias="GetColorTable" static_dispatch="false">
+    <function name="GetColorTableSGI" alias="GetColorTable">
         <param name="target" type="GLenum"/>
         <param name="format" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <glx vendorpriv="4098" dimensions_in_reply="true"/>
     </function>
 
-    <function name="GetColorTableParameterfvSGI" alias="GetColorTableParameterfv" static_dispatch="false">
+    <function name="GetColorTableParameterfvSGI" alias="GetColorTableParameterfv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx vendorpriv="4099"/>
     </function>
 
-    <function name="GetColorTableParameterivSGI" alias="GetColorTableParameteriv" static_dispatch="false">
+    <function name="GetColorTableParameterivSGI" alias="GetColorTableParameteriv">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
 </category>
 
 <category name="GL_SGIS_multisample" number="25">
-    <function name="SampleMaskSGIS" offset="assign" static_dispatch="false"
-              exec="skip">
+    <function name="SampleMaskSGIS" exec="skip">
         <param name="value" type="GLclampf"/>
         <param name="invert" type="GLboolean"/>
         <glx rop="2048"/>
     </function>
 
-    <function name="SamplePatternSGIS" offset="assign" static_dispatch="false"
-              exec="skip">
+    <function name="SamplePatternSGIS" exec="skip">
         <param name="pattern" type="GLenum"/>
         <glx rop="2049"/>
     </function>
         <param name="i" type="GLint"/>
     </function>
 
-    <function name="ColorPointerEXT" offset="assign" deprecated="3.1">
+    <function name="ColorPointerEXT" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
     </function>
 
-    <function name="EdgeFlagPointerEXT" offset="assign" deprecated="3.1">
+    <function name="EdgeFlagPointerEXT" deprecated="3.1">
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLboolean *"/>
         <param name="params" type="GLvoid **" output="true"/>
     </function>
 
-    <function name="IndexPointerEXT" offset="assign" deprecated="3.1">
+    <function name="IndexPointerEXT" deprecated="3.1">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="NormalPointerEXT" offset="assign" deprecated="3.1">
+    <function name="NormalPointerEXT" deprecated="3.1">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="TexCoordPointerEXT" offset="assign" deprecated="3.1">
+    <function name="TexCoordPointerEXT" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="VertexPointerEXT" offset="assign" deprecated="3.1">
+    <function name="VertexPointerEXT" deprecated="3.1">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
 <!-- Extension number 73 is not listed in the extension registry. -->
 
 <category name="GL_EXT_color_subtable" number="74">
-    <function name="ColorSubTableEXT" alias="ColorSubTable" static_dispatch="false">
+    <function name="ColorSubTableEXT" alias="ColorSubTable">
         <param name="target" type="GLenum"/>
         <param name="start" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="data" type="const GLvoid *"/>
     </function>
 
-    <function name="CopyColorSubTableEXT" alias="CopyColorSubTable" static_dispatch="false">
+    <function name="CopyColorSubTableEXT" alias="CopyColorSubTable">
         <param name="target" type="GLenum"/>
         <param name="start" type="GLsizei"/>
         <param name="x" type="GLint"/>
     <enum name="ARRAY_ELEMENT_LOCK_FIRST_EXT"             value="0x81A8"/>
     <enum name="ARRAY_ELEMENT_LOCK_COUNT_EXT"             value="0x81A9"/>
 
-    <function name="LockArraysEXT" offset="assign" deprecated="3.1">
+    <function name="LockArraysEXT" deprecated="3.1">
         <param name="first" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <glx handcode="true" ignore="true"/>
     </function>
 
-    <function name="UnlockArraysEXT" offset="assign" deprecated="3.1">
+    <function name="UnlockArraysEXT" deprecated="3.1">
         <glx handcode="true" ignore="true"/>
     </function>
 </category>
         <param name="v" type="const GLdouble *"/>
     </function>
 
-    <function name="SecondaryColor3fEXT" offset="assign" vectorequiv="SecondaryColor3fvEXT">
+    <function name="SecondaryColor3fEXT" vectorequiv="SecondaryColor3fvEXT">
         <param name="red" type="GLfloat"/>
         <param name="green" type="GLfloat"/>
         <param name="blue" type="GLfloat"/>
     </function>
 
-    <function name="SecondaryColor3fvEXT" offset="assign">
+    <function name="SecondaryColor3fvEXT">
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="4129"/>
     </function>
         <param name="primcount" type="GLsizei"/>
     </function>
 
-    <function name="MultiDrawElementsEXT" offset="assign" es1="1.0" es2="2.0"
-              exec="dynamic">
+    <function name="MultiDrawElementsEXT" es1="1.0" es2="2.0" exec="dynamic">
         <param name="mode" type="GLenum"/>
         <param name="count" type="const GLsizei *"/>
         <param name="type" type="GLenum"/>
 </category>
 
 <category name="GL_EXT_fog_coord" number="149">
-    <function name="FogCoordfEXT" offset="assign" vectorequiv="FogCoordfvEXT"
-              exec="dynamic">
+    <function name="FogCoordfEXT" vectorequiv="FogCoordfvEXT" exec="dynamic">
         <param name="coord" type="GLfloat"/>
     </function>
 
-    <function name="FogCoordfvEXT" offset="assign" exec="dynamic">
+    <function name="FogCoordfvEXT" exec="dynamic">
         <param name="coord" type="const GLfloat *" count="1"/>
         <glx rop="4124"/>
     </function>
 </category>
 
 <category name="GL_MESA_resize_buffers" number="196">
-    <function name="ResizeBuffersMESA" offset="assign" exec="skip">
+    <function name="ResizeBuffersMESA" exec="skip">
         <glx ignore="true"/>
     </function>
 </category>
         <param name="v" type="const GLshort *"/>
     </function>
 
-    <function name="WindowPos4dMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4dMESA" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4dvMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4dvMESA" deprecated="3.1">
         <param name="v" type="const GLdouble *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4fMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4fMESA" deprecated="3.1">
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4fvMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4fvMESA" deprecated="3.1">
         <param name="v" type="const GLfloat *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4iMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4iMESA" deprecated="3.1">
         <param name="x" type="GLint"/>
         <param name="y" type="GLint"/>
         <param name="z" type="GLint"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4ivMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4ivMESA" deprecated="3.1">
         <param name="v" type="const GLint *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4sMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4sMESA" deprecated="3.1">
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
         <param name="z" type="GLshort"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="WindowPos4svMESA" offset="assign" deprecated="3.1">
+    <function name="WindowPos4svMESA" deprecated="3.1">
         <param name="v" type="const GLshort *"/>
         <glx ignore="true"/>
     </function>
 </category>
 
 <category name="GL_IBM_multimode_draw_arrays" number="200">
-    <function name="MultiModeDrawArraysIBM" offset="assign" static_dispatch="false">
+    <function name="MultiModeDrawArraysIBM">
         <param name="mode" type="const GLenum *"/>
         <param name="first" type="const GLint *"/>
         <param name="count" type="const GLsizei *"/>
         <glx handcode="true" ignore="true"/>
     </function>
 
-    <function name="MultiModeDrawElementsIBM" offset="assign" static_dispatch="false">
+    <function name="MultiModeDrawElementsIBM">
         <param name="mode" type="const GLenum *"/>
         <param name="count" type="const GLsizei *"/>
         <param name="type" type="GLenum"/>
 </category>
 
 <category name="GL_EXT_multisample" number="209">
-    <function name="SampleMaskEXT" alias="SampleMaskSGIS" static_dispatch="false">
+    <function name="SampleMaskEXT" alias="SampleMaskSGIS">
         <param name="value" type="GLclampf"/>
         <param name="invert" type="GLboolean"/>
     </function>
 
-    <function name="SamplePatternEXT" alias="SamplePatternSGIS" static_dispatch="false">
+    <function name="SamplePatternEXT" alias="SamplePatternSGIS">
         <param name="pattern" type="GLenum"/>
     </function>
 </category>
     <enum name="MAP2_VERTEX_ATTRIB14_4_NV"                value="0x867E"/>
     <enum name="MAP2_VERTEX_ATTRIB15_4_NV"                value="0x867F"/>
 
-    <function name="AreProgramsResidentNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="AreProgramsResidentNV" deprecated="3.1" exec="skip">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="ids" type="const GLuint *" count="n"/>
         <param name="residences" type="GLboolean *" output="true" count="n"/>
         <param name="programs" type="const GLuint *"/>
     </function>
 
-    <function name="ExecuteProgramNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="ExecuteProgramNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="id" type="GLuint"/>
         <param name="params" type="const GLfloat *" count="4"/>
          of these functions.
       -->
 
-    <function name="GetProgramParameterdvNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetProgramParameterdvNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <glx vendorpriv="1297"/>
     </function>
 
-    <function name="GetProgramParameterfvNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetProgramParameterfvNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <glx vendorpriv="1296"/>
     </function>
 
-    <function name="GetProgramivNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetProgramivNV" deprecated="3.1" exec="skip">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <glx vendorpriv="1298"/>
     </function>
 
-    <function name="GetProgramStringNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetProgramStringNV" deprecated="3.1" exec="skip">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="program" type="GLubyte *" output="true"/>
         <glx vendorpriv="1299" handcode="server" always_array="true"/>
     </function>
 
-    <function name="GetTrackMatrixivNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetTrackMatrixivNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="address" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <glx vendorpriv="1300"/>
     </function>
 
-    <function name="GetVertexAttribdvNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetVertexAttribdvNV" deprecated="3.1" exec="skip">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLdouble *" output="true" variable_param="pname"/>
         <glx vendorpriv="1301"/>
     </function>
 
-    <function name="GetVertexAttribfvNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetVertexAttribfvNV" deprecated="3.1" exec="skip">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfloat *" output="true" variable_param="pname"/>
         <glx vendorpriv="1302"/>
     </function>
 
-    <function name="GetVertexAttribivNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="GetVertexAttribivNV" deprecated="3.1" exec="skip">
         <param name="index" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint *" output="true" variable_param="pname"/>
         <return type="GLboolean"/>
     </function>
 
-    <function name="LoadProgramNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="LoadProgramNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="id" type="GLuint"/>
         <param name="len" type="GLsizei" counter="true"/>
         <param name="params" type="const GLfloat *"/>
     </function>
 
-    <function name="ProgramParameters4dvNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="ProgramParameters4dvNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="num" type="GLsizei" counter="true"/>
         <glx rop="4187"/>
     </function>
 
-    <function name="ProgramParameters4fvNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="ProgramParameters4fvNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="num" type="GLsizei" counter="true"/>
         <glx rop="4186"/>
     </function>
 
-    <function name="RequestResidentProgramsNV" offset="assign"
-              deprecated="3.1" exec="skip">
+    <function name="RequestResidentProgramsNV" deprecated="3.1" exec="skip">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="ids" type="const GLuint *" count="n"/>
         <glx rop="4182"/>
     </function>
 
-    <function name="TrackMatrixNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="TrackMatrixNV" deprecated="3.1" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="address" type="GLuint"/>
         <param name="matrix" type="GLenum"/>
         <glx rop="4188"/>
     </function>
 
-    <function name="VertexAttribPointerNV" offset="assign" deprecated="3.1"
-              exec="skip">
+    <function name="VertexAttribPointerNV" deprecated="3.1" exec="skip">
         <param name="index" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="VertexAttrib1sNV" offset="assign"
+    <function name="VertexAttrib1sNV"
               vectorequiv="VertexAttrib1svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
     </function>
 
-    <function name="VertexAttrib1svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib1svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="1"/>
         <glx rop="4265"/>
     </function>
 
-    <function name="VertexAttrib2sNV" offset="assign"
+    <function name="VertexAttrib2sNV"
               vectorequiv="VertexAttrib2svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
         <param name="y" type="GLshort"/>
     </function>
 
-    <function name="VertexAttrib2svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib2svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="2"/>
         <glx rop="4266"/>
     </function>
 
-    <function name="VertexAttrib3sNV" offset="assign"
+    <function name="VertexAttrib3sNV"
               vectorequiv="VertexAttrib3svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
         <param name="z" type="GLshort"/>
     </function>
 
-    <function name="VertexAttrib3svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib3svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="3"/>
         <glx rop="4267"/>
     </function>
 
-    <function name="VertexAttrib4sNV" offset="assign"
+    <function name="VertexAttrib4sNV"
               vectorequiv="VertexAttrib4svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLshort"/>
         <param name="w" type="GLshort"/>
     </function>
 
-    <function name="VertexAttrib4svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib4svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLshort *" count="4"/>
         <glx rop="4268"/>
     </function>
 
-    <function name="VertexAttrib1fNV" offset="assign"
-              vectorequiv="VertexAttrib1fvNV" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib1fNV"
+              vectorequiv="VertexAttrib1fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib1fvNV" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib1fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="1"/>
         <glx rop="4269"/>
     </function>
 
-    <function name="VertexAttrib2fNV" offset="assign"
-              vectorequiv="VertexAttrib2fvNV" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib2fNV"
+              vectorequiv="VertexAttrib2fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib2fvNV" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib2fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="2"/>
         <glx rop="4270"/>
     </function>
 
-    <function name="VertexAttrib3fNV" offset="assign"
-              vectorequiv="VertexAttrib3fvNV" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib3fNV"
+              vectorequiv="VertexAttrib3fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="z" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib3fvNV" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib3fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="3"/>
         <glx rop="4271"/>
     </function>
 
-    <function name="VertexAttrib4fNV" offset="assign"
-              vectorequiv="VertexAttrib4fvNV" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib4fNV"
+              vectorequiv="VertexAttrib4fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLfloat"/>
         <param name="y" type="GLfloat"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="VertexAttrib4fvNV" offset="assign" deprecated="3.1"
-              exec="dynamic">
+    <function name="VertexAttrib4fvNV" deprecated="3.1" exec="dynamic">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLfloat *" count="4"/>
         <glx rop="4272"/>
     </function>
 
-    <function name="VertexAttrib1dNV" offset="assign"
+    <function name="VertexAttrib1dNV"
               vectorequiv="VertexAttrib1dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttrib1dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib1dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="1"/>
         <glx rop="4273" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttrib2dNV" offset="assign"
+    <function name="VertexAttrib2dNV"
               vectorequiv="VertexAttrib2dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttrib2dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib2dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="2"/>
         <glx rop="4274" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttrib3dNV" offset="assign"
+    <function name="VertexAttrib3dNV"
               vectorequiv="VertexAttrib3dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="z" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttrib3dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib3dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="3"/>
         <glx rop="4275" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttrib4dNV" offset="assign"
+    <function name="VertexAttrib4dNV"
               vectorequiv="VertexAttrib4dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLdouble"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="VertexAttrib4dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib4dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLdouble *" count="4"/>
         <glx rop="4276" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttrib4ubNV" offset="assign"
+    <function name="VertexAttrib4ubNV"
               vectorequiv="VertexAttrib4ubvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="x" type="GLubyte"/>
         <param name="w" type="GLubyte"/>
     </function>
 
-    <function name="VertexAttrib4ubvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttrib4ubvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLubyte *" count="4"/>
         <glx rop="4277"/>
     </function>
 
-    <function name="VertexAttribs1svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs1svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLshort *" count="n"/>
         <glx rop="4202"/>
     </function>
 
-    <function name="VertexAttribs2svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs2svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLshort *" count="n" count_scale="2"/>
         <glx rop="4203"/>
     </function>
 
-    <function name="VertexAttribs3svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs3svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLshort *" count="n" count_scale="3"/>
         <glx rop="4204"/>
     </function>
 
-    <function name="VertexAttribs4svNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs4svNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLshort *" count="n" count_scale="4"/>
         <glx rop="4205"/>
     </function>
 
-    <function name="VertexAttribs1fvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs1fvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLfloat *" count="n"/>
         <glx rop="4206"/>
     </function>
 
-    <function name="VertexAttribs2fvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs2fvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLfloat *" count="n" count_scale="2"/>
         <glx rop="4207"/>
     </function>
 
-    <function name="VertexAttribs3fvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs3fvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLfloat *" count="n" count_scale="3"/>
         <glx rop="4208"/>
     </function>
 
-    <function name="VertexAttribs4fvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs4fvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLfloat *" count="n" count_scale="4"/>
         <glx rop="4209"/>
     </function>
 
-    <function name="VertexAttribs1dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs1dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLdouble *" count="n"/>
         <glx rop="4210" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttribs2dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs2dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLdouble *" count="n" count_scale="2"/>
         <glx rop="4211" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttribs3dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs3dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLdouble *" count="n" count_scale="3"/>
         <glx rop="4212" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttribs4dvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs4dvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLdouble *" count="n" count_scale="4"/>
         <glx rop="4213" doubles_in_order="true"/>
     </function>
 
-    <function name="VertexAttribs4ubvNV" offset="assign" deprecated="3.1">
+    <function name="VertexAttribs4ubvNV" deprecated="3.1">
         <param name="index" type="GLuint"/>
         <param name="n" type="GLsizei" counter="true"/>
         <param name="v" type="const GLubyte *" count="n" count_scale="4"/>
         <size name="GetTexEnviv" mode="get"/>
         <size name="GetTexEnvfv" mode="get"/>
     </enum>
-    <function name="TexBumpParameterfvATI" offset="assign" deprecated="3.1" exec="skip">
+    <function name="TexBumpParameterfvATI" deprecated="3.1" exec="skip">
       <param name="pname" type="GLenum"/>
       <param name="param" type="const GLfloat *" variable_param="pname"/>
       <glx ignore="true"/>
     </function>
-    <function name="TexBumpParameterivATI" offset="assign" deprecated="3.1" exec="skip">
+    <function name="TexBumpParameterivATI" deprecated="3.1" exec="skip">
       <param name="pname" type="GLenum"/>
       <param name="param" type="const GLint *" variable_param="pname"/>
       <glx ignore="true"/>
     </function>
-    <function name="GetTexBumpParameterfvATI" offset="assign" deprecated="3.1" exec="skip">
+    <function name="GetTexBumpParameterfvATI" deprecated="3.1" exec="skip">
       <param name="pname" type="GLenum"/>
       <param name="param" type="GLfloat *" variable_param="pname"/>
       <glx ignore="true"/>
     </function>
-    <function name="GetTexBumpParameterivATI" offset="assign" deprecated="3.1" exec="skip">
+    <function name="GetTexBumpParameterivATI" deprecated="3.1" exec="skip">
       <param name="pname" type="GLenum"/>
       <param name="param" type="GLint *" variable_param="pname"/>
       <glx ignore="true"/>
     redudndant garbage.  There are a lot of enums with the value 0x00000001.
     -->
 
-    <function name="GenFragmentShadersATI" offset="assign" deprecated="3.1">
+    <function name="GenFragmentShadersATI" deprecated="3.1">
       <return type="GLuint"/>
       <param name="range" type="GLuint"/>
       <glx ignore="true"/>
     </function>
     
-    <function name="BindFragmentShaderATI" offset="assign" deprecated="3.1">
+    <function name="BindFragmentShaderATI" deprecated="3.1">
       <param name="id" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="DeleteFragmentShaderATI" offset="assign" deprecated="3.1">
+    <function name="DeleteFragmentShaderATI" deprecated="3.1">
       <param name="id" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="BeginFragmentShaderATI" offset="assign" deprecated="3.1">
+    <function name="BeginFragmentShaderATI" deprecated="3.1">
       <glx ignore="true"/>
     </function>
 
-    <function name="EndFragmentShaderATI" offset="assign" deprecated="3.1">
+    <function name="EndFragmentShaderATI" deprecated="3.1">
       <glx ignore="true"/>
     </function>
     
-    <function name="PassTexCoordATI" offset="assign" deprecated="3.1">
+    <function name="PassTexCoordATI" deprecated="3.1">
       <param name="dst" type="GLuint"/>
       <param name="coord" type="GLuint"/>
       <param name="swizzle" type="GLenum"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="SampleMapATI" offset="assign" deprecated="3.1">
+    <function name="SampleMapATI" deprecated="3.1">
       <param name="dst" type="GLuint"/>
       <param name="interp" type="GLuint"/>
       <param name="swizzle" type="GLenum"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="ColorFragmentOp1ATI" offset="assign" deprecated="3.1">
+    <function name="ColorFragmentOp1ATI" deprecated="3.1">
       <param name="op" type="GLenum"/>
       <param name="dst" type="GLuint"/>
       <param name="dstMask" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="ColorFragmentOp2ATI" offset="assign" deprecated="3.1">
+    <function name="ColorFragmentOp2ATI" deprecated="3.1">
       <param name="op" type="GLenum"/>
       <param name="dst" type="GLuint"/>
       <param name="dstMask" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="ColorFragmentOp3ATI" offset="assign" deprecated="3.1">
+    <function name="ColorFragmentOp3ATI" deprecated="3.1">
       <param name="op" type="GLenum"/>
       <param name="dst" type="GLuint"/>
       <param name="dstMask" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="AlphaFragmentOp1ATI" offset="assign" deprecated="3.1">
+    <function name="AlphaFragmentOp1ATI" deprecated="3.1">
       <param name="op" type="GLenum"/>
       <param name="dst" type="GLuint"/>
       <param name="dstMod" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="AlphaFragmentOp2ATI" offset="assign" deprecated="3.1">
+    <function name="AlphaFragmentOp2ATI" deprecated="3.1">
       <param name="op" type="GLenum"/>
       <param name="dst" type="GLuint"/>
       <param name="dstMod" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="AlphaFragmentOp3ATI" offset="assign" deprecated="3.1">
+    <function name="AlphaFragmentOp3ATI" deprecated="3.1">
       <param name="op" type="GLenum"/>
       <param name="dst" type="GLuint"/>
       <param name="dstMod" type="GLuint"/>
       <glx ignore="true"/>
     </function>
 
-    <function name="SetFragmentShaderConstantATI" offset="assign"
-              deprecated="3.1">
+    <function name="SetFragmentShaderConstantATI" deprecated="3.1">
       <param name="dst" type="GLuint"/>
       <param name="value" type="const GLfloat *"/>
       <glx ignore="true"/>
         <size name="Get" mode="get"/>
     </enum>
 
-    <function name="ActiveStencilFaceEXT" offset="assign"
-              static_dispatch="false" deprecated="3.1">
+    <function name="ActiveStencilFaceEXT" deprecated="3.1">
         <param name="face" type="GLenum"/>
         <glx rop="4220"/>
     </function>
     <enum name="MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV" value="0x8868"/>
     <enum name="PROGRAM_ERROR_STRING_NV"                  value="0x8874"/>
 
-    <function name="ProgramNamedParameter4fNV" offset="assign"
+    <function name="ProgramNamedParameter4fNV"
               vectorequiv="ProgramNamedParameter4fvNV" deprecated="3.1"
               exec="skip">
         <param name="id" type="GLuint"/>
         <param name="w" type="GLfloat"/>
     </function>
 
-    <function name="ProgramNamedParameter4dNV" offset="assign"
+    <function name="ProgramNamedParameter4dNV"
               vectorequiv="ProgramNamedParameter4dvNV" deprecated="3.1"
               exec="skip">
         <param name="id" type="GLuint"/>
         <param name="w" type="GLdouble"/>
     </function>
 
-    <function name="ProgramNamedParameter4fvNV" offset="assign"
-              deprecated="3.1" exec="skip">
+    <function name="ProgramNamedParameter4fvNV" deprecated="3.1" exec="skip">
         <param name="id" type="GLuint"/>
         <param name="len" type="GLsizei" counter="true"/>
         <param name="name" type="const GLubyte *" count="len"/>
         <glx rop="4218"/>
     </function>
 
-    <function name="ProgramNamedParameter4dvNV" offset="assign"
-              deprecated="3.1" exec="skip">
+    <function name="ProgramNamedParameter4dvNV" deprecated="3.1" exec="skip">
         <param name="id" type="GLuint"/>
         <param name="len" type="GLsizei" counter="true"/>
         <param name="name" type="const GLubyte *" count="len"/>
         <glx rop="4219"/>
     </function>
 
-    <function name="GetProgramNamedParameterfvNV" offset="assign"
-              deprecated="3.1" exec="skip">
+    <function name="GetProgramNamedParameterfvNV" deprecated="3.1" exec="skip">
         <param name="id" type="GLuint"/>
         <param name="len" type="GLsizei" counter="true"/>
         <param name="name" type="const GLubyte *" count="len"/>
         <glx vendorpriv="1310" always_array="true"/>
     </function>
 
-    <function name="GetProgramNamedParameterdvNV" offset="assign"
-              deprecated="3.1" exec="skip">
+    <function name="GetProgramNamedParameterdvNV" deprecated="3.1" exec="skip">
         <param name="id" type="GLuint"/>
         <param name="len" type="GLsizei" counter="true"/>
         <param name="name" type="const GLubyte *" count="len"/>
         <size name="Get" mode="get"/>
     </enum>
 
-    <function name="DepthBoundsEXT" offset="assign" static_dispatch="false">
+    <function name="DepthBoundsEXT">
         <param name="zmin" type="GLclampd"/>
         <param name="zmax" type="GLclampd"/>
         <glx rop="4229" ignore="true"/>
         <size name="Get" mode="get"/>
     </enum>
 
-    <function name="BlendEquationSeparateEXT" static_dispatch="false" alias="BlendEquationSeparate">
+    <function name="BlendEquationSeparateEXT" alias="BlendEquationSeparate">
         <param name="modeRGB" type="GLenum"/>
         <param name="modeA" type="GLenum"/>
     </function>
     <enum name="BUFFER_FLUSHING_UNMAP_APPLE" count="1" value="0x8A13">
         <size name="GetBufferParameteriv" mode="get"/>
     </enum>
-    <function name="BufferParameteriAPPLE" offset="assign"
-              static_dispatch="false" exec="skip">
+    <function name="BufferParameteriAPPLE" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLint"/>
     </function>
-    <function name="FlushMappedBufferRangeAPPLE" offset="assign"
-              static_dispatch="false" exec="skip">
+    <function name="FlushMappedBufferRangeAPPLE" exec="skip">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="size" type="GLsizeiptr"/>
     <enum name="POLYGON_OFFSET_CLAMP_EXT"             value="0x8E1B">
         <size name="Get" mode="get"/>
     </enum>
-    <function name="PolygonOffsetClampEXT" offset="assign">
+    <function name="PolygonOffsetClampEXT">
         <param name="factor" type="GLfloat"/>
         <param name="units"  type="GLfloat"/>
         <param name="clamp"  type="GLfloat"/>
 <!-- Unnumbered extensions sorted by name. -->
 
 <category name="GL_ATI_blend_equation_separate">
-    <function name="BlendEquationSeparateATI" alias="BlendEquationSeparate" static_dispatch="false">
+    <function name="BlendEquationSeparateATI" alias="BlendEquationSeparate">
         <param name="modeRGB" type="GLenum"/>
         <param name="modeA" type="GLenum"/>
     </function>
         <size name="Get" mode="get"/>
     </enum>
 
-    <function name="StencilOpSeparateATI" alias="StencilOpSeparate" static_dispatch="false">
+    <function name="StencilOpSeparateATI" alias="StencilOpSeparate">
         <param name="face" type="GLenum"/>
         <param name="sfail" type="GLenum"/>
         <param name="zfail" type="GLenum"/>
         <param name="zpass" type="GLenum"/>
     </function>
-    <function name="StencilFuncSeparateATI" offset="assign"
-              static_dispatch="false" deprecated="3.1">
+    <function name="StencilFuncSeparateATI" deprecated="3.1">
         <param name="frontfunc" type="GLenum"/>
         <param name="backfunc" type="GLenum"/>
         <param name="ref" type="GLint"/>
 </category>
 
 <category name="GL_EXT_gpu_program_parameters">
-    <function name="ProgramEnvParameters4fvEXT" offset="assign"
-              static_dispatch="false" deprecated="3.1">
+    <function name="ProgramEnvParameters4fvEXT" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="params" type="const GLfloat *"/>
     </function>
 
-    <function name="ProgramLocalParameters4fvEXT" offset="assign"
-              static_dispatch="false" deprecated="3.1">
+    <function name="ProgramLocalParameters4fvEXT" deprecated="3.1">
         <param name="target" type="GLenum"/>
         <param name="index" type="GLuint"/>
         <param name="count" type="GLsizei"/>
     <enum name="TIME_ELAPSED_EXT" value="0x88BF"/>
     <type name="int64EXT"                  size="8"/>
     <type name="uint64EXT" unsigned="true" size="8"/>
-    <function name="GetQueryObjecti64vEXT" static_dispatch="false" alias="GetQueryObjecti64v">
+    <function name="GetQueryObjecti64vEXT" alias="GetQueryObjecti64v">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLint64EXT *"/>
     </function>
-    <function name="GetQueryObjectui64vEXT" static_dispatch="false" alias="GetQueryObjectui64v">
+    <function name="GetQueryObjectui64vEXT" alias="GetQueryObjectui64v">
         <param name="id" type="GLuint"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLuint64EXT *"/>
 </category>
 
 <category name="GL_INGR_blend_func_separate">
-    <function name="BlendFuncSeparateINGR" alias="BlendFuncSeparate" static_dispatch="false">
+    <function name="BlendFuncSeparateINGR" alias="BlendFuncSeparate">
         <param name="sfactorRGB" type="GLenum"/>
         <param name="dfactorRGB" type="GLenum"/>
         <param name="sfactorAlpha" type="GLenum"/>
         <size name="PointParameterfv"/>
     </enum>
 
-    <function name="PointParameterfSGIS" alias="PointParameterf" static_dispatch="false">
+    <function name="PointParameterfSGIS" alias="PointParameterf">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfloat"/>
     </function>
 
-    <function name="PointParameterfvSGIS" alias="PointParameterfv" static_dispatch="false">
+    <function name="PointParameterfvSGIS" alias="PointParameterfv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfloat *"/>
     </function>
index 23e23295bec8164b95631e7a85a8630d6c07f4a1..fa6217e1b8f7112d90d78bf22e55a7ab0bc1f684 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import license
 import gl_XML, glX_XML
-import sys, getopt
 
 class PrintGenericStubs(gl_XML.gl_print_base):
     def __init__(self):
@@ -244,30 +245,24 @@ class PrintGenericStubs(gl_XML.gl_print_base):
         return
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
-    sys.exit(1)
+def _parser():
+    """Parse arguments and return a namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='An XML description of an API.')
+    return parser.parse_args()
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-    mode = "generic"
 
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
-    except Exception,e:
-        show_usage()
+def main():
+    """Main function."""
+    args = _parser()
+    printer = PrintGenericStubs()
 
-    for (arg,val) in args:
-        if arg == '-m':
-            mode = val
-        elif arg == "-f":
-            file_name = val
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
+    printer.Print(api)
 
-    if mode == "generic":
-        printer = PrintGenericStubs()
-    else:
-        print "ERROR: Invalid mode \"%s\" specified." % mode
-        show_usage()
 
-    api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
-    printer.Print(api)
+if __name__ == '__main__':
+    main()
index 1a2bc2b911224dc7fdfec2246cdba94b156b291f..67aba81a74e69e188c29663b5a46aefd7f4e45ab 100644 (file)
@@ -30,6 +30,7 @@ import xml.etree.ElementTree as ET
 import re, sys, string
 import os.path
 import typeexpr
+import static_data
 
 
 def parse_GL_API( file_name, factory = None ):
@@ -625,7 +626,7 @@ class gl_function( gl_item ):
         # Decimal('1.1') }.
         self.api_map = {}
 
-        self.assign_offset = 0
+        self.assign_offset = False
 
         self.static_entry_points = []
 
@@ -649,7 +650,7 @@ class gl_function( gl_item ):
         name = element.get( "name" )
         alias = element.get( "alias" )
 
-        if is_attr_true(element, "static_dispatch", "true"):
+        if name in static_data.functions:
             self.static_entry_points.append(name)
 
         self.entry_points.append( name )
@@ -684,16 +685,11 @@ class gl_function( gl_item ):
             # Only try to set the offset when a non-alias entry-point
             # is being processed.
 
-            offset = element.get( "offset" )
-            if offset:
-                try:
-                    o = int( offset )
-                    self.offset = o
-                except Exception, e:
-                    self.offset = -1
-                    if offset == "assign":
-                        self.assign_offset = 1
-
+            if name in static_data.offsets:
+                self.offset = static_data.offsets[name]
+            else:
+                self.offset = -1
+                self.assign_offset = self.exec_flavor != "skip" or name in static_data.unused_functions
 
         if not self.name:
             self.name = true_name
index d158a6b31f7b7fa16f5d0d8216c86243150ffbb1..fc152841028fd0bcec9f6c3567c55c7ed33f0330 100644 (file)
     <type name="fixed"   size="4"                                    />
     <type name="clampx"  size="4"                                    />
 
-    <function name="AlphaFuncx" es1="1.0" desktop="false" offset="assign">
+    <function name="AlphaFuncx" es1="1.0" desktop="false">
         <param name="func" type="GLenum"/>
         <param name="ref" type="GLclampx"/>
     </function>
 
-    <function name="ClearColorx" es1="1.0" desktop="false" offset="assign">
+    <function name="ClearColorx" es1="1.0" desktop="false">
         <param name="red" type="GLclampx"/>
         <param name="green" type="GLclampx"/>
         <param name="blue" type="GLclampx"/>
         <param name="alpha" type="GLclampx"/>
     </function>
 
-    <function name="ClearDepthx" es1="1.0" desktop="false" offset="assign">
+    <function name="ClearDepthx" es1="1.0" desktop="false">
         <param name="depth" type="GLclampx"/>
     </function>
 
-    <function name="Color4x" es1="1.0" desktop="false" offset="assign">
+    <function name="Color4x" es1="1.0" desktop="false">
         <param name="red" type="GLfixed"/>
         <param name="green" type="GLfixed"/>
         <param name="blue" type="GLfixed"/>
         <param name="alpha" type="GLfixed"/>
     </function>
 
-    <function name="DepthRangex" es1="1.0" desktop="false" offset="assign">
+    <function name="DepthRangex" es1="1.0" desktop="false">
         <param name="zNear" type="GLclampx"/>
         <param name="zFar" type="GLclampx"/>
     </function>
 
-    <function name="Fogx" es1="1.0" desktop="false" offset="assign">
+    <function name="Fogx" es1="1.0" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="Fogxv" es1="1.0" desktop="false" offset="assign">
+    <function name="Fogxv" es1="1.0" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
     </function>
 
-    <function name="Frustumx" es1="1.0" desktop="false" offset="assign">
+    <function name="Frustumx" es1="1.0" desktop="false">
         <param name="left" type="GLfixed"/>
         <param name="right" type="GLfixed"/>
         <param name="bottom" type="GLfixed"/>
         <param name="zFar" type="GLfixed"/>
     </function>
 
-    <function name="LightModelx" es1="1.0" desktop="false" offset="assign">
+    <function name="LightModelx" es1="1.0" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="LightModelxv" es1="1.0" desktop="false" offset="assign">
+    <function name="LightModelxv" es1="1.0" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
     </function>
 
-    <function name="Lightx" es1="1.0" desktop="false" offset="assign">
+    <function name="Lightx" es1="1.0" desktop="false">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="Lightxv" es1="1.0" desktop="false" offset="assign">
+    <function name="Lightxv" es1="1.0" desktop="false">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
     </function>
 
-    <function name="LineWidthx" es1="1.0" desktop="false" offset="assign">
+    <function name="LineWidthx" es1="1.0" desktop="false">
         <param name="width" type="GLfixed"/>
     </function>
 
-    <function name="LoadMatrixx" es1="1.0" desktop="false" offset="assign">
+    <function name="LoadMatrixx" es1="1.0" desktop="false">
         <param name="m" type="const GLfixed *" count="16"/>
     </function>
 
-    <function name="Materialx" es1="1.0" desktop="false" offset="assign">
+    <function name="Materialx" es1="1.0" desktop="false">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="Materialxv" es1="1.0" desktop="false" offset="assign">
+    <function name="Materialxv" es1="1.0" desktop="false">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
     </function>
 
-    <function name="MultMatrixx" es1="1.0" desktop="false" offset="assign">
+    <function name="MultMatrixx" es1="1.0" desktop="false">
         <param name="m" type="const GLfixed *" count="16"/>
     </function>
 
-    <function name="MultiTexCoord4x" es1="1.0" desktop="false" offset="assign">
+    <function name="MultiTexCoord4x" es1="1.0" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="s" type="GLfixed"/>
         <param name="t" type="GLfixed"/>
         <param name="q" type="GLfixed"/>
     </function>
 
-    <function name="Normal3x" es1="1.0" desktop="false" offset="assign">
+    <function name="Normal3x" es1="1.0" desktop="false">
         <param name="nx" type="GLfixed"/>
         <param name="ny" type="GLfixed"/>
         <param name="nz" type="GLfixed"/>
     </function>
 
-    <function name="Orthox" es1="1.0" desktop="false" offset="assign">
+    <function name="Orthox" es1="1.0" desktop="false">
         <param name="left" type="GLfixed"/>
         <param name="right" type="GLfixed"/>
         <param name="bottom" type="GLfixed"/>
         <param name="zFar" type="GLfixed"/>
     </function>
 
-    <function name="PointSizex" es1="1.0" desktop="false" offset="assign">
+    <function name="PointSizex" es1="1.0" desktop="false">
         <param name="size" type="GLfixed"/>
     </function>
 
-    <function name="PolygonOffsetx" es1="1.0" desktop="false" offset="assign">
+    <function name="PolygonOffsetx" es1="1.0" desktop="false">
         <param name="factor" type="GLfixed"/>
         <param name="units" type="GLfixed"/>
     </function>
 
-    <function name="Rotatex" es1="1.0" desktop="false" offset="assign">
+    <function name="Rotatex" es1="1.0" desktop="false">
         <param name="angle" type="GLfixed"/>
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
     </function>
 
-    <function name="SampleCoveragex" es1="1.0" desktop="false" offset="assign">
+    <function name="SampleCoveragex" es1="1.0" desktop="false">
         <param name="value" type="GLclampx"/>
         <param name="invert" type="GLboolean"/>
     </function>
 
-    <function name="Scalex" es1="1.0" desktop="false" offset="assign">
+    <function name="Scalex" es1="1.0" desktop="false">
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
     </function>
 
-    <function name="TexEnvx" es1="1.0" desktop="false" offset="assign">
+    <function name="TexEnvx" es1="1.0" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="TexEnvxv" es1="1.0" desktop="false" offset="assign">
+    <function name="TexEnvxv" es1="1.0" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
     </function>
 
-    <function name="TexParameterx" es1="1.0" desktop="false" offset="assign">
+    <function name="TexParameterx" es1="1.0" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="Translatex" es1="1.0" desktop="false" offset="assign">
+    <function name="Translatex" es1="1.0" desktop="false">
         <param name="x" type="GLfixed"/>
         <param name="y" type="GLfixed"/>
         <param name="z" type="GLfixed"/>
     </function>
 
     <!-- from GL_OES_single_precision -->
-    <function name="Frustumf" es1="1.0" desktop="false" offset="assign">
+    <function name="Frustumf" es1="1.0" desktop="false">
         <param name="left" type="GLfloat"/>
         <param name="right" type="GLfloat"/>
         <param name="bottom" type="GLfloat"/>
         <param name="zFar" type="GLfloat"/>
     </function>
 
-    <function name="Orthof" es1="1.0" desktop="false" offset="assign">
+    <function name="Orthof" es1="1.0" desktop="false">
         <param name="left" type="GLfloat"/>
         <param name="right" type="GLfloat"/>
         <param name="bottom" type="GLfloat"/>
 
 <category name="es1.1">
     <!-- from GL_OES_fixed_point -->
-    <function name="ClipPlanex" es1="1.1" desktop="false" offset="assign">
+    <function name="ClipPlanex" es1="1.1" desktop="false">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="const GLfixed *" count="4"/>
     </function>
 
-    <function name="GetClipPlanex" es1="1.1" offset="assign">
+    <function name="GetClipPlanex" es1="1.1">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="GLfixed *" output="true" count="4"/>
     </function>
 
-    <function name="GetFixedv" es1="1.1" desktop="false" offset="assign">
+    <function name="GetFixedv" es1="1.1" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="GetLightxv" es1="1.1" desktop="false" offset="assign">
+    <function name="GetLightxv" es1="1.1" desktop="false">
         <param name="light" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="GetMaterialxv" es1="1.1" desktop="false" offset="assign">
+    <function name="GetMaterialxv" es1="1.1" desktop="false">
         <param name="face" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="GetTexEnvxv" es1="1.1" desktop="false" offset="assign">
+    <function name="GetTexEnvxv" es1="1.1" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="GetTexParameterxv" es1="1.1" desktop="false" offset="assign">
+    <function name="GetTexParameterxv" es1="1.1" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLfixed *" output="true" variable_param="pname"/>
     </function>
 
-    <function name="PointParameterx" es1="1.1" desktop="false" offset="assign">
+    <function name="PointParameterx" es1="1.1" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="param" type="GLfixed"/>
     </function>
 
-    <function name="PointParameterxv" es1="1.1" desktop="false" offset="assign">
+    <function name="PointParameterxv" es1="1.1" desktop="false">
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *"/>
     </function>
 
-    <function name="TexParameterxv" es1="1.1" desktop="false" offset="assign">
+    <function name="TexParameterxv" es1="1.1" desktop="false">
         <param name="target" type="GLenum"/>
         <param name="pname" type="GLenum"/>
         <param name="params" type="const GLfixed *" variable_param="pname"/>
     </function>
 
     <!-- from GL_OES_single_precision -->
-    <function name="ClipPlanef" es1="1.1" desktop="false" offset="assign">
+    <function name="ClipPlanef" es1="1.1" desktop="false">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="const GLfloat *" count="4"/>
     </function>
 
-    <function name="GetClipPlanef" es1="1.1" offset="assign">
+    <function name="GetClipPlanef" es1="1.1">
         <param name="plane" type="GLenum"/>
         <param name="equation" type="GLfloat *" output="true" count="4"/>
     </function>
index 4157032c5f0a6229fda74be7844c738e3764ed64..5e985a2ecac60658ca42974e7b07054e6b62d898 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import gl_XML, glX_XML
 import license
-import sys, getopt
 
 class PrintGlOffsets(gl_XML.gl_print_base):
     def __init__(self, es=False):
@@ -301,27 +302,30 @@ _glapi_proc UNUSED_TABLE_NAME[] = {"""
         return
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0]
-    print "-c          Enable compatibility with OpenGL ES."
-    sys.exit(1)
-
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
+def _parser():
+    """Parser arguments and return a namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        metavar='<input file name>',
+                        dest='filename',
+                        default="gl_API.xml",
+                        help="An XML file describing the API.")
+    parser.add_argument('-c',
+                        action='store_true',
+                        dest='es',
+                        help="Enable OpenGL ES compatibility")
+    return parser.parse_args()
 
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:c")
-    except Exception,e:
-        show_usage()
 
-    es = False
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-c":
-            es = True
+def main():
+    """Main function."""
+    args = _parser()
 
-    api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
 
-    printer = PrintGlOffsets(es)
+    printer = PrintGlOffsets(args.es)
     printer.Print(api)
+
+
+if __name__ == '__main__':
+    main()
index f45782df85f168d83898af2cacd37bead386733f..955f27d08185f3f2e63634fe3d7e2227be989f92 100644 (file)
@@ -1,8 +1,8 @@
 #!/usr/bin/python2
 # -*- Mode: Python; py-indent-offset: 8 -*-
 
-# (C) Copyright Zack Rusin 2005
-# All Rights Reserved.
+# (C) Copyright Zack Rusin 2005. All Rights Reserved.
+# Copyright (C) 2015 Intel Corporation
 # 
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
@@ -26,6 +26,8 @@
 # Authors:
 #    Zack Rusin <zack@kde.org>
 
+import argparse
+
 import license
 import gl_XML
 import sys, getopt
@@ -201,21 +203,21 @@ _mesa_lookup_prim_by_nr(GLuint nr)
                 enum.append( [name, priority] )
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name]" % sys.argv[0]
-    sys.exit(1)
+def _parser():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f', '--input_file',
+                        required=True,
+                        help="Choose an xml file to parse.")
+    return parser.parse_args()
 
-if __name__ == '__main__':
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:")
-    except Exception,e:
-        show_usage()
 
-    api_list = []
-    for (arg,val) in args:
-        if arg == "-f":
-            api = gl_XML.parse_GL_API( val )
-            api_list.append(api);
+def main():
+    args = _parser()
+    api_list = [gl_XML.parse_GL_API(args.input_file)]
 
     printer = PrintGlEnums()
-    printer.Print( api_list )
+    printer.Print(api_list)
+
+
+if __name__ == '__main__':
+    main()
index 4e76fe3c2cd4251a150589ffa47c17d2c92d839a..26d8e7bfb3a881a8475fc2da6a1138c1ad5bb7e2 100644 (file)
 # _mesa_initialize_exec_table().  It is responsible for populating all
 # entries in the "exec" dispatch table that aren't dynamic.
 
+import argparse
 import collections
 import license
 import gl_XML
-import sys, getopt
+import sys
+import apiexec
 
 
 exec_flavor_map = {
@@ -175,18 +177,49 @@ class PrintCode(gl_XML.gl_print_base):
                 raise Exception(
                     'Unrecognized exec flavor {0!r}'.format(f.exec_flavor))
             condition_parts = []
-            if f.desktop:
-                if f.deprecated:
+            if f.name in apiexec.functions:
+                ex = apiexec.functions[f.name]
+                unconditional_count = 0
+
+                if ex.compatibility is not None:
                     condition_parts.append('ctx->API == API_OPENGL_COMPAT')
-                else:
-                    condition_parts.append('_mesa_is_desktop_gl(ctx)')
-            if 'es1' in f.api_map:
-                condition_parts.append('ctx->API == API_OPENGLES')
-            if 'es2' in f.api_map:
-                if f.api_map['es2'] > 2.0:
-                    condition_parts.append('(ctx->API == API_OPENGLES2 && ctx->Version >= {0})'.format(int(f.api_map['es2'] * 10)))
-                else:
-                    condition_parts.append('ctx->API == API_OPENGLES2')
+                    unconditional_count += 1
+
+                if ex.core is not None:
+                    condition_parts.append('ctx->API == API_OPENGL_CORE')
+                    unconditional_count += 1
+
+                if ex.es1 is not None:
+                    condition_parts.append('ctx->API == API_OPENGLES')
+                    unconditional_count += 1
+
+                if ex.es2 is not None:
+                    if ex.es2 > 20:
+                        condition_parts.append('(ctx->API == API_OPENGLES2 && ctx->Version >= {0})'.format(ex.es2))
+                    else:
+                        condition_parts.append('ctx->API == API_OPENGLES2')
+                        unconditional_count += 1
+
+                # If the function is unconditionally available in all four
+                # APIs, then it is always available.  Replace the complex
+                # tautology condition with "true" and let GCC do the right
+                # thing.
+                if unconditional_count == 4:
+                    condition_parts = ['true']
+            else:
+                if f.desktop:
+                    if f.deprecated:
+                        condition_parts.append('ctx->API == API_OPENGL_COMPAT')
+                    else:
+                        condition_parts.append('_mesa_is_desktop_gl(ctx)')
+                if 'es1' in f.api_map:
+                    condition_parts.append('ctx->API == API_OPENGLES')
+                if 'es2' in f.api_map:
+                    if f.api_map['es2'] > 2.0:
+                        condition_parts.append('(ctx->API == API_OPENGLES2 && ctx->Version >= {0})'.format(int(f.api_map['es2'] * 10)))
+                    else:
+                        condition_parts.append('ctx->API == API_OPENGLES2')
+
             if not condition_parts:
                 # This function does not exist in any API.
                 continue
@@ -207,24 +240,23 @@ class PrintCode(gl_XML.gl_print_base):
             print '   }'
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name]" % sys.argv[0]
-    sys.exit(1)
-
+def _parser():
+    """Parse arguments and return namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_and_es_API.xml',
+                        help='an xml file describing an API')
+    return parser.parse_args()
 
-if __name__ == '__main__':
-    file_name = "gl_and_es_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
-    except Exception,e:
-        show_usage()
-
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
 
+def main():
+    """Main function."""
+    args = _parser()
     printer = PrintCode()
-
-    api = gl_XML.parse_GL_API(file_name)
+    api = gl_XML.parse_GL_API(args.filename)
     printer.Print(api)
+
+
+if __name__ == '__main__':
+    main()
index 06a5ebf049f59ff98834e0d3906439551110c5b9..1b3eb72470d06ae36b6276e451ff2bab84545ce7 100644 (file)
@@ -2,6 +2,7 @@
 
 # (C) Copyright IBM Corporation 2004, 2005
 # (C) Copyright Apple Inc. 2011
+# Copyright (C) 2015 Intel Corporation
 # All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # Based on code ogiginally by:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import license
 import gl_XML, glX_XML
-import sys, getopt
 
 header = """/* GLXEXT is the define used in the xserver when the GLX extension is being
  * built.  Hijack this to determine whether this file is being built for the
@@ -186,23 +188,27 @@ class PrintCode(gl_XML.gl_print_base):
                 print body_template % vars
         return
 
-def show_usage():
-    print "Usage: %s [-f input_file_name]" % sys.argv[0]
-    sys.exit(1)
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
+def _parser():
+    """Parse arguments and return a namespace object."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='An XML file description of an API')
+
+    return parser.parse_args()
 
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
-    except Exception,e:
-        show_usage()
 
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
+def main():
+    """Main function."""
+    args = _parser()
 
     printer = PrintCode()
 
-    api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
     printer.Print(api)
+
+
+if __name__ == '__main__':
+    main()
index b1fffc4ca07568af57cc34cdd1d925f408f578a7..685e2fac345a00fd60be9d1140ba08aa0b1f1e3c 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import license
-import gl_XML, glX_XML
-import sys, getopt
+import gl_XML
+import glX_XML
+
 
 class PrintGlProcs(gl_XML.gl_print_base):
     def __init__(self, es=False):
@@ -39,7 +42,6 @@ class PrintGlProcs(gl_XML.gl_print_base):
 """Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
 (C) Copyright IBM Corporation 2004, 2006""", "BRIAN PAUL, IBM")
 
-
     def printRealHeader(self):
         print """
 /* This file is only included by glapi.c and is used for
@@ -161,26 +163,28 @@ typedef struct {
         return
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0]
-    print "-c          Enable compatibility with OpenGL ES."
-    sys.exit(1)
+def _parser():
+    """Parse arguments and return a namepsace."""
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f', '--filename',
+                        default='gl_API.xml',
+                        metavar="input_file_name",
+                        dest='file_name',
+                        help="Path to an XML description of OpenGL API.")
+    parser.add_argument('-c', '--es-version',
+                        dest='es',
+                        action="store_true",
+                        help="filter functions for es")
+    return parser.parse_args()
+
+
+def main():
+    """Main function."""
+    args = _parser()
+    api = gl_XML.parse_GL_API(args.file_name, glX_XML.glx_item_factory())
+    PrintGlProcs(args.es).Print(api)
+
 
 if __name__ == '__main__':
-    file_name = "gl_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:c")
-    except Exception,e:
-        show_usage()
-
-    es = False
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-c":
-            es = True
-
-    api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
-    printer = PrintGlProcs(es)
-    printer.Print(api)
+    main()
index fd384689f57b6a1a96c4cf7471966cf8f4b754de..e25971a698c3e4430ac90d55590b5b66ac074588 100644 (file)
@@ -2,6 +2,7 @@
 
 # (C) Copyright IBM Corporation 2004
 # All Rights Reserved.
+# Copyright (c) 2014 Intel Corporation
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import gl_XML
 import license
-import sys, getopt
+
 
 class PrintGlTable(gl_XML.gl_print_base):
-    def __init__(self, es=False):
+    def __init__(self):
         gl_XML.gl_print_base.__init__(self)
 
-        self.es = es
         self.header_tag = '_GLAPI_TABLE_H_'
         self.name = "gl_table.py (from Mesa)"
         self.license = license.bsd_license_template % ( \
 """Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
 (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM")
-        self.ifdef_emitted = False;
+        self.ifdef_emitted = False
         return
 
-
     def printBody(self, api):
         for f in api.functionIterateByOffset():
             if not f.is_abi() and not self.ifdef_emitted:
                 print '#if !defined HAVE_SHARED_GLAPI'
                 self.ifdef_emitted = True
             arg_string = f.get_parameter_string()
-            print '   %s (GLAPIENTRYP %s)(%s); /* %d */' % (f.return_type, f.name, arg_string, f.offset)
+            print '   %s (GLAPIENTRYP %s)(%s); /* %d */' % (
+                f.return_type, f.name, arg_string, f.offset)
 
         print '#endif /* !defined HAVE_SHARED_GLAPI */'
 
-
     def printRealHeader(self):
         print '#ifndef GLAPIENTRYP'
         print '# ifndef GLAPIENTRY'
@@ -68,20 +69,19 @@ class PrintGlTable(gl_XML.gl_print_base):
         print '{'
         return
 
-
     def printRealFooter(self):
         print '};'
         return
 
 
 class PrintRemapTable(gl_XML.gl_print_base):
-    def __init__(self, es=False):
+    def __init__(self):
         gl_XML.gl_print_base.__init__(self)
 
-        self.es = es
         self.header_tag = '_DISPATCH_H_'
         self.name = "gl_table.py (from Mesa)"
-        self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM")
+        self.license = license.bsd_license_template % (
+            "(C) Copyright IBM Corporation 2005", "IBM")
         return
 
 
@@ -100,6 +100,7 @@ class PrintRemapTable(gl_XML.gl_print_base):
 """
         return
 
+
     def printBody(self, api):
         print '#define CALL_by_offset(disp, cast, offset, parameters) \\'
         print '    (*(cast (GET_by_offset(disp, offset)))) parameters'
@@ -120,19 +121,13 @@ class PrintRemapTable(gl_XML.gl_print_base):
 
         functions = []
         abi_functions = []
-        alias_functions = []
         count = 0
         for f in api.functionIterateByOffset():
             if not f.is_abi():
-                functions.append( [f, count] )
+                functions.append([f, count])
                 count += 1
             else:
-                abi_functions.append( [f, -1] )
-
-            if self.es:
-                # remember functions with aliases
-                if len(f.entry_points) > 1:
-                    alias_functions.append(f)
+                abi_functions.append([f, -1])
 
         print '/* total number of offsets below */'
         print '#define _gloffset_COUNT %d' % (len(abi_functions + functions))
@@ -141,18 +136,11 @@ class PrintRemapTable(gl_XML.gl_print_base):
         for f, index in abi_functions:
             print '#define _gloffset_%s %d' % (f.name, f.offset)
 
-        if self.es:
-            remap_table = "esLocalRemapTable"
-
-            print '#define %s_size %u' % (remap_table, count)
-            print 'static int %s[ %s_size ];' % (remap_table, remap_table)
-            print ''
-        else:
-            remap_table = "driDispatchRemapTable"
+        remap_table = "driDispatchRemapTable"
 
-            print '#define %s_size %u' % (remap_table, count)
-            print 'extern int %s[ %s_size ];' % (remap_table, remap_table)
-            print ''
+        print '#define %s_size %u' % (remap_table, count)
+        print 'extern int %s[ %s_size ];' % (remap_table, remap_table)
+        print ''
 
         for f, index in functions:
             print '#define %s_remap_index %u' % (f.name, index)
@@ -165,7 +153,7 @@ class PrintRemapTable(gl_XML.gl_print_base):
         print ''
 
         for f, index in abi_functions + functions:
-            arg_string = gl_XML.create_parameter_string( f.parameters, 0 )
+            arg_string = gl_XML.create_parameter_string(f.parameters, 0)
 
             print 'typedef %s (GLAPIENTRYP _glptr_%s)(%s);' % (f.return_type, f.name, arg_string)
             print '#define CALL_%s(disp, parameters) \\' % (f.name)
@@ -179,60 +167,38 @@ class PrintRemapTable(gl_XML.gl_print_base):
             print '}'
             print
 
-        if alias_functions:
-            print ''
-            print '/* define aliases for compatibility */'
-            for f in alias_functions:
-                for name in f.entry_points:
-                    if name != f.name:
-                        print '#define CALL_%s(disp, parameters) CALL_%s(disp, parameters)' % (name, f.name)
-                        print '#define GET_%s(disp) GET_%s(disp)' % (name, f.name)
-                        print '#define SET_%s(disp, fn) SET_%s(disp, fn)' % (name, f.name)
-            print ''
-
-            for f in alias_functions:
-                for name in f.entry_points:
-                    if name != f.name:
-                        print '#define %s_remap_index %s_remap_index' % (name, f.name)
-            print ''
-
         return
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-m mode] [-c ver]" % sys.argv[0]
-    print "    -m mode   Mode can be 'table' or 'remap_table'."
-    print "    -c ver    Version can be 'es1' or 'es2'."
-    sys.exit(1)
+def _parser():
+    """Parse arguments and return a namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f', '--filename',
+                        default='gl_API.xml',
+                        metavar="input_file_name",
+                        dest='file_name',
+                        help="Path to an XML description of OpenGL API.")
+    parser.add_argument('-m', '--mode',
+                        choices=['table', 'remap_table'],
+                        default='table',
+                        metavar="mode",
+                        help="Generate either a table or a remap_table")
+    return parser.parse_args()
+
+
+def main():
+    """Main function."""
+    args = _parser()
+
+    api = gl_XML.parse_GL_API(args.file_name)
+
+    if args.mode == "table":
+        printer = PrintGlTable()
+    elif args.mode == "remap_table":
+        printer = PrintRemapTable()
+
+    printer.Print(api)
+
 
 if __name__ == '__main__':
-    file_name = "gl_API.xml"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:m:c:")
-    except Exception,e:
-        show_usage()
-
-    mode = "table"
-    es = None
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-m":
-            mode = val
-        elif arg == "-c":
-            es = val
-
-    if mode == "table":
-        printer = PrintGlTable(es)
-    elif mode == "remap_table":
-        printer = PrintRemapTable(es)
-    else:
-        show_usage()
-
-    api = gl_XML.parse_GL_API( file_name )
-
-    if es is not None:
-        api.filter_functions_by_api(es)
-
-    printer.Print( api )
+    main()
index 7afc2b108f954669068a61992ac0b4639c18a069..cf42371f8c3b8ea022866e4b4f423bffddd8b61b 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+import copy
+
 import license
 import gl_XML, glX_XML
-import sys, getopt, copy
 
 def should_use_push(registers):
     for [reg, offset] in registers:
@@ -289,30 +291,25 @@ class PrintGenericStubs(gl_XML.gl_print_base):
 
         return
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
-    sys.exit(1)
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-    mode = "generic"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
-    except Exception,e:
-        show_usage()
-
-    for (arg,val) in args:
-        if arg == '-m':
-            mode = val
-        elif arg == "-f":
-            file_name = val
-
-    if mode == "generic":
-        printer = PrintGenericStubs()
-    else:
-        print "ERROR: Invalid mode \"%s\" specified." % mode
-        show_usage()
+def _parser():
+    """Parse arguments and return a namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        default='gl_API.xml',
+                        dest='filename',
+                        help='An XML file describing an API')
+    return parser.parse_args()
+
+
+def main():
+    """Main file."""
+    args = _parser()
+    printer = PrintGenericStubs()
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
 
-    api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
     printer.Print(api)
+
+
+if __name__ == '__main__':
+    main()
index f855dbaaa418ef916dc868a70b2dc4b8807aa27c..c0c7941ce10b4f250b44f459b2e785148030c0c8 100644 (file)
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import license
 import gl_XML, glX_XML
-import sys, getopt
 
 class PrintGenericStubs(gl_XML.gl_print_base):
 
@@ -217,30 +218,22 @@ class PrintGenericStubs(gl_XML.gl_print_base):
 
         return
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
-    sys.exit(1)
+def _parser():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='An XML file describing an API.')
+    return parser.parse_args()
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
-    mode = "generic"
-
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
-    except Exception,e:
-        show_usage()
-
-    for (arg,val) in args:
-        if arg == '-m':
-            mode = val
-        elif arg == "-f":
-            file_name = val
-
-    if mode == "generic":
-        printer = PrintGenericStubs()
-    else:
-        print "ERROR: Invalid mode \"%s\" specified." % mode
-        show_usage()
-
-    api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
+
+def main():
+    args = _parser()
+    printer = PrintGenericStubs()
+
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
     printer.Print(api)
+
+
+if __name__ == '__main__':
+    main()
index e1a13d0b3dde9bc048751aa227dafc92fd72d20c..edc6c3e14b68717f6ae950bd965c581f8c03ad8b 100644 (file)
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 # IN THE SOFTWARE.
 
-import gl_XML
+import argparse
+
 import license
-import sys, getopt, string
+import gl_XML
+
 
 def get_function_spec(func):
     sig = ""
@@ -54,6 +56,7 @@ def get_function_spec(func):
 
     return spec
 
+
 class PrintGlRemap(gl_XML.gl_print_base):
     def __init__(self):
         gl_XML.gl_print_base.__init__(self)
@@ -163,30 +166,26 @@ class PrintGlRemap(gl_XML.gl_print_base):
         return
 
 
-def show_usage():
-    print "Usage: %s [-f input_file_name] [-c ver]" % sys.argv[0]
-    print "    -c ver    Version can be 'es1' or 'es2'."
-    sys.exit(1)
+def _parser():
+    """Parse input options and return a namsepace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f', '--filename',
+                        default="gl_API.xml",
+                        metavar="input_file_name",
+                        dest='file_name',
+                        help="An xml description file.")
+    return parser.parse_args()
 
-if __name__ == '__main__':
-    file_name = "gl_API.xml"
 
-    try:
-        (args, trail) = getopt.getopt(sys.argv[1:], "f:c:")
-    except Exception,e:
-        show_usage()
+def main():
+    """Main function."""
+    args = _parser()
 
-    es = None
-    for (arg,val) in args:
-        if arg == "-f":
-            file_name = val
-        elif arg == "-c":
-            es = val
+    api = gl_XML.parse_GL_API(args.file_name)
 
-    api = gl_XML.parse_GL_API( file_name )
+    printer = PrintGlRemap()
+    printer.Print(api)
 
-    if es is not None:
-        api.filter_functions_by_api(es)
 
-    printer = PrintGlRemap()
-    printer.Print( api )
+if __name__ == '__main__':
+    main()
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
new file mode 100644 (file)
index 0000000..142c503
--- /dev/null
@@ -0,0 +1,1729 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2015 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+"""Table of functions that have ABI-mandated offsets in the dispatch table.
+
+This list will never change."""
+offsets = {
+    "NewList": 0,
+    "EndList": 1,
+    "CallList": 2,
+    "CallLists": 3,
+    "DeleteLists": 4,
+    "GenLists": 5,
+    "ListBase": 6,
+    "Begin": 7,
+    "Bitmap": 8,
+    "Color3b": 9,
+    "Color3bv": 10,
+    "Color3d": 11,
+    "Color3dv": 12,
+    "Color3f": 13,
+    "Color3fv": 14,
+    "Color3i": 15,
+    "Color3iv": 16,
+    "Color3s": 17,
+    "Color3sv": 18,
+    "Color3ub": 19,
+    "Color3ubv": 20,
+    "Color3ui": 21,
+    "Color3uiv": 22,
+    "Color3us": 23,
+    "Color3usv": 24,
+    "Color4b": 25,
+    "Color4bv": 26,
+    "Color4d": 27,
+    "Color4dv": 28,
+    "Color4f": 29,
+    "Color4fv": 30,
+    "Color4i": 31,
+    "Color4iv": 32,
+    "Color4s": 33,
+    "Color4sv": 34,
+    "Color4ub": 35,
+    "Color4ubv": 36,
+    "Color4ui": 37,
+    "Color4uiv": 38,
+    "Color4us": 39,
+    "Color4usv": 40,
+    "EdgeFlag": 41,
+    "EdgeFlagv": 42,
+    "End": 43,
+    "Indexd": 44,
+    "Indexdv": 45,
+    "Indexf": 46,
+    "Indexfv": 47,
+    "Indexi": 48,
+    "Indexiv": 49,
+    "Indexs": 50,
+    "Indexsv": 51,
+    "Normal3b": 52,
+    "Normal3bv": 53,
+    "Normal3d": 54,
+    "Normal3dv": 55,
+    "Normal3f": 56,
+    "Normal3fv": 57,
+    "Normal3i": 58,
+    "Normal3iv": 59,
+    "Normal3s": 60,
+    "Normal3sv": 61,
+    "RasterPos2d": 62,
+    "RasterPos2dv": 63,
+    "RasterPos2f": 64,
+    "RasterPos2fv": 65,
+    "RasterPos2i": 66,
+    "RasterPos2iv": 67,
+    "RasterPos2s": 68,
+    "RasterPos2sv": 69,
+    "RasterPos3d": 70,
+    "RasterPos3dv": 71,
+    "RasterPos3f": 72,
+    "RasterPos3fv": 73,
+    "RasterPos3i": 74,
+    "RasterPos3iv": 75,
+    "RasterPos3s": 76,
+    "RasterPos3sv": 77,
+    "RasterPos4d": 78,
+    "RasterPos4dv": 79,
+    "RasterPos4f": 80,
+    "RasterPos4fv": 81,
+    "RasterPos4i": 82,
+    "RasterPos4iv": 83,
+    "RasterPos4s": 84,
+    "RasterPos4sv": 85,
+    "Rectd": 86,
+    "Rectdv": 87,
+    "Rectf": 88,
+    "Rectfv": 89,
+    "Recti": 90,
+    "Rectiv": 91,
+    "Rects": 92,
+    "Rectsv": 93,
+    "TexCoord1d": 94,
+    "TexCoord1dv": 95,
+    "TexCoord1f": 96,
+    "TexCoord1fv": 97,
+    "TexCoord1i": 98,
+    "TexCoord1iv": 99,
+    "TexCoord1s": 100,
+    "TexCoord1sv": 101,
+    "TexCoord2d": 102,
+    "TexCoord2dv": 103,
+    "TexCoord2f": 104,
+    "TexCoord2fv": 105,
+    "TexCoord2i": 106,
+    "TexCoord2iv": 107,
+    "TexCoord2s": 108,
+    "TexCoord2sv": 109,
+    "TexCoord3d": 110,
+    "TexCoord3dv": 111,
+    "TexCoord3f": 112,
+    "TexCoord3fv": 113,
+    "TexCoord3i": 114,
+    "TexCoord3iv": 115,
+    "TexCoord3s": 116,
+    "TexCoord3sv": 117,
+    "TexCoord4d": 118,
+    "TexCoord4dv": 119,
+    "TexCoord4f": 120,
+    "TexCoord4fv": 121,
+    "TexCoord4i": 122,
+    "TexCoord4iv": 123,
+    "TexCoord4s": 124,
+    "TexCoord4sv": 125,
+    "Vertex2d": 126,
+    "Vertex2dv": 127,
+    "Vertex2f": 128,
+    "Vertex2fv": 129,
+    "Vertex2i": 130,
+    "Vertex2iv": 131,
+    "Vertex2s": 132,
+    "Vertex2sv": 133,
+    "Vertex3d": 134,
+    "Vertex3dv": 135,
+    "Vertex3f": 136,
+    "Vertex3fv": 137,
+    "Vertex3i": 138,
+    "Vertex3iv": 139,
+    "Vertex3s": 140,
+    "Vertex3sv": 141,
+    "Vertex4d": 142,
+    "Vertex4dv": 143,
+    "Vertex4f": 144,
+    "Vertex4fv": 145,
+    "Vertex4i": 146,
+    "Vertex4iv": 147,
+    "Vertex4s": 148,
+    "Vertex4sv": 149,
+    "ClipPlane": 150,
+    "ColorMaterial": 151,
+    "CullFace": 152,
+    "Fogf": 153,
+    "Fogfv": 154,
+    "Fogi": 155,
+    "Fogiv": 156,
+    "FrontFace": 157,
+    "Hint": 158,
+    "Lightf": 159,
+    "Lightfv": 160,
+    "Lighti": 161,
+    "Lightiv": 162,
+    "LightModelf": 163,
+    "LightModelfv": 164,
+    "LightModeli": 165,
+    "LightModeliv": 166,
+    "LineStipple": 167,
+    "LineWidth": 168,
+    "Materialf": 169,
+    "Materialfv": 170,
+    "Materiali": 171,
+    "Materialiv": 172,
+    "PointSize": 173,
+    "PolygonMode": 174,
+    "PolygonStipple": 175,
+    "Scissor": 176,
+    "ShadeModel": 177,
+    "TexParameterf": 178,
+    "TexParameterfv": 179,
+    "TexParameteri": 180,
+    "TexParameteriv": 181,
+    "TexImage1D": 182,
+    "TexImage2D": 183,
+    "TexEnvf": 184,
+    "TexEnvfv": 185,
+    "TexEnvi": 186,
+    "TexEnviv": 187,
+    "TexGend": 188,
+    "TexGendv": 189,
+    "TexGenf": 190,
+    "TexGenfv": 191,
+    "TexGeni": 192,
+    "TexGeniv": 193,
+    "FeedbackBuffer": 194,
+    "SelectBuffer": 195,
+    "RenderMode": 196,
+    "InitNames": 197,
+    "LoadName": 198,
+    "PassThrough": 199,
+    "PopName": 200,
+    "PushName": 201,
+    "DrawBuffer": 202,
+    "Clear": 203,
+    "ClearAccum": 204,
+    "ClearIndex": 205,
+    "ClearColor": 206,
+    "ClearStencil": 207,
+    "ClearDepth": 208,
+    "StencilMask": 209,
+    "ColorMask": 210,
+    "DepthMask": 211,
+    "IndexMask": 212,
+    "Accum": 213,
+    "Disable": 214,
+    "Enable": 215,
+    "Finish": 216,
+    "Flush": 217,
+    "PopAttrib": 218,
+    "PushAttrib": 219,
+    "Map1d": 220,
+    "Map1f": 221,
+    "Map2d": 222,
+    "Map2f": 223,
+    "MapGrid1d": 224,
+    "MapGrid1f": 225,
+    "MapGrid2d": 226,
+    "MapGrid2f": 227,
+    "EvalCoord1d": 228,
+    "EvalCoord1dv": 229,
+    "EvalCoord1f": 230,
+    "EvalCoord1fv": 231,
+    "EvalCoord2d": 232,
+    "EvalCoord2dv": 233,
+    "EvalCoord2f": 234,
+    "EvalCoord2fv": 235,
+    "EvalMesh1": 236,
+    "EvalPoint1": 237,
+    "EvalMesh2": 238,
+    "EvalPoint2": 239,
+    "AlphaFunc": 240,
+    "BlendFunc": 241,
+    "LogicOp": 242,
+    "StencilFunc": 243,
+    "StencilOp": 244,
+    "DepthFunc": 245,
+    "PixelZoom": 246,
+    "PixelTransferf": 247,
+    "PixelTransferi": 248,
+    "PixelStoref": 249,
+    "PixelStorei": 250,
+    "PixelMapfv": 251,
+    "PixelMapuiv": 252,
+    "PixelMapusv": 253,
+    "ReadBuffer": 254,
+    "CopyPixels": 255,
+    "ReadPixels": 256,
+    "DrawPixels": 257,
+    "GetBooleanv": 258,
+    "GetClipPlane": 259,
+    "GetDoublev": 260,
+    "GetError": 261,
+    "GetFloatv": 262,
+    "GetIntegerv": 263,
+    "GetLightfv": 264,
+    "GetLightiv": 265,
+    "GetMapdv": 266,
+    "GetMapfv": 267,
+    "GetMapiv": 268,
+    "GetMaterialfv": 269,
+    "GetMaterialiv": 270,
+    "GetPixelMapfv": 271,
+    "GetPixelMapuiv": 272,
+    "GetPixelMapusv": 273,
+    "GetPolygonStipple": 274,
+    "GetString": 275,
+    "GetTexEnvfv": 276,
+    "GetTexEnviv": 277,
+    "GetTexGendv": 278,
+    "GetTexGenfv": 279,
+    "GetTexGeniv": 280,
+    "GetTexImage": 281,
+    "GetTexParameterfv": 282,
+    "GetTexParameteriv": 283,
+    "GetTexLevelParameterfv": 284,
+    "GetTexLevelParameteriv": 285,
+    "IsEnabled": 286,
+    "IsList": 287,
+    "DepthRange": 288,
+    "Frustum": 289,
+    "LoadIdentity": 290,
+    "LoadMatrixf": 291,
+    "LoadMatrixd": 292,
+    "MatrixMode": 293,
+    "MultMatrixf": 294,
+    "MultMatrixd": 295,
+    "Ortho": 296,
+    "PopMatrix": 297,
+    "PushMatrix": 298,
+    "Rotated": 299,
+    "Rotatef": 300,
+    "Scaled": 301,
+    "Scalef": 302,
+    "Translated": 303,
+    "Translatef": 304,
+    "Viewport": 305,
+    "ArrayElement": 306,
+    "ColorPointer": 308,
+    "DisableClientState": 309,
+    "DrawArrays": 310,
+    "DrawElements": 311,
+    "EdgeFlagPointer": 312,
+    "EnableClientState": 313,
+    "GetPointerv": 329,
+    "IndexPointer": 314,
+    "InterleavedArrays": 317,
+    "NormalPointer": 318,
+    "TexCoordPointer": 320,
+    "VertexPointer": 321,
+    "PolygonOffset": 319,
+    "CopyTexImage1D": 323,
+    "CopyTexImage2D": 324,
+    "CopyTexSubImage1D": 325,
+    "CopyTexSubImage2D": 326,
+    "TexSubImage1D": 332,
+    "TexSubImage2D": 333,
+    "AreTexturesResident": 322,
+    "BindTexture": 307,
+    "DeleteTextures": 327,
+    "GenTextures": 328,
+    "IsTexture": 330,
+    "PrioritizeTextures": 331,
+    "Indexub": 315,
+    "Indexubv": 316,
+    "PopClientAttrib": 334,
+    "PushClientAttrib": 335,
+    "BlendColor": 336,
+    "BlendEquation": 337,
+    "DrawRangeElements": 338,
+    "ColorTable": 339,
+    "ColorTableParameterfv": 340,
+    "ColorTableParameteriv": 341,
+    "CopyColorTable": 342,
+    "GetColorTable": 343,
+    "GetColorTableParameterfv": 344,
+    "GetColorTableParameteriv": 345,
+    "ColorSubTable": 346,
+    "CopyColorSubTable": 347,
+    "ConvolutionFilter1D": 348,
+    "ConvolutionFilter2D": 349,
+    "ConvolutionParameterf": 350,
+    "ConvolutionParameterfv": 351,
+    "ConvolutionParameteri": 352,
+    "ConvolutionParameteriv": 353,
+    "CopyConvolutionFilter1D": 354,
+    "CopyConvolutionFilter2D": 355,
+    "GetConvolutionFilter": 356,
+    "GetConvolutionParameterfv": 357,
+    "GetConvolutionParameteriv": 358,
+    "GetSeparableFilter": 359,
+    "SeparableFilter2D": 360,
+    "GetHistogram": 361,
+    "GetHistogramParameterfv": 362,
+    "GetHistogramParameteriv": 363,
+    "GetMinmax": 364,
+    "GetMinmaxParameterfv": 365,
+    "GetMinmaxParameteriv": 366,
+    "Histogram": 367,
+    "Minmax": 368,
+    "ResetHistogram": 369,
+    "ResetMinmax": 370,
+    "TexImage3D": 371,
+    "TexSubImage3D": 372,
+    "CopyTexSubImage3D": 373,
+    "ActiveTexture": 374,
+    "ClientActiveTexture": 375,
+    "MultiTexCoord1d": 376,
+    "MultiTexCoord1dv": 377,
+    "MultiTexCoord1fARB": 378,
+    "MultiTexCoord1fvARB": 379,
+    "MultiTexCoord1i": 380,
+    "MultiTexCoord1iv": 381,
+    "MultiTexCoord1s": 382,
+    "MultiTexCoord1sv": 383,
+    "MultiTexCoord2d": 384,
+    "MultiTexCoord2dv": 385,
+    "MultiTexCoord2fARB": 386,
+    "MultiTexCoord2fvARB": 387,
+    "MultiTexCoord2i": 388,
+    "MultiTexCoord2iv": 389,
+    "MultiTexCoord2s": 390,
+    "MultiTexCoord2sv": 391,
+    "MultiTexCoord3d": 392,
+    "MultiTexCoord3dv": 393,
+    "MultiTexCoord3fARB": 394,
+    "MultiTexCoord3fvARB": 395,
+    "MultiTexCoord3i": 396,
+    "MultiTexCoord3iv": 397,
+    "MultiTexCoord3s": 398,
+    "MultiTexCoord3sv": 399,
+    "MultiTexCoord4d": 400,
+    "MultiTexCoord4dv": 401,
+    "MultiTexCoord4fARB": 402,
+    "MultiTexCoord4fvARB": 403,
+    "MultiTexCoord4i": 404,
+    "MultiTexCoord4iv": 405,
+    "MultiTexCoord4s": 406,
+    "MultiTexCoord4sv": 407
+}
+
+functions = [
+   "Accum",
+   "ActiveTexture",
+   "ActiveTextureARB",
+   "AlphaFunc",
+   "AlphaFuncx",
+   "AreTexturesResident",
+   "AreTexturesResidentEXT",
+   "ArrayElement",
+   "ArrayElementEXT",
+   "AttachObjectARB",
+   "AttachShader",
+   "Begin",
+   "BeginConditionalRender",
+   "BeginConditionalRenderNV",
+   "BeginQuery",
+   "BeginQueryARB",
+   "BeginQueryIndexed",
+   "BeginTransformFeedback",
+   "BindAttribLocation",
+   "BindAttribLocationARB",
+   "BindBuffer",
+   "BindBufferARB",
+   "BindBufferBase",
+   "BindBufferRange",
+   "BindBuffersBase",
+   "BindBuffersRange",
+   "BindFragDataLocation",
+   "BindFragDataLocationEXT",
+   "BindFragDataLocationIndexed",
+   "BindFramebuffer",
+   "BindFramebufferEXT",
+   "BindImageTexture",
+   "BindImageTextures",
+   "BindProgramARB",
+   "BindRenderbuffer",
+   "BindRenderbufferEXT",
+   "BindSampler",
+   "BindSamplers",
+   "BindTexture",
+   "BindTextureEXT",
+   "BindTextures",
+   "BindTransformFeedback",
+   "BindVertexArray",
+   "BindVertexBuffer",
+   "BindVertexBuffers",
+   "Bitmap",
+   "BlendColor",
+   "BlendColorEXT",
+   "BlendEquation",
+   "BlendEquationEXT",
+   "BlendEquationiARB",
+   "BlendEquationSeparate",
+   "BlendEquationSeparateiARB",
+   "BlendFunc",
+   "BlendFunciARB",
+   "BlendFuncSeparate",
+   "BlendFuncSeparateEXT",
+   "BlendFuncSeparateiARB",
+   "BlitFramebuffer",
+   "BufferData",
+   "BufferDataARB",
+   "BufferStorage",
+   "BufferSubData",
+   "BufferSubDataARB",
+   "CallList",
+   "CallLists",
+   "CheckFramebufferStatus",
+   "CheckFramebufferStatusEXT",
+   "ClampColor",
+   "ClampColorARB",
+   "Clear",
+   "ClearAccum",
+   "ClearBufferData",
+   "ClearBufferfi",
+   "ClearBufferfv",
+   "ClearBufferiv",
+   "ClearBufferSubData",
+   "ClearBufferuiv",
+   "ClearColor",
+   "ClearColorIiEXT",
+   "ClearColorIuiEXT",
+   "ClearColorx",
+   "ClearDepth",
+   "ClearDepthf",
+   "ClearDepthx",
+   "ClearIndex",
+   "ClearStencil",
+   "ClearTexImage",
+   "ClearTexSubImage",
+   "ClientActiveTexture",
+   "ClientActiveTextureARB",
+   "ClientWaitSync",
+   "ClipPlane",
+   "ClipPlanef",
+   "ClipPlanex",
+   "Color3b",
+   "Color3bv",
+   "Color3d",
+   "Color3dv",
+   "Color3f",
+   "Color3fv",
+   "Color3i",
+   "Color3iv",
+   "Color3s",
+   "Color3sv",
+   "Color3ub",
+   "Color3ubv",
+   "Color3ui",
+   "Color3uiv",
+   "Color3us",
+   "Color3usv",
+   "Color4b",
+   "Color4bv",
+   "Color4d",
+   "Color4dv",
+   "Color4f",
+   "Color4fv",
+   "Color4i",
+   "Color4iv",
+   "Color4s",
+   "Color4sv",
+   "Color4ub",
+   "Color4ubv",
+   "Color4ui",
+   "Color4uiv",
+   "Color4us",
+   "Color4usv",
+   "Color4x",
+   "ColorMask",
+   "ColorMaski",
+   "ColorMaskIndexedEXT",
+   "ColorMaterial",
+   "ColorP3ui",
+   "ColorP3uiv",
+   "ColorP4ui",
+   "ColorP4uiv",
+   "ColorPointer",
+   "ColorPointerEXT",
+   "ColorSubTable",
+   "ColorTable",
+   "ColorTableParameterfv",
+   "ColorTableParameteriv",
+   "CompileShader",
+   "CompileShaderARB",
+   "CompressedTexImage1D",
+   "CompressedTexImage1DARB",
+   "CompressedTexImage2D",
+   "CompressedTexImage2DARB",
+   "CompressedTexImage3D",
+   "CompressedTexImage3DARB",
+   "CompressedTexSubImage1D",
+   "CompressedTexSubImage1DARB",
+   "CompressedTexSubImage2D",
+   "CompressedTexSubImage2DARB",
+   "CompressedTexSubImage3D",
+   "CompressedTexSubImage3DARB",
+   "ConvolutionFilter1D",
+   "ConvolutionFilter2D",
+   "ConvolutionParameterf",
+   "ConvolutionParameterfv",
+   "ConvolutionParameteri",
+   "ConvolutionParameteriv",
+   "CopyBufferSubData",
+   "CopyColorSubTable",
+   "CopyColorTable",
+   "CopyConvolutionFilter1D",
+   "CopyConvolutionFilter2D",
+   "CopyImageSubData",
+   "CopyPixels",
+   "CopyTexImage1D",
+   "CopyTexImage2D",
+   "CopyTexSubImage1D",
+   "CopyTexSubImage2D",
+   "CopyTexSubImage3D",
+   "CopyTexSubImage3DEXT",
+   "CreateProgram",
+   "CreateProgramObjectARB",
+   "CreateShader",
+   "CreateShaderObjectARB",
+   "CullFace",
+   "DebugMessageCallback",
+   "DebugMessageCallbackARB",
+   "DebugMessageControl",
+   "DebugMessageControlARB",
+   "DebugMessageInsert",
+   "DebugMessageInsertARB",
+   "DeleteBuffers",
+   "DeleteBuffersARB",
+   "DeleteFramebuffers",
+   "DeleteFramebuffersEXT",
+   "DeleteLists",
+   "DeleteObjectARB",
+   "DeleteProgram",
+   "DeleteProgramsARB",
+   "DeleteQueries",
+   "DeleteQueriesARB",
+   "DeleteRenderbuffers",
+   "DeleteRenderbuffersEXT",
+   "DeleteSamplers",
+   "DeleteShader",
+   "DeleteSync",
+   "DeleteTextures",
+   "DeleteTexturesEXT",
+   "DeleteTransformFeedbacks",
+   "DeleteVertexArrays",
+   "DepthFunc",
+   "DepthMask",
+   "DepthRange",
+   "DepthRangeArrayv",
+   "DepthRangef",
+   "DepthRangeIndexed",
+   "DepthRangex",
+   "DetachObjectARB",
+   "DetachShader",
+   "Disable",
+   "DisableClientState",
+   "Disablei",
+   "DisableIndexedEXT",
+   "DisableVertexAttribArray",
+   "DisableVertexAttribArrayARB",
+   "DispatchCompute",
+   "DispatchComputeIndirect",
+   "DrawArrays",
+   "DrawArraysEXT",
+   "DrawArraysIndirect",
+   "DrawArraysInstanced",
+   "DrawArraysInstancedARB",
+   "DrawArraysInstancedBaseInstance",
+   "DrawArraysInstancedEXT",
+   "DrawBuffer",
+   "DrawBuffers",
+   "DrawBuffersARB",
+   "DrawBuffersATI",
+   "DrawElements",
+   "DrawElementsBaseVertex",
+   "DrawElementsIndirect",
+   "DrawElementsInstanced",
+   "DrawElementsInstancedARB",
+   "DrawElementsInstancedBaseInstance",
+   "DrawElementsInstancedBaseVertex",
+   "DrawElementsInstancedBaseVertexBaseInstance",
+   "DrawElementsInstancedEXT",
+   "DrawPixels",
+   "DrawRangeElements",
+   "DrawRangeElementsBaseVertex",
+   "DrawRangeElementsEXT",
+   "DrawTransformFeedback",
+   "DrawTransformFeedbackInstanced",
+   "DrawTransformFeedbackStream",
+   "DrawTransformFeedbackStreamInstanced",
+   "EdgeFlag",
+   "EdgeFlagPointer",
+   "EdgeFlagPointerEXT",
+   "EdgeFlagv",
+   "Enable",
+   "EnableClientState",
+   "Enablei",
+   "EnableIndexedEXT",
+   "EnableVertexAttribArray",
+   "EnableVertexAttribArrayARB",
+   "End",
+   "EndConditionalRender",
+   "EndConditionalRenderNV",
+   "EndList",
+   "EndQuery",
+   "EndQueryARB",
+   "EndQueryIndexed",
+   "EndTransformFeedback",
+   "EvalCoord1d",
+   "EvalCoord1dv",
+   "EvalCoord1f",
+   "EvalCoord1fv",
+   "EvalCoord2d",
+   "EvalCoord2dv",
+   "EvalCoord2f",
+   "EvalCoord2fv",
+   "EvalMesh1",
+   "EvalMesh2",
+   "EvalPoint1",
+   "EvalPoint2",
+   "FeedbackBuffer",
+   "FenceSync",
+   "Finish",
+   "Flush",
+   "FlushMappedBufferRange",
+   "FogCoordd",
+   "FogCoorddEXT",
+   "FogCoorddv",
+   "FogCoorddvEXT",
+   "FogCoordf",
+   "FogCoordfEXT",
+   "FogCoordfv",
+   "FogCoordfvEXT",
+   "FogCoordPointer",
+   "FogCoordPointerEXT",
+   "Fogf",
+   "Fogfv",
+   "Fogi",
+   "Fogiv",
+   "Fogx",
+   "Fogxv",
+   "FramebufferRenderbuffer",
+   "FramebufferRenderbufferEXT",
+   "FramebufferTexture",
+   "FramebufferTexture1D",
+   "FramebufferTexture1DEXT",
+   "FramebufferTexture2D",
+   "FramebufferTexture2DEXT",
+   "FramebufferTexture3D",
+   "FramebufferTexture3DEXT",
+   "FramebufferTextureARB",
+   "FramebufferTextureLayer",
+   "FramebufferTextureLayerARB",
+   "FramebufferTextureLayerEXT",
+   "FrontFace",
+   "Frustum",
+   "Frustumf",
+   "Frustumx",
+   "GenBuffers",
+   "GenBuffersARB",
+   "GenerateMipmap",
+   "GenerateMipmapEXT",
+   "GenFramebuffers",
+   "GenFramebuffersEXT",
+   "GenLists",
+   "GenProgramsARB",
+   "GenQueries",
+   "GenQueriesARB",
+   "GenRenderbuffers",
+   "GenRenderbuffersEXT",
+   "GenSamplers",
+   "GenTextures",
+   "GenTexturesEXT",
+   "GenTransformFeedbacks",
+   "GenVertexArrays",
+   "GetActiveAtomicCounterBufferiv",
+   "GetActiveAttrib",
+   "GetActiveAttribARB",
+   "GetActiveUniform",
+   "GetActiveUniformARB",
+   "GetActiveUniformBlockiv",
+   "GetActiveUniformBlockName",
+   "GetActiveUniformName",
+   "GetActiveUniformsiv",
+   "GetAttachedObjectsARB",
+   "GetAttachedShaders",
+   "GetAttribLocation",
+   "GetAttribLocationARB",
+   "GetBooleanIndexedvEXT",
+   "GetBooleani_v",
+   "GetBooleanv",
+   "GetBufferParameteri64v",
+   "GetBufferParameteriv",
+   "GetBufferParameterivARB",
+   "GetBufferPointerv",
+   "GetBufferPointervARB",
+   "GetBufferSubData",
+   "GetBufferSubDataARB",
+   "GetClipPlane",
+   "GetClipPlanef",
+   "GetClipPlanex",
+   "GetColorTable",
+   "GetColorTableParameterfv",
+   "GetColorTableParameteriv",
+   "GetCompressedTexImage",
+   "GetCompressedTexImageARB",
+   "GetConvolutionFilter",
+   "GetConvolutionParameterfv",
+   "GetConvolutionParameteriv",
+   "GetDebugMessageLog",
+   "GetDebugMessageLogARB",
+   "GetDoublei_v",
+   "GetDoublev",
+   "GetError",
+   "GetFixedv",
+   "GetFloati_v",
+   "GetFloatv",
+   "GetFragDataIndex",
+   "GetFragDataLocation",
+   "GetFragDataLocationEXT",
+   "GetFramebufferAttachmentParameteriv",
+   "GetFramebufferAttachmentParameterivEXT",
+   "GetGraphicsResetStatusARB",
+   "GetHandleARB",
+   "GetHistogram",
+   "GetHistogramParameterfv",
+   "GetHistogramParameteriv",
+   "GetInfoLogARB",
+   "GetInteger64i_v",
+   "GetInteger64v",
+   "GetIntegerIndexedvEXT",
+   "GetIntegeri_v",
+   "GetIntegerv",
+   "GetLightfv",
+   "GetLightiv",
+   "GetLightxv",
+   "GetMapdv",
+   "GetMapfv",
+   "GetMapiv",
+   "GetMaterialfv",
+   "GetMaterialiv",
+   "GetMaterialxv",
+   "GetMinmax",
+   "GetMinmaxParameterfv",
+   "GetMinmaxParameteriv",
+   "GetMultisamplefv",
+   "GetnColorTableARB",
+   "GetnCompressedTexImageARB",
+   "GetnConvolutionFilterARB",
+   "GetnHistogramARB",
+   "GetnMapdvARB",
+   "GetnMapfvARB",
+   "GetnMapivARB",
+   "GetnMinmaxARB",
+   "GetnPixelMapfvARB",
+   "GetnPixelMapuivARB",
+   "GetnPixelMapusvARB",
+   "GetnPolygonStippleARB",
+   "GetnSeparableFilterARB",
+   "GetnTexImageARB",
+   "GetnUniformdvARB",
+   "GetnUniformfvARB",
+   "GetnUniformivARB",
+   "GetnUniformuivARB",
+   "GetObjectLabel",
+   "GetObjectParameterfvARB",
+   "GetObjectParameterivARB",
+   "GetObjectPtrLabel",
+   "GetPixelMapfv",
+   "GetPixelMapuiv",
+   "GetPixelMapusv",
+   "GetPointerv",
+   "GetPointervEXT",
+   "GetPolygonStipple",
+   "GetProgramBinary",
+   "GetProgramEnvParameterdvARB",
+   "GetProgramEnvParameterfvARB",
+   "GetProgramInfoLog",
+   "GetProgramiv",
+   "GetProgramivARB",
+   "GetProgramLocalParameterdvARB",
+   "GetProgramLocalParameterfvARB",
+   "GetProgramStringARB",
+   "GetQueryIndexediv",
+   "GetQueryiv",
+   "GetQueryivARB",
+   "GetQueryObjectiv",
+   "GetQueryObjectivARB",
+   "GetQueryObjectuiv",
+   "GetQueryObjectuivARB",
+   "GetRenderbufferParameteriv",
+   "GetRenderbufferParameterivEXT",
+   "GetSamplerParameterfv",
+   "GetSamplerParameterIiv",
+   "GetSamplerParameterIuiv",
+   "GetSamplerParameteriv",
+   "GetSeparableFilter",
+   "GetShaderInfoLog",
+   "GetShaderiv",
+   "GetShaderPrecisionFormat",
+   "GetShaderSource",
+   "GetShaderSourceARB",
+   "GetString",
+   "GetStringi",
+   "GetSynciv",
+   "GetTexEnvfv",
+   "GetTexEnviv",
+   "GetTexEnvxv",
+   "GetTexGendv",
+   "GetTexGenfv",
+   "GetTexGeniv",
+   "GetTexImage",
+   "GetTexLevelParameterfv",
+   "GetTexLevelParameteriv",
+   "GetTexParameterfv",
+   "GetTexParameterIiv",
+   "GetTexParameterIivEXT",
+   "GetTexParameterIuiv",
+   "GetTexParameterIuivEXT",
+   "GetTexParameteriv",
+   "GetTexParameterxv",
+   "GetTransformFeedbackVarying",
+   "GetUniformBlockIndex",
+   "GetUniformfv",
+   "GetUniformfvARB",
+   "GetUniformIndices",
+   "GetUniformiv",
+   "GetUniformivARB",
+   "GetUniformLocation",
+   "GetUniformLocationARB",
+   "GetUniformuiv",
+   "GetUniformuivEXT",
+   "GetVertexAttribdv",
+   "GetVertexAttribdvARB",
+   "GetVertexAttribfv",
+   "GetVertexAttribfvARB",
+   "GetVertexAttribIiv",
+   "GetVertexAttribIivEXT",
+   "GetVertexAttribIuiv",
+   "GetVertexAttribIuivEXT",
+   "GetVertexAttribiv",
+   "GetVertexAttribivARB",
+   "GetVertexAttribPointerv",
+   "GetVertexAttribPointervARB",
+   "Hint",
+   "Histogram",
+   "Indexd",
+   "Indexdv",
+   "Indexf",
+   "Indexfv",
+   "Indexi",
+   "Indexiv",
+   "IndexMask",
+   "IndexPointer",
+   "IndexPointerEXT",
+   "Indexs",
+   "Indexsv",
+   "Indexub",
+   "Indexubv",
+   "InitNames",
+   "InterleavedArrays",
+   "InvalidateBufferData",
+   "InvalidateBufferSubData",
+   "InvalidateFramebuffer",
+   "InvalidateSubFramebuffer",
+   "InvalidateTexImage",
+   "InvalidateTexSubImage",
+   "IsBuffer",
+   "IsBufferARB",
+   "IsEnabled",
+   "IsEnabledi",
+   "IsEnabledIndexedEXT",
+   "IsFramebuffer",
+   "IsFramebufferEXT",
+   "IsList",
+   "IsProgram",
+   "IsProgramARB",
+   "IsQuery",
+   "IsQueryARB",
+   "IsRenderbuffer",
+   "IsRenderbufferEXT",
+   "IsSampler",
+   "IsShader",
+   "IsSync",
+   "IsTexture",
+   "IsTextureEXT",
+   "IsTransformFeedback",
+   "IsVertexArray",
+   "Lightf",
+   "Lightfv",
+   "Lighti",
+   "Lightiv",
+   "LightModelf",
+   "LightModelfv",
+   "LightModeli",
+   "LightModeliv",
+   "LightModelx",
+   "LightModelxv",
+   "Lightx",
+   "Lightxv",
+   "LineStipple",
+   "LineWidth",
+   "LineWidthx",
+   "LinkProgram",
+   "LinkProgramARB",
+   "ListBase",
+   "LoadIdentity",
+   "LoadMatrixd",
+   "LoadMatrixf",
+   "LoadMatrixx",
+   "LoadName",
+   "LoadTransposeMatrixd",
+   "LoadTransposeMatrixdARB",
+   "LoadTransposeMatrixf",
+   "LoadTransposeMatrixfARB",
+   "LockArraysEXT",
+   "LogicOp",
+   "Map1d",
+   "Map1f",
+   "Map2d",
+   "Map2f",
+   "MapBuffer",
+   "MapBufferARB",
+   "MapBufferRange",
+   "MapGrid1d",
+   "MapGrid1f",
+   "MapGrid2d",
+   "MapGrid2f",
+   "Materialf",
+   "Materialfv",
+   "Materiali",
+   "Materialiv",
+   "Materialx",
+   "Materialxv",
+   "MatrixMode",
+   "MemoryBarrier",
+   "Minmax",
+   "MinSampleShading",
+   "MinSampleShadingARB",
+   "MultiDrawArrays",
+   "MultiDrawArraysEXT",
+   "MultiDrawArraysIndirect",
+   "MultiDrawElements",
+   "MultiDrawElementsBaseVertex",
+   "MultiDrawElementsEXT",
+   "MultiDrawElementsIndirect",
+   "MultiTexCoord1d",
+   "MultiTexCoord1dARB",
+   "MultiTexCoord1dv",
+   "MultiTexCoord1dvARB",
+   "MultiTexCoord1f",
+   "MultiTexCoord1fARB",
+   "MultiTexCoord1fv",
+   "MultiTexCoord1fvARB",
+   "MultiTexCoord1i",
+   "MultiTexCoord1iARB",
+   "MultiTexCoord1iv",
+   "MultiTexCoord1ivARB",
+   "MultiTexCoord1s",
+   "MultiTexCoord1sARB",
+   "MultiTexCoord1sv",
+   "MultiTexCoord1svARB",
+   "MultiTexCoord2d",
+   "MultiTexCoord2dARB",
+   "MultiTexCoord2dv",
+   "MultiTexCoord2dvARB",
+   "MultiTexCoord2f",
+   "MultiTexCoord2fARB",
+   "MultiTexCoord2fv",
+   "MultiTexCoord2fvARB",
+   "MultiTexCoord2i",
+   "MultiTexCoord2iARB",
+   "MultiTexCoord2iv",
+   "MultiTexCoord2ivARB",
+   "MultiTexCoord2s",
+   "MultiTexCoord2sARB",
+   "MultiTexCoord2sv",
+   "MultiTexCoord2svARB",
+   "MultiTexCoord3d",
+   "MultiTexCoord3dARB",
+   "MultiTexCoord3dv",
+   "MultiTexCoord3dvARB",
+   "MultiTexCoord3f",
+   "MultiTexCoord3fARB",
+   "MultiTexCoord3fv",
+   "MultiTexCoord3fvARB",
+   "MultiTexCoord3i",
+   "MultiTexCoord3iARB",
+   "MultiTexCoord3iv",
+   "MultiTexCoord3ivARB",
+   "MultiTexCoord3s",
+   "MultiTexCoord3sARB",
+   "MultiTexCoord3sv",
+   "MultiTexCoord3svARB",
+   "MultiTexCoord4d",
+   "MultiTexCoord4dARB",
+   "MultiTexCoord4dv",
+   "MultiTexCoord4dvARB",
+   "MultiTexCoord4f",
+   "MultiTexCoord4fARB",
+   "MultiTexCoord4fv",
+   "MultiTexCoord4fvARB",
+   "MultiTexCoord4i",
+   "MultiTexCoord4iARB",
+   "MultiTexCoord4iv",
+   "MultiTexCoord4ivARB",
+   "MultiTexCoord4s",
+   "MultiTexCoord4sARB",
+   "MultiTexCoord4sv",
+   "MultiTexCoord4svARB",
+   "MultiTexCoord4x",
+   "MultiTexCoordP1ui",
+   "MultiTexCoordP1uiv",
+   "MultiTexCoordP2ui",
+   "MultiTexCoordP2uiv",
+   "MultiTexCoordP3ui",
+   "MultiTexCoordP3uiv",
+   "MultiTexCoordP4ui",
+   "MultiTexCoordP4uiv",
+   "MultMatrixd",
+   "MultMatrixf",
+   "MultMatrixx",
+   "MultTransposeMatrixd",
+   "MultTransposeMatrixdARB",
+   "MultTransposeMatrixf",
+   "MultTransposeMatrixfARB",
+   "NewList",
+   "Normal3b",
+   "Normal3bv",
+   "Normal3d",
+   "Normal3dv",
+   "Normal3f",
+   "Normal3fv",
+   "Normal3i",
+   "Normal3iv",
+   "Normal3s",
+   "Normal3sv",
+   "Normal3x",
+   "NormalP3ui",
+   "NormalP3uiv",
+   "NormalPointer",
+   "NormalPointerEXT",
+   "ObjectLabel",
+   "ObjectPtrLabel",
+   "Ortho",
+   "Orthof",
+   "Orthox",
+   "PassThrough",
+   "PauseTransformFeedback",
+   "PixelMapfv",
+   "PixelMapuiv",
+   "PixelMapusv",
+   "PixelStoref",
+   "PixelStorei",
+   "PixelTransferf",
+   "PixelTransferi",
+   "PixelZoom",
+   "PointParameterf",
+   "PointParameterfARB",
+   "PointParameterfEXT",
+   "PointParameterfv",
+   "PointParameterfvARB",
+   "PointParameterfvEXT",
+   "PointParameteri",
+   "PointParameteriv",
+   "PointParameterx",
+   "PointParameterxv",
+   "PointSize",
+   "PointSizePointerOES",
+   "PointSizex",
+   "PolygonMode",
+   "PolygonOffset",
+   "PolygonOffsetx",
+   "PolygonStipple",
+   "PopAttrib",
+   "PopClientAttrib",
+   "PopDebugGroup",
+   "PopMatrix",
+   "PopName",
+   "PrimitiveRestartIndex",
+   "PrimitiveRestartIndexNV",
+   "PrimitiveRestartNV",
+   "PrioritizeTextures",
+   "PrioritizeTexturesEXT",
+   "ProgramBinary",
+   "ProgramEnvParameter4dARB",
+   "ProgramEnvParameter4dvARB",
+   "ProgramEnvParameter4fARB",
+   "ProgramEnvParameter4fvARB",
+   "ProgramLocalParameter4dARB",
+   "ProgramLocalParameter4dvARB",
+   "ProgramLocalParameter4fARB",
+   "ProgramLocalParameter4fvARB",
+   "ProgramParameteri",
+   "ProgramParameteriARB",
+   "ProgramStringARB",
+   "ProvokingVertex",
+   "ProvokingVertexEXT",
+   "PushAttrib",
+   "PushClientAttrib",
+   "PushDebugGroup",
+   "PushMatrix",
+   "PushName",
+   "RasterPos2d",
+   "RasterPos2dv",
+   "RasterPos2f",
+   "RasterPos2fv",
+   "RasterPos2i",
+   "RasterPos2iv",
+   "RasterPos2s",
+   "RasterPos2sv",
+   "RasterPos3d",
+   "RasterPos3dv",
+   "RasterPos3f",
+   "RasterPos3fv",
+   "RasterPos3i",
+   "RasterPos3iv",
+   "RasterPos3s",
+   "RasterPos3sv",
+   "RasterPos4d",
+   "RasterPos4dv",
+   "RasterPos4f",
+   "RasterPos4fv",
+   "RasterPos4i",
+   "RasterPos4iv",
+   "RasterPos4s",
+   "RasterPos4sv",
+   "ReadBuffer",
+   "ReadnPixelsARB",
+   "ReadPixels",
+   "Rectd",
+   "Rectdv",
+   "Rectf",
+   "Rectfv",
+   "Recti",
+   "Rectiv",
+   "Rects",
+   "Rectsv",
+   "ReleaseShaderCompiler",
+   "RenderbufferStorage",
+   "RenderbufferStorageEXT",
+   "RenderbufferStorageMultisample",
+   "RenderbufferStorageMultisampleEXT",
+   "RenderMode",
+   "ResetHistogram",
+   "ResetMinmax",
+   "ResumeTransformFeedback",
+   "Rotated",
+   "Rotatef",
+   "Rotatex",
+   "SampleCoverage",
+   "SampleCoverageARB",
+   "SampleCoveragex",
+   "SampleMaski",
+   "SamplerParameterf",
+   "SamplerParameterfv",
+   "SamplerParameteri",
+   "SamplerParameterIiv",
+   "SamplerParameterIuiv",
+   "SamplerParameteriv",
+   "Scaled",
+   "Scalef",
+   "Scalex",
+   "Scissor",
+   "ScissorArrayv",
+   "ScissorIndexed",
+   "ScissorIndexedv",
+   "SecondaryColor3b",
+   "SecondaryColor3bEXT",
+   "SecondaryColor3bv",
+   "SecondaryColor3bvEXT",
+   "SecondaryColor3d",
+   "SecondaryColor3dEXT",
+   "SecondaryColor3dv",
+   "SecondaryColor3dvEXT",
+   "SecondaryColor3f",
+   "SecondaryColor3fEXT",
+   "SecondaryColor3fv",
+   "SecondaryColor3fvEXT",
+   "SecondaryColor3i",
+   "SecondaryColor3iEXT",
+   "SecondaryColor3iv",
+   "SecondaryColor3ivEXT",
+   "SecondaryColor3s",
+   "SecondaryColor3sEXT",
+   "SecondaryColor3sv",
+   "SecondaryColor3svEXT",
+   "SecondaryColor3ub",
+   "SecondaryColor3ubEXT",
+   "SecondaryColor3ubv",
+   "SecondaryColor3ubvEXT",
+   "SecondaryColor3ui",
+   "SecondaryColor3uiEXT",
+   "SecondaryColor3uiv",
+   "SecondaryColor3uivEXT",
+   "SecondaryColor3us",
+   "SecondaryColor3usEXT",
+   "SecondaryColor3usv",
+   "SecondaryColor3usvEXT",
+   "SecondaryColorP3ui",
+   "SecondaryColorP3uiv",
+   "SecondaryColorPointer",
+   "SecondaryColorPointerEXT",
+   "SelectBuffer",
+   "SeparableFilter2D",
+   "ShadeModel",
+   "ShaderBinary",
+   "ShaderSource",
+   "ShaderSourceARB",
+   "StencilFunc",
+   "StencilFuncSeparate",
+   "StencilMask",
+   "StencilMaskSeparate",
+   "StencilOp",
+   "StencilOpSeparate",
+   "TexBuffer",
+   "TexBufferARB",
+   "TexBufferRange",
+   "TexCoord1d",
+   "TexCoord1dv",
+   "TexCoord1f",
+   "TexCoord1fv",
+   "TexCoord1i",
+   "TexCoord1iv",
+   "TexCoord1s",
+   "TexCoord1sv",
+   "TexCoord2d",
+   "TexCoord2dv",
+   "TexCoord2f",
+   "TexCoord2fv",
+   "TexCoord2i",
+   "TexCoord2iv",
+   "TexCoord2s",
+   "TexCoord2sv",
+   "TexCoord3d",
+   "TexCoord3dv",
+   "TexCoord3f",
+   "TexCoord3fv",
+   "TexCoord3i",
+   "TexCoord3iv",
+   "TexCoord3s",
+   "TexCoord3sv",
+   "TexCoord4d",
+   "TexCoord4dv",
+   "TexCoord4f",
+   "TexCoord4fv",
+   "TexCoord4i",
+   "TexCoord4iv",
+   "TexCoord4s",
+   "TexCoord4sv",
+   "TexCoordP1ui",
+   "TexCoordP1uiv",
+   "TexCoordP2ui",
+   "TexCoordP2uiv",
+   "TexCoordP3ui",
+   "TexCoordP3uiv",
+   "TexCoordP4ui",
+   "TexCoordP4uiv",
+   "TexCoordPointer",
+   "TexCoordPointerEXT",
+   "TexEnvf",
+   "TexEnvfv",
+   "TexEnvi",
+   "TexEnviv",
+   "TexEnvx",
+   "TexEnvxv",
+   "TexGend",
+   "TexGendv",
+   "TexGenf",
+   "TexGenfv",
+   "TexGeni",
+   "TexGeniv",
+   "TexImage1D",
+   "TexImage2D",
+   "TexImage2DMultisample",
+   "TexImage3D",
+   "TexImage3DEXT",
+   "TexImage3DMultisample",
+   "TexParameterf",
+   "TexParameterfv",
+   "TexParameteri",
+   "TexParameterIiv",
+   "TexParameterIivEXT",
+   "TexParameterIuiv",
+   "TexParameterIuivEXT",
+   "TexParameteriv",
+   "TexParameterx",
+   "TexParameterxv",
+   "TexStorage1D",
+   "TexStorage2D",
+   "TexStorage2DMultisample",
+   "TexStorage3D",
+   "TexStorage3DMultisample",
+   "TexSubImage1D",
+   "TexSubImage2D",
+   "TexSubImage3D",
+   "TexSubImage3DEXT",
+   "TextureBarrierNV",
+   "TextureStorage1DEXT",
+   "TextureStorage2DEXT",
+   "TextureStorage3DEXT",
+   "TextureView",
+   "TransformFeedbackVaryings",
+   "Translated",
+   "Translatef",
+   "Translatex",
+   "Uniform1f",
+   "Uniform1fARB",
+   "Uniform1fv",
+   "Uniform1fvARB",
+   "Uniform1i",
+   "Uniform1iARB",
+   "Uniform1iv",
+   "Uniform1ivARB",
+   "Uniform1ui",
+   "Uniform1uiEXT",
+   "Uniform1uiv",
+   "Uniform1uivEXT",
+   "Uniform2f",
+   "Uniform2fARB",
+   "Uniform2fv",
+   "Uniform2fvARB",
+   "Uniform2i",
+   "Uniform2iARB",
+   "Uniform2iv",
+   "Uniform2ivARB",
+   "Uniform2ui",
+   "Uniform2uiEXT",
+   "Uniform2uiv",
+   "Uniform2uivEXT",
+   "Uniform3f",
+   "Uniform3fARB",
+   "Uniform3fv",
+   "Uniform3fvARB",
+   "Uniform3i",
+   "Uniform3iARB",
+   "Uniform3iv",
+   "Uniform3ivARB",
+   "Uniform3ui",
+   "Uniform3uiEXT",
+   "Uniform3uiv",
+   "Uniform3uivEXT",
+   "Uniform4f",
+   "Uniform4fARB",
+   "Uniform4fv",
+   "Uniform4fvARB",
+   "Uniform4i",
+   "Uniform4iARB",
+   "Uniform4iv",
+   "Uniform4ivARB",
+   "Uniform4ui",
+   "Uniform4uiEXT",
+   "Uniform4uiv",
+   "Uniform4uivEXT",
+   "UniformBlockBinding",
+   "UniformMatrix2fv",
+   "UniformMatrix2fvARB",
+   "UniformMatrix2x3fv",
+   "UniformMatrix2x4fv",
+   "UniformMatrix3fv",
+   "UniformMatrix3fvARB",
+   "UniformMatrix3x2fv",
+   "UniformMatrix3x4fv",
+   "UniformMatrix4fv",
+   "UniformMatrix4fvARB",
+   "UniformMatrix4x2fv",
+   "UniformMatrix4x3fv",
+   "UnlockArraysEXT",
+   "UnmapBuffer",
+   "UnmapBufferARB",
+   "UseProgram",
+   "UseProgramObjectARB",
+   "ValidateProgram",
+   "ValidateProgramARB",
+   "Vertex2d",
+   "Vertex2dv",
+   "Vertex2f",
+   "Vertex2fv",
+   "Vertex2i",
+   "Vertex2iv",
+   "Vertex2s",
+   "Vertex2sv",
+   "Vertex3d",
+   "Vertex3dv",
+   "Vertex3f",
+   "Vertex3fv",
+   "Vertex3i",
+   "Vertex3iv",
+   "Vertex3s",
+   "Vertex3sv",
+   "Vertex4d",
+   "Vertex4dv",
+   "Vertex4f",
+   "Vertex4fv",
+   "Vertex4i",
+   "Vertex4iv",
+   "Vertex4s",
+   "Vertex4sv",
+   "VertexAttrib1d",
+   "VertexAttrib1dARB",
+   "VertexAttrib1dv",
+   "VertexAttrib1dvARB",
+   "VertexAttrib1f",
+   "VertexAttrib1fARB",
+   "VertexAttrib1fv",
+   "VertexAttrib1fvARB",
+   "VertexAttrib1s",
+   "VertexAttrib1sARB",
+   "VertexAttrib1sv",
+   "VertexAttrib1svARB",
+   "VertexAttrib2d",
+   "VertexAttrib2dARB",
+   "VertexAttrib2dv",
+   "VertexAttrib2dvARB",
+   "VertexAttrib2f",
+   "VertexAttrib2fARB",
+   "VertexAttrib2fv",
+   "VertexAttrib2fvARB",
+   "VertexAttrib2s",
+   "VertexAttrib2sARB",
+   "VertexAttrib2sv",
+   "VertexAttrib2svARB",
+   "VertexAttrib3d",
+   "VertexAttrib3dARB",
+   "VertexAttrib3dv",
+   "VertexAttrib3dvARB",
+   "VertexAttrib3f",
+   "VertexAttrib3fARB",
+   "VertexAttrib3fv",
+   "VertexAttrib3fvARB",
+   "VertexAttrib3s",
+   "VertexAttrib3sARB",
+   "VertexAttrib3sv",
+   "VertexAttrib3svARB",
+   "VertexAttrib4bv",
+   "VertexAttrib4bvARB",
+   "VertexAttrib4d",
+   "VertexAttrib4dARB",
+   "VertexAttrib4dv",
+   "VertexAttrib4dvARB",
+   "VertexAttrib4f",
+   "VertexAttrib4fARB",
+   "VertexAttrib4fv",
+   "VertexAttrib4fvARB",
+   "VertexAttrib4iv",
+   "VertexAttrib4ivARB",
+   "VertexAttrib4Nbv",
+   "VertexAttrib4NbvARB",
+   "VertexAttrib4Niv",
+   "VertexAttrib4NivARB",
+   "VertexAttrib4Nsv",
+   "VertexAttrib4NsvARB",
+   "VertexAttrib4Nub",
+   "VertexAttrib4NubARB",
+   "VertexAttrib4Nubv",
+   "VertexAttrib4NubvARB",
+   "VertexAttrib4Nuiv",
+   "VertexAttrib4NuivARB",
+   "VertexAttrib4Nusv",
+   "VertexAttrib4NusvARB",
+   "VertexAttrib4s",
+   "VertexAttrib4sARB",
+   "VertexAttrib4sv",
+   "VertexAttrib4svARB",
+   "VertexAttrib4ubv",
+   "VertexAttrib4ubvARB",
+   "VertexAttrib4uiv",
+   "VertexAttrib4uivARB",
+   "VertexAttrib4usv",
+   "VertexAttrib4usvARB",
+   "VertexAttribBinding",
+   "VertexAttribDivisor",
+   "VertexAttribDivisorARB",
+   "VertexAttribFormat",
+   "VertexAttribI1i",
+   "VertexAttribI1iEXT",
+   "VertexAttribI1iv",
+   "VertexAttribI1ivEXT",
+   "VertexAttribI1ui",
+   "VertexAttribI1uiEXT",
+   "VertexAttribI1uiv",
+   "VertexAttribI1uivEXT",
+   "VertexAttribI2i",
+   "VertexAttribI2iEXT",
+   "VertexAttribI2iv",
+   "VertexAttribI2ivEXT",
+   "VertexAttribI2ui",
+   "VertexAttribI2uiEXT",
+   "VertexAttribI2uiv",
+   "VertexAttribI2uivEXT",
+   "VertexAttribI3i",
+   "VertexAttribI3iEXT",
+   "VertexAttribI3iv",
+   "VertexAttribI3ivEXT",
+   "VertexAttribI3ui",
+   "VertexAttribI3uiEXT",
+   "VertexAttribI3uiv",
+   "VertexAttribI3uivEXT",
+   "VertexAttribI4bv",
+   "VertexAttribI4bvEXT",
+   "VertexAttribI4i",
+   "VertexAttribI4iEXT",
+   "VertexAttribI4iv",
+   "VertexAttribI4ivEXT",
+   "VertexAttribI4sv",
+   "VertexAttribI4svEXT",
+   "VertexAttribI4ubv",
+   "VertexAttribI4ubvEXT",
+   "VertexAttribI4ui",
+   "VertexAttribI4uiEXT",
+   "VertexAttribI4uiv",
+   "VertexAttribI4uivEXT",
+   "VertexAttribI4usv",
+   "VertexAttribI4usvEXT",
+   "VertexAttribIFormat",
+   "VertexAttribIPointer",
+   "VertexAttribIPointerEXT",
+   "VertexAttribLFormat",
+   "VertexAttribP1ui",
+   "VertexAttribP1uiv",
+   "VertexAttribP2ui",
+   "VertexAttribP2uiv",
+   "VertexAttribP3ui",
+   "VertexAttribP3uiv",
+   "VertexAttribP4ui",
+   "VertexAttribP4uiv",
+   "VertexAttribPointer",
+   "VertexAttribPointerARB",
+   "VertexBindingDivisor",
+   "VertexP2ui",
+   "VertexP2uiv",
+   "VertexP3ui",
+   "VertexP3uiv",
+   "VertexP4ui",
+   "VertexP4uiv",
+   "VertexPointer",
+   "VertexPointerEXT",
+   "Viewport",
+   "ViewportArrayv",
+   "ViewportIndexedf",
+   "ViewportIndexedfv",
+   "WaitSync",
+   "WindowPos2d",
+   "WindowPos2dARB",
+   "WindowPos2dv",
+   "WindowPos2dvARB",
+   "WindowPos2f",
+   "WindowPos2fARB",
+   "WindowPos2fv",
+   "WindowPos2fvARB",
+   "WindowPos2i",
+   "WindowPos2iARB",
+   "WindowPos2iv",
+   "WindowPos2ivARB",
+   "WindowPos2s",
+   "WindowPos2sARB",
+   "WindowPos2sv",
+   "WindowPos2svARB",
+   "WindowPos3d",
+   "WindowPos3dARB",
+   "WindowPos3dv",
+   "WindowPos3dvARB",
+   "WindowPos3f",
+   "WindowPos3fARB",
+   "WindowPos3fv",
+   "WindowPos3fvARB",
+   "WindowPos3i",
+   "WindowPos3iARB",
+   "WindowPos3iv",
+   "WindowPos3ivARB",
+   "WindowPos3s",
+   "WindowPos3sARB",
+   "WindowPos3sv",
+   "WindowPos3svARB",
+]
+
+"""Functions that need dispatch slots but are not used
+
+Some of these functions may have GLX protocol support (for
+indirect-rendering).  Other were used in previous versions of Mesa.  They keep
+slots in the dispatch table so that newer versions of libGL can still be used
+with older drivers."""
+unused_functions = [
+    # SGIS_multisample
+    "SampleMaskSGIS",
+    "SamplePatternSGIS",
+
+    # NV_vertex_program
+    "AreProgramsResidentNV",
+    "ExecuteProgramNV",
+    "GetProgramParameterdvNV",
+    "GetProgramParameterfvNV",
+    "GetProgramivNV",
+    "GetProgramStringNV",
+    "GetTrackMatrixivNV",
+    "GetVertexAttribdvNV",
+    "GetVertexAttribfvNV",
+    "GetVertexAttribivNV",
+    "LoadProgramNV",
+    "ProgramParameters4dvNV",
+    "ProgramParameters4fvNV",
+    "RequestResidentProgramsNV",
+    "TrackMatrixNV",
+    "VertexAttribPointerNV",
+
+    # MESA_resize_buffers
+    "ResizeBuffersMESA",
+
+    # ATI_envmap_bumpmap
+    "TexBumpParameterfvATI",
+    "TexBumpParameterivATI",
+    "GetTexBumpParameterfvATI",
+    "GetTexBumpParameterivATI",
+
+    # NV_fragment_program
+    "ProgramNamedParameter4fNV",
+    "ProgramNamedParameter4dNV",
+    "ProgramNamedParameter4fvNV",
+    "ProgramNamedParameter4dvNV",
+    "GetProgramNamedParameterfvNV",
+    "GetProgramNamedParameterdvNV",
+
+    # APPLE_flush_buffer_range
+    "BufferParameteriAPPLE",
+    "FlushMappedBufferRangeAPPLE",
+
+    # EXT_separate_shader_objects
+    "UseShaderProgramEXT",
+    "ActiveProgramEXT",
+    "CreateShaderProgramEXT",
+]
index 50f710edc8af82e59594c01919ad68b074e6a3b0..337913acc711c2b276039861e1d305e0fcc90306 100644 (file)
@@ -49,6 +49,10 @@ typedef void *GLeglImageOES;
 #include "glapi/glapi.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* getproc */
 
 extern void
@@ -106,4 +110,8 @@ get_entrypoint_address(unsigned int functionOffset);
 #define MAX_EXTENSION_FUNCS 256
 
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index 5d759df76d9ee05fcdb43fc5c4dd13f6df359023..09bf4f3585c29b382e4cfca2e8239baf9e7e173c 100644 (file)
@@ -1137,7 +1137,6 @@ const struct name_offset known_dispatch[] = {
    { "glDrawElementsInstancedARB", _O(DrawElementsInstancedARB) },
    { "glRenderbufferStorageMultisample", _O(RenderbufferStorageMultisample) },
    { "glFramebufferTexture", _O(FramebufferTexture) },
-   { "glFramebufferTextureFaceARB", _O(FramebufferTextureFaceARB) },
    { "glProgramParameteri", _O(ProgramParameteri) },
    { "glVertexAttribDivisor", _O(VertexAttribDivisor) },
    { "glFlushMappedBufferRange", _O(FlushMappedBufferRange) },
index cc979547e0a5eae45c3740d70f81ef30a440d041..145f2594cda908f8fb3b7329c933a90c90beda08 100644 (file)
@@ -115,9 +115,11 @@ $(intermediates)/main/api_exec.c: $(dispatch_deps)
 
 GET_HASH_GEN := $(LOCAL_PATH)/main/get_hash_generator.py
 
+$(intermediates)/main/get_hash.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(GET_HASH_GEN)
+$(intermediates)/main/get_hash.h: PRIVATE_XML := -f $(glapi)/gl_and_es_API.xml
 $(intermediates)/main/get_hash.h: $(glapi)/gl_and_es_API.xml \
                $(LOCAL_PATH)/main/get_hash_params.py $(GET_HASH_GEN)
-       @$(MESA_PYTHON2) $(GET_HASH_GEN) -f $< > $@
+       $(call es-gen)
 
 FORMAT_INFO := $(LOCAL_PATH)/main/format_info.py
 format_info_deps := \
@@ -125,8 +127,10 @@ format_info_deps := \
        $(LOCAL_PATH)/main/format_parser.py \
        $(FORMAT_INFO)
 
+$(intermediates)/main/format_info.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(FORMAT_INFO)
+$(intermediates)/main/format_info.h: PRIVATE_XML :=
 $(intermediates)/main/format_info.h: $(format_info_deps)
-       @$(MESA_PYTHON2) $(FORMAT_INFO) $< > $@
+       $(call es-gen, $<)
 
 FORMAT_PACK := $(LOCAL_PATH)/main/format_pack.py
 format_pack_deps := \
@@ -134,8 +138,10 @@ format_pack_deps := \
        $(LOCAL_PATH)/main/format_parser.py \
        $(FORMAT_PACK)
 
+$(intermediates)/main/format_pack.c: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(FORMAT_PACK)
+$(intermediates)/main/format_pack.c: PRIVATE_XML :=
 $(intermediates)/main/format_pack.c: $(format_pack_deps)
-       $(hide) $(MESA_PYTHON2) $(FORMAT_PACK) $< > $@
+       $(call es-gen, $<)
 
 FORMAT_UNPACK := $(LOCAL_PATH)/main/format_unpack.py
 format_unpack_deps := \
@@ -143,5 +149,7 @@ format_unpack_deps := \
        $(LOCAL_PATH)/main/format_parser.py \
        $(FORMAT_UNPACK)
 
+$(intermediates)/main/format_unpack.c: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(FORMAT_UNPACK)
+$(intermediates)/main/format_unpack.c: PRIVATE_XML :=
 $(intermediates)/main/format_unpack.c: $(format_unpack_deps)
-       $(hide) $(MESA_PYTHON2) $(FORMAT_UNPACK) $< > $@
+       $(call es-gen, $<)
index 3497377af8c8b17f781060d59f569b55c1d09685..ed620ac648cfa25361f061b05dcd758c514e6364 100644 (file)
@@ -44,7 +44,8 @@ LOCAL_C_INCLUDES := \
 LOCAL_SRC_FILES := \
        main/imports.c \
        program/prog_hash_table.c \
-       program/symbol_table.c
+       program/symbol_table.c \
+       program/dummy_errors.c
 
 include $(MESA_COMMON_MK)
 include $(BUILD_STATIC_LIBRARY)
@@ -68,7 +69,8 @@ LOCAL_C_INCLUDES := \
 LOCAL_SRC_FILES := \
        main/imports.c \
        program/prog_hash_table.c \
-       program/symbol_table.c
+       program/symbol_table.c \
+       program/dummy_errors.c
 
 include $(MESA_COMMON_MK)
 include $(BUILD_HOST_STATIC_LIBRARY)
index 60114e4f66a89809cade5bec85a9ff4317d0f85e..71794b5dada199f66b4ef3dd27d73843cfc44d16 100644 (file)
@@ -60,7 +60,6 @@ main/git_sha1.h: main/git_sha1.h.tmp
 include Makefile.sources
 
 EXTRA_DIST = \
-       drivers/haiku \
        drivers/SConscript \
        main/format_info.py \
        main/format_pack.py \
index db656780c0b848f292a059e717fa66d428501602..5d654f538bec4e8368c9e58e1c9392e2d94d3a56 100644 (file)
@@ -8,6 +8,3 @@ if env['dri']:
         'dri/common/xmlpool/SConscript',
         'dri/common/SConscript',
     ])
-
-if env['platform'] == 'haiku':
-    SConscript('haiku/swrast/SConscript')
index 0d094ddf4e60457f90d6c33963a42556c39ec817..71c1a763912f2f4093d7d9234b7a18b69b951663 100644 (file)
@@ -172,7 +172,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->UnmapRenderbuffer = _swrast_unmap_soft_renderbuffer;
    driver->RenderTexture = _swrast_render_texture;
    driver->FinishRenderTexture = _swrast_finish_render_texture;
-   driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
+   driver->FramebufferRenderbuffer = _mesa_FramebufferRenderbuffer_sw;
    driver->ValidateFramebuffer = _mesa_validate_framebuffer;
 
    driver->BlitFramebuffer = _swrast_BlitFramebuffer;
index d2ab7b8ded9ea764841d9b6c1fbeec02372fc0e6..214a68a9129b72dc3c7e4a3c313a93964b83784f 100644 (file)
@@ -1211,7 +1211,8 @@ _mesa_meta_end(struct gl_context *ctx)
       _mesa_BindRenderbuffer(GL_RENDERBUFFER, save->RenderbufferName);
 
    if (state & MESA_META_DRAW_BUFFERS) {
-      _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, save->ColorDrawBuffers, NULL);
+      _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers,
+                        save->ColorDrawBuffers, NULL);
    }
 
    ctx->Meta->SaveStackDepth--;
index bb2164276b2c98f63018ab7bdf0425cd9124ae7e..9cace2b245afbbb3c336e6e66d9782b8c577f5ea 100644 (file)
@@ -82,7 +82,7 @@ setup_glsl_msaa_blit_scaled_shader(struct gl_context *ctx,
    y_scale = samples * 0.5;
 
    /* We expect only power of 2 samples in source multisample buffer. */
-   assert(samples > 0 && (samples & (samples - 1)) == 0);
+   assert(samples > 0 && is_power_of_two(samples));
    while (samples >> (shader_offset + 1)) {
       shader_offset++;
    }
@@ -263,7 +263,7 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
    }
 
    /* We expect only power of 2 samples in source multisample buffer. */
-   assert(samples > 0 && (samples & (samples - 1)) == 0);
+   assert(samples > 0 && is_power_of_two(samples));
    while (samples >> (shader_offset + 1)) {
       shader_offset++;
    }
@@ -434,7 +434,7 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
           * (so the floating point exponent just gets increased), rather than
           * doing a naive sum and dividing.
           */
-         assert((samples & (samples - 1)) == 0);
+         assert(is_power_of_two(samples));
          /* Fetch each individual sample. */
          sample_resolve = rzalloc_size(mem_ctx, 1);
          for (i = 0; i < samples; i++) {
index ad6e7873ecd1f3c8299435718e204f4f8f8766c9..d2474f52718d96b58fd3960a2d9bd7e2dbea1866 100644 (file)
@@ -34,6 +34,7 @@
 #include "macros.h"
 #include "meta.h"
 #include "pbo.h"
+#include "readpix.h"
 #include "shaderapi.h"
 #include "state.h"
 #include "teximage.h"
@@ -150,7 +151,8 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
    bool success = false;
    int z;
 
-   if (!_mesa_is_bufferobj(packing->BufferObj) && !create_pbo)
+   if (!_mesa_is_bufferobj(packing->BufferObj) &&
+       (!create_pbo || pixels == NULL))
       return false;
 
    if (format == GL_DEPTH_COMPONENT ||
@@ -257,6 +259,7 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
    GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
    int full_height, image_height;
    struct gl_texture_image *pbo_tex_image;
+   struct gl_renderbuffer *rb = NULL;
    GLenum status;
    bool success = false;
    int z;
@@ -273,6 +276,13 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
    if (ctx->_ImageTransferState)
       return false;
 
+
+   if (!tex_image) {
+      rb = ctx->ReadBuffer->_ColorReadBuffer;
+      if (_mesa_need_rgb_to_luminance_conversion(rb->Format, format))
+         return false;
+   }
+
    /* For arrays, use a tall (height * depth) 2D texture but taking into
     * account the inter-image padding specified with the image height packing
     * property.
index fa1de103b56fe213ce2ea65d3436febb73f3d883..08a8e6455219da5b9cf53557d83fc4143aed9331 100644 (file)
@@ -60,6 +60,7 @@ mesa_dri_drivers_la_LIBADD = \
         ../../libmesa.la \
         common/libmegadriver_stub.la \
         common/libdricommon.la \
+        common/libxmlconfig.la \
         $(MEGADRIVERS_DEPS) \
         $(DRI_LIB_DEPS) \
         $()
index a7fcd6d572a78c3d602d29e4020659dcd82df59a..6986f5e8cb4577f10942382d69c32032dbb8e476 100644 (file)
@@ -39,7 +39,9 @@ intermediates := $(call local-generated-sources-dir)
 LOCAL_C_INCLUDES := \
     $(MESA_DRI_C_INCLUDES)
 
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(intermediates)
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH) \
+    $(intermediates)
 
 # swrast only
 ifeq ($(MESA_GPU_DRIVERS),swrast)
@@ -48,7 +50,9 @@ else
 LOCAL_SHARED_LIBRARIES := libdrm
 endif
 
-LOCAL_SRC_FILES := $(DRI_COMMON_FILES)
+LOCAL_SRC_FILES := \
+       $(DRI_COMMON_FILES) \
+       $(XMLCONFIG_FILES)
 
 MESA_DRI_OPTIONS_H := $(intermediates)/xmlpool/options.h
 LOCAL_GENERATED_SOURCES := $(MESA_DRI_OPTIONS_H)
index da8f97a980e21a9dddca8f2d596b35ee0ec2f37d..ae19fcb356593861ca2614ca4036c6602430d32a 100644 (file)
@@ -33,16 +33,20 @@ AM_CFLAGS = \
        -I$(top_srcdir)/src/gallium/include \
        -I$(top_srcdir)/src/gallium/auxiliary \
        $(DEFINES) \
-       $(EXPAT_CFLAGS) \
        $(VISIBILITY_CFLAGS)
 
 noinst_LTLIBRARIES = \
        libdricommon.la \
+       libxmlconfig.la \
        libmegadriver_stub.la \
        libdri_test_stubs.la
 
 libdricommon_la_SOURCES = $(DRI_COMMON_FILES)
 
+libxmlconfig_la_SOURCES = $(XMLCONFIG_FILES)
+libxmlconfig_la_CFLAGS = $(AM_CFLAGS) $(EXPAT_CFLAGS)
+libxmlconfig_la_LIBADD = $(EXPAT_LIBS) -lm
+
 libdri_test_stubs_la_SOURCES = $(test_stubs_FILES)
 libdri_test_stubs_la_CFLAGS = $(AM_CFLAGS) -DNO_MAIN
 
index d00ec5f7334aa5115e8afafa84916c9c00f626bd..d5d8da8fceed2021d07bf909d9d78ff68475018c 100644 (file)
@@ -2,7 +2,9 @@ DRI_COMMON_FILES := \
        utils.c \
        utils.h \
        dri_util.c \
-       dri_util.h \
+       dri_util.h
+
+XMLCONFIG_FILES := \
        xmlconfig.c \
        xmlconfig.h
 
index 0bee1b41fc6f86f87e847e4838d413efd8d3e039..b402736db691dbb5e42c23ddc9cacc5e78a270ed 100644 (file)
@@ -37,7 +37,7 @@ drienv.PkgUseModules('DRM')
 # else
 #env.Append(CPPDEFINES = ['__NOT_HAVE_DRM_H'])
 
-sources = drienv.ParseSourceList('Makefile.sources', 'DRI_COMMON_FILES')
+sources = drienv.ParseSourceList('Makefile.sources', ['DRI_COMMON_FILES', 'XMLCONFIG_FILES' ])
 
 dri_common = drienv.ConvenienceLibrary(
        target = 'dri_common',
index d6e875fcfeb968aeadb9873574f0371bd449132c..e7ababe0b6775a7228d6c4c2f4085e54aa6d36a1 100644 (file)
@@ -162,13 +162,21 @@ driCreateNewScreen2(int scrn, int fd,
        return NULL;
     }
 
-    int gl_version_override = _mesa_get_gl_version_override();
-    if (gl_version_override >= 31) {
-       psp->max_gl_core_version = MAX2(psp->max_gl_core_version,
-                                       gl_version_override);
-    } else {
-       psp->max_gl_compat_version = MAX2(psp->max_gl_compat_version,
-                                         gl_version_override);
+    struct gl_constants consts = { 0 };
+    gl_api api;
+    unsigned version;
+
+    api = API_OPENGLES2;
+    if (_mesa_override_gl_version_contextless(&consts, &api, &version))
+       psp->max_gl_es2_version = version;
+
+    api = API_OPENGL_COMPAT;
+    if (_mesa_override_gl_version_contextless(&consts, &api, &version)) {
+       if (api == API_OPENGL_CORE) {
+          psp->max_gl_core_version = version;
+       } else {
+          psp->max_gl_compat_version = version;
+       }
     }
 
     psp->api_mask = (1 << __DRI_API_OPENGL);
index 91da977aceecc65e0f41d6f599b254092de3a91d..8ed8ff555ba66ea17b574a7d6572026587dc2516 100644 (file)
@@ -730,9 +730,9 @@ i830_update_draw_buffer(struct intel_context *intel)
     */
    if (ctx->NewState & _NEW_BUFFERS) {
       /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
-      _mesa_update_framebuffer(ctx);
+      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
       /* this updates the DrawBuffer's Width/Height if it's a FBO */
-      _mesa_update_draw_buffer_bounds(ctx);
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
    }
 
    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
index 9b002236adda732e2759e1334bda62e3fcceea2a..03c32e56d8274b5e16af041fe32fc9576b96dac0 100644 (file)
@@ -220,7 +220,7 @@ get_result_flags(const struct prog_instruction *inst)
 {
    GLuint flags = 0;
 
-   if (inst->SaturateMode == SATURATE_ZERO_ONE)
+   if (inst->Saturate)
       flags |= A0_DEST_SATURATE;
    if (inst->DstReg.WriteMask & WRITEMASK_X)
       flags |= A0_DEST_CHANNEL_X;
index 97bf81ed7594db027e34eb71a5dee652f33af9b1..80bd249fa7b85a99c5e86822d91d44050d885f81 100644 (file)
@@ -732,9 +732,9 @@ i915_update_draw_buffer(struct intel_context *intel)
     */
    if (ctx->NewState & _NEW_BUFFERS) {
       /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
-      _mesa_update_framebuffer(ctx);
+      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
       /* this updates the DrawBuffer's Width/Height if it's a FBO */
-      _mesa_update_draw_buffer_bounds(ctx);
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
    }
 
    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
index 24c318049c4073e30c8f25f5ad684f9825f4dcf8..a5d5c5832fb1a2b96cb1a70b30d0e943bfb393a4 100644 (file)
@@ -427,7 +427,7 @@ intel_framebuffer_renderbuffer(struct gl_context * ctx,
 {
    DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
 
-   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+   _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb);
    intel_draw_buffer(ctx);
 }
 
index cf2424e34b411939dcd47535019b445d010ace44..9c947be88a08cbf4db6dd817dc624a8366eb9115 100644 (file)
@@ -48,6 +48,7 @@ libi965_dri_la_LIBADD = $(INTEL_LIBS)
 TEST_LIBS = \
        libi965_dri.la \
        ../common/libdricommon.la \
+       ../common/libxmlconfig.la \
        ../common/libmegadriver_stub.la \
         ../../../libmesa.la \
        $(DRI_LIB_DEPS) \
index 1ae93e1d5f3e3c8942b9c0e5a55026184ebb98ac..981fe79b132f42c99ecda8c8e6a8e15157a80629 100644 (file)
@@ -18,9 +18,11 @@ i965_FILES = \
        brw_clip_unfilled.c \
        brw_clip_util.c \
        brw_compute.c \
+       brw_conditional_render.c \
        brw_context.c \
        brw_context.h \
        brw_cs.cpp \
+       brw_cs.h \
        brw_cubemap_normalize.cpp \
        brw_curbe.c \
        brw_dead_control_flow.cpp \
@@ -40,6 +42,7 @@ i965_FILES = \
        brw_ff_gs.c \
        brw_ff_gs_emit.c \
        brw_ff_gs.h \
+       brw_fs_builder.h \
        brw_fs_channel_expressions.cpp \
        brw_fs_cmod_propagation.cpp \
        brw_fs_combine_constants.cpp \
@@ -47,7 +50,6 @@ i965_FILES = \
        brw_fs.cpp \
        brw_fs_cse.cpp \
        brw_fs_dead_code_eliminate.cpp \
-       brw_fs_fp.cpp \
        brw_fs_generator.cpp \
        brw_fs.h \
        brw_fs_live_variables.cpp \
@@ -128,6 +130,7 @@ i965_FILES = \
        brw_vs.h \
        brw_vs_state.c \
        brw_vs_surface_state.c \
+       brw_vue_map.c \
        brw_wm.c \
        brw_wm.h \
        brw_wm_iz.cpp \
index c1b760920d91fc17859c28b88da002679b9d3fe4..789520c73535214f54d903ecf5711e00f57e2691 100644 (file)
@@ -29,7 +29,8 @@
 brw_blorp_eu_emitter::brw_blorp_eu_emitter(struct brw_context *brw,
                                            bool debug_flag)
    : mem_ctx(ralloc_context(NULL)),
-     generator(brw, mem_ctx, (void *) rzalloc(mem_ctx, struct brw_wm_prog_key),
+     generator(brw->intelScreen->compiler, brw,
+               mem_ctx, (void *) rzalloc(mem_ctx, struct brw_wm_prog_key),
                (struct brw_stage_prog_data *) rzalloc(mem_ctx, struct brw_wm_prog_data),
                NULL, 0, false, "BLORP")
 {
index 7e7770e43cdba1902febb4bb61ce17c785116df9..f1f230e3751b5b73f9f34baa831b75791e769921 100644 (file)
@@ -141,12 +141,12 @@ bblock_t::combine_with(bblock_t *that)
 }
 
 void
-bblock_t::dump(backend_visitor *v) const
+bblock_t::dump(backend_shader *s) const
 {
    int ip = this->start_ip;
    foreach_inst_in_block(backend_instruction, inst, this) {
       fprintf(stderr, "%5d: ", ip);
-      v->dump_instruction(inst);
+      s->dump_instruction(inst);
       ip++;
    }
 }
@@ -231,6 +231,7 @@ cfg_t::cfg_t(exec_list *instructions)
          if (cur_else) {
             cur_else->add_successor(mem_ctx, cur_endif);
          } else {
+            assert(cur_if != NULL);
             cur_if->add_successor(mem_ctx, cur_endif);
          }
 
@@ -299,6 +300,7 @@ cfg_t::cfg_t(exec_list *instructions)
          inst->exec_node::remove();
          cur->instructions.push_tail(inst);
 
+         assert(cur_do != NULL && cur_while != NULL);
         cur->add_successor(mem_ctx, cur_do);
         set_next_block(&cur, cur_while, ip);
 
@@ -411,7 +413,7 @@ cfg_t::make_block_array()
 }
 
 void
-cfg_t::dump(backend_visitor *v)
+cfg_t::dump(backend_shader *s)
 {
    if (idom_dirty)
       calculate_idom();
@@ -423,8 +425,8 @@ cfg_t::dump(backend_visitor *v)
                  link->block->num);
       }
       fprintf(stderr, "\n");
-      if (v != NULL)
-         block->dump(v);
+      if (s != NULL)
+         block->dump(s);
       fprintf(stderr, "END B%d", block->num);
       foreach_list_typed(bblock_link, link, link, &block->children) {
          fprintf(stderr, " ->B%d",
index 56d7d07abdfbccc80a2dea57329c387c8cdda197..a09491781e6015757594c2e2db93666ef9a3841a 100644 (file)
@@ -60,7 +60,7 @@ struct bblock_t {
    bool is_successor_of(const bblock_t *block) const;
    bool can_combine_with(const bblock_t *that) const;
    void combine_with(bblock_t *that);
-   void dump(backend_visitor *v) const;
+   void dump(backend_shader *s) const;
 
    backend_instruction *start();
    const backend_instruction *start() const;
@@ -273,7 +273,7 @@ struct cfg_t {
    void calculate_idom();
    static bblock_t *intersect(bblock_t *b1, bblock_t *b2);
 
-   void dump(backend_visitor *v);
+   void dump(backend_shader *s);
    void dump_cfg();
    void dump_domtree();
 #endif
index 12314204803064b0612080dc0e1d0183731a23bd..1d4ba3cac7e93cb385b34b50f63a2bb8c48027ca 100644 (file)
@@ -121,8 +121,9 @@ brw_fast_clear_depth(struct gl_context *ctx)
     * first.
     */
    if ((ctx->Scissor.EnableFlags & 1) && !noop_scissor(ctx, fb)) {
-      perf_debug("Failed to fast clear depth due to scissor being enabled.  "
-                 "Possible 5%% performance win if avoided.\n");
+      perf_debug("Failed to fast clear %dx%d depth because of scissors.  "
+                 "Possible 5%% performance win if avoided.\n",
+                 mt->logical_width0, mt->logical_height0);
       return false;
    }
 
index 32238341aaeb1625f937c6d86e4042a0418ca3db..dee74dba8afaa936760443f4a4e3c7bb52d9aa6e 100644 (file)
@@ -32,6 +32,7 @@
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
+#include "main/framebuffer.h"
 
 static void
 upload_clip_vp(struct brw_context *brw)
@@ -59,7 +60,9 @@ brw_upload_clip_unit(struct brw_context *brw)
    struct brw_clip_unit_state *clip;
 
    /* _NEW_BUFFERS */
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   const struct gl_framebuffer *fb = ctx->DrawBuffer;
+   const float fb_width = (float)_mesa_geometric_width(fb);
+   const float fb_height = (float)_mesa_geometric_height(fb);
 
    upload_clip_vp(brw);
 
@@ -127,8 +130,8 @@ brw_upload_clip_unit(struct brw_context *brw)
    /* enable guardband clipping if we can */
    if (ctx->ViewportArray[0].X == 0 &&
        ctx->ViewportArray[0].Y == 0 &&
-       ctx->ViewportArray[0].Width == (float) fb->Width &&
-       ctx->ViewportArray[0].Height == (float) fb->Height)
+       ctx->ViewportArray[0].Width == fb_width &&
+       ctx->ViewportArray[0].Height == fb_height)
    {
       clip->clip5.guard_band_enable = 1;
       clip->clip6.clipper_viewport_state_ptr =
index b3d6de51adcc41e7ba0f42d0128a829ee9855cfb..5693ab507d474c788bec3da04850f9477ec503db 100644 (file)
@@ -45,7 +45,7 @@ brw_emit_gpgpu_walker(struct brw_context *brw, const GLuint *num_groups)
    unsigned thread_width_max =
       (group_size + simd_size - 1) / simd_size;
 
-   uint32_t right_mask = (1u << simd_size) - 1;
+   uint32_t right_mask = 0xffffffffu >> (32 - simd_size);
    const unsigned right_non_aligned = group_size & (simd_size - 1);
    if (right_non_aligned != 0)
       right_mask >>= (simd_size - right_non_aligned);
diff --git a/src/mesa/drivers/dri/i965/brw_conditional_render.c b/src/mesa/drivers/dri/i965/brw_conditional_render.c
new file mode 100644 (file)
index 0000000..6d37c3b
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright Â© 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Neil Roberts <neil@linux.intel.com>
+ */
+
+/** @file brw_conditional_render.c
+ *
+ * Support for conditional rendering based on query objects
+ * (GL_NV_conditional_render, GL_ARB_conditional_render_inverted) on Gen7+.
+ */
+
+#include "main/imports.h"
+#include "main/condrender.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "intel_batchbuffer.h"
+
+static void
+set_predicate_enable(struct brw_context *brw,
+                     bool value)
+{
+   if (value)
+      brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
+   else
+      brw->predicate.state = BRW_PREDICATE_STATE_DONT_RENDER;
+}
+
+static void
+set_predicate_for_result(struct brw_context *brw,
+                         struct brw_query_object *query,
+                         bool inverted)
+{
+   int load_op;
+
+   assert(query->bo != NULL);
+
+   brw_load_register_mem64(brw,
+                           MI_PREDICATE_SRC0,
+                           query->bo,
+                           I915_GEM_DOMAIN_INSTRUCTION,
+                           0, /* write domain */
+                           0 /* offset */);
+   brw_load_register_mem64(brw,
+                           MI_PREDICATE_SRC1,
+                           query->bo,
+                           I915_GEM_DOMAIN_INSTRUCTION,
+                           0, /* write domain */
+                           8 /* offset */);
+
+   if (inverted)
+      load_op = MI_PREDICATE_LOADOP_LOAD;
+   else
+      load_op = MI_PREDICATE_LOADOP_LOADINV;
+
+   BEGIN_BATCH(1);
+   OUT_BATCH(GEN7_MI_PREDICATE |
+             load_op |
+             MI_PREDICATE_COMBINEOP_SET |
+             MI_PREDICATE_COMPAREOP_SRCS_EQUAL);
+   ADVANCE_BATCH();
+
+   brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;
+}
+
+static void
+brw_begin_conditional_render(struct gl_context *ctx,
+                             struct gl_query_object *q,
+                             GLenum mode)
+{
+   struct brw_context *brw = brw_context(ctx);
+   struct brw_query_object *query = (struct brw_query_object *) q;
+   bool inverted;
+
+   if (!brw->predicate.supported)
+      return;
+
+   switch (mode) {
+   case GL_QUERY_WAIT:
+   case GL_QUERY_NO_WAIT:
+   case GL_QUERY_BY_REGION_WAIT:
+   case GL_QUERY_BY_REGION_NO_WAIT:
+      inverted = false;
+      break;
+   case GL_QUERY_WAIT_INVERTED:
+   case GL_QUERY_NO_WAIT_INVERTED:
+   case GL_QUERY_BY_REGION_WAIT_INVERTED:
+   case GL_QUERY_BY_REGION_NO_WAIT_INVERTED:
+      inverted = true;
+      break;
+   default:
+      unreachable("Unexpected conditional render mode");
+   }
+
+   /* If there are already samples from a BLT operation or if the query object
+    * is ready then we can avoid looking at the values in the buffer and just
+    * decide whether to draw using the CPU without stalling.
+    */
+   if (query->Base.Result || query->Base.Ready)
+      set_predicate_enable(brw, (query->Base.Result != 0) ^ inverted);
+   else
+      set_predicate_for_result(brw, query, inverted);
+}
+
+static void
+brw_end_conditional_render(struct gl_context *ctx,
+                           struct gl_query_object *q)
+{
+   struct brw_context *brw = brw_context(ctx);
+
+   /* When there is no longer a conditional render in progress it should
+    * always render.
+    */
+   brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
+}
+
+void
+brw_init_conditional_render_functions(struct dd_function_table *functions)
+{
+   functions->BeginConditionalRender = brw_begin_conditional_render;
+   functions->EndConditionalRender = brw_end_conditional_render;
+}
+
+bool
+brw_check_conditional_render(struct brw_context *brw)
+{
+   if (brw->predicate.supported) {
+      /* In some cases it is possible to determine that the primitives should
+       * be skipped without needing the predicate enable bit and still without
+       * stalling.
+       */
+      return brw->predicate.state != BRW_PREDICATE_STATE_DONT_RENDER;
+   } else if (brw->ctx.Query.CondRenderQuery) {
+      perf_debug("Conditional rendering is implemented in software and may "
+                 "stall.\n");
+      return _mesa_check_conditional_render(&brw->ctx);
+   } else {
+      return true;
+   }
+}
index 23838056690fa5a1422cab8c3e803fd3212737c7..ebf12fab69e6f5aacc6065581bbfaa2769533752 100644 (file)
@@ -50,6 +50,7 @@
 
 #include "brw_context.h"
 #include "brw_defines.h"
+#include "brw_shader.h"
 #include "brw_draw.h"
 #include "brw_state.h"
 
@@ -68,8 +69,6 @@
 #include "tnl/t_pipeline.h"
 #include "util/ralloc.h"
 
-#include "glsl/nir/nir.h"
-
 /***************************************
  * Mesa's Driver Functions
  ***************************************/
@@ -289,6 +288,8 @@ brw_init_driver_functions(struct brw_context *brw,
    else
       gen4_init_queryobj_functions(functions);
    brw_init_compute_functions(functions);
+   if (brw->gen >= 7)
+      brw_init_conditional_render_functions(functions);
 
    functions->QuerySamplesForFormat = brw_query_samples_for_format;
 
@@ -427,11 +428,7 @@ brw_initialize_context_constants(struct brw_context *brw)
 
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
-   if (brw->gen >= 9 || brw->is_cherryview) {
-      ctx->Const.MaxLineWidth = 40.0;
-      ctx->Const.MaxLineWidthAA = 40.0;
-      ctx->Const.LineWidthGranularity = 0.125;
-   } else if (brw->gen >= 6) {
+   if (brw->gen >= 6) {
       ctx->Const.MaxLineWidth = 7.375;
       ctx->Const.MaxLineWidthAA = 7.375;
       ctx->Const.LineWidthGranularity = 0.125;
@@ -441,6 +438,13 @@ brw_initialize_context_constants(struct brw_context *brw)
       ctx->Const.LineWidthGranularity = 0.5;
    }
 
+   /* For non-antialiased lines, we have to round the line width to the
+    * nearest whole number. Make sure that we don't advertise a line
+    * width that, when rounded, will be beyond the actual hardware
+    * maximum.
+    */
+   assert(roundf(ctx->Const.MaxLineWidth) <= ctx->Const.MaxLineWidth);
+
    ctx->Const.MinPointSize = 1.0;
    ctx->Const.MinPointSizeAA = 1.0;
    ctx->Const.MaxPointSize = 255.0;
@@ -544,6 +548,7 @@ brw_initialize_context_constants(struct brw_context *brw)
     */
    ctx->Const.UniformBufferOffsetAlignment = 16;
    ctx->Const.TextureBufferOffsetAlignment = 16;
+   ctx->Const.MaxTextureBufferSize = 128 * 1024 * 1024;
 
    if (brw->gen >= 6) {
       ctx->Const.MaxVarying = 32;
@@ -553,51 +558,12 @@ brw_initialize_context_constants(struct brw_context *brw)
       ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 128;
    }
 
-   static const nir_shader_compiler_options nir_options = {
-      .native_integers = true,
-      /* In order to help allow for better CSE at the NIR level we tell NIR
-       * to split all ffma instructions during opt_algebraic and we then
-       * re-combine them as a later step.
-       */
-      .lower_ffma = true,
-      .lower_sub = true,
-   };
-
    /* We want the GLSL compiler to emit code that uses condition codes */
    for (int i = 0; i < MESA_SHADER_STAGES; i++) {
-      ctx->Const.ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
-      ctx->Const.ShaderCompilerOptions[i].EmitCondCodes = true;
-      ctx->Const.ShaderCompilerOptions[i].EmitNoNoise = true;
-      ctx->Const.ShaderCompilerOptions[i].EmitNoMainReturn = true;
-      ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectInput = true;
-      ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectOutput =
-        (i == MESA_SHADER_FRAGMENT);
-      ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectTemp =
-        (i == MESA_SHADER_FRAGMENT);
-      ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectUniform = false;
-      ctx->Const.ShaderCompilerOptions[i].LowerClipDistance = true;
+      ctx->Const.ShaderCompilerOptions[i] =
+         brw->intelScreen->compiler->glsl_compiler_options[i];
    }
 
-   ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
-   ctx->Const.ShaderCompilerOptions[MESA_SHADER_GEOMETRY].OptimizeForAOS = true;
-
-   if (brw->scalar_vs) {
-      /* If we're using the scalar backend for vertex shaders, we need to
-       * configure these accordingly.
-       */
-      ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoIndirectOutput = true;
-      ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoIndirectTemp = true;
-      ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = false;
-
-      if (brw_env_var_as_boolean("INTEL_USE_NIR", true))
-         ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].NirOptions = &nir_options;
-   }
-
-   if (brw_env_var_as_boolean("INTEL_USE_NIR", true))
-      ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions = &nir_options;
-
-   ctx->Const.ShaderCompilerOptions[MESA_SHADER_COMPUTE].NirOptions = &nir_options;
-
    /* ARB_viewport_array */
    if (brw->gen >= 6 && ctx->API == API_OPENGL_CORE) {
       ctx->Const.MaxViewports = GEN6_NUM_VIEWPORTS;
@@ -612,6 +578,12 @@ brw_initialize_context_constants(struct brw_context *brw)
    /* ARB_gpu_shader5 */
    if (brw->gen >= 7)
       ctx->Const.MaxVertexStreams = MIN2(4, MAX_VERTEX_STREAMS);
+
+   /* ARB_framebuffer_no_attachments */
+   ctx->Const.MaxFramebufferWidth = ctx->Const.MaxViewportWidth;
+   ctx->Const.MaxFramebufferHeight = ctx->Const.MaxViewportHeight;
+   ctx->Const.MaxFramebufferLayers = ctx->Const.MaxArrayTextureLayers;
+   ctx->Const.MaxFramebufferSamples = max_samples;
 }
 
 static void
@@ -814,10 +786,9 @@ brwCreateContext(gl_api api,
    _mesa_meta_init(ctx);
 
    brw_process_driconf_options(brw);
-   brw_process_intel_debug_variable(brw);
 
-   if (brw->gen >= 8 && !(INTEL_DEBUG & DEBUG_VEC4VS))
-      brw->scalar_vs = true;
+   if (INTEL_DEBUG & DEBUG_PERF)
+      brw->perf_debug = true;
 
    brw_initialize_context_constants(brw);
 
@@ -894,6 +865,8 @@ brwCreateContext(gl_api api,
    brw->gs.enabled = false;
    brw->sf.viewport_transform_enable = true;
 
+   brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
+
    ctx->VertexProgram._MaintainTnlProgram = true;
    ctx->FragmentProgram._MaintainTexEnvProgram = true;
 
index cb4cc7fb36b0dacafb06d72c28adf792d8c1e36e..9e1f722df9e7a29ec3f95a250c65a823aab9279d 100644 (file)
@@ -611,6 +611,12 @@ struct brw_ff_gs_prog_data {
    unsigned svbi_postincrement_value;
 };
 
+enum shader_dispatch_mode {
+   DISPATCH_MODE_4X1_SINGLE = 0,
+   DISPATCH_MODE_4X2_DUAL_INSTANCE = 1,
+   DISPATCH_MODE_4X2_DUAL_OBJECT = 2,
+   DISPATCH_MODE_SIMD8 = 3,
+};
 
 /* Note: brw_vue_prog_data_compare() must be updated when adding fields to
  * this struct!
@@ -628,7 +634,7 @@ struct brw_vue_prog_data {
     */
    GLuint urb_entry_size;
 
-   bool simd8;
+   enum shader_dispatch_mode dispatch_mode;
 };
 
 
@@ -725,14 +731,6 @@ struct brw_gs_prog_data
 
    int invocations;
 
-   /**
-    * Dispatch mode, can be any of:
-    * GEN7_GS_DISPATCH_MODE_DUAL_OBJECT
-    * GEN7_GS_DISPATCH_MODE_DUAL_INSTANCE
-    * GEN7_GS_DISPATCH_MODE_SINGLE
-    */
-   int dispatch_mode;
-
    /**
     * Gen6 transform feedback enabled flag.
     */
@@ -829,20 +827,10 @@ struct brw_tracked_state {
 enum shader_time_shader_type {
    ST_NONE,
    ST_VS,
-   ST_VS_WRITTEN,
-   ST_VS_RESET,
    ST_GS,
-   ST_GS_WRITTEN,
-   ST_GS_RESET,
    ST_FS8,
-   ST_FS8_WRITTEN,
-   ST_FS8_RESET,
    ST_FS16,
-   ST_FS16_WRITTEN,
-   ST_FS16_RESET,
    ST_CS,
-   ST_CS_WRITTEN,
-   ST_CS_RESET,
 };
 
 struct brw_vertex_buffer {
@@ -972,6 +960,22 @@ struct brw_stage_state
    uint32_t sampler_offset;
 };
 
+enum brw_predicate_state {
+   /* The first two states are used if we can determine whether to draw
+    * without having to look at the values in the query object buffer. This
+    * will happen if there is no conditional render in progress, if the query
+    * object is already completed or if something else has already added
+    * samples to the preliminary result such as via a BLT command.
+    */
+   BRW_PREDICATE_STATE_RENDER,
+   BRW_PREDICATE_STATE_DONT_RENDER,
+   /* In this case whether to draw or not depends on the result of an
+    * MI_PREDICATE command so the predicate enable bit needs to be checked.
+    */
+   BRW_PREDICATE_STATE_USE_BIT
+};
+
+struct shader_times;
 
 /**
  * brw_context is derived from gl_context.
@@ -1131,7 +1135,6 @@ struct brw_context
    bool has_pln;
    bool no_simd8;
    bool use_rep_send;
-   bool scalar_vs;
 
    /**
     * Some versions of Gen hardware don't do centroid interpolation correctly
@@ -1407,6 +1410,11 @@ struct brw_context
       bool begin_emitted;
    } query;
 
+   struct {
+      enum brw_predicate_state state;
+      bool supported;
+   } predicate;
+
    struct {
       /** A map from pipeline statistics counter IDs to MMIO addresses. */
       const int *statistics_registers;
@@ -1453,6 +1461,7 @@ struct brw_context
       uint32_t offset;
       uint32_t size;
       enum aub_state_struct_type type;
+      int index;
    } *state_batch_list;
    int state_batch_count;
 
@@ -1492,7 +1501,7 @@ struct brw_context
       const char **names;
       int *ids;
       enum shader_time_shader_type *types;
-      uint64_t *cumulative;
+      struct shader_times *cumulative;
       int num_entries;
       int max_entries;
       double report_time;
@@ -1606,12 +1615,21 @@ void brw_write_depth_count(struct brw_context *brw, drm_intel_bo *bo, int idx);
 void brw_store_register_mem64(struct brw_context *brw,
                               drm_intel_bo *bo, uint32_t reg, int idx);
 
+/** brw_conditional_render.c */
+void brw_init_conditional_render_functions(struct dd_function_table *functions);
+bool brw_check_conditional_render(struct brw_context *brw);
+
 /** intel_batchbuffer.c */
 void brw_load_register_mem(struct brw_context *brw,
                            uint32_t reg,
                            drm_intel_bo *bo,
                            uint32_t read_domains, uint32_t write_domain,
                            uint32_t offset);
+void brw_load_register_mem64(struct brw_context *brw,
+                             uint32_t reg,
+                             drm_intel_bo *bo,
+                             uint32_t read_domains, uint32_t write_domain,
+                             uint32_t offset);
 
 /*======================================================================
  * brw_state_dump.c
@@ -1991,6 +2009,10 @@ void intel_context_destroy(struct brw_context *brw);
 void
 brw_initialize_context_constants(struct brw_context *brw);
 
+bool
+gen9_use_linear_1d_layout(const struct brw_context *brw,
+                          const struct intel_mipmap_tree *mt);
+
 #ifdef __cplusplus
 }
 #endif
index 2432875d0f492e726a0f5192e7b7f880fa277a87..42a082b57b663b9d165e60d17ad41365990eb694 100644 (file)
@@ -88,9 +88,15 @@ brw_cs_emit(struct brw_context *brw,
    cfg_t *cfg = NULL;
    const char *fail_msg = NULL;
 
+   int st_index = -1;
+   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+      st_index = brw_get_shader_time_index(brw, prog, &cp->Base, ST_CS);
+
    /* Now the main event: Visit the shader IR and generate our CS IR for it.
     */
-   fs_visitor v8(brw, mem_ctx, key, prog_data, prog, cp, 8);
+   fs_visitor v8(brw->intelScreen->compiler, brw,
+                 mem_ctx, MESA_SHADER_COMPUTE, key, &prog_data->base, prog,
+                 &cp->Base, 8, st_index);
    if (!v8.run_cs()) {
       fail_msg = v8.fail_msg;
    } else if (local_workgroup_size <= 8 * brw->max_cs_threads) {
@@ -98,7 +104,9 @@ brw_cs_emit(struct brw_context *brw,
       prog_data->simd_size = 8;
    }
 
-   fs_visitor v16(brw, mem_ctx, key, prog_data, prog, cp, 16);
+   fs_visitor v16(brw->intelScreen->compiler, brw,
+                  mem_ctx, MESA_SHADER_COMPUTE, key, &prog_data->base, prog,
+                  &cp->Base, 16, st_index);
    if (likely(!(INTEL_DEBUG & DEBUG_NO16)) &&
        !fail_msg && !v8.simd16_unsupported &&
        local_workgroup_size <= 16 * brw->max_cs_threads) {
@@ -126,7 +134,8 @@ brw_cs_emit(struct brw_context *brw,
       return NULL;
    }
 
-   fs_generator g(brw, mem_ctx, (void*) key, &prog_data->base, &cp->Base,
+   fs_generator g(brw->intelScreen->compiler, brw,
+                  mem_ctx, (void*) key, &prog_data->base, &cp->Base,
                   v8.promoted_constants, v8.runtime_check_aads_emit, "CS");
    if (INTEL_DEBUG & DEBUG_CS) {
       char *name = ralloc_asprintf(mem_ctx, "%s compute shader %d",
@@ -368,9 +377,11 @@ brw_upload_cs_state(struct brw_context *brw)
 
 extern "C"
 const struct brw_tracked_state brw_cs_state = {
-   .dirty = {
-      .mesa  = 0,
-      .brw   = BRW_NEW_CS_PROG_DATA,
+   /* explicit initialisers aren't valid C++, comment
+    * them for documentation purposes */
+   /* .dirty = */{
+      /* .mesa = */ 0,
+      /* .brw = */  BRW_NEW_CS_PROG_DATA,
    },
-   .emit = brw_upload_cs_state
+   /* .emit = */ brw_upload_cs_state
 };
index 03f838dd9ae6ebc0ed89bc42844c882aca12d6d9..61f25811cb2e51baa3fb1a560183275a3a5ae5ed 100644 (file)
  *   - if/else/endif
  */
 bool
-dead_control_flow_eliminate(backend_visitor *v)
+dead_control_flow_eliminate(backend_shader *s)
 {
    bool progress = false;
 
-   foreach_block_safe (block, v->cfg) {
+   foreach_block_safe (block, s->cfg) {
       bblock_t *if_block = NULL, *else_block = NULL, *endif_block = block;
       bool found = false;
 
@@ -115,7 +115,7 @@ dead_control_flow_eliminate(backend_visitor *v)
    }
 
    if (progress)
-      v->invalidate_live_intervals();
+      s->invalidate_live_intervals();
 
    return progress;
 }
index 57a4dabc83c1df10948f55b7463eafd859cb551c..83fd9b1e79e866e55de39f319a3f6d5b3e099712 100644 (file)
@@ -23,4 +23,4 @@
 
 #include "brw_shader.h"
 
-bool dead_control_flow_eliminate(backend_visitor *v);
+bool dead_control_flow_eliminate(backend_shader *s);
index 3c704ee9d08a8c958906adcb897d3af54fab2ff5..c113d52a3d3aa8f9cae45108ac1ca830956ef720 100644 (file)
@@ -38,6 +38,7 @@
       fieldval & field ## _MASK;                                        \
    })
 
+#define GET_BITS(data, high, low) ((data & INTEL_MASK((high), (low))) >> (low))
 #define GET_FIELD(word, field) (((word)  & field ## _MASK) >> field ## _SHIFT)
 
 #ifndef BRW_DEFINES_H
@@ -51,6 +52,7 @@
 # define GEN4_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 15)
 # define GEN4_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM     (1 << 15)
 # define GEN7_3DPRIM_INDIRECT_PARAMETER_ENABLE      (1 << 10)
+# define GEN7_3DPRIM_PREDICATE_ENABLE               (1 << 8)
 /* DW1 */
 # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 8)
 # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM     (1 << 8)
 #define GEN7_SURFACE_ARYSPC_FULL       (0 << 10)
 #define GEN7_SURFACE_ARYSPC_LOD0       (1 << 10)
 
-/* Surface state DW0 */
+/* Surface state DW1 */
 #define GEN8_SURFACE_MOCS_SHIFT         24
 #define GEN8_SURFACE_MOCS_MASK          INTEL_MASK(30, 24)
+#define GEN8_SURFACE_QPITCH_SHIFT       0
+#define GEN8_SURFACE_QPITCH_MASK        INTEL_MASK(14, 0)
 
 /* Surface state DW2 */
 #define BRW_SURFACE_HEIGHT_SHIFT       19
 #define GEN7_SURFACE_MOCS_SHIFT                 16
 #define GEN7_SURFACE_MOCS_MASK                  INTEL_MASK(19, 16)
 
+#define GEN9_SURFACE_TRMODE_SHIFT          18
+#define GEN9_SURFACE_TRMODE_MASK           INTEL_MASK(19, 18)
+#define GEN9_SURFACE_TRMODE_NONE           0
+#define GEN9_SURFACE_TRMODE_TILEYF         1
+#define GEN9_SURFACE_TRMODE_TILEYS         2
+
+#define GEN9_SURFACE_MIP_TAIL_START_LOD_SHIFT      8
+#define GEN9_SURFACE_MIP_TAIL_START_LOD_MASK       INTEL_MASK(11, 8)
+
 /* Surface state DW6 */
 #define GEN7_SURFACE_MCS_ENABLE                 (1 << 0)
 #define GEN7_SURFACE_MCS_PITCH_SHIFT            3
 #define GEN8_SURFACE_AUX_MODE_HIZ               3
 
 /* Surface state DW7 */
+#define GEN9_SURFACE_RT_COMPRESSION_SHIFT       30
+#define GEN9_SURFACE_RT_COMPRESSION_MASK        INTEL_MASK(30, 30)
 #define GEN7_SURFACE_CLEAR_COLOR_SHIFT         28
 #define GEN7_SURFACE_SCS_R_SHIFT                25
 #define GEN7_SURFACE_SCS_R_MASK                 INTEL_MASK(27, 25)
@@ -1131,6 +1146,11 @@ enum opcode {
     * Terminate the compute shader.
     */
    CS_OPCODE_CS_TERMINATE,
+
+   /**
+    * GLSL barrier()
+    */
+   SHADER_OPCODE_BARRIER,
 };
 
 enum brw_urb_write_flags {
@@ -1592,6 +1612,14 @@ enum brw_message_target {
 #define BRW_SCRATCH_SPACE_SIZE_1M     10
 #define BRW_SCRATCH_SPACE_SIZE_2M     11
 
+#define BRW_MESSAGE_GATEWAY_SFID_OPEN_GATEWAY         0
+#define BRW_MESSAGE_GATEWAY_SFID_CLOSE_GATEWAY        1
+#define BRW_MESSAGE_GATEWAY_SFID_FORWARD_MSG          2
+#define BRW_MESSAGE_GATEWAY_SFID_GET_TIMESTAMP        3
+#define BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG          4
+#define BRW_MESSAGE_GATEWAY_SFID_UPDATE_GATEWAY_STATE 5
+#define BRW_MESSAGE_GATEWAY_SFID_MMIO_READ_WRITE      6
+
 
 #define CMD_URB_FENCE                 0x6000
 #define CMD_CS_URB_STATE              0x6001
@@ -1769,9 +1797,8 @@ enum brw_message_target {
 # define GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_SID         1
 # define GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT                20
 # define GEN7_GS_INSTANCE_CONTROL_SHIFT                        15
-# define GEN7_GS_DISPATCH_MODE_SINGLE                  (0 << 11)
-# define GEN7_GS_DISPATCH_MODE_DUAL_INSTANCE           (1 << 11)
-# define GEN7_GS_DISPATCH_MODE_DUAL_OBJECT             (2 << 11)
+# define GEN7_GS_DISPATCH_MODE_SHIFT                    11
+# define GEN7_GS_DISPATCH_MODE_MASK                     INTEL_MASK(12, 11)
 # define GEN6_GS_STATISTICS_ENABLE                     (1 << 10)
 # define GEN6_GS_SO_STATISTICS_ENABLE                  (1 << 9)
 # define GEN6_GS_RENDERING_ENABLE                      (1 << 8)
@@ -2470,8 +2497,8 @@ enum brw_wm_barycentric_interp_mode {
  * cache settings.  We still use only either write-back or write-through; and
  * rely on the documented default values.
  */
-#define SKL_MOCS_WB 9
-#define SKL_MOCS_WT 5
+#define SKL_MOCS_WB (0b001001 << 1)
+#define SKL_MOCS_WT (0b000101 << 1)
 
 #define MEDIA_VFE_STATE                         0x7000
 /* GEN7 DW2, GEN8+ DW3 */
index 95e262a361be6569b5e82e086e65014185f27266..1075c5acba579c0922f25e64b859d0480cab0130 100644 (file)
@@ -402,6 +402,16 @@ static const char *const gen6_sfid[16] = {
    [HSW_SFID_CRE]                      = "cre",
 };
 
+static const char *const gen7_gateway_subfuncid[8] = {
+   [BRW_MESSAGE_GATEWAY_SFID_OPEN_GATEWAY] = "open",
+   [BRW_MESSAGE_GATEWAY_SFID_CLOSE_GATEWAY] = "close",
+   [BRW_MESSAGE_GATEWAY_SFID_FORWARD_MSG] = "forward msg",
+   [BRW_MESSAGE_GATEWAY_SFID_GET_TIMESTAMP] = "get timestamp",
+   [BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG] = "barrier msg",
+   [BRW_MESSAGE_GATEWAY_SFID_UPDATE_GATEWAY_STATE] = "update state",
+   [BRW_MESSAGE_GATEWAY_SFID_MMIO_READ_WRITE] = "mmio read/write",
+};
+
 static const char *const dp_write_port_msg_type[8] = {
    [0b000] = "OWord block write",
    [0b001] = "OWord dual block write",
@@ -977,13 +987,14 @@ src0_3src(FILE *file, const struct brw_device_info *devinfo, brw_inst *inst)
               brw_inst_3src_src0_reg_nr(devinfo, inst));
    if (err == -1)
       return 0;
-   if (src0_subreg_nr)
+   if (src0_subreg_nr || brw_inst_3src_src0_rep_ctrl(devinfo, inst))
       format(file, ".%d", src0_subreg_nr);
    if (brw_inst_3src_src0_rep_ctrl(devinfo, inst))
       string(file, "<0,1,0>");
-   else
+   else {
       string(file, "<4,4,1>");
-   err |= src_swizzle(file, brw_inst_3src_src0_swizzle(devinfo, inst));
+      err |= src_swizzle(file, brw_inst_3src_src0_swizzle(devinfo, inst));
+   }
    err |= control(file, "src da16 reg type", three_source_reg_encoding,
                   brw_inst_3src_src_type(devinfo, inst), NULL);
    return err;
@@ -1003,13 +1014,14 @@ src1_3src(FILE *file, const struct brw_device_info *devinfo, brw_inst *inst)
               brw_inst_3src_src1_reg_nr(devinfo, inst));
    if (err == -1)
       return 0;
-   if (src1_subreg_nr)
+   if (src1_subreg_nr || brw_inst_3src_src1_rep_ctrl(devinfo, inst))
       format(file, ".%d", src1_subreg_nr);
    if (brw_inst_3src_src1_rep_ctrl(devinfo, inst))
       string(file, "<0,1,0>");
-   else
+   else {
       string(file, "<4,4,1>");
-   err |= src_swizzle(file, brw_inst_3src_src1_swizzle(devinfo, inst));
+      err |= src_swizzle(file, brw_inst_3src_src1_swizzle(devinfo, inst));
+   }
    err |= control(file, "src da16 reg type", three_source_reg_encoding,
                   brw_inst_3src_src_type(devinfo, inst), NULL);
    return err;
@@ -1030,13 +1042,14 @@ src2_3src(FILE *file, const struct brw_device_info *devinfo, brw_inst *inst)
               brw_inst_3src_src2_reg_nr(devinfo, inst));
    if (err == -1)
       return 0;
-   if (src2_subreg_nr)
+   if (src2_subreg_nr || brw_inst_3src_src2_rep_ctrl(devinfo, inst))
       format(file, ".%d", src2_subreg_nr);
    if (brw_inst_3src_src2_rep_ctrl(devinfo, inst))
       string(file, "<0,1,0>");
-   else
+   else {
       string(file, "<4,4,1>");
-   err |= src_swizzle(file, brw_inst_3src_src2_swizzle(devinfo, inst));
+      err |= src_swizzle(file, brw_inst_3src_src2_swizzle(devinfo, inst));
+   }
    err |= control(file, "src da16 reg type", three_source_reg_encoding,
                   brw_inst_3src_src_type(devinfo, inst), NULL);
    return err;
@@ -1495,6 +1508,12 @@ brw_disassemble_inst(FILE *file, const struct brw_device_info *devinfo,
             break;
          case BRW_SFID_THREAD_SPAWNER:
             break;
+
+         case BRW_SFID_MESSAGE_GATEWAY:
+            format(file, " (%s)",
+                   gen7_gateway_subfuncid[brw_inst_gateway_subfuncid(devinfo, inst)]);
+            break;
+
          case GEN7_SFID_DATAPORT_DATA_CACHE:
             if (devinfo->gen >= 7) {
                format(file, " (");
index 96e2369792394d806595eb27fa533481f9dd6bc1..b91597a9f5dbbdec0c9d050155aff7cd0c7cd768 100644 (file)
@@ -92,8 +92,10 @@ get_hw_prim_for_gl_prim(int mode)
 {
    if (mode >= BRW_PRIM_OFFSET)
       return mode - BRW_PRIM_OFFSET;
-   else
+   else {
+      assert(mode < ARRAY_SIZE(prim_to_hw_prim));
       return prim_to_hw_prim[mode];
+   }
 }
 
 
@@ -178,6 +180,7 @@ static void brw_emit_prim(struct brw_context *brw,
    int verts_per_instance;
    int vertex_access_type;
    int indirect_flag;
+   int predicate_enable;
 
    DBG("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode),
        prim->start, prim->count);
@@ -258,10 +261,14 @@ static void brw_emit_prim(struct brw_context *brw,
       indirect_flag = 0;
    }
 
-
    if (brw->gen >= 7) {
+      if (brw->predicate.state == BRW_PREDICATE_STATE_USE_BIT)
+         predicate_enable = GEN7_3DPRIM_PREDICATE_ENABLE;
+      else
+         predicate_enable = 0;
+
       BEGIN_BATCH(7);
-      OUT_BATCH(CMD_3D_PRIM << 16 | (7 - 2) | indirect_flag);
+      OUT_BATCH(CMD_3D_PRIM << 16 | (7 - 2) | indirect_flag | predicate_enable);
       OUT_BATCH(hw_prim | vertex_access_type);
    } else {
       BEGIN_BATCH(6);
@@ -561,12 +568,7 @@ void brw_draw_prims( struct gl_context *ctx,
 
    assert(unused_tfb_object == NULL);
 
-   if (ctx->Query.CondRenderQuery) {
-      perf_debug("Conditional rendering is implemented in software and may "
-                 "stall.  This should be fixed in the driver.\n");
-   }
-
-   if (!_mesa_check_conditional_render(ctx))
+   if (!brw_check_conditional_render(brw))
       return;
 
    /* Handle primitive restart if needed */
index 0e7be1e1ea068d7736912ee9b054a5accf67b69b..761aa0ec5fa892aa5115588be8b0c3058f2bd9dd 100644 (file)
@@ -361,6 +361,8 @@ brw_jump_scale(const struct brw_device_info *devinfo)
    return 1;
 }
 
+void brw_barrier(struct brw_codegen *p, struct brw_reg src);
+
 /* If/else/endif.  Works by manipulating the execution flags on each
  * channel.
  */
@@ -390,6 +392,8 @@ brw_inst *brw_JMPI(struct brw_codegen *p, struct brw_reg index,
 
 void brw_NOP(struct brw_codegen *p);
 
+void brw_WAIT(struct brw_codegen *p);
+
 /* Special case: there is never a destination, execution size will be
  * taken from src0:
  */
index 69cb114b94532f76a8b48485371422bd5788652f..67f0b45ac04b08f362d7eef7bb10c76d940d8770 100644 (file)
@@ -849,6 +849,12 @@ set_3src_source_index(const struct brw_device_info *devinfo,
 static bool
 has_unmapped_bits(const struct brw_device_info *devinfo, brw_inst *src)
 {
+   /* EOT can only be mapped on a send if the src1 is an immediate */
+   if ((brw_inst_opcode(devinfo, src) == BRW_OPCODE_SENDC ||
+        brw_inst_opcode(devinfo, src) == BRW_OPCODE_SEND) &&
+       brw_inst_eot(devinfo, src))
+      return true;
+
    /* Check for instruction bits that don't map to any of the fields of the
     * compacted instruction.  The instruction cannot be compacted if any of
     * them are set.  They overlap with:
index e78d0bec268111443e2b3ab8803d91eaedbb4f63..0f536046f6f5cf296fb37d9152f11bf934d97704 100644 (file)
@@ -914,6 +914,8 @@ brw_alu3(struct brw_codegen *p, unsigned opcode, struct brw_reg dest,
          brw_inst_set_3src_src_type(devinfo, inst, BRW_3SRC_TYPE_UD);
          brw_inst_set_3src_dst_type(devinfo, inst, BRW_3SRC_TYPE_UD);
          break;
+      default:
+         unreachable("not reached");
       }
    }
 
@@ -3404,3 +3406,54 @@ void brw_shader_time_add(struct brw_codegen *p,
 
    brw_pop_insn_state(p);
 }
+
+
+/**
+ * Emit the SEND message for a barrier
+ */
+void
+brw_barrier(struct brw_codegen *p, struct brw_reg src)
+{
+   const struct brw_device_info *devinfo = p->devinfo;
+   struct brw_inst *inst;
+
+   assert(devinfo->gen >= 7);
+
+   inst = next_insn(p, BRW_OPCODE_SEND);
+   brw_set_dest(p, inst, brw_null_reg());
+   brw_set_src0(p, inst, src);
+   brw_set_src1(p, inst, brw_null_reg());
+
+   brw_set_message_descriptor(p, inst, BRW_SFID_MESSAGE_GATEWAY,
+                              1 /* msg_length */,
+                              0 /* response_length */,
+                              false /* header_present */,
+                              false /* end_of_thread */);
+
+   brw_inst_set_gateway_notify(devinfo, inst, 1);
+   brw_inst_set_gateway_subfuncid(devinfo, inst,
+                                  BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG);
+
+   brw_inst_set_mask_control(devinfo, inst, BRW_MASK_DISABLE);
+}
+
+
+/**
+ * Emit the wait instruction for a barrier
+ */
+void
+brw_WAIT(struct brw_codegen *p)
+{
+   const struct brw_device_info *devinfo = p->devinfo;
+   struct brw_inst *insn;
+
+   struct brw_reg src = brw_notification_reg();
+
+   insn = next_insn(p, BRW_OPCODE_WAIT);
+   brw_set_dest(p, insn, src);
+   brw_set_src0(p, insn, src);
+   brw_set_src1(p, insn, brw_null_reg());
+
+   brw_inst_set_exec_size(devinfo, insn, BRW_EXECUTE_1);
+   brw_inst_set_mask_control(devinfo, insn, BRW_MASK_DISABLE);
+}
index 5ce1dfc663305a4ddc6cb06c6623c009fbc9ecd3..2c0ff961182cea05f8998dfeeeeab99874db5fa5 100644 (file)
@@ -49,6 +49,8 @@
 #include "glsl/glsl_types.h"
 #include "program/sampler.h"
 
+using namespace brw;
+
 void
 fs_inst::init(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
               const fs_reg *src, unsigned sources)
@@ -212,152 +214,13 @@ fs_inst::resize_sources(uint8_t num_sources)
    }
 }
 
-#define ALU1(op)                                                        \
-   fs_inst *                                                            \
-   fs_visitor::op(const fs_reg &dst, const fs_reg &src0)                \
-   {                                                                    \
-      return new(mem_ctx) fs_inst(BRW_OPCODE_##op, dst, src0);          \
-   }
-
-#define ALU2(op)                                                        \
-   fs_inst *                                                            \
-   fs_visitor::op(const fs_reg &dst, const fs_reg &src0,                \
-                  const fs_reg &src1)                                   \
-   {                                                                    \
-      return new(mem_ctx) fs_inst(BRW_OPCODE_##op, dst, src0, src1);    \
-   }
-
-#define ALU2_ACC(op)                                                    \
-   fs_inst *                                                            \
-   fs_visitor::op(const fs_reg &dst, const fs_reg &src0,                \
-                  const fs_reg &src1)                                   \
-   {                                                                    \
-      fs_inst *inst = new(mem_ctx) fs_inst(BRW_OPCODE_##op, dst, src0, src1);\
-      inst->writes_accumulator = true;                                  \
-      return inst;                                                      \
-   }
-
-#define ALU3(op)                                                        \
-   fs_inst *                                                            \
-   fs_visitor::op(const fs_reg &dst, const fs_reg &src0,                \
-                  const fs_reg &src1, const fs_reg &src2)               \
-   {                                                                    \
-      return new(mem_ctx) fs_inst(BRW_OPCODE_##op, dst, src0, src1, src2);\
-   }
-
-ALU1(NOT)
-ALU1(MOV)
-ALU1(FRC)
-ALU1(RNDD)
-ALU1(RNDE)
-ALU1(RNDZ)
-ALU2(ADD)
-ALU2(MUL)
-ALU2_ACC(MACH)
-ALU2(AND)
-ALU2(OR)
-ALU2(XOR)
-ALU2(SHL)
-ALU2(SHR)
-ALU2(ASR)
-ALU3(LRP)
-ALU1(BFREV)
-ALU3(BFE)
-ALU2(BFI1)
-ALU3(BFI2)
-ALU1(FBH)
-ALU1(FBL)
-ALU1(CBIT)
-ALU3(MAD)
-ALU2_ACC(ADDC)
-ALU2_ACC(SUBB)
-ALU2(SEL)
-ALU2(MAC)
-
-/** Gen4 predicated IF. */
-fs_inst *
-fs_visitor::IF(enum brw_predicate predicate)
-{
-   fs_inst *inst = new(mem_ctx) fs_inst(BRW_OPCODE_IF, dispatch_width);
-   inst->predicate = predicate;
-   return inst;
-}
-
-/** Gen6 IF with embedded comparison. */
-fs_inst *
-fs_visitor::IF(const fs_reg &src0, const fs_reg &src1,
-               enum brw_conditional_mod condition)
-{
-   assert(devinfo->gen == 6);
-   fs_inst *inst = new(mem_ctx) fs_inst(BRW_OPCODE_IF, dispatch_width,
-                                        reg_null_d, src0, src1);
-   inst->conditional_mod = condition;
-   return inst;
-}
-
-/**
- * CMP: Sets the low bit of the destination channels with the result
- * of the comparison, while the upper bits are undefined, and updates
- * the flag register with the packed 16 bits of the result.
- */
-fs_inst *
-fs_visitor::CMP(fs_reg dst, fs_reg src0, fs_reg src1,
-                enum brw_conditional_mod condition)
-{
-   fs_inst *inst;
-
-   /* Take the instruction:
-    *
-    * CMP null<d> src0<f> src1<f>
-    *
-    * Original gen4 does type conversion to the destination type before
-    * comparison, producing garbage results for floating point comparisons.
-    *
-    * The destination type doesn't matter on newer generations, so we set the
-    * type to match src0 so we can compact the instruction.
-    */
-   dst.type = src0.type;
-   if (dst.file == HW_REG)
-      dst.fixed_hw_reg.type = dst.type;
-
-   resolve_ud_negate(&src0);
-   resolve_ud_negate(&src1);
-
-   inst = new(mem_ctx) fs_inst(BRW_OPCODE_CMP, dst, src0, src1);
-   inst->conditional_mod = condition;
-
-   return inst;
-}
-
-fs_inst *
-fs_visitor::LOAD_PAYLOAD(const fs_reg &dst, fs_reg *src, int sources,
-                         int header_size)
-{
-   assert(dst.width % 8 == 0);
-   fs_inst *inst = new(mem_ctx) fs_inst(SHADER_OPCODE_LOAD_PAYLOAD, dst.width,
-                                        dst, src, sources);
-   inst->header_size = header_size;
-
-   for (int i = 0; i < header_size; i++)
-      assert(src[i].file != GRF || src[i].width * type_sz(src[i].type) == 32);
-   inst->regs_written = header_size;
-
-   for (int i = header_size; i < sources; ++i)
-      assert(src[i].file != GRF || src[i].width == dst.width);
-   inst->regs_written += (sources - header_size) * (dst.width / 8);
-
-   return inst;
-}
-
-exec_list
-fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_reg &dst,
+void
+fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_builder &bld,
+                                       const fs_reg &dst,
                                        const fs_reg &surf_index,
                                        const fs_reg &varying_offset,
                                        uint32_t const_offset)
 {
-   exec_list instructions;
-   fs_inst *inst;
-
    /* We have our constant surface use a pitch of 4 bytes, so our index can
     * be any component of a vector, and then we load 4 contiguous
     * components starting from that.
@@ -370,8 +233,7 @@ fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_reg &dst,
     * the redundant ones.
     */
    fs_reg vec4_offset = vgrf(glsl_type::int_type);
-   instructions.push_tail(ADD(vec4_offset,
-                              varying_offset, fs_reg(const_offset & ~3)));
+   bld.ADD(vec4_offset, varying_offset, fs_reg(const_offset & ~3));
 
    int scale = 1;
    if (devinfo->gen == 4 && dst.width == 8) {
@@ -393,9 +255,8 @@ fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_reg &dst,
    int regs_written = 4 * (dst.width / 8) * scale;
    fs_reg vec4_result = fs_reg(GRF, alloc.allocate(regs_written),
                                dst.type, dst.width);
-   inst = new(mem_ctx) fs_inst(op, vec4_result, surf_index, vec4_offset);
+   fs_inst *inst = bld.emit(op, vec4_result, surf_index, vec4_offset);
    inst->regs_written = regs_written;
-   instructions.push_tail(inst);
 
    if (devinfo->gen < 7) {
       inst->base_mrf = 13;
@@ -406,30 +267,23 @@ fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_reg &dst,
          inst->mlen = 1 + dispatch_width / 8;
    }
 
-   fs_reg result = offset(vec4_result, (const_offset & 3) * scale);
-   instructions.push_tail(MOV(dst, result));
-
-   return instructions;
+   bld.MOV(dst, offset(vec4_result, (const_offset & 3) * scale));
 }
 
 /**
  * A helper for MOV generation for fixing up broken hardware SEND dependency
  * handling.
  */
-fs_inst *
-fs_visitor::DEP_RESOLVE_MOV(int grf)
+void
+fs_visitor::DEP_RESOLVE_MOV(const fs_builder &bld, int grf)
 {
-   fs_inst *inst = MOV(brw_null_reg(), fs_reg(GRF, grf, BRW_REGISTER_TYPE_F));
-
-   inst->ir = NULL;
-   inst->annotation = "send dependency resolve";
-
    /* The caller always wants uncompressed to emit the minimal extra
     * dependencies, and to avoid having to deal with aligning its regs to 2.
     */
-   inst->exec_size = 8;
+   const fs_builder ubld = bld.annotate("send dependency resolve")
+                              .half(0);
 
-   return inst;
+   ubld.MOV(ubld.null_reg_f(), fs_reg(GRF, grf, BRW_REGISTER_TYPE_F));
 }
 
 bool
@@ -685,7 +539,7 @@ fs_visitor::type_size(const struct glsl_type *type)
  * the destination of the MOV, with extra parameters set.
  */
 fs_reg
-fs_visitor::get_timestamp(fs_inst **out_mov)
+fs_visitor::get_timestamp(const fs_builder &bld)
 {
    assert(devinfo->gen >= 7);
 
@@ -696,11 +550,10 @@ fs_visitor::get_timestamp(fs_inst **out_mov)
 
    fs_reg dst = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD, 4);
 
-   fs_inst *mov = MOV(dst, ts);
    /* We want to read the 3 fields we care about even if it's not enabled in
     * the dispatch.
     */
-   mov->force_writemask_all = true;
+   bld.exec_all().MOV(dst, ts);
 
    /* The caller wants the low 32 bits of the timestamp.  Since it's running
     * at the GPU clock rate of ~1.2ghz, it will roll over every ~3 seconds,
@@ -714,105 +567,60 @@ fs_visitor::get_timestamp(fs_inst **out_mov)
     */
    dst.set_smear(0);
 
-   *out_mov = mov;
    return dst;
 }
 
 void
 fs_visitor::emit_shader_time_begin()
 {
-   current_annotation = "shader time start";
-   fs_inst *mov;
-   shader_start_time = get_timestamp(&mov);
-   emit(mov);
+   shader_start_time = get_timestamp(bld.annotate("shader time start"));
 }
 
 void
 fs_visitor::emit_shader_time_end()
 {
-   current_annotation = "shader time end";
-
-   enum shader_time_shader_type type, written_type, reset_type;
-   switch (stage) {
-   case MESA_SHADER_VERTEX:
-      type = ST_VS;
-      written_type = ST_VS_WRITTEN;
-      reset_type = ST_VS_RESET;
-      break;
-   case MESA_SHADER_GEOMETRY:
-      type = ST_GS;
-      written_type = ST_GS_WRITTEN;
-      reset_type = ST_GS_RESET;
-      break;
-   case MESA_SHADER_FRAGMENT:
-      if (dispatch_width == 8) {
-         type = ST_FS8;
-         written_type = ST_FS8_WRITTEN;
-         reset_type = ST_FS8_RESET;
-      } else {
-         assert(dispatch_width == 16);
-         type = ST_FS16;
-         written_type = ST_FS16_WRITTEN;
-         reset_type = ST_FS16_RESET;
-      }
-      break;
-   case MESA_SHADER_COMPUTE:
-      type = ST_CS;
-      written_type = ST_CS_WRITTEN;
-      reset_type = ST_CS_RESET;
-      break;
-   default:
-      unreachable("fs_visitor::emit_shader_time_end missing code");
-   }
-
    /* Insert our code just before the final SEND with EOT. */
    exec_node *end = this->instructions.get_tail();
    assert(end && ((fs_inst *) end)->eot);
+   const fs_builder ibld = bld.annotate("shader time end")
+                              .exec_all().at(NULL, end);
 
-   fs_inst *tm_read;
-   fs_reg shader_end_time = get_timestamp(&tm_read);
-   end->insert_before(tm_read);
+   fs_reg shader_end_time = get_timestamp(ibld);
 
    /* Check that there weren't any timestamp reset events (assuming these
     * were the only two timestamp reads that happened).
     */
    fs_reg reset = shader_end_time;
    reset.set_smear(2);
-   fs_inst *test = AND(reg_null_d, reset, fs_reg(1u));
-   test->conditional_mod = BRW_CONDITIONAL_Z;
-   test->force_writemask_all = true;
-   end->insert_before(test);
-   end->insert_before(IF(BRW_PREDICATE_NORMAL));
+   set_condmod(BRW_CONDITIONAL_Z,
+               ibld.AND(ibld.null_reg_ud(), reset, fs_reg(1u)));
+   ibld.IF(BRW_PREDICATE_NORMAL);
 
    fs_reg start = shader_start_time;
    start.negate = true;
    fs_reg diff = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD, 1);
    diff.set_smear(0);
-   fs_inst *add = ADD(diff, start, shader_end_time);
-   add->force_writemask_all = true;
-   end->insert_before(add);
+   ibld.ADD(diff, start, shader_end_time);
 
    /* If there were no instructions between the two timestamp gets, the diff
     * is 2 cycles.  Remove that overhead, so I can forget about that when
     * trying to determine the time taken for single instructions.
     */
-   add = ADD(diff, diff, fs_reg(-2u));
-   add->force_writemask_all = true;
-   end->insert_before(add);
-
-   end->insert_before(SHADER_TIME_ADD(type, diff));
-   end->insert_before(SHADER_TIME_ADD(written_type, fs_reg(1u)));
-   end->insert_before(new(mem_ctx) fs_inst(BRW_OPCODE_ELSE, dispatch_width));
-   end->insert_before(SHADER_TIME_ADD(reset_type, fs_reg(1u)));
-   end->insert_before(new(mem_ctx) fs_inst(BRW_OPCODE_ENDIF, dispatch_width));
+   ibld.ADD(diff, diff, fs_reg(-2u));
+   SHADER_TIME_ADD(ibld, 0, diff);
+   SHADER_TIME_ADD(ibld, 1, fs_reg(1u));
+   ibld.emit(BRW_OPCODE_ELSE);
+   SHADER_TIME_ADD(ibld, 2, fs_reg(1u));
+   ibld.emit(BRW_OPCODE_ENDIF);
 }
 
-fs_inst *
-fs_visitor::SHADER_TIME_ADD(enum shader_time_shader_type type, fs_reg value)
+void
+fs_visitor::SHADER_TIME_ADD(const fs_builder &bld,
+                            int shader_time_subindex,
+                            fs_reg value)
 {
-   int shader_time_index =
-      brw_get_shader_time_index(brw, shader_prog, prog, type);
-   fs_reg offset = fs_reg(shader_time_index * SHADER_TIME_STRIDE);
+   int index = shader_time_index * 3 + shader_time_subindex;
+   fs_reg offset = fs_reg(index * SHADER_TIME_STRIDE);
 
    fs_reg payload;
    if (dispatch_width == 8)
@@ -820,8 +628,7 @@ fs_visitor::SHADER_TIME_ADD(enum shader_time_shader_type type, fs_reg value)
    else
       payload = vgrf(glsl_type::uint_type);
 
-   return new(mem_ctx) fs_inst(SHADER_OPCODE_SHADER_TIME_ADD,
-                               fs_reg(), payload, offset, value);
+   bld.emit(SHADER_OPCODE_SHADER_TIME_ADD, fs_reg(), payload, offset, value);
 }
 
 void
@@ -864,65 +671,16 @@ fs_visitor::fail(const char *format, ...)
  * During a SIMD16 compile (if one happens anyway), this just calls fail().
  */
 void
-fs_visitor::no16(const char *format, ...)
+fs_visitor::no16(const char *msg)
 {
-   va_list va;
-
-   va_start(va, format);
-
    if (dispatch_width == 16) {
-      vfail(format, va);
+      fail("%s", msg);
    } else {
       simd16_unsupported = true;
 
-      if (brw->perf_debug) {
-         if (no16_msg)
-            ralloc_vasprintf_append(&no16_msg, format, va);
-         else
-            no16_msg = ralloc_vasprintf(mem_ctx, format, va);
-      }
+      compiler->shader_perf_log(log_data,
+                                "SIMD16 shader failed to compile: %s", msg);
    }
-
-   va_end(va);
-}
-
-fs_inst *
-fs_visitor::emit(enum opcode opcode)
-{
-   return emit(new(mem_ctx) fs_inst(opcode, dispatch_width));
-}
-
-fs_inst *
-fs_visitor::emit(enum opcode opcode, const fs_reg &dst)
-{
-   return emit(new(mem_ctx) fs_inst(opcode, dst));
-}
-
-fs_inst *
-fs_visitor::emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0)
-{
-   return emit(new(mem_ctx) fs_inst(opcode, dst, src0));
-}
-
-fs_inst *
-fs_visitor::emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0,
-                 const fs_reg &src1)
-{
-   return emit(new(mem_ctx) fs_inst(opcode, dst, src0, src1));
-}
-
-fs_inst *
-fs_visitor::emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0,
-                 const fs_reg &src1, const fs_reg &src2)
-{
-   return emit(new(mem_ctx) fs_inst(opcode, dst, src0, src1, src2));
-}
-
-fs_inst *
-fs_visitor::emit(enum opcode opcode, const fs_reg &dst,
-                 fs_reg src[], int sources)
-{
-   return emit(new(mem_ctx) fs_inst(opcode, dst, src, sources));
 }
 
 /**
@@ -1051,7 +809,7 @@ fs_visitor::implied_mrf_writes(fs_inst *inst)
    case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD:
       return inst->mlen;
    case SHADER_OPCODE_GEN4_SCRATCH_WRITE:
-      return 2;
+      return inst->mlen;
    case SHADER_OPCODE_UNTYPED_ATOMIC:
    case SHADER_OPCODE_UNTYPED_SURFACE_READ:
    case SHADER_OPCODE_UNTYPED_SURFACE_WRITE:
@@ -1077,14 +835,6 @@ fs_visitor::vgrf(const glsl_type *const type)
                  brw_type_for_base_type(type), dispatch_width);
 }
 
-fs_reg
-fs_visitor::vgrf(int num_components)
-{
-   int reg_width = dispatch_width / 8;
-   return fs_reg(GRF, alloc.allocate(num_components * reg_width),
-                 BRW_REGISTER_TYPE_F, dispatch_width);
-}
-
 /** Fixed HW reg constructor. */
 fs_reg::fs_reg(enum register_file file, int reg)
 {
@@ -1130,117 +880,18 @@ fs_reg::fs_reg(enum register_file file, int reg, enum brw_reg_type type,
    this->width = width;
 }
 
-fs_reg *
-fs_visitor::variable_storage(ir_variable *var)
-{
-   return (fs_reg *)hash_table_find(this->variable_ht, var);
-}
-
-void
-import_uniforms_callback(const void *key,
-                        void *data,
-                        void *closure)
-{
-   struct hash_table *dst_ht = (struct hash_table *)closure;
-   const fs_reg *reg = (const fs_reg *)data;
-
-   if (reg->file != UNIFORM)
-      return;
-
-   hash_table_insert(dst_ht, data, key);
-}
-
 /* For SIMD16, we need to follow from the uniform setup of SIMD8 dispatch.
  * This brings in those uniform definitions
  */
 void
 fs_visitor::import_uniforms(fs_visitor *v)
 {
-   hash_table_call_foreach(v->variable_ht,
-                          import_uniforms_callback,
-                          variable_ht);
    this->push_constant_loc = v->push_constant_loc;
    this->pull_constant_loc = v->pull_constant_loc;
    this->uniforms = v->uniforms;
    this->param_size = v->param_size;
 }
 
-/* Our support for uniforms is piggy-backed on the struct
- * gl_fragment_program, because that's where the values actually
- * get stored, rather than in some global gl_shader_program uniform
- * store.
- */
-void
-fs_visitor::setup_uniform_values(ir_variable *ir)
-{
-   int namelen = strlen(ir->name);
-
-   /* The data for our (non-builtin) uniforms is stored in a series of
-    * gl_uniform_driver_storage structs for each subcomponent that
-    * glGetUniformLocation() could name.  We know it's been set up in the same
-    * order we'd walk the type, so walk the list of storage and find anything
-    * with our name, or the prefix of a component that starts with our name.
-    */
-   unsigned params_before = uniforms;
-   for (unsigned u = 0; u < shader_prog->NumUserUniformStorage; u++) {
-      struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
-
-      if (strncmp(ir->name, storage->name, namelen) != 0 ||
-          (storage->name[namelen] != 0 &&
-           storage->name[namelen] != '.' &&
-           storage->name[namelen] != '[')) {
-         continue;
-      }
-
-      unsigned slots = storage->type->component_slots();
-      if (storage->array_elements)
-         slots *= storage->array_elements;
-
-      for (unsigned i = 0; i < slots; i++) {
-         stage_prog_data->param[uniforms++] = &storage->storage[i];
-      }
-   }
-
-   /* Make sure we actually initialized the right amount of stuff here. */
-   assert(params_before + ir->type->component_slots() == uniforms);
-   (void)params_before;
-}
-
-
-/* Our support for builtin uniforms is even scarier than non-builtin.
- * It sits on top of the PROG_STATE_VAR parameters that are
- * automatically updated from GL context state.
- */
-void
-fs_visitor::setup_builtin_uniform_values(ir_variable *ir)
-{
-   const ir_state_slot *const slots = ir->get_state_slots();
-   assert(slots != NULL);
-
-   for (unsigned int i = 0; i < ir->get_num_state_slots(); i++) {
-      /* This state reference has already been setup by ir_to_mesa, but we'll
-       * get the same index back here.
-       */
-      int index = _mesa_add_state_reference(this->prog->Parameters,
-                                           (gl_state_index *)slots[i].tokens);
-
-      /* Add each of the unique swizzles of the element as a parameter.
-       * This'll end up matching the expected layout of the
-       * array/matrix/structure we're trying to fill in.
-       */
-      int last_swiz = -1;
-      for (unsigned int j = 0; j < 4; j++) {
-        int swiz = GET_SWZ(slots[i].swizzle, j);
-        if (swiz == last_swiz)
-           break;
-        last_swiz = swiz;
-
-         stage_prog_data->param[uniforms++] =
-            &prog->Parameters->ParameterValues[index][swiz];
-      }
-   }
-}
-
 fs_reg *
 fs_visitor::emit_fragcoord_interpolation(bool pixel_center_integer,
                                          bool origin_upper_left)
@@ -1253,15 +904,15 @@ fs_visitor::emit_fragcoord_interpolation(bool pixel_center_integer,
 
    /* gl_FragCoord.x */
    if (pixel_center_integer) {
-      emit(MOV(wpos, this->pixel_x));
+      bld.MOV(wpos, this->pixel_x);
    } else {
-      emit(ADD(wpos, this->pixel_x, fs_reg(0.5f)));
+      bld.ADD(wpos, this->pixel_x, fs_reg(0.5f));
    }
    wpos = offset(wpos, 1);
 
    /* gl_FragCoord.y */
    if (!flip && pixel_center_integer) {
-      emit(MOV(wpos, this->pixel_y));
+      bld.MOV(wpos, this->pixel_y);
    } else {
       fs_reg pixel_y = this->pixel_y;
       float offset = (pixel_center_integer ? 0.0 : 0.5);
@@ -1271,22 +922,22 @@ fs_visitor::emit_fragcoord_interpolation(bool pixel_center_integer,
         offset += key->drawable_height - 1.0;
       }
 
-      emit(ADD(wpos, pixel_y, fs_reg(offset)));
+      bld.ADD(wpos, pixel_y, fs_reg(offset));
    }
    wpos = offset(wpos, 1);
 
    /* gl_FragCoord.z */
    if (devinfo->gen >= 6) {
-      emit(MOV(wpos, fs_reg(brw_vec8_grf(payload.source_depth_reg, 0))));
+      bld.MOV(wpos, fs_reg(brw_vec8_grf(payload.source_depth_reg, 0)));
    } else {
-      emit(FS_OPCODE_LINTERP, wpos,
+      bld.emit(FS_OPCODE_LINTERP, wpos,
            this->delta_xy[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
            interp_reg(VARYING_SLOT_POS, 2));
    }
    wpos = offset(wpos, 1);
 
    /* gl_FragCoord.w: Already set up in emit_interpolation */
-   emit(BRW_OPCODE_MOV, wpos, this->wpos_w);
+   bld.MOV(wpos, this->wpos_w);
 
    return reg;
 }
@@ -1321,8 +972,8 @@ fs_visitor::emit_linterp(const fs_reg &attr, const fs_reg &interp,
        */
       barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
    }
-   return emit(FS_OPCODE_LINTERP, attr,
-               this->delta_xy[barycoord_mode], interp);
+   return bld.emit(FS_OPCODE_LINTERP, attr,
+                   this->delta_xy[barycoord_mode], interp);
 }
 
 void
@@ -1380,7 +1031,7 @@ fs_visitor::emit_general_interpolation(fs_reg attr, const char *name,
               struct brw_reg interp = interp_reg(location, k);
               interp = suboffset(interp, 3);
                interp.type = attr.type;
-              emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
+               bld.emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
               attr = offset(attr, 1);
            }
         } else {
@@ -1393,7 +1044,7 @@ fs_visitor::emit_general_interpolation(fs_reg attr, const char *name,
                    * unlit, replace the centroid data with non-centroid
                    * data.
                    */
-                  emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
+                  bld.emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
 
                   fs_inst *inst;
                   inst = emit_linterp(attr, fs_reg(interp), interpolation_mode,
@@ -1417,7 +1068,7 @@ fs_visitor::emit_general_interpolation(fs_reg attr, const char *name,
                                mod_sample || key->persample_shading);
                }
                if (devinfo->gen < 6 && interpolation_mode == INTERP_QUALIFIER_SMOOTH) {
-                  emit(BRW_OPCODE_MUL, attr, attr, this->pixel_w);
+                  bld.MUL(attr, attr, this->pixel_w);
                }
               attr = offset(attr, 1);
            }
@@ -1448,7 +1099,7 @@ fs_visitor::emit_frontfacing_interpolation()
       fs_reg g0 = fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_W));
       g0.negate = true;
 
-      emit(ASR(*reg, g0, fs_reg(15)));
+      bld.ASR(*reg, g0, fs_reg(15));
    } else {
       /* Bit 31 of g1.6 is 0 if the polygon is front facing. We want to create
        * a boolean result from this (1/true or 0/false).
@@ -1463,7 +1114,7 @@ fs_visitor::emit_frontfacing_interpolation()
       fs_reg g1_6 = fs_reg(retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_D));
       g1_6.negate = true;
 
-      emit(ASR(*reg, g1_6, fs_reg(31)));
+      bld.ASR(*reg, g1_6, fs_reg(31));
    }
 
    return reg;
@@ -1478,9 +1129,9 @@ fs_visitor::compute_sample_position(fs_reg dst, fs_reg int_sample_pos)
 
    if (key->compute_pos_offset) {
       /* Convert int_sample_pos to floating point */
-      emit(MOV(dst, int_sample_pos));
+      bld.MOV(dst, int_sample_pos);
       /* Scale to the range [0, 1] */
-      emit(MUL(dst, dst, fs_reg(1 / 16.0f)));
+      bld.MUL(dst, dst, fs_reg(1 / 16.0f));
    }
    else {
       /* From ARB_sample_shading specification:
@@ -1488,7 +1139,7 @@ fs_visitor::compute_sample_position(fs_reg dst, fs_reg int_sample_pos)
        *  rasterization is disabled, gl_SamplePosition will always be
        *  (0.5, 0.5).
        */
-      emit(MOV(dst, fs_reg(0.5f)));
+      bld.MOV(dst, fs_reg(0.5f));
    }
 }
 
@@ -1497,7 +1148,7 @@ fs_visitor::emit_samplepos_setup()
 {
    assert(devinfo->gen >= 6);
 
-   this->current_annotation = "compute sample position";
+   const fs_builder abld = bld.annotate("compute sample position");
    fs_reg *reg = new(this->mem_ctx) fs_reg(vgrf(glsl_type::vec2_type));
    fs_reg pos = *reg;
    fs_reg int_sample_x = vgrf(glsl_type::int_type);
@@ -1519,22 +1170,22 @@ fs_visitor::emit_samplepos_setup()
                     BRW_REGISTER_TYPE_B), 16, 8, 2);
 
    if (dispatch_width == 8) {
-      emit(MOV(int_sample_x, fs_reg(sample_pos_reg)));
+      abld.MOV(int_sample_x, fs_reg(sample_pos_reg));
    } else {
-      emit(MOV(half(int_sample_x, 0), fs_reg(sample_pos_reg)));
-      emit(MOV(half(int_sample_x, 1), fs_reg(suboffset(sample_pos_reg, 16))))
-         ->force_sechalf = true;
+      abld.half(0).MOV(half(int_sample_x, 0), fs_reg(sample_pos_reg));
+      abld.half(1).MOV(half(int_sample_x, 1),
+                       fs_reg(suboffset(sample_pos_reg, 16)));
    }
    /* Compute gl_SamplePosition.x */
    compute_sample_position(pos, int_sample_x);
    pos = offset(pos, 1);
    if (dispatch_width == 8) {
-      emit(MOV(int_sample_y, fs_reg(suboffset(sample_pos_reg, 1))));
+      abld.MOV(int_sample_y, fs_reg(suboffset(sample_pos_reg, 1)));
    } else {
-      emit(MOV(half(int_sample_y, 0),
-               fs_reg(suboffset(sample_pos_reg, 1))));
-      emit(MOV(half(int_sample_y, 1), fs_reg(suboffset(sample_pos_reg, 17))))
-         ->force_sechalf = true;
+      abld.half(0).MOV(half(int_sample_y, 0),
+                       fs_reg(suboffset(sample_pos_reg, 1)));
+      abld.half(1).MOV(half(int_sample_y, 1),
+                       fs_reg(suboffset(sample_pos_reg, 17)));
    }
    /* Compute gl_SamplePosition.y */
    compute_sample_position(pos, int_sample_y);
@@ -1548,7 +1199,7 @@ fs_visitor::emit_sampleid_setup()
    brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
    assert(devinfo->gen >= 6);
 
-   this->current_annotation = "compute sample id";
+   const fs_builder abld = bld.annotate("compute sample id");
    fs_reg *reg = new(this->mem_ctx) fs_reg(vgrf(glsl_type::int_type));
 
    if (key->compute_sample_id) {
@@ -1575,26 +1226,25 @@ fs_visitor::emit_sampleid_setup()
        * are sample 1 of subspan 0; the third group is sample 0 of
        * subspan 1, and finally sample 1 of subspan 1.
        */
-      fs_inst *inst;
-      inst = emit(BRW_OPCODE_AND, t1,
-                  fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD)),
-                  fs_reg(0xc0));
-      inst->force_writemask_all = true;
-      inst = emit(BRW_OPCODE_SHR, t1, t1, fs_reg(5));
-      inst->force_writemask_all = true;
+      abld.exec_all()
+          .AND(t1, fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD)),
+               fs_reg(0xc0));
+      abld.exec_all().SHR(t1, t1, fs_reg(5));
+
       /* This works for both SIMD8 and SIMD16 */
-      inst = emit(MOV(t2, brw_imm_v(key->persample_2x ? 0x1010 : 0x3210)));
-      inst->force_writemask_all = true;
+      abld.exec_all()
+          .MOV(t2, brw_imm_v(key->persample_2x ? 0x1010 : 0x3210));
+
       /* This special instruction takes care of setting vstride=1,
        * width=4, hstride=0 of t2 during an ADD instruction.
        */
-      emit(FS_OPCODE_SET_SAMPLE_ID, *reg, t1, t2);
+      abld.emit(FS_OPCODE_SET_SAMPLE_ID, *reg, t1, t2);
    } else {
       /* As per GL_ARB_sample_shading specification:
        * "When rendering to a non-multisample buffer, or if multisample
        *  rasterization is disabled, gl_SampleID will always be zero."
        */
-      emit(BRW_OPCODE_MOV, *reg, fs_reg(0));
+      abld.MOV(*reg, fs_reg(0));
    }
 
    return reg;
@@ -1606,111 +1256,11 @@ fs_visitor::resolve_source_modifiers(fs_reg *src)
    if (!src->abs && !src->negate)
       return;
 
-   fs_reg temp = retype(vgrf(1), src->type);
-   emit(MOV(temp, *src));
+   fs_reg temp = bld.vgrf(src->type);
+   bld.MOV(temp, *src);
    *src = temp;
 }
 
-fs_reg
-fs_visitor::fix_math_operand(fs_reg src)
-{
-   /* Can't do hstride == 0 args on gen6 math, so expand it out. We
-    * might be able to do better by doing execsize = 1 math and then
-    * expanding that result out, but we would need to be careful with
-    * masking.
-    *
-    * The hardware ignores source modifiers (negate and abs) on math
-    * instructions, so we also move to a temp to set those up.
-    */
-   if (devinfo->gen == 6 && src.file != UNIFORM && src.file != IMM &&
-       !src.abs && !src.negate)
-      return src;
-
-   /* Gen7 relaxes most of the above restrictions, but still can't use IMM
-    * operands to math
-    */
-   if (devinfo->gen >= 7 && src.file != IMM)
-      return src;
-
-   fs_reg expanded = vgrf(glsl_type::float_type);
-   expanded.type = src.type;
-   emit(BRW_OPCODE_MOV, expanded, src);
-   return expanded;
-}
-
-fs_inst *
-fs_visitor::emit_math(enum opcode opcode, fs_reg dst, fs_reg src)
-{
-   switch (opcode) {
-   case SHADER_OPCODE_RCP:
-   case SHADER_OPCODE_RSQ:
-   case SHADER_OPCODE_SQRT:
-   case SHADER_OPCODE_EXP2:
-   case SHADER_OPCODE_LOG2:
-   case SHADER_OPCODE_SIN:
-   case SHADER_OPCODE_COS:
-      break;
-   default:
-      unreachable("not reached: bad math opcode");
-   }
-
-   /* Can't do hstride == 0 args to gen6 math, so expand it out.  We
-    * might be able to do better by doing execsize = 1 math and then
-    * expanding that result out, but we would need to be careful with
-    * masking.
-    *
-    * Gen 6 hardware ignores source modifiers (negate and abs) on math
-    * instructions, so we also move to a temp to set those up.
-    */
-   if (devinfo->gen == 6 || devinfo->gen == 7)
-      src = fix_math_operand(src);
-
-   fs_inst *inst = emit(opcode, dst, src);
-
-   if (devinfo->gen < 6) {
-      inst->base_mrf = 2;
-      inst->mlen = dispatch_width / 8;
-   }
-
-   return inst;
-}
-
-fs_inst *
-fs_visitor::emit_math(enum opcode opcode, fs_reg dst, fs_reg src0, fs_reg src1)
-{
-   int base_mrf = 2;
-   fs_inst *inst;
-
-   if (devinfo->gen >= 8) {
-      inst = emit(opcode, dst, src0, src1);
-   } else if (devinfo->gen >= 6) {
-      src0 = fix_math_operand(src0);
-      src1 = fix_math_operand(src1);
-
-      inst = emit(opcode, dst, src0, src1);
-   } else {
-      /* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13
-       * "Message Payload":
-       *
-       * "Operand0[7].  For the INT DIV functions, this operand is the
-       *  denominator."
-       *  ...
-       * "Operand1[7].  For the INT DIV functions, this operand is the
-       *  numerator."
-       */
-      bool is_int_div = opcode != SHADER_OPCODE_POW;
-      fs_reg &op0 = is_int_div ? src1 : src0;
-      fs_reg &op1 = is_int_div ? src0 : src1;
-
-      emit(MOV(fs_reg(MRF, base_mrf + 1, op1.type, dispatch_width), op1));
-      inst = emit(opcode, dst, op0, reg_null_f);
-
-      inst->base_mrf = base_mrf;
-      inst->mlen = 2 * dispatch_width / 8;
-   }
-   return inst;
-}
-
 void
 fs_visitor::emit_discard_jump()
 {
@@ -1719,7 +1269,7 @@ fs_visitor::emit_discard_jump()
    /* For performance, after a discard, jump to the end of the
     * shader if all relevant channels have been discarded.
     */
-   fs_inst *discard_jump = emit(FS_OPCODE_DISCARD_JUMP);
+   fs_inst *discard_jump = bld.emit(FS_OPCODE_DISCARD_JUMP);
    discard_jump->flag_subreg = 1;
 
    discard_jump->predicate = (dispatch_width == 8)
@@ -2317,26 +1867,22 @@ fs_visitor::demote_pull_constants()
            continue;
 
          /* Set up the annotation tracking for new generated instructions. */
-         base_ir = inst->ir;
-         current_annotation = inst->annotation;
-
+         const fs_builder ibld = bld.annotate(inst->annotation, inst->ir)
+                                    .at(block, inst);
          fs_reg surf_index(stage_prog_data->binding_table.pull_constants_start);
          fs_reg dst = vgrf(glsl_type::float_type);
 
          /* Generate a pull load into dst. */
          if (inst->src[i].reladdr) {
-            exec_list list = VARYING_PULL_CONSTANT_LOAD(dst,
-                                                        surf_index,
-                                                        *inst->src[i].reladdr,
-                                                        pull_index);
-            inst->insert_before(block, &list);
+            VARYING_PULL_CONSTANT_LOAD(ibld, dst,
+                                       surf_index,
+                                       *inst->src[i].reladdr,
+                                       pull_index);
             inst->src[i].reladdr = NULL;
          } else {
             fs_reg offset = fs_reg((unsigned)(pull_index * 4) & ~15);
-            fs_inst *pull =
-               new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, 8,
-                                    dst, surf_index, offset);
-            inst->insert_before(block, pull);
+            ibld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
+                      dst, surf_index, offset);
             inst->src[i].set_smear(pull_index & 3);
          }
 
@@ -2663,6 +2209,16 @@ fs_visitor::opt_sampler_eot()
    if (unlikely(tex_inst->is_head_sentinel()) || !tex_inst->is_tex())
       return false;
 
+   /* This optimisation doesn't seem to work for textureGather for some
+    * reason. I can't find any documentation or known workarounds to indicate
+    * that this is expected, but considering that it is probably pretty
+    * unlikely that a shader would directly write out the results from
+    * textureGather we might as well just disable it.
+    */
+   if (tex_inst->opcode == SHADER_OPCODE_TG4 ||
+       tex_inst->opcode == SHADER_OPCODE_TG4_OFFSET)
+      return false;
+
    /* If there's no header present, we need to munge the LOAD_PAYLOAD as well.
     * It's very likely to be the previous instruction.
     */
@@ -2676,7 +2232,7 @@ fs_visitor::opt_sampler_eot()
 
    tex_inst->offset |= fb_write->target << 24;
    tex_inst->eot = true;
-   tex_inst->dst = reg_null_ud;
+   tex_inst->dst = bld.null_reg_ud();
    fb_write->remove(cfg->blocks[cfg->num_blocks - 1]);
 
    /* If a header is present, marking the eot is sufficient. Otherwise, we need
@@ -2688,7 +2244,8 @@ fs_visitor::opt_sampler_eot()
    if (tex_inst->header_size != 0)
       return true;
 
-   fs_reg send_header = vgrf(load_payload->sources + 1);
+   fs_reg send_header = bld.vgrf(BRW_REGISTER_TYPE_F,
+                                 load_payload->sources + 1);
    fs_reg *new_sources =
       ralloc_array(mem_ctx, fs_reg, load_payload->sources + 1);
 
@@ -3041,8 +2598,8 @@ fs_visitor::emit_repclear_shader()
    fs_inst *mov;
 
    if (uniforms == 1) {
-      mov = emit(MOV(vec4(brw_message_reg(color_mrf)),
-                     fs_reg(UNIFORM, 0, BRW_REGISTER_TYPE_F)));
+      mov = bld.exec_all().MOV(vec4(brw_message_reg(color_mrf)),
+                               fs_reg(UNIFORM, 0, BRW_REGISTER_TYPE_F));
    } else {
       struct brw_reg reg =
          brw_reg(BRW_GENERAL_REGISTER_FILE,
@@ -3051,14 +2608,13 @@ fs_visitor::emit_repclear_shader()
                  BRW_WIDTH_2,
                  BRW_HORIZONTAL_STRIDE_4, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
 
-      mov = emit(MOV(vec4(brw_message_reg(color_mrf)), fs_reg(reg)));
+      mov = bld.exec_all().MOV(vec4(brw_message_reg(color_mrf)),
+                               fs_reg(reg));
    }
 
-   mov->force_writemask_all = true;
-
    fs_inst *write;
    if (key->nr_color_regions == 1) {
-      write = emit(FS_OPCODE_REP_FB_WRITE);
+      write = bld.emit(FS_OPCODE_REP_FB_WRITE);
       write->saturate = key->clamp_fragment_color;
       write->base_mrf = color_mrf;
       write->target = 0;
@@ -3067,7 +2623,7 @@ fs_visitor::emit_repclear_shader()
    } else {
       assume(key->nr_color_regions > 0);
       for (int i = 0; i < key->nr_color_regions; ++i) {
-         write = emit(FS_OPCODE_REP_FB_WRITE);
+         write = bld.emit(FS_OPCODE_REP_FB_WRITE);
          write->saturate = key->clamp_fragment_color;
          write->base_mrf = base_mrf;
          write->target = i;
@@ -3223,9 +2779,8 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(bblock_t *block,
        */
       if (block->start() == scan_inst) {
          for (int i = 0; i < write_len; i++) {
-            if (needs_dep[i]) {
-               inst->insert_before(block, DEP_RESOLVE_MOV(first_write_grf + i));
-            }
+            if (needs_dep[i])
+               DEP_RESOLVE_MOV(bld.at(block, inst), first_write_grf + i);
          }
          return;
       }
@@ -3241,7 +2796,7 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(bblock_t *block,
             if (reg >= first_write_grf &&
                 reg < first_write_grf + write_len &&
                 needs_dep[reg - first_write_grf]) {
-               inst->insert_before(block, DEP_RESOLVE_MOV(reg));
+               DEP_RESOLVE_MOV(bld.at(block, inst), reg);
                needs_dep[reg - first_write_grf] = false;
                if (scan_inst->exec_size == 16)
                   needs_dep[reg - first_write_grf + 1] = false;
@@ -3288,8 +2843,7 @@ fs_visitor::insert_gen4_post_send_dependency_workarounds(bblock_t *block, fs_ins
       if (block->end() == scan_inst) {
          for (int i = 0; i < write_len; i++) {
             if (needs_dep[i])
-               scan_inst->insert_before(block,
-                                        DEP_RESOLVE_MOV(first_write_grf + i));
+               DEP_RESOLVE_MOV(bld.at(block, scan_inst), first_write_grf + i);
          }
          return;
       }
@@ -3304,7 +2858,7 @@ fs_visitor::insert_gen4_post_send_dependency_workarounds(bblock_t *block, fs_ins
           scan_inst->dst.reg >= first_write_grf &&
           scan_inst->dst.reg < first_write_grf + write_len &&
           needs_dep[scan_inst->dst.reg - first_write_grf]) {
-         scan_inst->insert_before(block, DEP_RESOLVE_MOV(scan_inst->dst.reg));
+         DEP_RESOLVE_MOV(bld.at(block, scan_inst), scan_inst->dst.reg);
          needs_dep[scan_inst->dst.reg - first_write_grf] = false;
       }
 
@@ -3429,6 +2983,9 @@ fs_visitor::lower_load_payload()
       assert(inst->dst.file == MRF || inst->dst.file == GRF);
       assert(inst->saturate == false);
 
+      const fs_builder ibld = bld.group(inst->exec_size, inst->force_sechalf)
+                                 .exec_all(inst->force_writemask_all)
+                                 .at(block, inst);
       fs_reg dst = inst->dst;
 
       /* Get rid of COMPR4.  We'll add it back in if we need it */
@@ -3441,9 +2998,7 @@ fs_visitor::lower_load_payload()
             fs_reg mov_dst = retype(dst, BRW_REGISTER_TYPE_UD);
             fs_reg mov_src = retype(inst->src[i], BRW_REGISTER_TYPE_UD);
             mov_src.width = 8;
-            fs_inst *mov = MOV(mov_dst, mov_src);
-            mov->force_writemask_all = true;
-            inst->insert_before(block, mov);
+            ibld.exec_all().MOV(mov_dst, mov_src);
          }
          dst = offset(dst, 1);
       }
@@ -3474,23 +3029,13 @@ fs_visitor::lower_load_payload()
                if (devinfo->has_compr4) {
                   fs_reg compr4_dst = retype(dst, inst->src[i].type);
                   compr4_dst.reg |= BRW_MRF_COMPR4;
-
-                  fs_inst *mov = MOV(compr4_dst, inst->src[i]);
-                  mov->force_writemask_all = inst->force_writemask_all;
-                  inst->insert_before(block, mov);
+                  ibld.MOV(compr4_dst, inst->src[i]);
                } else {
                   /* Platform doesn't have COMPR4.  We have to fake it */
                   fs_reg mov_dst = retype(dst, inst->src[i].type);
                   mov_dst.width = 8;
-
-                  fs_inst *mov = MOV(mov_dst, half(inst->src[i], 0));
-                  mov->force_writemask_all = inst->force_writemask_all;
-                  inst->insert_before(block, mov);
-
-                  mov = MOV(offset(mov_dst, 4), half(inst->src[i], 1));
-                  mov->force_writemask_all = inst->force_writemask_all;
-                  mov->force_sechalf = true;
-                  inst->insert_before(block, mov);
+                  ibld.half(0).MOV(mov_dst, half(inst->src[i], 0));
+                  ibld.half(1).MOV(offset(mov_dst, 4), half(inst->src[i], 1));
                }
             }
 
@@ -3513,12 +3058,8 @@ fs_visitor::lower_load_payload()
       }
 
       for (uint8_t i = inst->header_size; i < inst->sources; i++) {
-         if (inst->src[i].file != BAD_FILE) {
-            fs_inst *mov = MOV(retype(dst, inst->src[i].type),
-                               inst->src[i]);
-            mov->force_writemask_all = inst->force_writemask_all;
-            inst->insert_before(block, mov);
-         }
+         if (inst->src[i].file != BAD_FILE)
+            ibld.MOV(retype(dst, inst->src[i].type), inst->src[i]);
          dst = offset(dst, 1);
       }
 
@@ -3532,6 +3073,172 @@ fs_visitor::lower_load_payload()
    return progress;
 }
 
+bool
+fs_visitor::lower_integer_multiplication()
+{
+   bool progress = false;
+
+   /* Gen8's MUL instruction can do a 32-bit x 32-bit -> 32-bit operation
+    * directly, but Cherryview cannot.
+    */
+   if (devinfo->gen >= 8 && !devinfo->is_cherryview)
+      return false;
+
+   foreach_block_and_inst_safe(block, fs_inst, inst, cfg) {
+      if (inst->opcode != BRW_OPCODE_MUL ||
+          inst->dst.is_accumulator() ||
+          (inst->dst.type != BRW_REGISTER_TYPE_D &&
+           inst->dst.type != BRW_REGISTER_TYPE_UD))
+         continue;
+
+      const fs_builder ibld = bld.at(block, inst);
+
+      /* The MUL instruction isn't commutative. On Gen <= 6, only the low
+       * 16-bits of src0 are read, and on Gen >= 7 only the low 16-bits of
+       * src1 are used.
+       *
+       * If multiplying by an immediate value that fits in 16-bits, do a
+       * single MUL instruction with that value in the proper location.
+       */
+      if (inst->src[1].file == IMM &&
+          inst->src[1].fixed_hw_reg.dw1.ud < (1 << 16)) {
+         if (devinfo->gen < 7) {
+            fs_reg imm(GRF, alloc.allocate(dispatch_width / 8),
+                       inst->dst.type, dispatch_width);
+            ibld.MOV(imm, inst->src[1]);
+            ibld.MUL(inst->dst, imm, inst->src[0]);
+         } else {
+            ibld.MUL(inst->dst, inst->src[0], inst->src[1]);
+         }
+      } else {
+         /* Gen < 8 (and some Gen8+ low-power parts like Cherryview) cannot
+          * do 32-bit integer multiplication in one instruction, but instead
+          * must do a sequence (which actually calculates a 64-bit result):
+          *
+          *    mul(8)  acc0<1>D   g3<8,8,1>D      g4<8,8,1>D
+          *    mach(8) null       g3<8,8,1>D      g4<8,8,1>D
+          *    mov(8)  g2<1>D     acc0<8,8,1>D
+          *
+          * But on Gen > 6, the ability to use second accumulator register
+          * (acc1) for non-float data types was removed, preventing a simple
+          * implementation in SIMD16. A 16-channel result can be calculated by
+          * executing the three instructions twice in SIMD8, once with quarter
+          * control of 1Q for the first eight channels and again with 2Q for
+          * the second eight channels.
+          *
+          * Which accumulator register is implicitly accessed (by AccWrEnable
+          * for instance) is determined by the quarter control. Unfortunately
+          * Ivybridge (and presumably Baytrail) has a hardware bug in which an
+          * implicit accumulator access by an instruction with 2Q will access
+          * acc1 regardless of whether the data type is usable in acc1.
+          *
+          * Specifically, the 2Q mach(8) writes acc1 which does not exist for
+          * integer data types.
+          *
+          * Since we only want the low 32-bits of the result, we can do two
+          * 32-bit x 16-bit multiplies (like the mul and mach are doing), and
+          * adjust the high result and add them (like the mach is doing):
+          *
+          *    mul(8)  g7<1>D     g3<8,8,1>D      g4.0<8,8,1>UW
+          *    mul(8)  g8<1>D     g3<8,8,1>D      g4.1<8,8,1>UW
+          *    shl(8)  g9<1>D     g8<8,8,1>D      16D
+          *    add(8)  g2<1>D     g7<8,8,1>D      g8<8,8,1>D
+          *
+          * We avoid the shl instruction by realizing that we only want to add
+          * the low 16-bits of the "high" result to the high 16-bits of the
+          * "low" result and using proper regioning on the add:
+          *
+          *    mul(8)  g7<1>D     g3<8,8,1>D      g4.0<16,8,2>UW
+          *    mul(8)  g8<1>D     g3<8,8,1>D      g4.1<16,8,2>UW
+          *    add(8)  g7.1<2>UW  g7.1<16,8,2>UW  g8<16,8,2>UW
+          *
+          * Since it does not use the (single) accumulator register, we can
+          * schedule multi-component multiplications much better.
+          */
+
+         if (inst->conditional_mod && inst->dst.is_null()) {
+            inst->dst = fs_reg(GRF, alloc.allocate(dispatch_width / 8),
+                               inst->dst.type, dispatch_width);
+         }
+         fs_reg low = inst->dst;
+         fs_reg high(GRF, alloc.allocate(dispatch_width / 8),
+                     inst->dst.type, dispatch_width);
+
+         if (devinfo->gen >= 7) {
+            fs_reg src1_0_w = inst->src[1];
+            fs_reg src1_1_w = inst->src[1];
+
+            if (inst->src[1].file == IMM) {
+               src1_0_w.fixed_hw_reg.dw1.ud &= 0xffff;
+               src1_1_w.fixed_hw_reg.dw1.ud >>= 16;
+            } else {
+               src1_0_w.type = BRW_REGISTER_TYPE_UW;
+               if (src1_0_w.stride != 0) {
+                  assert(src1_0_w.stride == 1);
+                  src1_0_w.stride = 2;
+               }
+
+               src1_1_w.type = BRW_REGISTER_TYPE_UW;
+               if (src1_1_w.stride != 0) {
+                  assert(src1_1_w.stride == 1);
+                  src1_1_w.stride = 2;
+               }
+               src1_1_w.subreg_offset += type_sz(BRW_REGISTER_TYPE_UW);
+            }
+            ibld.MUL(low, inst->src[0], src1_0_w);
+            ibld.MUL(high, inst->src[0], src1_1_w);
+         } else {
+            fs_reg src0_0_w = inst->src[0];
+            fs_reg src0_1_w = inst->src[0];
+
+            src0_0_w.type = BRW_REGISTER_TYPE_UW;
+            if (src0_0_w.stride != 0) {
+               assert(src0_0_w.stride == 1);
+               src0_0_w.stride = 2;
+            }
+
+            src0_1_w.type = BRW_REGISTER_TYPE_UW;
+            if (src0_1_w.stride != 0) {
+               assert(src0_1_w.stride == 1);
+               src0_1_w.stride = 2;
+            }
+            src0_1_w.subreg_offset += type_sz(BRW_REGISTER_TYPE_UW);
+
+            ibld.MUL(low, src0_0_w, inst->src[1]);
+            ibld.MUL(high, src0_1_w, inst->src[1]);
+         }
+
+         fs_reg dst = inst->dst;
+         dst.type = BRW_REGISTER_TYPE_UW;
+         dst.subreg_offset = 2;
+         dst.stride = 2;
+
+         high.type = BRW_REGISTER_TYPE_UW;
+         high.stride = 2;
+
+         low.type = BRW_REGISTER_TYPE_UW;
+         low.subreg_offset = 2;
+         low.stride = 2;
+
+         ibld.ADD(dst, low, high);
+
+         if (inst->conditional_mod) {
+            fs_reg null(retype(ibld.null_reg_f(), inst->dst.type));
+            set_condmod(inst->conditional_mod,
+                        ibld.MOV(null, inst->dst));
+         }
+      }
+
+      inst->remove(block);
+      progress = true;
+   }
+
+   if (progress)
+      invalidate_live_intervals();
+
+   return progress;
+}
+
 void
 fs_visitor::dump_instructions()
 {
@@ -3602,6 +3309,9 @@ fs_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)
    }
    fprintf(file, "(%d) ", inst->exec_size);
 
+   if (inst->mlen) {
+      fprintf(file, "(mlen: %d) ", inst->mlen);
+   }
 
    switch (inst->dst.file) {
    case GRF:
@@ -3895,7 +3605,7 @@ fs_visitor::setup_vs_payload()
 void
 fs_visitor::setup_cs_payload()
 {
-   assert(brw->gen >= 7);
+   assert(devinfo->gen >= 7);
 
    payload.num_regs = 1;
 }
@@ -3938,6 +3648,17 @@ fs_visitor::calculate_register_pressure()
 void
 fs_visitor::optimize()
 {
+   /* bld is the common builder object pointing at the end of the program we
+    * used to translate it into i965 IR.  For the optimization and lowering
+    * passes coming next, any code added after the end of the program without
+    * having explicitly called fs_builder::at() clearly points at a mistake.
+    * Ideally optimization passes wouldn't be part of the visitor so they
+    * wouldn't have access to bld at all, but they do, so just in case some
+    * pass forgets to ask for a location explicitly set it to NULL here to
+    * make it trip.
+    */
+   bld = bld.at(NULL, NULL);
+
    split_virtual_grfs();
 
    move_uniform_array_access_to_pull_constants();
@@ -3953,7 +3674,7 @@ fs_visitor::optimize()
          snprintf(filename, 64, "%s%d-%04d-%02d-%02d-" #pass,              \
                   stage_abbrev, dispatch_width, shader_prog ? shader_prog->Name : 0, iteration, pass_num); \
                                                                         \
-         backend_visitor::dump_instructions(filename);                  \
+         backend_shader::dump_instructions(filename);                   \
       }                                                                 \
                                                                         \
       progress = progress || this_progress;                             \
@@ -3966,7 +3687,7 @@ fs_visitor::optimize()
                stage_abbrev, dispatch_width,
                shader_prog ? shader_prog->Name : 0);
 
-      backend_visitor::dump_instructions(filename);
+      backend_shader::dump_instructions(filename);
    }
 
    bool progress;
@@ -4010,6 +3731,7 @@ fs_visitor::optimize()
    }
 
    OPT(opt_combine_constants);
+   OPT(lower_integer_multiplication);
 
    lower_uniform_pull_constant_loads();
 }
@@ -4066,9 +3788,11 @@ fs_visitor::allocate_registers()
          fail("Failure to register allocate.  Reduce number of "
               "live scalar values to avoid this.");
       } else {
-         perf_debug("%s shader triggered register spilling.  "
-                    "Try reducing the number of live scalar values to "
-                    "improve performance.\n", stage_name);
+         compiler->shader_perf_log(log_data,
+                                   "%s shader triggered register spilling.  "
+                                   "Try reducing the number of live scalar "
+                                   "values to improve performance.\n",
+                                   stage_name);
       }
 
       /* Since we're out of heuristics, just go spill registers until we
@@ -4097,7 +3821,7 @@ fs_visitor::allocate_registers()
 }
 
 bool
-fs_visitor::run_vs()
+fs_visitor::run_vs(gl_clip_plane *clip_planes)
 {
    assert(stage == MESA_SHADER_VERTEX);
 
@@ -4105,26 +3829,17 @@ fs_visitor::run_vs()
       assign_common_binding_table_offsets(0);
    setup_vs_payload();
 
-   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+   if (shader_time_index >= 0)
       emit_shader_time_begin();
 
-   if (brw->ctx.Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].NirOptions) {
-      emit_nir_code();
-   } else {
-      foreach_in_list(ir_instruction, ir, shader->base.ir) {
-         base_ir = ir;
-         this->result = reg_undef;
-         ir->accept(this);
-      }
-      base_ir = NULL;
-   }
+   emit_nir_code();
 
    if (failed)
       return false;
 
-   emit_urb_writes();
+   emit_urb_writes(clip_planes);
 
-   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+   if (shader_time_index >= 0)
       emit_shader_time_end();
 
    calculate_cfg();
@@ -4141,7 +3856,7 @@ fs_visitor::run_vs()
 }
 
 bool
-fs_visitor::run_fs()
+fs_visitor::run_fs(bool do_rep_send)
 {
    brw_wm_prog_data *wm_prog_data = (brw_wm_prog_data *) this->prog_data;
    brw_wm_prog_key *wm_key = (brw_wm_prog_key *) this->key;
@@ -4160,10 +3875,11 @@ fs_visitor::run_fs()
 
    if (0) {
       emit_dummy_fs();
-   } else if (brw->use_rep_send && dispatch_width == 16) {
+   } else if (do_rep_send) {
+      assert(dispatch_width == 16);
       emit_repclear_shader();
    } else {
-      if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+      if (shader_time_index >= 0)
          emit_shader_time_begin();
 
       calculate_urb_setup();
@@ -4178,37 +3894,27 @@ fs_visitor::run_fs()
        * Initialize it with the dispatched pixels.
        */
       if (wm_prog_data->uses_kill) {
-         fs_inst *discard_init = emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
+         fs_inst *discard_init = bld.emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
          discard_init->flag_subreg = 1;
       }
 
       /* Generate FS IR for main().  (the visitor only descends into
        * functions called "main").
        */
-      if (brw->ctx.Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions) {
-         emit_nir_code();
-      } else if (shader) {
-         foreach_in_list(ir_instruction, ir, shader->base.ir) {
-            base_ir = ir;
-            this->result = reg_undef;
-            ir->accept(this);
-         }
-      } else {
-         emit_fragment_program_code();
-      }
-      base_ir = NULL;
+      emit_nir_code();
+
       if (failed)
         return false;
 
       if (wm_prog_data->uses_kill)
-         emit(FS_OPCODE_PLACEHOLDER_HALT);
+         bld.emit(FS_OPCODE_PLACEHOLDER_HALT);
 
       if (wm_key->alpha_test_func)
          emit_alpha_test();
 
       emit_fb_writes();
 
-      if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+      if (shader_time_index >= 0)
          emit_shader_time_end();
 
       calculate_cfg();
@@ -4252,7 +3958,7 @@ fs_visitor::run_cs()
 
    setup_cs_payload();
 
-   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+   if (shader_time_index >= 0)
       emit_shader_time_begin();
 
    emit_nir_code();
@@ -4262,7 +3968,7 @@ fs_visitor::run_cs()
 
    emit_cs_terminate();
 
-   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+   if (shader_time_index >= 0)
       emit_shader_time_end();
 
    calculate_cfg();
@@ -4312,10 +4018,18 @@ brw_wm_fs_emit(struct brw_context *brw,
    if (unlikely(INTEL_DEBUG & DEBUG_WM))
       brw_dump_ir("fragment", prog, &shader->base, &fp->Base);
 
+   int st_index8 = -1, st_index16 = -1;
+   if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
+      st_index8 = brw_get_shader_time_index(brw, prog, &fp->Base, ST_FS8);
+      st_index16 = brw_get_shader_time_index(brw, prog, &fp->Base, ST_FS16);
+   }
+
    /* Now the main event: Visit the shader IR and generate our FS IR for it.
     */
-   fs_visitor v(brw, mem_ctx, key, prog_data, prog, fp, 8);
-   if (!v.run_fs()) {
+   fs_visitor v(brw->intelScreen->compiler, brw,
+                mem_ctx, MESA_SHADER_FRAGMENT, key, &prog_data->base,
+                prog, &fp->Base, 8, st_index8);
+   if (!v.run_fs(false /* do_rep_send */)) {
       if (prog) {
          prog->LinkStatus = false;
          ralloc_strcat(&prog->InfoLog, v.fail_msg);
@@ -4328,20 +4042,18 @@ brw_wm_fs_emit(struct brw_context *brw,
    }
 
    cfg_t *simd16_cfg = NULL;
-   fs_visitor v2(brw, mem_ctx, key, prog_data, prog, fp, 16);
+   fs_visitor v2(brw->intelScreen->compiler, brw,
+                 mem_ctx, MESA_SHADER_FRAGMENT, key, &prog_data->base,
+                 prog, &fp->Base, 16, st_index16);
    if (likely(!(INTEL_DEBUG & DEBUG_NO16) || brw->use_rep_send)) {
       if (!v.simd16_unsupported) {
          /* Try a SIMD16 compile */
          v2.import_uniforms(&v);
-         if (!v2.run_fs()) {
-            perf_debug("SIMD16 shader failed to compile, falling back to "
-                       "SIMD8 at a 10-20%% performance cost: %s", v2.fail_msg);
+         if (!v2.run_fs(brw->use_rep_send)) {
+            perf_debug("SIMD16 shader failed to compile: %s", v2.fail_msg);
          } else {
             simd16_cfg = v2.cfg;
          }
-      } else {
-         perf_debug("SIMD16 shader unsupported, falling back to "
-                    "SIMD8 at a 10-20%% performance cost: %s", v.no16_msg);
       }
    }
 
@@ -4355,7 +4067,8 @@ brw_wm_fs_emit(struct brw_context *brw,
       prog_data->no_8 = false;
    }
 
-   fs_generator g(brw, mem_ctx, (void *) key, &prog_data->base,
+   fs_generator g(brw->intelScreen->compiler, brw,
+                  mem_ctx, (void *) key, &prog_data->base,
                   &fp->Base, v.promoted_constants, v.runtime_check_aads_emit, "FS");
 
    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
index 1d7de2effbd2a0e6ab6ae10719363a66ac05f5db..243baf688ded3f0b8b29454f59b46c52427f1b68 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "brw_shader.h"
 #include "brw_ir_fs.h"
+#include "brw_fs_builder.h"
 
 extern "C" {
 
@@ -66,138 +67,44 @@ namespace brw {
  *
  * Translates either GLSL IR or Mesa IR (for ARB_fragment_program) into FS IR.
  */
-class fs_visitor : public backend_visitor
+class fs_visitor : public backend_shader
 {
 public:
-   const fs_reg reg_null_f;
-   const fs_reg reg_null_d;
-   const fs_reg reg_null_ud;
-
-   fs_visitor(struct brw_context *brw,
+   fs_visitor(const struct brw_compiler *compiler, void *log_data,
               void *mem_ctx,
-              const struct brw_wm_prog_key *key,
-              struct brw_wm_prog_data *prog_data,
+              gl_shader_stage stage,
+              const void *key,
+              struct brw_stage_prog_data *prog_data,
               struct gl_shader_program *shader_prog,
-              struct gl_fragment_program *fp,
-              unsigned dispatch_width);
-
-   fs_visitor(struct brw_context *brw,
-              void *mem_ctx,
-              const struct brw_vs_prog_key *key,
-              struct brw_vs_prog_data *prog_data,
-              struct gl_shader_program *shader_prog,
-              struct gl_vertex_program *cp,
-              unsigned dispatch_width);
-
-   fs_visitor(struct brw_context *brw,
-              void *mem_ctx,
-              const struct brw_cs_prog_key *key,
-              struct brw_cs_prog_data *prog_data,
-              struct gl_shader_program *shader_prog,
-              struct gl_compute_program *cp,
-              unsigned dispatch_width);
+              struct gl_program *prog,
+              unsigned dispatch_width,
+              int shader_time_index);
 
    ~fs_visitor();
-   void init();
 
-   fs_reg *variable_storage(ir_variable *var);
    fs_reg vgrf(const glsl_type *const type);
-   fs_reg vgrf(int num_components);
    void import_uniforms(fs_visitor *v);
-   void setup_uniform_clipplane_values();
-   void compute_clip_distance();
-
-   void visit(ir_variable *ir);
-   void visit(ir_assignment *ir);
-   void visit(ir_dereference_variable *ir);
-   void visit(ir_dereference_record *ir);
-   void visit(ir_dereference_array *ir);
-   void visit(ir_expression *ir);
-   void visit(ir_texture *ir);
-   void visit(ir_if *ir);
-   void visit(ir_constant *ir);
-   void visit(ir_swizzle *ir);
-   void visit(ir_return *ir);
-   void visit(ir_loop *ir);
-   void visit(ir_loop_jump *ir);
-   void visit(ir_discard *ir);
-   void visit(ir_call *ir);
-   void visit(ir_function *ir);
-   void visit(ir_function_signature *ir);
-   void visit(ir_emit_vertex *);
-   void visit(ir_end_primitive *);
+   void setup_uniform_clipplane_values(gl_clip_plane *clip_planes);
+   void compute_clip_distance(gl_clip_plane *clip_planes);
 
    uint32_t gather_channel(int orig_chan, uint32_t sampler);
    void swizzle_result(ir_texture_opcode op, int dest_components,
                        fs_reg orig_val, uint32_t sampler);
 
-   fs_inst *emit(fs_inst *inst);
-   void emit(exec_list list);
-
-   fs_inst *emit(enum opcode opcode);
-   fs_inst *emit(enum opcode opcode, const fs_reg &dst);
-   fs_inst *emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0);
-   fs_inst *emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0,
-                 const fs_reg &src1);
-   fs_inst *emit(enum opcode opcode, const fs_reg &dst,
-                 const fs_reg &src0, const fs_reg &src1, const fs_reg &src2);
-   fs_inst *emit(enum opcode opcode, const fs_reg &dst,
-                 fs_reg src[], int sources);
-
-   fs_inst *MOV(const fs_reg &dst, const fs_reg &src);
-   fs_inst *NOT(const fs_reg &dst, const fs_reg &src);
-   fs_inst *RNDD(const fs_reg &dst, const fs_reg &src);
-   fs_inst *RNDE(const fs_reg &dst, const fs_reg &src);
-   fs_inst *RNDZ(const fs_reg &dst, const fs_reg &src);
-   fs_inst *FRC(const fs_reg &dst, const fs_reg &src);
-   fs_inst *ADD(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *MUL(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *MACH(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *MAC(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *SHL(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *SHR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *ASR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *AND(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *OR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *XOR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *IF(enum brw_predicate predicate);
-   fs_inst *IF(const fs_reg &src0, const fs_reg &src1,
-               enum brw_conditional_mod condition);
-   fs_inst *CMP(fs_reg dst, fs_reg src0, fs_reg src1,
-                enum brw_conditional_mod condition);
-   fs_inst *LRP(const fs_reg &dst, const fs_reg &a, const fs_reg &y,
-                const fs_reg &x);
-   fs_inst *DEP_RESOLVE_MOV(int grf);
-   fs_inst *BFREV(const fs_reg &dst, const fs_reg &value);
-   fs_inst *BFE(const fs_reg &dst, const fs_reg &bits, const fs_reg &offset,
-                const fs_reg &value);
-   fs_inst *BFI1(const fs_reg &dst, const fs_reg &bits, const fs_reg &offset);
-   fs_inst *BFI2(const fs_reg &dst, const fs_reg &bfi1_dst,
-                 const fs_reg &insert, const fs_reg &base);
-   fs_inst *FBH(const fs_reg &dst, const fs_reg &value);
-   fs_inst *FBL(const fs_reg &dst, const fs_reg &value);
-   fs_inst *CBIT(const fs_reg &dst, const fs_reg &value);
-   fs_inst *MAD(const fs_reg &dst, const fs_reg &c, const fs_reg &b,
-                const fs_reg &a);
-   fs_inst *ADDC(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *SUBB(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-   fs_inst *SEL(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1);
-
    int type_size(const struct glsl_type *type);
    fs_inst *get_instruction_generating_reg(fs_inst *start,
                                           fs_inst *end,
                                           const fs_reg &reg);
 
-   fs_inst *LOAD_PAYLOAD(const fs_reg &dst, fs_reg *src, int sources,
-                         int header_size);
-
-   exec_list VARYING_PULL_CONSTANT_LOAD(const fs_reg &dst,
-                                        const fs_reg &surf_index,
-                                        const fs_reg &varying_offset,
-                                        uint32_t const_offset);
+   void VARYING_PULL_CONSTANT_LOAD(const brw::fs_builder &bld,
+                                   const fs_reg &dst,
+                                   const fs_reg &surf_index,
+                                   const fs_reg &varying_offset,
+                                   uint32_t const_offset);
+   void DEP_RESOLVE_MOV(const brw::fs_builder &bld, int grf);
 
-   bool run_fs();
-   bool run_vs();
+   bool run_fs(bool do_rep_send);
+   bool run_vs(gl_clip_plane *clip_planes);
    bool run_cs();
    void optimize();
    void allocate_registers();
@@ -213,11 +120,8 @@ public:
    void assign_vs_urb_setup();
    bool assign_regs(bool allow_spilling);
    void assign_regs_trivial();
-   void get_used_mrfs(bool *mrf_used);
    void setup_payload_interference(struct ra_graph *g, int payload_reg_count,
                                    int first_payload_node);
-   void setup_mrf_hack_interference(struct ra_graph *g,
-                                    int first_mrf_hack_node);
    int choose_spill_reg(struct ra_graph *g);
    void spill_reg(int spill_reg);
    void split_virtual_grfs();
@@ -254,9 +158,10 @@ public:
                                                      fs_inst *inst);
    void vfail(const char *msg, va_list args);
    void fail(const char *msg, ...);
-   void no16(const char *msg, ...);
+   void no16(const char *msg);
    void lower_uniform_pull_constant_loads();
    bool lower_load_payload();
+   bool lower_integer_multiplication();
    bool opt_combine_constants();
 
    void emit_dummy_fs();
@@ -318,58 +223,18 @@ public:
    fs_reg emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler);
    void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
    void resolve_source_modifiers(fs_reg *src);
-   fs_reg fix_math_operand(fs_reg src);
-   fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
-   fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
-   fs_inst *emit_lrp(const fs_reg &dst, const fs_reg &x, const fs_reg &y,
-                     const fs_reg &a);
-   void emit_minmax(enum brw_conditional_mod conditionalmod, const fs_reg &dst,
-                    const fs_reg &src0, const fs_reg &src1);
    void emit_discard_jump();
-   /** Copy any live channel from \p src to the first channel of \p dst. */
-   void emit_uniformize(const fs_reg &dst, const fs_reg &src);
-   bool try_emit_b2f_of_comparison(ir_expression *ir);
-   bool try_emit_saturate(ir_expression *ir);
-   bool try_emit_line(ir_expression *ir);
-   bool try_emit_mad(ir_expression *ir);
    bool try_replace_with_sel();
-   bool try_opt_frontfacing_ternary(ir_if *ir);
    bool opt_peephole_sel();
    bool opt_peephole_predicated_break();
    bool opt_saturate_propagation();
    bool opt_cmod_propagation();
    bool opt_zero_samples();
-   void emit_bool_to_cond_code(ir_rvalue *condition);
-   void emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3]);
-   void emit_if_gen6(ir_if *ir);
    void emit_unspill(bblock_t *block, fs_inst *inst, fs_reg reg,
                      uint32_t spill_offset, int count);
    void emit_spill(bblock_t *block, fs_inst *inst, fs_reg reg,
                    uint32_t spill_offset, int count);
 
-   void emit_fragment_program_code();
-   void setup_fp_regs();
-   fs_reg get_fp_src_reg(const prog_src_register *src);
-   fs_reg get_fp_dst_reg(const prog_dst_register *dst);
-   void emit_fp_alu1(enum opcode opcode,
-                     const struct prog_instruction *fpi,
-                     fs_reg dst, fs_reg src);
-   void emit_fp_alu2(enum opcode opcode,
-                     const struct prog_instruction *fpi,
-                     fs_reg dst, fs_reg src0, fs_reg src1);
-   void emit_fp_scalar_write(const struct prog_instruction *fpi,
-                             fs_reg dst, fs_reg src);
-   void emit_fp_scalar_math(enum opcode opcode,
-                            const struct prog_instruction *fpi,
-                            fs_reg dst, fs_reg src);
-
-   void emit_fp_minmax(const struct prog_instruction *fpi,
-                       fs_reg dst, fs_reg src0, fs_reg src1);
-
-   void emit_fp_sop(enum brw_conditional_mod conditional_mod,
-                    const struct prog_instruction *fpi,
-                    fs_reg dst, fs_reg src0, fs_reg src1, fs_reg one);
-
    void emit_nir_code();
    void nir_setup_inputs(nir_shader *shader);
    void nir_setup_outputs(nir_shader *shader);
@@ -383,13 +248,17 @@ public:
    void nir_emit_loop(nir_loop *loop);
    void nir_emit_block(nir_block *block);
    void nir_emit_instr(nir_instr *instr);
-   void nir_emit_alu(nir_alu_instr *instr);
-   void nir_emit_intrinsic(nir_intrinsic_instr *instr);
-   void nir_emit_texture(nir_tex_instr *instr);
-   void nir_emit_jump(nir_jump_instr *instr);
+   void nir_emit_alu(const brw::fs_builder &bld, nir_alu_instr *instr);
+   void nir_emit_intrinsic(const brw::fs_builder &bld,
+                           nir_intrinsic_instr *instr);
+   void nir_emit_texture(const brw::fs_builder &bld,
+                         nir_tex_instr *instr);
+   void nir_emit_jump(const brw::fs_builder &bld,
+                      nir_jump_instr *instr);
    fs_reg get_nir_src(nir_src src);
    fs_reg get_nir_dest(nir_dest dest);
-   void emit_percomp(fs_inst *inst, unsigned wr_mask);
+   void emit_percomp(const brw::fs_builder &bld, const fs_inst &inst,
+                     unsigned wr_mask);
 
    bool optimize_frontfacing_ternary(nir_alu_instr *instr,
                                      const fs_reg &result);
@@ -397,16 +266,21 @@ public:
    void setup_color_payload(fs_reg *dst, fs_reg color, unsigned components,
                             unsigned exec_size, bool use_2nd_half);
    void emit_alpha_test();
-   fs_inst *emit_single_fb_write(fs_reg color1, fs_reg color2,
+   fs_inst *emit_single_fb_write(const brw::fs_builder &bld,
+                                 fs_reg color1, fs_reg color2,
                                  fs_reg src0_alpha, unsigned components,
                                  unsigned exec_size, bool use_2nd_half = false);
    void emit_fb_writes();
-   void emit_urb_writes();
+   void emit_urb_writes(gl_clip_plane *clip_planes);
    void emit_cs_terminate();
 
+   void emit_barrier();
+
    void emit_shader_time_begin();
    void emit_shader_time_end();
-   fs_inst *SHADER_TIME_ADD(enum shader_time_shader_type type, fs_reg value);
+   void SHADER_TIME_ADD(const brw::fs_builder &bld,
+                        int shader_time_subindex,
+                        fs_reg value);
 
    void emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
                             fs_reg dst, fs_reg offset, fs_reg src0,
@@ -415,23 +289,9 @@ public:
    void emit_untyped_surface_read(unsigned surf_index, fs_reg dst,
                                   fs_reg offset);
 
-   void emit_interpolate_expression(ir_expression *ir);
-
-   bool try_rewrite_rhs_to_dst(ir_assignment *ir,
-                              fs_reg dst,
-                              fs_reg src,
-                              fs_inst *pre_rhs_inst,
-                              fs_inst *last_rhs_inst);
-   void emit_assignment_writes(fs_reg &l, fs_reg &r,
-                              const glsl_type *type, bool predicated);
-   void resolve_ud_negate(fs_reg *reg);
-   void resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg);
-
-   fs_reg get_timestamp(fs_inst **out_mov);
+   fs_reg get_timestamp(const brw::fs_builder &bld);
 
    struct brw_reg interp_reg(int location, int channel);
-   void setup_uniform_values(ir_variable *ir);
-   void setup_builtin_uniform_values(ir_variable *ir);
    int implied_mrf_writes(fs_inst *inst);
 
    virtual void dump_instructions();
@@ -439,8 +299,6 @@ public:
    void dump_instruction(backend_instruction *inst);
    void dump_instruction(backend_instruction *inst, FILE *file);
 
-   void visit_atomic_counter_intrinsic(ir_call *ir);
-
    const void *const key;
    const struct brw_sampler_prog_key_data *key_tex;
 
@@ -476,7 +334,6 @@ public:
     */
    int *push_constant_loc;
 
-   struct hash_table *variable_ht;
    fs_reg frag_depth;
    fs_reg sample_mask;
    fs_reg outputs[VARYING_SLOT_MAX];
@@ -487,26 +344,18 @@ public:
    /** Either BRW_MAX_GRF or GEN7_MRF_HACK_START */
    unsigned max_grf;
 
-   fs_reg *fp_temp_regs;
-   fs_reg *fp_input_regs;
-
    fs_reg *nir_locals;
    fs_reg *nir_globals;
    fs_reg nir_inputs;
    fs_reg nir_outputs;
    fs_reg *nir_system_values;
 
-   /** @{ debug annotation info */
-   const char *current_annotation;
-   const void *base_ir;
-   /** @} */
-
    bool failed;
    char *fail_msg;
    bool simd16_unsupported;
    char *no16_msg;
 
-   /* Result of last visit() method. */
+   /* Result of last visit() method. Still used by emit_texture() */
    fs_reg result;
 
    /** Register numbers for thread payload fields. */
@@ -539,7 +388,10 @@ public:
 
    const unsigned dispatch_width; /**< 8 or 16 */
 
+   int shader_time_index;
+
    unsigned promoted_constants;
+   brw::fs_builder bld;
 };
 
 /**
@@ -550,7 +402,7 @@ public:
 class fs_generator
 {
 public:
-   fs_generator(struct brw_context *brw,
+   fs_generator(const struct brw_compiler *compiler, void *log_data,
                 void *mem_ctx,
                 const void *key,
                 struct brw_stage_prog_data *prog_data,
@@ -572,6 +424,7 @@ private:
    void generate_fb_write(fs_inst *inst, struct brw_reg payload);
    void generate_urb_write(fs_inst *inst, struct brw_reg payload);
    void generate_cs_terminate(fs_inst *inst, struct brw_reg payload);
+   void generate_barrier(fs_inst *inst, struct brw_reg src);
    void generate_blorp_fb_write(fs_inst *inst);
    void generate_linterp(fs_inst *inst, struct brw_reg dst,
                         struct brw_reg *src);
@@ -644,7 +497,9 @@ private:
 
    bool patch_discard_jumps_to_fb_writes();
 
-   struct brw_context *brw;
+   const struct brw_compiler *compiler;
+   void *log_data; /* Passed to compiler->*_log functions */
+
    const struct brw_device_info *devinfo;
 
    struct brw_codegen *p;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_builder.h b/src/mesa/drivers/dri/i965/brw_fs_builder.h
new file mode 100644 (file)
index 0000000..58ac598
--- /dev/null
@@ -0,0 +1,652 @@
+/* -*- c++ -*- */
+/*
+ * Copyright Â© 2010-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef BRW_FS_BUILDER_H
+#define BRW_FS_BUILDER_H
+
+#include "brw_ir_fs.h"
+#include "brw_shader.h"
+#include "brw_context.h"
+
+namespace brw {
+   /**
+    * Toolbox to assemble an FS IR program out of individual instructions.
+    *
+    * This object is meant to have an interface consistent with
+    * brw::vec4_builder.  They cannot be fully interchangeable because
+    * brw::fs_builder generates scalar code while brw::vec4_builder generates
+    * vector code.
+    */
+   class fs_builder {
+   public:
+      /** Type used in this IR to represent a source of an instruction. */
+      typedef fs_reg src_reg;
+
+      /** Type used in this IR to represent the destination of an instruction. */
+      typedef fs_reg dst_reg;
+
+      /** Type used in this IR to represent an instruction. */
+      typedef fs_inst instruction;
+
+      /**
+       * Construct an fs_builder that inserts instructions into \p shader.
+       * \p dispatch_width gives the native execution width of the program.
+       */
+      fs_builder(backend_shader *shader,
+                 unsigned dispatch_width) :
+         shader(shader), block(NULL), cursor(NULL),
+         _dispatch_width(dispatch_width),
+         _group(0),
+         force_writemask_all(false),
+         annotation()
+      {
+      }
+
+      /**
+       * Construct an fs_builder that inserts instructions before \p cursor in
+       * basic block \p block, inheriting other code generation parameters
+       * from this.
+       */
+      fs_builder
+      at(bblock_t *block, exec_node *cursor) const
+      {
+         fs_builder bld = *this;
+         bld.block = block;
+         bld.cursor = cursor;
+         return bld;
+      }
+
+      /**
+       * Construct an fs_builder appending instructions at the end of the
+       * instruction list of the shader, inheriting other code generation
+       * parameters from this.
+       */
+      fs_builder
+      at_end() const
+      {
+         return at(NULL, (exec_node *)&shader->instructions.tail);
+      }
+
+      /**
+       * Construct a builder specifying the default SIMD width and group of
+       * channel enable signals, inheriting other code generation parameters
+       * from this.
+       *
+       * \p n gives the default SIMD width, \p i gives the slot group used for
+       * predication and control flow masking in multiples of \p n channels.
+       */
+      fs_builder
+      group(unsigned n, unsigned i) const
+      {
+         assert(n <= dispatch_width() &&
+                i < dispatch_width() / n);
+         fs_builder bld = *this;
+         bld._dispatch_width = n;
+         bld._group += i * n;
+         return bld;
+      }
+
+      /**
+       * Alias for group() with width equal to eight.
+       */
+      fs_builder
+      half(unsigned i) const
+      {
+         return group(8, i);
+      }
+
+      /**
+       * Construct a builder with per-channel control flow execution masking
+       * disabled if \p b is true.  If control flow execution masking is
+       * already disabled this has no effect.
+       */
+      fs_builder
+      exec_all(bool b = true) const
+      {
+         fs_builder bld = *this;
+         if (b)
+            bld.force_writemask_all = true;
+         return bld;
+      }
+
+      /**
+       * Construct a builder with the given debug annotation info.
+       */
+      fs_builder
+      annotate(const char *str, const void *ir = NULL) const
+      {
+         fs_builder bld = *this;
+         bld.annotation.str = str;
+         bld.annotation.ir = ir;
+         return bld;
+      }
+
+      /**
+       * Get the SIMD width in use.
+       */
+      unsigned
+      dispatch_width() const
+      {
+         return _dispatch_width;
+      }
+
+      /**
+       * Allocate a virtual register of natural vector size (one for this IR)
+       * and SIMD width.  \p n gives the amount of space to allocate in
+       * dispatch_width units (which is just enough space for one logical
+       * component in this IR).
+       */
+      dst_reg
+      vgrf(enum brw_reg_type type, unsigned n = 1) const
+      {
+         return dst_reg(GRF, shader->alloc.allocate(
+                           DIV_ROUND_UP(n * type_sz(type) * dispatch_width(),
+                                        REG_SIZE)),
+                        type, dispatch_width());
+      }
+
+      /**
+       * Create a null register of floating type.
+       */
+      dst_reg
+      null_reg_f() const
+      {
+         return dst_reg(retype(brw_null_vec(dispatch_width()),
+                               BRW_REGISTER_TYPE_F));
+      }
+
+      /**
+       * Create a null register of signed integer type.
+       */
+      dst_reg
+      null_reg_d() const
+      {
+         return dst_reg(retype(brw_null_vec(dispatch_width()),
+                               BRW_REGISTER_TYPE_D));
+      }
+
+      /**
+       * Create a null register of unsigned integer type.
+       */
+      dst_reg
+      null_reg_ud() const
+      {
+         return dst_reg(retype(brw_null_vec(dispatch_width()),
+                               BRW_REGISTER_TYPE_UD));
+      }
+
+      /**
+       * Get the mask of SIMD channels enabled by dispatch and not yet
+       * disabled by discard.
+       */
+      src_reg
+      sample_mask_reg() const
+      {
+         const bool uses_kill =
+            (shader->stage == MESA_SHADER_FRAGMENT &&
+             ((brw_wm_prog_data *)shader->stage_prog_data)->uses_kill);
+         return (shader->stage != MESA_SHADER_FRAGMENT ? src_reg(0xffff) :
+                 uses_kill ? brw_flag_reg(0, 1) :
+                 retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD));
+      }
+
+      /**
+       * Insert an instruction into the program.
+       */
+      instruction *
+      emit(const instruction &inst) const
+      {
+         return emit(new(shader->mem_ctx) instruction(inst));
+      }
+
+      /**
+       * Create and insert a nullary control instruction into the program.
+       */
+      instruction *
+      emit(enum opcode opcode) const
+      {
+         return emit(instruction(opcode, dispatch_width()));
+      }
+
+      /**
+       * Create and insert a nullary instruction into the program.
+       */
+      instruction *
+      emit(enum opcode opcode, const dst_reg &dst) const
+      {
+         return emit(instruction(opcode, dst));
+      }
+
+      /**
+       * Create and insert a unary instruction into the program.
+       */
+      instruction *
+      emit(enum opcode opcode, const dst_reg &dst, const src_reg &src0) const
+      {
+         switch (opcode) {
+         case SHADER_OPCODE_RCP:
+         case SHADER_OPCODE_RSQ:
+         case SHADER_OPCODE_SQRT:
+         case SHADER_OPCODE_EXP2:
+         case SHADER_OPCODE_LOG2:
+         case SHADER_OPCODE_SIN:
+         case SHADER_OPCODE_COS:
+            return fix_math_instruction(
+               emit(instruction(opcode, dst.width, dst,
+                                fix_math_operand(src0))));
+
+         default:
+            return emit(instruction(opcode, dst.width, dst, src0));
+         }
+      }
+
+      /**
+       * Create and insert a binary instruction into the program.
+       */
+      instruction *
+      emit(enum opcode opcode, const dst_reg &dst, const src_reg &src0,
+           const src_reg &src1) const
+      {
+         switch (opcode) {
+         case SHADER_OPCODE_POW:
+         case SHADER_OPCODE_INT_QUOTIENT:
+         case SHADER_OPCODE_INT_REMAINDER:
+            return fix_math_instruction(
+               emit(instruction(opcode, dst.width, dst,
+                                fix_math_operand(src0),
+                                fix_math_operand(src1))));
+
+         default:
+            return emit(instruction(opcode, dst.width, dst, src0, src1));
+
+         }
+      }
+
+      /**
+       * Create and insert a ternary instruction into the program.
+       */
+      instruction *
+      emit(enum opcode opcode, const dst_reg &dst, const src_reg &src0,
+           const src_reg &src1, const src_reg &src2) const
+      {
+         switch (opcode) {
+         case BRW_OPCODE_BFE:
+         case BRW_OPCODE_BFI2:
+         case BRW_OPCODE_MAD:
+         case BRW_OPCODE_LRP:
+            return emit(instruction(opcode, dst.width, dst,
+                                    fix_3src_operand(src0),
+                                    fix_3src_operand(src1),
+                                    fix_3src_operand(src2)));
+
+         default:
+            return emit(instruction(opcode, dst.width, dst, src0, src1, src2));
+         }
+      }
+
+      /**
+       * Insert a preallocated instruction into the program.
+       */
+      instruction *
+      emit(instruction *inst) const
+      {
+         assert(inst->exec_size == dispatch_width() ||
+                force_writemask_all);
+         assert(_group == 0 || _group == 8);
+
+         inst->force_sechalf = (_group == 8);
+         inst->force_writemask_all = force_writemask_all;
+         inst->annotation = annotation.str;
+         inst->ir = annotation.ir;
+
+         if (block)
+            static_cast<instruction *>(cursor)->insert_before(block, inst);
+         else
+            cursor->insert_before(inst);
+
+         return inst;
+      }
+
+      /**
+       * Select \p src0 if the comparison of both sources with the given
+       * conditional mod evaluates to true, otherwise select \p src1.
+       *
+       * Generally useful to get the minimum or maximum of two values.
+       */
+      void
+      emit_minmax(const dst_reg &dst, const src_reg &src0,
+                  const src_reg &src1, brw_conditional_mod mod) const
+      {
+         if (shader->devinfo->gen >= 6) {
+            set_condmod(mod, SEL(dst, fix_unsigned_negate(src0),
+                                 fix_unsigned_negate(src1)));
+         } else {
+            CMP(null_reg_d(), src0, src1, mod);
+            set_predicate(BRW_PREDICATE_NORMAL,
+                          SEL(dst, src0, src1));
+         }
+      }
+
+      /**
+       * Copy any live channel from \p src to the first channel of \p dst.
+       */
+      void
+      emit_uniformize(const dst_reg &dst, const src_reg &src) const
+      {
+         const fs_builder ubld = exec_all();
+         const dst_reg chan_index = vgrf(BRW_REGISTER_TYPE_UD);
+
+         ubld.emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, component(chan_index, 0));
+         ubld.emit(SHADER_OPCODE_BROADCAST, component(dst, 0),
+                   src, component(chan_index, 0));
+      }
+
+      /**
+       * Assorted arithmetic ops.
+       * @{
+       */
+#define ALU1(op)                                        \
+      instruction *                                     \
+      op(const dst_reg &dst, const src_reg &src0) const \
+      {                                                 \
+         return emit(BRW_OPCODE_##op, dst, src0);       \
+      }
+
+#define ALU2(op)                                                        \
+      instruction *                                                     \
+      op(const dst_reg &dst, const src_reg &src0, const src_reg &src1) const \
+      {                                                                 \
+         return emit(BRW_OPCODE_##op, dst, src0, src1);                 \
+      }
+
+#define ALU2_ACC(op)                                                    \
+      instruction *                                                     \
+      op(const dst_reg &dst, const src_reg &src0, const src_reg &src1) const \
+      {                                                                 \
+         instruction *inst = emit(BRW_OPCODE_##op, dst, src0, src1);    \
+         inst->writes_accumulator = true;                               \
+         return inst;                                                   \
+      }
+
+#define ALU3(op)                                                        \
+      instruction *                                                     \
+      op(const dst_reg &dst, const src_reg &src0, const src_reg &src1,  \
+         const src_reg &src2) const                                     \
+      {                                                                 \
+         return emit(BRW_OPCODE_##op, dst, src0, src1, src2);           \
+      }
+
+      ALU2(ADD)
+      ALU2_ACC(ADDC)
+      ALU2(AND)
+      ALU2(ASR)
+      ALU2(AVG)
+      ALU3(BFE)
+      ALU2(BFI1)
+      ALU3(BFI2)
+      ALU1(BFREV)
+      ALU1(CBIT)
+      ALU2(CMPN)
+      ALU3(CSEL)
+      ALU2(DP2)
+      ALU2(DP3)
+      ALU2(DP4)
+      ALU2(DPH)
+      ALU1(F16TO32)
+      ALU1(F32TO16)
+      ALU1(FBH)
+      ALU1(FBL)
+      ALU1(FRC)
+      ALU2(LINE)
+      ALU1(LZD)
+      ALU2(MAC)
+      ALU2_ACC(MACH)
+      ALU3(MAD)
+      ALU1(MOV)
+      ALU2(MUL)
+      ALU1(NOT)
+      ALU2(OR)
+      ALU2(PLN)
+      ALU1(RNDD)
+      ALU1(RNDE)
+      ALU1(RNDU)
+      ALU1(RNDZ)
+      ALU2(SAD2)
+      ALU2_ACC(SADA2)
+      ALU2(SEL)
+      ALU2(SHL)
+      ALU2(SHR)
+      ALU2_ACC(SUBB)
+      ALU2(XOR)
+
+#undef ALU3
+#undef ALU2_ACC
+#undef ALU2
+#undef ALU1
+      /** @} */
+
+      /**
+       * CMP: Sets the low bit of the destination channels with the result
+       * of the comparison, while the upper bits are undefined, and updates
+       * the flag register with the packed 16 bits of the result.
+       */
+      instruction *
+      CMP(const dst_reg &dst, const src_reg &src0, const src_reg &src1,
+          brw_conditional_mod condition) const
+      {
+         /* Take the instruction:
+          *
+          * CMP null<d> src0<f> src1<f>
+          *
+          * Original gen4 does type conversion to the destination type
+          * before comparison, producing garbage results for floating
+          * point comparisons.
+          *
+          * The destination type doesn't matter on newer generations,
+          * so we set the type to match src0 so we can compact the
+          * instruction.
+          */
+         return set_condmod(condition,
+                            emit(BRW_OPCODE_CMP, retype(dst, src0.type),
+                                 fix_unsigned_negate(src0),
+                                 fix_unsigned_negate(src1)));
+      }
+
+      /**
+       * Gen4 predicated IF.
+       */
+      instruction *
+      IF(brw_predicate predicate) const
+      {
+         return set_predicate(predicate, emit(BRW_OPCODE_IF));
+      }
+
+      /**
+       * Emit a linear interpolation instruction.
+       */
+      instruction *
+      LRP(const dst_reg &dst, const src_reg &x, const src_reg &y,
+          const src_reg &a) const
+      {
+         if (shader->devinfo->gen >= 6) {
+            /* The LRP instruction actually does op1 * op0 + op2 * (1 - op0), so
+             * we need to reorder the operands.
+             */
+            return emit(BRW_OPCODE_LRP, dst, a, y, x);
+
+         } else {
+            /* We can't use the LRP instruction.  Emit x*(1-a) + y*a. */
+            const dst_reg y_times_a = vgrf(dst.type);
+            const dst_reg one_minus_a = vgrf(dst.type);
+            const dst_reg x_times_one_minus_a = vgrf(dst.type);
+
+            MUL(y_times_a, y, a);
+            ADD(one_minus_a, negate(a), src_reg(1.0f));
+            MUL(x_times_one_minus_a, x, src_reg(one_minus_a));
+            return ADD(dst, src_reg(x_times_one_minus_a), src_reg(y_times_a));
+         }
+      }
+
+      /**
+       * Collect a number of registers in a contiguous range of registers.
+       */
+      instruction *
+      LOAD_PAYLOAD(const dst_reg &dst, const src_reg *src,
+                   unsigned sources, unsigned header_size) const
+      {
+         assert(dst.width % 8 == 0);
+         instruction *inst = emit(instruction(SHADER_OPCODE_LOAD_PAYLOAD,
+                                              dst.width, dst, src, sources));
+         inst->header_size = header_size;
+
+         for (unsigned i = 0; i < header_size; i++)
+            assert(src[i].file != GRF ||
+                   src[i].width * type_sz(src[i].type) == 32);
+         inst->regs_written = header_size;
+
+         for (unsigned i = header_size; i < sources; ++i)
+            assert(src[i].file != GRF ||
+                   src[i].width == dst.width);
+         inst->regs_written += (sources - header_size) * (dst.width / 8);
+
+         return inst;
+      }
+
+      backend_shader *shader;
+
+   private:
+      /**
+       * Workaround for negation of UD registers.  See comment in
+       * fs_generator::generate_code() for more details.
+       */
+      src_reg
+      fix_unsigned_negate(const src_reg &src) const
+      {
+         if (src.type == BRW_REGISTER_TYPE_UD &&
+             src.negate) {
+            dst_reg temp = vgrf(BRW_REGISTER_TYPE_UD);
+            MOV(temp, src);
+            return src_reg(temp);
+         } else {
+            return src;
+         }
+      }
+
+      /**
+       * Workaround for source register modes not supported by the ternary
+       * instruction encoding.
+       */
+      src_reg
+      fix_3src_operand(const src_reg &src) const
+      {
+         if (src.file == GRF || src.file == UNIFORM || src.stride > 1) {
+            return src;
+         } else {
+            dst_reg expanded = vgrf(src.type);
+            MOV(expanded, src);
+            return expanded;
+         }
+      }
+
+      /**
+       * Workaround for source register modes not supported by the math
+       * instruction.
+       */
+      src_reg
+      fix_math_operand(const src_reg &src) const
+      {
+         /* Can't do hstride == 0 args on gen6 math, so expand it out. We
+          * might be able to do better by doing execsize = 1 math and then
+          * expanding that result out, but we would need to be careful with
+          * masking.
+          *
+          * Gen6 hardware ignores source modifiers (negate and abs) on math
+          * instructions, so we also move to a temp to set those up.
+          *
+          * Gen7 relaxes most of the above restrictions, but still can't use IMM
+          * operands to math
+          */
+         if ((shader->devinfo->gen == 6 &&
+              (src.file == IMM || src.file == UNIFORM ||
+               src.abs || src.negate)) ||
+             (shader->devinfo->gen == 7 && src.file == IMM)) {
+            const dst_reg tmp = vgrf(src.type);
+            MOV(tmp, src);
+            return tmp;
+         } else {
+            return src;
+         }
+      }
+
+      /**
+       * Workaround other weirdness of the math instruction.
+       */
+      instruction *
+      fix_math_instruction(instruction *inst) const
+      {
+         if (shader->devinfo->gen < 6) {
+            inst->base_mrf = 2;
+            inst->mlen = inst->sources * dispatch_width() / 8;
+
+            if (inst->sources > 1) {
+               /* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13
+                * "Message Payload":
+                *
+                * "Operand0[7].  For the INT DIV functions, this operand is the
+                *  denominator."
+                *  ...
+                * "Operand1[7].  For the INT DIV functions, this operand is the
+                *  numerator."
+                */
+               const bool is_int_div = inst->opcode != SHADER_OPCODE_POW;
+               const fs_reg src0 = is_int_div ? inst->src[1] : inst->src[0];
+               const fs_reg src1 = is_int_div ? inst->src[0] : inst->src[1];
+
+               inst->resize_sources(1);
+               inst->src[0] = src0;
+
+               at(block, inst).MOV(fs_reg(MRF, inst->base_mrf + 1, src1.type,
+                                          dispatch_width()), src1);
+            }
+         }
+
+         return inst;
+      }
+
+      bblock_t *block;
+      exec_node *cursor;
+
+      unsigned _dispatch_width;
+      unsigned _group;
+      bool force_writemask_all;
+
+      /** Debug annotation info. */
+      struct {
+         const char *str;
+         const void *ir;
+      } annotation;
+   };
+}
+
+#endif
index aa62031df73ed558ce8e49966eef01b3ab3c93c5..0af5a915c9f2d636b728d5ee883d8f7d253ffd2c 100644 (file)
@@ -38,6 +38,8 @@
 #include "brw_fs_live_variables.h"
 #include "brw_cfg.h"
 
+using namespace brw;
+
 /* Returns whether an instruction could co-issue if its immediate source were
  * replaced with a GRF source.
  */
@@ -270,15 +272,14 @@ fs_visitor::opt_combine_constants()
    reg.stride = 0;
    for (int i = 0; i < table.len; i++) {
       struct imm *imm = &table.imm[i];
-
-      fs_inst *mov = MOV(reg, fs_reg(imm->val));
-      mov->force_writemask_all = true;
-      if (imm->inst) {
-         imm->inst->insert_before(imm->block, mov);
-      } else {
-         backend_instruction *inst = imm->block->last_non_control_flow_inst();
-         inst->insert_after(imm->block, mov);
-      }
+      /* Insert it either before the instruction that generated the immediate
+       * or after the last non-control flow instruction of the common ancestor.
+       */
+      exec_node *n = (imm->inst ? imm->inst :
+                      imm->block->last_non_control_flow_inst()->next);
+      const fs_builder ibld = bld.at(imm->block, n).exec_all();
+
+      ibld.MOV(reg, fs_reg(imm->val));
       imm->reg = reg.reg;
       imm->subreg_offset = reg.subreg_offset;
 
index 52bfa921dc3c19e4719b84d50917551bc7625d8f..c92aae4b1d6beac1b84e22058b3d73442a0a9c56 100644 (file)
@@ -541,8 +541,16 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry)
             /* Fit this constant in by commuting the operands.
              * Exception: we can't do this for 32-bit integer MUL/MACH
              * because it's asymmetric.
+             *
+             * The BSpec says for Broadwell that
+             *
+             *    "When multiplying DW x DW, the dst cannot be accumulator."
+             *
+             * Integer MUL with a non-accumulator destination will be lowered
+             * by lower_integer_multiplication(), so don't restrict it.
              */
-            if ((inst->opcode == BRW_OPCODE_MUL ||
+            if (((inst->opcode == BRW_OPCODE_MUL &&
+                  inst->dst.is_accumulator()) ||
                  inst->opcode == BRW_OPCODE_MACH) &&
                 (inst->src[1].type == BRW_REGISTER_TYPE_D ||
                  inst->src[1].type == BRW_REGISTER_TYPE_UD))
index db01f8cf7abae6aff524673e4a9e1a916de67f2d..70f0217b93d53048f1f64d078c6ace24e9ad17ec 100644 (file)
@@ -32,6 +32,8 @@
  * 13.1 (p378).
  */
 
+using namespace brw;
+
 namespace {
 struct aeb_entry : public exec_node {
    /** The instruction that generates the expression value. */
@@ -152,28 +154,34 @@ static bool
 instructions_match(fs_inst *a, fs_inst *b, bool *negate)
 {
    return a->opcode == b->opcode &&
+          a->force_writemask_all == b->force_writemask_all &&
+          a->exec_size == b->exec_size &&
+          a->force_sechalf == b->force_sechalf &&
           a->saturate == b->saturate &&
           a->predicate == b->predicate &&
           a->predicate_inverse == b->predicate_inverse &&
           a->conditional_mod == b->conditional_mod &&
+          a->flag_subreg == b->flag_subreg &&
           a->dst.type == b->dst.type &&
+          a->offset == b->offset &&
+          a->mlen == b->mlen &&
+          a->regs_written == b->regs_written &&
+          a->base_mrf == b->base_mrf &&
+          a->eot == b->eot &&
+          a->header_size == b->header_size &&
+          a->shadow_compare == b->shadow_compare &&
+          a->pi_noperspective == b->pi_noperspective &&
           a->sources == b->sources &&
-          (a->is_tex() ? (a->offset == b->offset &&
-                          a->mlen == b->mlen &&
-                          a->regs_written == b->regs_written &&
-                          a->base_mrf == b->base_mrf &&
-                          a->eot == b->eot &&
-                          a->header_size == b->header_size &&
-                          a->shadow_compare == b->shadow_compare)
-                       : true) &&
           operands_match(a, b, negate);
 }
 
-static fs_inst *
-create_copy_instr(fs_visitor *v, fs_inst *inst, fs_reg src, bool negate)
+static void
+create_copy_instr(const fs_builder &bld, fs_inst *inst, fs_reg src, bool negate)
 {
    int written = inst->regs_written;
    int dst_width = inst->dst.width / 8;
+   const fs_builder ubld = bld.group(inst->exec_size, inst->force_sechalf)
+                              .exec_all(inst->force_writemask_all);
    fs_inst *copy;
 
    if (written > dst_width) {
@@ -189,7 +197,7 @@ create_copy_instr(fs_visitor *v, fs_inst *inst, fs_reg src, bool negate)
       }
 
       assert(src.file == GRF);
-      payload = ralloc_array(v->mem_ctx, fs_reg, sources);
+      payload = ralloc_array(bld.shader->mem_ctx, fs_reg, sources);
       for (int i = 0; i < header_size; i++) {
          payload[i] = src;
          payload[i].width = 8;
@@ -199,15 +207,12 @@ create_copy_instr(fs_visitor *v, fs_inst *inst, fs_reg src, bool negate)
          payload[i] = src;
          src = offset(src, 1);
       }
-      copy = v->LOAD_PAYLOAD(inst->dst, payload, sources, header_size);
+      copy = ubld.LOAD_PAYLOAD(inst->dst, payload, sources, header_size);
    } else {
-      copy = v->MOV(inst->dst, src);
-      copy->force_writemask_all = inst->force_writemask_all;
+      copy = ubld.MOV(inst->dst, src);
       copy->src[0].negate = negate;
    }
    assert(copy->regs_written == written);
-
-   return copy;
 }
 
 bool
@@ -261,9 +266,8 @@ fs_visitor::opt_cse_local(bblock_t *block)
                                    entry->generator->dst.type,
                                    entry->generator->dst.width);
 
-               fs_inst *copy = create_copy_instr(this, entry->generator,
-                                                 entry->tmp, false);
-               entry->generator->insert_after(block, copy);
+               create_copy_instr(bld.at(block, entry->generator->next),
+                                 entry->generator, entry->tmp, false);
 
                entry->generator->dst = entry->tmp;
             }
@@ -274,9 +278,7 @@ fs_visitor::opt_cse_local(bblock_t *block)
                assert(inst->dst.width == entry->generator->dst.width);
                assert(inst->dst.type == entry->tmp.type);
 
-               fs_inst *copy = create_copy_instr(this, inst,
-                                                 entry->tmp, negate);
-               inst->insert_before(block, copy);
+               create_copy_instr(bld.at(block, inst), inst, entry->tmp, negate);
             }
 
             /* Set our iterator so that next time through the loop inst->next
diff --git a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
deleted file mode 100644 (file)
index 6518ff6..0000000
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Copyright Â© 2012 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-/** @file brw_fs_fp.cpp
- *
- * Implementation of the compiler for GL_ARB_fragment_program shaders on top
- * of the GLSL compiler backend.
- */
-
-#include "brw_context.h"
-#include "brw_fs.h"
-
-void
-fs_visitor::emit_fp_alu1(enum opcode opcode,
-                         const struct prog_instruction *fpi,
-                         fs_reg dst, fs_reg src)
-{
-   for (int i = 0; i < 4; i++) {
-      if (fpi->DstReg.WriteMask & (1 << i))
-         emit(opcode, offset(dst, i), offset(src, i));
-   }
-}
-
-void
-fs_visitor::emit_fp_alu2(enum opcode opcode,
-                         const struct prog_instruction *fpi,
-                         fs_reg dst, fs_reg src0, fs_reg src1)
-{
-   for (int i = 0; i < 4; i++) {
-      if (fpi->DstReg.WriteMask & (1 << i))
-         emit(opcode, offset(dst, i),
-              offset(src0, i), offset(src1, i));
-   }
-}
-
-void
-fs_visitor::emit_fp_minmax(const prog_instruction *fpi,
-                           fs_reg dst, fs_reg src0, fs_reg src1)
-{
-   enum brw_conditional_mod conditionalmod;
-   if (fpi->Opcode == OPCODE_MIN)
-      conditionalmod = BRW_CONDITIONAL_L;
-   else
-      conditionalmod = BRW_CONDITIONAL_GE;
-
-   for (int i = 0; i < 4; i++) {
-      if (fpi->DstReg.WriteMask & (1 << i)) {
-         emit_minmax(conditionalmod, offset(dst, i),
-                     offset(src0, i), offset(src1, i));
-      }
-   }
-}
-
-void
-fs_visitor::emit_fp_sop(enum brw_conditional_mod conditional_mod,
-                        const struct prog_instruction *fpi,
-                        fs_reg dst, fs_reg src0, fs_reg src1,
-                        fs_reg one)
-{
-   for (int i = 0; i < 4; i++) {
-      if (fpi->DstReg.WriteMask & (1 << i)) {
-         fs_inst *inst;
-
-         emit(CMP(reg_null_d, offset(src0, i), offset(src1, i),
-                  conditional_mod));
-
-         inst = emit(BRW_OPCODE_SEL, offset(dst, i), one, fs_reg(0.0f));
-         inst->predicate = BRW_PREDICATE_NORMAL;
-      }
-   }
-}
-
-void
-fs_visitor::emit_fp_scalar_write(const struct prog_instruction *fpi,
-                                 fs_reg dst, fs_reg src)
-{
-   for (int i = 0; i < 4; i++) {
-      if (fpi->DstReg.WriteMask & (1 << i))
-         emit(MOV(offset(dst, i), src));
-   }
-}
-
-void
-fs_visitor::emit_fp_scalar_math(enum opcode opcode,
-                                const struct prog_instruction *fpi,
-                                fs_reg dst, fs_reg src)
-{
-   fs_reg temp = vgrf(glsl_type::float_type);
-   emit_math(opcode, temp, src);
-   emit_fp_scalar_write(fpi, dst, temp);
-}
-
-void
-fs_visitor::emit_fragment_program_code()
-{
-   setup_fp_regs();
-
-   /* Keep a reg with 1.0 around, for reuse by emit_fp_sop so that it can just
-    * be:
-    *
-    * sel.f0 dst 1.0 0.0
-    *
-    * instead of
-    *
-    * mov    dst 0.0
-    * mov.f0 dst 1.0
-    */
-   fs_reg one = vgrf(glsl_type::float_type);
-   emit(MOV(one, fs_reg(1.0f)));
-
-   for (unsigned int insn = 0; insn < prog->NumInstructions; insn++) {
-      const struct prog_instruction *fpi = &prog->Instructions[insn];
-      base_ir = fpi;
-
-      fs_reg dst;
-      fs_reg src[3];
-
-      /* We always emit into a temporary destination register to avoid
-       * aliasing issues.
-       */
-      dst = vgrf(glsl_type::vec4_type);
-
-      for (int i = 0; i < 3; i++)
-         src[i] = get_fp_src_reg(&fpi->SrcReg[i]);
-
-      switch (fpi->Opcode) {
-      case OPCODE_ABS:
-         src[0].abs = true;
-         src[0].negate = false;
-         emit_fp_alu1(BRW_OPCODE_MOV, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_ADD:
-         emit_fp_alu2(BRW_OPCODE_ADD, fpi, dst, src[0], src[1]);
-         break;
-
-      case OPCODE_CMP:
-         for (int i = 0; i < 4; i++) {
-            if (fpi->DstReg.WriteMask & (1 << i)) {
-               fs_inst *inst;
-
-               emit(CMP(reg_null_f, offset(src[0], i), fs_reg(0.0f),
-                        BRW_CONDITIONAL_L));
-
-               inst = emit(BRW_OPCODE_SEL, offset(dst, i),
-                           offset(src[1], i), offset(src[2], i));
-               inst->predicate = BRW_PREDICATE_NORMAL;
-            }
-         }
-         break;
-
-      case OPCODE_COS:
-         emit_fp_scalar_math(SHADER_OPCODE_COS, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_DP2:
-      case OPCODE_DP3:
-      case OPCODE_DP4:
-      case OPCODE_DPH: {
-         fs_reg mul = vgrf(glsl_type::float_type);
-         fs_reg acc = vgrf(glsl_type::float_type);
-         int count;
-
-         switch (fpi->Opcode) {
-         case OPCODE_DP2: count = 2; break;
-         case OPCODE_DP3: count = 3; break;
-         case OPCODE_DP4: count = 4; break;
-         case OPCODE_DPH: count = 3; break;
-         default: unreachable("not reached");
-         }
-
-         emit(MUL(acc, offset(src[0], 0), offset(src[1], 0)));
-         for (int i = 1; i < count; i++) {
-            emit(MUL(mul, offset(src[0], i), offset(src[1], i)));
-            emit(ADD(acc, acc, mul));
-         }
-
-         if (fpi->Opcode == OPCODE_DPH)
-            emit(ADD(acc, acc, offset(src[1], 3)));
-
-         emit_fp_scalar_write(fpi, dst, acc);
-         break;
-      }
-
-      case OPCODE_DST:
-         if (fpi->DstReg.WriteMask & WRITEMASK_X)
-            emit(MOV(dst, fs_reg(1.0f)));
-         if (fpi->DstReg.WriteMask & WRITEMASK_Y) {
-            emit(MUL(offset(dst, 1),
-                     offset(src[0], 1), offset(src[1], 1)));
-         }
-         if (fpi->DstReg.WriteMask & WRITEMASK_Z)
-            emit(MOV(offset(dst, 2), offset(src[0], 2)));
-         if (fpi->DstReg.WriteMask & WRITEMASK_W)
-            emit(MOV(offset(dst, 3), offset(src[1], 3)));
-         break;
-
-      case OPCODE_EX2:
-         emit_fp_scalar_math(SHADER_OPCODE_EXP2, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_FLR:
-         emit_fp_alu1(BRW_OPCODE_RNDD, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_FRC:
-         emit_fp_alu1(BRW_OPCODE_FRC, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_KIL: {
-         for (int i = 0; i < 4; i++) {
-            /* In most cases the argument to a KIL will be something like
-             * TEMP[0].wwww, so there's no point in checking whether .w is < 0
-             * 4 times in a row.
-             */
-            if (i > 0 &&
-                GET_SWZ(fpi->SrcReg[0].Swizzle, i) ==
-                GET_SWZ(fpi->SrcReg[0].Swizzle, i - 1) &&
-                ((fpi->SrcReg[0].Negate >> i) & 1) ==
-                ((fpi->SrcReg[0].Negate >> (i - 1)) & 1)) {
-               continue;
-            }
-
-
-            /* Emit an instruction that's predicated on the current
-             * undiscarded pixels, and updates just those pixels to be
-             * turned off.
-             */
-            fs_inst *cmp = emit(CMP(reg_null_f, offset(src[0], i),
-                                    fs_reg(0.0f), BRW_CONDITIONAL_GE));
-            cmp->predicate = BRW_PREDICATE_NORMAL;
-            cmp->flag_subreg = 1;
-
-            if (devinfo->gen >= 6)
-               emit_discard_jump();
-         }
-         break;
-      }
-
-      case OPCODE_LG2:
-         emit_fp_scalar_math(SHADER_OPCODE_LOG2, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_LIT:
-         /* From the ARB_fragment_program spec:
-          *
-          *      tmp = VectorLoad(op0);
-          *      if (tmp.x < 0) tmp.x = 0;
-          *      if (tmp.y < 0) tmp.y = 0;
-          *      if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon);
-          *      else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon;
-          *      result.x = 1.0;
-          *      result.y = tmp.x;
-          *      result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0;
-          *      result.w = 1.0;
-          *
-          * Note that we don't do the clamping to +/- 128.  We didn't in
-          * brw_wm_emit.c either.
-          */
-         if (fpi->DstReg.WriteMask & WRITEMASK_X)
-            emit(MOV(offset(dst, 0), fs_reg(1.0f)));
-
-         if (fpi->DstReg.WriteMask & WRITEMASK_YZ) {
-            fs_inst *inst;
-            emit(CMP(reg_null_f, offset(src[0], 0), fs_reg(0.0f),
-                     BRW_CONDITIONAL_LE));
-
-            if (fpi->DstReg.WriteMask & WRITEMASK_Y) {
-               emit(MOV(offset(dst, 1), offset(src[0], 0)));
-               inst = emit(MOV(offset(dst, 1), fs_reg(0.0f)));
-               inst->predicate = BRW_PREDICATE_NORMAL;
-            }
-
-            if (fpi->DstReg.WriteMask & WRITEMASK_Z) {
-               emit_math(SHADER_OPCODE_POW, offset(dst, 2),
-                         offset(src[0], 1), offset(src[0], 3));
-
-               inst = emit(MOV(offset(dst, 2), fs_reg(0.0f)));
-               inst->predicate = BRW_PREDICATE_NORMAL;
-            }
-         }
-
-         if (fpi->DstReg.WriteMask & WRITEMASK_W)
-            emit(MOV(offset(dst, 3), fs_reg(1.0f)));
-
-         break;
-
-      case OPCODE_LRP:
-         for (int i = 0; i < 4; i++) {
-            if (fpi->DstReg.WriteMask & (1 << i)) {
-               fs_reg a = offset(src[0], i);
-               fs_reg y = offset(src[1], i);
-               fs_reg x = offset(src[2], i);
-               emit_lrp(offset(dst, i), x, y, a);
-            }
-         }
-         break;
-
-      case OPCODE_MAD:
-         for (int i = 0; i < 4; i++) {
-            if (fpi->DstReg.WriteMask & (1 << i)) {
-               if (devinfo->gen >= 6) {
-                  emit(MAD(offset(dst, i), offset(src[2], i),
-                           offset(src[1], i), offset(src[0], i)));
-               } else {
-                  fs_reg temp = vgrf(glsl_type::float_type);
-                  emit(MUL(temp, offset(src[0], i), offset(src[1], i)));
-                  emit(ADD(offset(dst, i), temp, offset(src[2], i)));
-               }
-            }
-         }
-         break;
-
-      case OPCODE_MAX:
-         emit_fp_minmax(fpi, dst, src[0], src[1]);
-         break;
-
-      case OPCODE_MOV:
-         emit_fp_alu1(BRW_OPCODE_MOV, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_MIN:
-         emit_fp_minmax(fpi, dst, src[0], src[1]);
-         break;
-
-      case OPCODE_MUL:
-         emit_fp_alu2(BRW_OPCODE_MUL, fpi, dst, src[0], src[1]);
-         break;
-
-      case OPCODE_POW: {
-         fs_reg temp = vgrf(glsl_type::float_type);
-         emit_math(SHADER_OPCODE_POW, temp, src[0], src[1]);
-         emit_fp_scalar_write(fpi, dst, temp);
-         break;
-      }
-
-      case OPCODE_RCP:
-         emit_fp_scalar_math(SHADER_OPCODE_RCP, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_RSQ:
-         emit_fp_scalar_math(SHADER_OPCODE_RSQ, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_SCS:
-         if (fpi->DstReg.WriteMask & WRITEMASK_X) {
-            emit_math(SHADER_OPCODE_COS, offset(dst, 0),
-                      offset(src[0], 0));
-         }
-
-         if (fpi->DstReg.WriteMask & WRITEMASK_Y) {
-            emit_math(SHADER_OPCODE_SIN, offset(dst, 1),
-                      offset(src[0], 1));
-         }
-         break;
-
-      case OPCODE_SGE:
-         emit_fp_sop(BRW_CONDITIONAL_GE, fpi, dst, src[0], src[1], one);
-         break;
-
-      case OPCODE_SIN:
-         emit_fp_scalar_math(SHADER_OPCODE_SIN, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_SLT:
-         emit_fp_sop(BRW_CONDITIONAL_L, fpi, dst, src[0], src[1], one);
-         break;
-
-      case OPCODE_SUB: {
-         fs_reg neg_src1 = src[1];
-         neg_src1.negate = !src[1].negate;
-
-         emit_fp_alu2(BRW_OPCODE_ADD, fpi, dst, src[0], neg_src1);
-         break;
-      }
-
-      case OPCODE_TEX:
-      case OPCODE_TXB:
-      case OPCODE_TXP: {
-         ir_texture_opcode op;
-         fs_reg lod;
-         fs_reg dpdy;
-         fs_reg coordinate = src[0];
-         fs_reg shadow_c;
-         fs_reg sample_index;
-         fs_reg texel_offset; /* No offsets; leave as BAD_FILE. */
-
-         switch (fpi->Opcode) {
-         case OPCODE_TEX:
-            op = ir_tex;
-            break;
-         case OPCODE_TXP: {
-            op = ir_tex;
-
-            coordinate = vgrf(glsl_type::vec3_type);
-            fs_reg invproj = vgrf(glsl_type::float_type);
-            emit_math(SHADER_OPCODE_RCP, invproj, offset(src[0], 3));
-            for (int i = 0; i < 3; i++) {
-               emit(MUL(offset(coordinate, i),
-                        offset(src[0], i), invproj));
-            }
-            break;
-         }
-         case OPCODE_TXB:
-            op = ir_txb;
-            lod = offset(src[0], 3);
-            break;
-         default:
-            unreachable("not reached");
-         }
-
-         int coord_components;
-         switch (fpi->TexSrcTarget) {
-         case TEXTURE_1D_INDEX:
-            coord_components = 1;
-            break;
-
-         case TEXTURE_2D_INDEX:
-         case TEXTURE_1D_ARRAY_INDEX:
-         case TEXTURE_RECT_INDEX:
-         case TEXTURE_EXTERNAL_INDEX:
-            coord_components = 2;
-            break;
-
-         case TEXTURE_3D_INDEX:
-         case TEXTURE_2D_ARRAY_INDEX:
-            coord_components = 3;
-            break;
-
-         case TEXTURE_CUBE_INDEX: {
-            coord_components = 3;
-
-            fs_reg temp = vgrf(glsl_type::float_type);
-            fs_reg cubecoord = vgrf(glsl_type::vec3_type);
-            fs_reg abscoord = coordinate;
-            abscoord.negate = false;
-            abscoord.abs = true;
-            emit_minmax(BRW_CONDITIONAL_GE, temp,
-                        offset(abscoord, 0), offset(abscoord, 1));
-            emit_minmax(BRW_CONDITIONAL_GE, temp,
-                        temp, offset(abscoord, 2));
-            emit_math(SHADER_OPCODE_RCP, temp, temp);
-            for (int i = 0; i < 3; i++) {
-               emit(MUL(offset(cubecoord, i),
-                        offset(coordinate, i), temp));
-            }
-
-            coordinate = cubecoord;
-            break;
-         }
-
-         default:
-            unreachable("not reached");
-         }
-
-         if (fpi->TexShadow)
-            shadow_c = offset(coordinate, 2);
-
-         emit_texture(op, glsl_type::vec4_type, coordinate, coord_components,
-                      shadow_c, lod, dpdy, 0, sample_index,
-                      reg_undef, /* offset */
-                      reg_undef, /* mcs */
-                      0, /* gather component */
-                      false, /* is cube array */
-                      fpi->TexSrcTarget == TEXTURE_RECT_INDEX,
-                      fpi->TexSrcUnit, fs_reg(fpi->TexSrcUnit),
-                      fpi->TexSrcUnit);
-         dst = this->result;
-
-         break;
-      }
-
-      case OPCODE_SWZ:
-         /* Note that SWZ's extended swizzles are handled in the general
-          * get_src_reg() code.
-          */
-         emit_fp_alu1(BRW_OPCODE_MOV, fpi, dst, src[0]);
-         break;
-
-      case OPCODE_XPD:
-         for (int i = 0; i < 3; i++) {
-            if (fpi->DstReg.WriteMask & (1 << i)) {
-               int i1 = (i + 1) % 3;
-               int i2 = (i + 2) % 3;
-
-               fs_reg temp = vgrf(glsl_type::float_type);
-               fs_reg neg_src1_1 = offset(src[1], i1);
-               neg_src1_1.negate = !neg_src1_1.negate;
-               emit(MUL(temp, offset(src[0], i2), neg_src1_1));
-               emit(MUL(offset(dst, i),
-                        offset(src[0], i1), offset(src[1], i2)));
-               emit(ADD(offset(dst, i), offset(dst, i), temp));
-            }
-         }
-         break;
-
-      case OPCODE_END:
-         break;
-
-      default:
-         _mesa_problem(ctx, "Unsupported opcode %s in fragment program\n",
-                       _mesa_opcode_string(fpi->Opcode));
-      }
-
-      /* To handle saturates, we emit a MOV with a saturate bit, which
-       * optimization should fold into the preceding instructions when safe.
-       */
-      if (_mesa_num_inst_dst_regs(fpi->Opcode) != 0) {
-         fs_reg real_dst = get_fp_dst_reg(&fpi->DstReg);
-
-         for (int i = 0; i < 4; i++) {
-            if (fpi->DstReg.WriteMask & (1 << i)) {
-               fs_inst *inst = emit(MOV(offset(real_dst, i),
-                                        offset(dst, i)));
-               inst->saturate = fpi->SaturateMode;
-            }
-         }
-      }
-   }
-
-   /* Epilogue:
-    *
-    * Fragment depth has this strange convention of being the .z component of
-    * a vec4.  emit_fb_write() wants to see a float value, instead.
-    */
-   this->current_annotation = "result.depth write";
-   if (frag_depth.file != BAD_FILE) {
-      fs_reg temp = vgrf(glsl_type::float_type);
-      emit(MOV(temp, offset(frag_depth, 2)));
-      frag_depth = temp;
-   }
-}
-
-void
-fs_visitor::setup_fp_regs()
-{
-   /* PROGRAM_TEMPORARY */
-   int num_temp = prog->NumTemporaries;
-   fp_temp_regs = rzalloc_array(mem_ctx, fs_reg, num_temp);
-   for (int i = 0; i < num_temp; i++)
-      fp_temp_regs[i] = vgrf(glsl_type::vec4_type);
-
-   /* PROGRAM_STATE_VAR etc. */
-   if (dispatch_width == 8) {
-      for (unsigned p = 0;
-           p < prog->Parameters->NumParameters; p++) {
-         for (unsigned int i = 0; i < 4; i++) {
-            stage_prog_data->param[uniforms++] =
-               &prog->Parameters->ParameterValues[p][i];
-         }
-      }
-   }
-
-   fp_input_regs = rzalloc_array(mem_ctx, fs_reg, VARYING_SLOT_MAX);
-   for (int i = 0; i < VARYING_SLOT_MAX; i++) {
-      if (prog->InputsRead & BITFIELD64_BIT(i)) {
-         this->current_annotation = ralloc_asprintf(ctx, "interpolate input %d",
-                                                    i);
-
-         switch (i) {
-         case VARYING_SLOT_POS:
-            {
-               assert(stage == MESA_SHADER_FRAGMENT);
-               gl_fragment_program *fp = (gl_fragment_program*) prog;
-               fp_input_regs[i] =
-                  *emit_fragcoord_interpolation(fp->PixelCenterInteger,
-                                                fp->OriginUpperLeft);
-            }
-            break;
-         case VARYING_SLOT_FACE:
-            fp_input_regs[i] = *emit_frontfacing_interpolation();
-            break;
-         default:
-            fp_input_regs[i] = vgrf(glsl_type::vec4_type);
-            emit_general_interpolation(fp_input_regs[i], "fp_input",
-                                       glsl_type::vec4_type,
-                                       INTERP_QUALIFIER_NONE,
-                                       i, false, false);
-
-            if (i == VARYING_SLOT_FOGC) {
-               emit(MOV(offset(fp_input_regs[i], 1), fs_reg(0.0f)));
-               emit(MOV(offset(fp_input_regs[i], 2), fs_reg(0.0f)));
-               emit(MOV(offset(fp_input_regs[i], 3), fs_reg(1.0f)));
-            }
-
-            break;
-         }
-
-         this->current_annotation = NULL;
-      }
-   }
-}
-
-fs_reg
-fs_visitor::get_fp_dst_reg(const prog_dst_register *dst)
-{
-   assert(stage == MESA_SHADER_FRAGMENT);
-   brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
-
-   switch (dst->File) {
-   case PROGRAM_TEMPORARY:
-      return fp_temp_regs[dst->Index];
-
-   case PROGRAM_OUTPUT:
-      if (dst->Index == FRAG_RESULT_DEPTH) {
-         if (frag_depth.file == BAD_FILE)
-            frag_depth = vgrf(glsl_type::vec4_type);
-         return frag_depth;
-      } else if (dst->Index == FRAG_RESULT_COLOR) {
-         if (outputs[0].file == BAD_FILE) {
-            outputs[0] = vgrf(glsl_type::vec4_type);
-            output_components[0] = 4;
-
-            /* Tell emit_fb_writes() to smear fragment.color across all the
-             * color attachments.
-             */
-            for (int i = 1; i < key->nr_color_regions; i++) {
-               outputs[i] = outputs[0];
-               output_components[i] = output_components[0];
-            }
-         }
-         return outputs[0];
-      } else {
-         int output_index = dst->Index - FRAG_RESULT_DATA0;
-         if (outputs[output_index].file == BAD_FILE) {
-            outputs[output_index] = vgrf(glsl_type::vec4_type);
-         }
-         output_components[output_index] = 4;
-         return outputs[output_index];
-      }
-
-   case PROGRAM_UNDEFINED:
-      return fs_reg();
-
-   default:
-      _mesa_problem(ctx, "bad dst register file: %s\n",
-                    _mesa_register_file_name((gl_register_file)dst->File));
-      return vgrf(glsl_type::vec4_type);
-   }
-}
-
-fs_reg
-fs_visitor::get_fp_src_reg(const prog_src_register *src)
-{
-   struct gl_program_parameter_list *plist = prog->Parameters;
-
-   fs_reg result;
-
-   assert(!src->Abs);
-
-   switch (src->File) {
-   case PROGRAM_UNDEFINED:
-      return fs_reg();
-   case PROGRAM_TEMPORARY:
-      result = fp_temp_regs[src->Index];
-      break;
-
-   case PROGRAM_INPUT:
-      result = fp_input_regs[src->Index];
-      break;
-
-   case PROGRAM_STATE_VAR:
-   case PROGRAM_UNIFORM:
-   case PROGRAM_CONSTANT:
-      /* We actually want to look at the type in the Parameters list for this,
-       * because this lets us upload constant builtin uniforms, as actual
-       * constants.
-       */
-      switch (plist->Parameters[src->Index].Type) {
-      case PROGRAM_CONSTANT: {
-         result = vgrf(glsl_type::vec4_type);
-
-         for (int i = 0; i < 4; i++) {
-            emit(MOV(offset(result, i),
-                     fs_reg(plist->ParameterValues[src->Index][i].f)));
-         }
-         break;
-      }
-
-      case PROGRAM_STATE_VAR:
-      case PROGRAM_UNIFORM:
-         result = fs_reg(UNIFORM, src->Index * 4);
-         break;
-
-      default:
-         _mesa_problem(ctx, "bad uniform src register file: %s\n",
-                       _mesa_register_file_name((gl_register_file)src->File));
-         return vgrf(glsl_type::vec4_type);
-      }
-      break;
-
-   default:
-      _mesa_problem(ctx, "bad src register file: %s\n",
-                    _mesa_register_file_name((gl_register_file)src->File));
-      return vgrf(glsl_type::vec4_type);
-   }
-
-   if (src->Swizzle != SWIZZLE_NOOP || src->Negate) {
-      fs_reg unswizzled = result;
-      result = vgrf(glsl_type::vec4_type);
-      for (int i = 0; i < 4; i++) {
-         bool negate = src->Negate & (1 << i);
-         /* The ZERO, ONE, and Negate options are only used for OPCODE_SWZ,
-          * but it costs us nothing to support it.
-          */
-         int src_swiz = GET_SWZ(src->Swizzle, i);
-         if (src_swiz == SWIZZLE_ZERO) {
-            emit(MOV(offset(result, i), fs_reg(0.0f)));
-         } else if (src_swiz == SWIZZLE_ONE) {
-            emit(MOV(offset(result, i),
-                     negate ? fs_reg(-1.0f) : fs_reg(1.0f)));
-         } else {
-            fs_reg src = offset(unswizzled, src_swiz);
-            if (negate)
-               src.negate = !src.negate;
-            emit(MOV(offset(result, i), src));
-         }
-      }
-   }
-
-   return result;
-}
index a99b7f75b266ca3083b793545f112548e4f48b68..2ed0bac6fd9d520d874f9e9e6122e452e44fe218 100644 (file)
@@ -121,7 +121,7 @@ brw_reg_from_fs_reg(fs_reg *reg)
    return brw_reg;
 }
 
-fs_generator::fs_generator(struct brw_context *brw,
+fs_generator::fs_generator(const struct brw_compiler *compiler, void *log_data,
                            void *mem_ctx,
                            const void *key,
                            struct brw_stage_prog_data *prog_data,
@@ -130,7 +130,8 @@ fs_generator::fs_generator(struct brw_context *brw,
                            bool runtime_check_aads_emit,
                            const char *stage_abbrev)
 
-   : brw(brw), devinfo(brw->intelScreen->devinfo), key(key),
+   : compiler(compiler), log_data(log_data),
+     devinfo(compiler->devinfo), key(key),
      prog_data(prog_data),
      prog(prog), promoted_constants(promoted_constants),
      runtime_check_aads_emit(runtime_check_aads_emit), debug_flag(false),
@@ -400,6 +401,13 @@ fs_generator::generate_cs_terminate(fs_inst *inst, struct brw_reg payload)
    brw_inst_set_mask_control(devinfo, insn, BRW_MASK_DISABLE);
 }
 
+void
+fs_generator::generate_barrier(fs_inst *inst, struct brw_reg src)
+{
+   brw_barrier(p, src);
+   brw_WAIT(p);
+}
+
 void
 fs_generator::generate_blorp_fb_write(fs_inst *inst)
 {
@@ -779,27 +787,19 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src
       brw_mark_surface_used(prog_data, sampler + base_binding_table_index);
    } else {
       /* Non-const sampler index */
-      /* Note: this clobbers `dst` as a temporary before emitting the send */
 
       struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD));
-      struct brw_reg temp = vec1(retype(dst, BRW_REGISTER_TYPE_UD));
-
       struct brw_reg sampler_reg = vec1(retype(sampler_index, BRW_REGISTER_TYPE_UD));
 
       brw_push_insn_state(p);
       brw_set_default_mask_control(p, BRW_MASK_DISABLE);
       brw_set_default_access_mode(p, BRW_ALIGN_1);
 
-      /* Some care required: `sampler` and `temp` may alias:
-       *    addr = sampler & 0xff
-       *    temp = (sampler << 8) & 0xf00
-       *    addr = addr | temp
-       */
-      brw_ADD(p, addr, sampler_reg, brw_imm_ud(base_binding_table_index));
-      brw_SHL(p, temp, sampler_reg, brw_imm_ud(8u));
-      brw_AND(p, temp, temp, brw_imm_ud(0x0f00));
-      brw_AND(p, addr, addr, brw_imm_ud(0x0ff));
-      brw_OR(p, addr, addr, temp);
+      /* addr = ((sampler * 0x101) + base_binding_table_index) & 0xfff */
+      brw_MUL(p, addr, sampler_reg, brw_imm_uw(0x101));
+      if (base_binding_table_index)
+         brw_ADD(p, addr, addr, brw_imm_ud(base_binding_table_index));
+      brw_AND(p, addr, addr, brw_imm_ud(0xfff));
 
       brw_pop_insn_state(p);
 
@@ -941,6 +941,7 @@ fs_generator::generate_ddy(enum opcode opcode,
       brw_push_insn_state(p);
       brw_set_default_access_mode(p, BRW_ALIGN_16);
       if (unroll_to_simd8) {
+         brw_set_default_exec_size(p, BRW_EXECUTE_8);
          brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
          if (negate_value) {
             brw_ADD(p, firsthalf(dst), firsthalf(src1), negate(firsthalf(src0)));
@@ -1600,10 +1601,13 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          break;
       case 16:
       case 32:
-         if (type_sz(inst->dst.type) < sizeof(float))
-            brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
-         else
+         /* If the instruction writes to more than one register, it needs to
+          * be a "compressed" instruction on Gen <= 5.
+          */
+         if (inst->exec_size * inst->dst.stride * type_sz(inst->dst.type) > 32)
             brw_set_default_compression_control(p, BRW_COMPRESSION_COMPRESSED);
+         else
+            brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
          break;
       default:
          unreachable("Invalid instruction width");
@@ -2121,6 +2125,10 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          generate_cs_terminate(inst, src[0]);
          break;
 
+      case SHADER_OPCODE_BARRIER:
+        generate_barrier(inst, src[0]);
+        break;
+
       default:
          unreachable("Unsupported opcode");
 
@@ -2166,15 +2174,13 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
       ralloc_free(annotation.ann);
    }
 
-   static GLuint msg_id = 0;
-   _mesa_gl_debug(&brw->ctx, &msg_id,
-                  MESA_DEBUG_SOURCE_SHADER_COMPILER,
-                  MESA_DEBUG_TYPE_OTHER,
-                  MESA_DEBUG_SEVERITY_NOTIFICATION,
-                  "%s SIMD%d shader: %d inst, %d loops, %d:%d spills:fills, "
-                  "Promoted %u constants, compacted %d to %d bytes.\n",
-                  stage_abbrev, dispatch_width, before_size / 16, loop_count,
-                  spill_count, fill_count, promoted_constants, before_size, after_size);
+   compiler->shader_debug_log(log_data,
+                              "%s SIMD%d shader: %d inst, %d loops, "
+                              "%d:%d spills:fills, Promoted %u constants, "
+                              "compacted %d to %d bytes.\n",
+                              stage_abbrev, dispatch_width, before_size / 16,
+                              loop_count, spill_count, fill_count,
+                              promoted_constants, before_size, after_size);
 
    return start_offset;
 }
index 270131a73d15c979e8804380e42dd8726414fa94..a378019af5b3c258751e2e7f4880e98c4a4311bf 100644 (file)
@@ -28,6 +28,8 @@
 #include "brw_fs.h"
 #include "brw_nir.h"
 
+using namespace brw;
+
 void
 fs_visitor::emit_nir_code()
 {
@@ -38,12 +40,12 @@ fs_visitor::emit_nir_code()
     */
 
    if (nir->num_inputs > 0) {
-      nir_inputs = vgrf(nir->num_inputs);
+      nir_inputs = bld.vgrf(BRW_REGISTER_TYPE_F, nir->num_inputs);
       nir_setup_inputs(nir);
    }
 
    if (nir->num_outputs > 0) {
-      nir_outputs = vgrf(nir->num_outputs);
+      nir_outputs = bld.vgrf(BRW_REGISTER_TYPE_F, nir->num_outputs);
       nir_setup_outputs(nir);
    }
 
@@ -58,7 +60,7 @@ fs_visitor::emit_nir_code()
       unsigned array_elems =
          reg->num_array_elems == 0 ? 1 : reg->num_array_elems;
       unsigned size = array_elems * reg->num_components;
-      nir_globals[reg->index] = vgrf(size);
+      nir_globals[reg->index] = bld.vgrf(BRW_REGISTER_TYPE_F, size);
    }
 
    /* get the main function and emit it */
@@ -93,8 +95,8 @@ fs_visitor::nir_setup_inputs(nir_shader *shader)
          unsigned array_length = var->type->is_array() ? var->type->length : 1;
          for (unsigned i = 0; i < array_length; i++) {
             for (unsigned j = 0; j < components; j++) {
-               emit(MOV(retype(offset(input, components * i + j), type),
-                        offset(fs_reg(ATTR, var->data.location + i, type), j)));
+               bld.MOV(retype(offset(input, components * i + j), type),
+                       offset(fs_reg(ATTR, var->data.location + i, type), j));
             }
          }
          break;
@@ -107,7 +109,7 @@ fs_visitor::nir_setup_inputs(nir_shader *shader)
          if (var->data.location == VARYING_SLOT_POS) {
             reg = *emit_fragcoord_interpolation(var->data.pixel_center_integer,
                                                 var->data.origin_upper_left);
-            emit_percomp(MOV(input, reg), 0xF);
+            emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, input, reg), 0xF);
          } else {
             emit_general_interpolation(input, var->name, var->type,
                                        (glsl_interp_qualifier) var->data.interpolation,
@@ -218,9 +220,12 @@ fs_visitor::nir_setup_uniform(nir_variable *var)
       * our name.
       */
    unsigned index = var->data.driver_location;
-   for (unsigned u = 0; u < shader_prog->NumUserUniformStorage; u++) {
+   for (unsigned u = 0; u < shader_prog->NumUniformStorage; u++) {
       struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
 
+      if (storage->builtin)
+              continue;
+
       if (strncmp(var->name, storage->name, namelen) != 0 ||
          (storage->name[namelen] != 0 &&
          storage->name[namelen] != '.' &&
@@ -358,7 +363,7 @@ fs_visitor::nir_emit_impl(nir_function_impl *impl)
       unsigned array_elems =
          reg->num_array_elems == 0 ? 1 : reg->num_array_elems;
       unsigned size = array_elems * reg->num_components;
-      nir_locals[reg->index] = vgrf(size);
+      nir_locals[reg->index] = bld.vgrf(BRW_REGISTER_TYPE_F, size);
    }
 
    nir_emit_cf_list(&impl->body);
@@ -392,21 +397,21 @@ void
 fs_visitor::nir_emit_if(nir_if *if_stmt)
 {
    /* first, put the condition into f0 */
-   fs_inst *inst = emit(MOV(reg_null_d,
+   fs_inst *inst = bld.MOV(bld.null_reg_d(),
                             retype(get_nir_src(if_stmt->condition),
-                                   BRW_REGISTER_TYPE_D)));
+                                   BRW_REGISTER_TYPE_D));
    inst->conditional_mod = BRW_CONDITIONAL_NZ;
 
-   emit(IF(BRW_PREDICATE_NORMAL));
+   bld.IF(BRW_PREDICATE_NORMAL);
 
    nir_emit_cf_list(&if_stmt->then_list);
 
    /* note: if the else is empty, dead CF elimination will remove it */
-   emit(BRW_OPCODE_ELSE);
+   bld.emit(BRW_OPCODE_ELSE);
 
    nir_emit_cf_list(&if_stmt->else_list);
 
-   emit(BRW_OPCODE_ENDIF);
+   bld.emit(BRW_OPCODE_ENDIF);
 
    if (!try_replace_with_sel() && devinfo->gen < 6) {
       no16("Can't support (non-uniform) control flow on SIMD16\n");
@@ -420,11 +425,11 @@ fs_visitor::nir_emit_loop(nir_loop *loop)
       no16("Can't support (non-uniform) control flow on SIMD16\n");
    }
 
-   emit(BRW_OPCODE_DO);
+   bld.emit(BRW_OPCODE_DO);
 
    nir_emit_cf_list(&loop->body);
 
-   emit(BRW_OPCODE_WHILE);
+   bld.emit(BRW_OPCODE_WHILE);
 }
 
 void
@@ -438,19 +443,19 @@ fs_visitor::nir_emit_block(nir_block *block)
 void
 fs_visitor::nir_emit_instr(nir_instr *instr)
 {
-   this->base_ir = instr;
+   const fs_builder abld = bld.annotate(NULL, instr);
 
    switch (instr->type) {
    case nir_instr_type_alu:
-      nir_emit_alu(nir_instr_as_alu(instr));
+      nir_emit_alu(abld, nir_instr_as_alu(instr));
       break;
 
    case nir_instr_type_intrinsic:
-      nir_emit_intrinsic(nir_instr_as_intrinsic(instr));
+      nir_emit_intrinsic(abld, nir_instr_as_intrinsic(instr));
       break;
 
    case nir_instr_type_tex:
-      nir_emit_texture(nir_instr_as_tex(instr));
+      nir_emit_texture(abld, nir_instr_as_tex(instr));
       break;
 
    case nir_instr_type_load_const:
@@ -460,14 +465,12 @@ fs_visitor::nir_emit_instr(nir_instr *instr)
       break;
 
    case nir_instr_type_jump:
-      nir_emit_jump(nir_instr_as_jump(instr));
+      nir_emit_jump(abld, nir_instr_as_jump(instr));
       break;
 
    default:
       unreachable("unknown instruction type");
    }
-
-   this->base_ir = NULL;
 }
 
 static brw_reg_type
@@ -540,7 +543,7 @@ fs_visitor::optimize_frontfacing_ternary(nir_alu_instr *instr,
       tmp.subreg_offset = 2;
       tmp.stride = 2;
 
-      fs_inst *or_inst = emit(OR(tmp, g0, fs_reg(0x3f80)));
+      fs_inst *or_inst = bld.OR(tmp, g0, fs_reg(0x3f80));
       or_inst->src[1].type = BRW_REGISTER_TYPE_UW;
 
       tmp.type = BRW_REGISTER_TYPE_D;
@@ -565,15 +568,15 @@ fs_visitor::optimize_frontfacing_ternary(nir_alu_instr *instr,
          g1_6.negate = true;
       }
 
-      emit(OR(tmp, g1_6, fs_reg(0x3f800000)));
+      bld.OR(tmp, g1_6, fs_reg(0x3f800000));
    }
-   emit(AND(retype(result, BRW_REGISTER_TYPE_D), tmp, fs_reg(0xbf800000)));
+   bld.AND(retype(result, BRW_REGISTER_TYPE_D), tmp, fs_reg(0xbf800000));
 
    return true;
 }
 
 void
-fs_visitor::nir_emit_alu(nir_alu_instr *instr)
+fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
 {
    struct brw_wm_prog_key *fs_key = (struct brw_wm_prog_key *) this->key;
    fs_inst *inst;
@@ -605,7 +608,7 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
          if (!instr->src[i].src.is_ssa &&
              instr->dest.dest.reg.reg == instr->src[i].src.reg.reg) {
             need_extra_copy = true;
-            temp = retype(vgrf(4), result.type);
+            temp = bld.vgrf(result.type, 4);
             break;
          }
       }
@@ -615,11 +618,11 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
             continue;
 
          if (instr->op == nir_op_imov || instr->op == nir_op_fmov) {
-            inst = emit(MOV(offset(temp, i),
-                        offset(op[0], instr->src[0].swizzle[i])));
+            inst = bld.MOV(offset(temp, i),
+                           offset(op[0], instr->src[0].swizzle[i]));
          } else {
-            inst = emit(MOV(offset(temp, i),
-                        offset(op[i], instr->src[i].swizzle[0])));
+            inst = bld.MOV(offset(temp, i),
+                           offset(op[i], instr->src[i].swizzle[0]));
          }
          inst->saturate = instr->dest.saturate;
       }
@@ -633,7 +636,7 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
             if (!(instr->dest.write_mask & (1 << i)))
                continue;
 
-            emit(MOV(offset(result, i), offset(temp, i)));
+            bld.MOV(offset(result, i), offset(temp, i));
          }
       }
       return;
@@ -665,13 +668,13 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
    switch (instr->op) {
    case nir_op_i2f:
    case nir_op_u2f:
-      inst = emit(MOV(result, op[0]));
+      inst = bld.MOV(result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_f2i:
    case nir_op_f2u:
-      emit(MOV(result, op[0]));
+      bld.MOV(result, op[0]);
       break;
 
    case nir_op_fsign: {
@@ -680,17 +683,17 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
          * Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
          * zero.
          */
-      emit(CMP(reg_null_f, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
+      bld.CMP(bld.null_reg_f(), op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ);
 
       fs_reg result_int = retype(result, BRW_REGISTER_TYPE_UD);
       op[0].type = BRW_REGISTER_TYPE_UD;
       result.type = BRW_REGISTER_TYPE_UD;
-      emit(AND(result_int, op[0], fs_reg(0x80000000u)));
+      bld.AND(result_int, op[0], fs_reg(0x80000000u));
 
-      inst = emit(OR(result_int, result_int, fs_reg(0x3f800000u)));
+      inst = bld.OR(result_int, result_int, fs_reg(0x3f800000u));
       inst->predicate = BRW_PREDICATE_NORMAL;
       if (instr->dest.saturate) {
-         inst = emit(MOV(result, result));
+         inst = bld.MOV(result, result);
          inst->saturate = true;
       }
       break;
@@ -701,120 +704,88 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
        *               -> non-negative val generates 0x00000000.
        *  Predicated OR sets 1 if val is positive.
        */
-      emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_G));
-      emit(ASR(result, op[0], fs_reg(31)));
-      inst = emit(OR(result, result, fs_reg(1)));
+      bld.CMP(bld.null_reg_d(), op[0], fs_reg(0), BRW_CONDITIONAL_G);
+      bld.ASR(result, op[0], fs_reg(31));
+      inst = bld.OR(result, result, fs_reg(1));
       inst->predicate = BRW_PREDICATE_NORMAL;
       break;
 
    case nir_op_frcp:
-      inst = emit_math(SHADER_OPCODE_RCP, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_RCP, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fexp2:
-      inst = emit_math(SHADER_OPCODE_EXP2, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_EXP2, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_flog2:
-      inst = emit_math(SHADER_OPCODE_LOG2, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_LOG2, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fsin:
-      inst = emit_math(SHADER_OPCODE_SIN, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_SIN, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fcos:
-      inst = emit_math(SHADER_OPCODE_COS, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_COS, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fddx:
       if (fs_key->high_quality_derivatives) {
-         inst = emit(FS_OPCODE_DDX_FINE, result, op[0]);
+         inst = bld.emit(FS_OPCODE_DDX_FINE, result, op[0]);
       } else {
-         inst = emit(FS_OPCODE_DDX_COARSE, result, op[0]);
+         inst = bld.emit(FS_OPCODE_DDX_COARSE, result, op[0]);
       }
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_fddx_fine:
-      inst = emit(FS_OPCODE_DDX_FINE, result, op[0]);
+      inst = bld.emit(FS_OPCODE_DDX_FINE, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_fddx_coarse:
-      inst = emit(FS_OPCODE_DDX_COARSE, result, op[0]);
+      inst = bld.emit(FS_OPCODE_DDX_COARSE, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_fddy:
       if (fs_key->high_quality_derivatives) {
-         inst = emit(FS_OPCODE_DDY_FINE, result, op[0],
-                     fs_reg(fs_key->render_to_fbo));
+         inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0],
+                         fs_reg(fs_key->render_to_fbo));
       } else {
-         inst = emit(FS_OPCODE_DDY_COARSE, result, op[0],
-                     fs_reg(fs_key->render_to_fbo));
+         inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0],
+                         fs_reg(fs_key->render_to_fbo));
       }
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_fddy_fine:
-      inst = emit(FS_OPCODE_DDY_FINE, result, op[0],
-                  fs_reg(fs_key->render_to_fbo));
+      inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0],
+                      fs_reg(fs_key->render_to_fbo));
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_fddy_coarse:
-      inst = emit(FS_OPCODE_DDY_COARSE, result, op[0],
-                  fs_reg(fs_key->render_to_fbo));
+      inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0],
+                      fs_reg(fs_key->render_to_fbo));
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fadd:
    case nir_op_iadd:
-      inst = emit(ADD(result, op[0], op[1]));
+      inst = bld.ADD(result, op[0], op[1]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fmul:
-      inst = emit(MUL(result, op[0], op[1]));
+      inst = bld.MUL(result, op[0], op[1]);
       inst->saturate = instr->dest.saturate;
       break;
 
-   case nir_op_imul: {
-      if (devinfo->gen >= 8) {
-         emit(MUL(result, op[0], op[1]));
-         break;
-      } else {
-         nir_const_value *value0 = nir_src_as_const_value(instr->src[0].src);
-         nir_const_value *value1 = nir_src_as_const_value(instr->src[1].src);
-
-         if (value0 && value0->u[0] < (1 << 16)) {
-            if (devinfo->gen < 7) {
-               emit(MUL(result, op[0], op[1]));
-            } else {
-               emit(MUL(result, op[1], op[0]));
-            }
-            break;
-         } else if (value1 && value1->u[0] < (1 << 16)) {
-            if (devinfo->gen < 7) {
-               emit(MUL(result, op[1], op[0]));
-            } else {
-               emit(MUL(result, op[0], op[1]));
-            }
-            break;
-         }
-      }
-
-      if (devinfo->gen >= 7)
-         no16("SIMD16 explicit accumulator operands unsupported\n");
-
-      struct brw_reg acc = retype(brw_acc_reg(dispatch_width), result.type);
-
-      emit(MUL(acc, op[0], op[1]));
-      emit(MACH(reg_null_d, op[0], op[1]));
-      emit(MOV(result, fs_reg(acc)));
+   case nir_op_imul:
+      bld.MUL(result, op[0], op[1]);
       break;
-   }
 
    case nir_op_imul_high:
    case nir_op_umul_high: {
@@ -823,8 +794,8 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
 
       struct brw_reg acc = retype(brw_acc_reg(dispatch_width), result.type);
 
-      fs_inst *mul = emit(MUL(acc, op[0], op[1]));
-      emit(MACH(result, op[0], op[1]));
+      fs_inst *mul = bld.MUL(acc, op[0], op[1]);
+      bld.MACH(result, op[0], op[1]);
 
       /* Until Gen8, integer multiplies read 32-bits from one source, and
        * 16-bits from the other, and relying on the MACH instruction to
@@ -852,7 +823,7 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
 
    case nir_op_idiv:
    case nir_op_udiv:
-      emit_math(SHADER_OPCODE_INT_QUOTIENT, result, op[0], op[1]);
+      bld.emit(SHADER_OPCODE_INT_QUOTIENT, result, op[0], op[1]);
       break;
 
    case nir_op_uadd_carry: {
@@ -862,8 +833,8 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
       struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
                                   BRW_REGISTER_TYPE_UD);
 
-      emit(ADDC(reg_null_ud, op[0], op[1]));
-      emit(MOV(result, fs_reg(acc)));
+      bld.ADDC(bld.null_reg_ud(), op[0], op[1]);
+      bld.MOV(result, fs_reg(acc));
       break;
    }
 
@@ -874,63 +845,63 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
       struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
                                   BRW_REGISTER_TYPE_UD);
 
-      emit(SUBB(reg_null_ud, op[0], op[1]));
-      emit(MOV(result, fs_reg(acc)));
+      bld.SUBB(bld.null_reg_ud(), op[0], op[1]);
+      bld.MOV(result, fs_reg(acc));
       break;
    }
 
    case nir_op_umod:
-      emit_math(SHADER_OPCODE_INT_REMAINDER, result, op[0], op[1]);
+      bld.emit(SHADER_OPCODE_INT_REMAINDER, result, op[0], op[1]);
       break;
 
    case nir_op_flt:
    case nir_op_ilt:
    case nir_op_ult:
-      emit(CMP(result, op[0], op[1], BRW_CONDITIONAL_L));
+      bld.CMP(result, op[0], op[1], BRW_CONDITIONAL_L);
       break;
 
    case nir_op_fge:
    case nir_op_ige:
    case nir_op_uge:
-      emit(CMP(result, op[0], op[1], BRW_CONDITIONAL_GE));
+      bld.CMP(result, op[0], op[1], BRW_CONDITIONAL_GE);
       break;
 
    case nir_op_feq:
    case nir_op_ieq:
-      emit(CMP(result, op[0], op[1], BRW_CONDITIONAL_Z));
+      bld.CMP(result, op[0], op[1], BRW_CONDITIONAL_Z);
       break;
 
    case nir_op_fne:
    case nir_op_ine:
-      emit(CMP(result, op[0], op[1], BRW_CONDITIONAL_NZ));
+      bld.CMP(result, op[0], op[1], BRW_CONDITIONAL_NZ);
       break;
 
    case nir_op_inot:
       if (devinfo->gen >= 8) {
          resolve_source_modifiers(&op[0]);
       }
-      emit(NOT(result, op[0]));
+      bld.NOT(result, op[0]);
       break;
    case nir_op_ixor:
       if (devinfo->gen >= 8) {
          resolve_source_modifiers(&op[0]);
          resolve_source_modifiers(&op[1]);
       }
-      emit(XOR(result, op[0], op[1]));
+      bld.XOR(result, op[0], op[1]);
       break;
    case nir_op_ior:
       if (devinfo->gen >= 8) {
          resolve_source_modifiers(&op[0]);
          resolve_source_modifiers(&op[1]);
       }
-      emit(OR(result, op[0], op[1]));
+      bld.OR(result, op[0], op[1]);
       break;
    case nir_op_iand:
       if (devinfo->gen >= 8) {
          resolve_source_modifiers(&op[0]);
          resolve_source_modifiers(&op[1]);
       }
-      emit(AND(result, op[0], op[1]));
+      bld.AND(result, op[0], op[1]);
       break;
 
    case nir_op_fdot2:
@@ -978,53 +949,53 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
       unreachable("not reached: should be handled by ldexp_to_arith()");
 
    case nir_op_fsqrt:
-      inst = emit_math(SHADER_OPCODE_SQRT, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_SQRT, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_frsq:
-      inst = emit_math(SHADER_OPCODE_RSQ, result, op[0]);
+      inst = bld.emit(SHADER_OPCODE_RSQ, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_b2i:
-      emit(AND(result, op[0], fs_reg(1)));
+      bld.AND(result, op[0], fs_reg(1));
       break;
    case nir_op_b2f:
-      emit(AND(retype(result, BRW_REGISTER_TYPE_UD), op[0], fs_reg(0x3f800000u)));
+      bld.AND(retype(result, BRW_REGISTER_TYPE_UD), op[0], fs_reg(0x3f800000u));
       break;
 
    case nir_op_f2b:
-      emit(CMP(result, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
+      bld.CMP(result, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ);
       break;
    case nir_op_i2b:
-      emit(CMP(result, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
+      bld.CMP(result, op[0], fs_reg(0), BRW_CONDITIONAL_NZ);
       break;
 
    case nir_op_ftrunc:
-      inst = emit(RNDZ(result, op[0]));
+      inst = bld.RNDZ(result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fceil: {
       op[0].negate = !op[0].negate;
       fs_reg temp = vgrf(glsl_type::float_type);
-      emit(RNDD(temp, op[0]));
+      bld.RNDD(temp, op[0]);
       temp.negate = true;
-      inst = emit(MOV(result, temp));
+      inst = bld.MOV(result, temp);
       inst->saturate = instr->dest.saturate;
       break;
    }
    case nir_op_ffloor:
-      inst = emit(RNDD(result, op[0]));
+      inst = bld.RNDD(result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_ffract:
-      inst = emit(FRC(result, op[0]));
+      inst = bld.FRC(result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_fround_even:
-      inst = emit(RNDE(result, op[0]));
+      inst = bld.RNDE(result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
@@ -1032,11 +1003,11 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
    case nir_op_imin:
    case nir_op_umin:
       if (devinfo->gen >= 6) {
-         inst = emit(BRW_OPCODE_SEL, result, op[0], op[1]);
+         inst = bld.emit(BRW_OPCODE_SEL, result, op[0], op[1]);
          inst->conditional_mod = BRW_CONDITIONAL_L;
       } else {
-         emit(CMP(reg_null_d, op[0], op[1], BRW_CONDITIONAL_L));
-         inst = emit(SEL(result, op[0], op[1]));
+         bld.CMP(bld.null_reg_d(), op[0], op[1], BRW_CONDITIONAL_L);
+         inst = bld.SEL(result, op[0], op[1]);
          inst->predicate = BRW_PREDICATE_NORMAL;
       }
       inst->saturate = instr->dest.saturate;
@@ -1046,11 +1017,11 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
    case nir_op_imax:
    case nir_op_umax:
       if (devinfo->gen >= 6) {
-         inst = emit(BRW_OPCODE_SEL, result, op[0], op[1]);
+         inst = bld.emit(BRW_OPCODE_SEL, result, op[0], op[1]);
          inst->conditional_mod = BRW_CONDITIONAL_GE;
       } else {
-         emit(CMP(reg_null_d, op[0], op[1], BRW_CONDITIONAL_GE));
-         inst = emit(SEL(result, op[0], op[1]));
+         bld.CMP(bld.null_reg_d(), op[0], op[1], BRW_CONDITIONAL_GE);
+         inst = bld.SEL(result, op[0], op[1]);
          inst->predicate = BRW_PREDICATE_NORMAL;
       }
       inst->saturate = instr->dest.saturate;
@@ -1069,57 +1040,57 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
       unreachable("not reached: should be handled by lower_packing_builtins");
 
    case nir_op_unpack_half_2x16_split_x:
-      inst = emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X, result, op[0]);
+      inst = bld.emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
    case nir_op_unpack_half_2x16_split_y:
-      inst = emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y, result, op[0]);
+      inst = bld.emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y, result, op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_fpow:
-      inst = emit_math(SHADER_OPCODE_POW, result, op[0], op[1]);
+      inst = bld.emit(SHADER_OPCODE_POW, result, op[0], op[1]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_bitfield_reverse:
-      emit(BFREV(result, op[0]));
+      bld.BFREV(result, op[0]);
       break;
 
    case nir_op_bit_count:
-      emit(CBIT(result, op[0]));
+      bld.CBIT(result, op[0]);
       break;
 
    case nir_op_ufind_msb:
    case nir_op_ifind_msb: {
-      emit(FBH(retype(result, BRW_REGISTER_TYPE_UD), op[0]));
+      bld.FBH(retype(result, BRW_REGISTER_TYPE_UD), op[0]);
 
       /* FBH counts from the MSB side, while GLSL's findMSB() wants the count
        * from the LSB side. If FBH didn't return an error (0xFFFFFFFF), then
        * subtract the result from 31 to convert the MSB count into an LSB count.
        */
 
-      emit(CMP(reg_null_d, result, fs_reg(-1), BRW_CONDITIONAL_NZ));
+      bld.CMP(bld.null_reg_d(), result, fs_reg(-1), BRW_CONDITIONAL_NZ);
       fs_reg neg_result(result);
       neg_result.negate = true;
-      inst = emit(ADD(result, neg_result, fs_reg(31)));
+      inst = bld.ADD(result, neg_result, fs_reg(31));
       inst->predicate = BRW_PREDICATE_NORMAL;
       break;
    }
 
    case nir_op_find_lsb:
-      emit(FBL(result, op[0]));
+      bld.FBL(result, op[0]);
       break;
 
    case nir_op_ubitfield_extract:
    case nir_op_ibitfield_extract:
-      emit(BFE(result, op[2], op[1], op[0]));
+      bld.BFE(result, op[2], op[1], op[0]);
       break;
    case nir_op_bfm:
-      emit(BFI1(result, op[0], op[1]));
+      bld.BFI1(result, op[0], op[1]);
       break;
    case nir_op_bfi:
-      emit(BFI2(result, op[0], op[1], op[2]));
+      bld.BFI2(result, op[0], op[1], op[2]);
       break;
 
    case nir_op_bitfield_insert:
@@ -1127,26 +1098,26 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
                   "lower_instructions::bitfield_insert_to_bfm_bfi");
 
    case nir_op_ishl:
-      emit(SHL(result, op[0], op[1]));
+      bld.SHL(result, op[0], op[1]);
       break;
    case nir_op_ishr:
-      emit(ASR(result, op[0], op[1]));
+      bld.ASR(result, op[0], op[1]);
       break;
    case nir_op_ushr:
-      emit(SHR(result, op[0], op[1]));
+      bld.SHR(result, op[0], op[1]);
       break;
 
    case nir_op_pack_half_2x16_split:
-      emit(FS_OPCODE_PACK_HALF_2x16_SPLIT, result, op[0], op[1]);
+      bld.emit(FS_OPCODE_PACK_HALF_2x16_SPLIT, result, op[0], op[1]);
       break;
 
    case nir_op_ffma:
-      inst = emit(MAD(result, op[2], op[1], op[0]));
+      inst = bld.MAD(result, op[2], op[1], op[0]);
       inst->saturate = instr->dest.saturate;
       break;
 
    case nir_op_flrp:
-      inst = emit_lrp(result, op[0], op[1], op[2]);
+      inst = bld.LRP(result, op[0], op[1], op[2]);
       inst->saturate = instr->dest.saturate;
       break;
 
@@ -1154,8 +1125,8 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
       if (optimize_frontfacing_ternary(instr, result))
          return;
 
-      emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
-      inst = emit(SEL(result, op[1], op[2]));
+      bld.CMP(bld.null_reg_d(), op[0], fs_reg(0), BRW_CONDITIONAL_NZ);
+      inst = bld.SEL(result, op[1], op[2]);
       inst->predicate = BRW_PREDICATE_NORMAL;
       break;
 
@@ -1169,9 +1140,9 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
    if (devinfo->gen <= 5 &&
        (instr->instr.pass_flags & BRW_NIR_BOOLEAN_MASK) == BRW_NIR_BOOLEAN_NEEDS_RESOLVE) {
       fs_reg masked = vgrf(glsl_type::int_type);
-      emit(AND(masked, result, fs_reg(1)));
+      bld.AND(masked, result, fs_reg(1));
       masked.negate = true;
-      emit(MOV(retype(result, BRW_REGISTER_TYPE_D), masked));
+      bld.MOV(retype(result, BRW_REGISTER_TYPE_D), masked);
    }
 }
 
@@ -1190,8 +1161,8 @@ fs_reg_for_nir_reg(fs_visitor *v, nir_register *nir_reg,
       int multiplier = nir_reg->num_components * (v->dispatch_width / 8);
 
       reg.reladdr = new(v->mem_ctx) fs_reg(v->vgrf(glsl_type::int_type));
-      v->emit(v->MUL(*reg.reladdr, v->get_nir_src(*indirect),
-                     fs_reg(multiplier)));
+      v->bld.MUL(*reg.reladdr, v->get_nir_src(*indirect),
+                 fs_reg(multiplier));
    }
 
    return reg;
@@ -1203,11 +1174,10 @@ fs_visitor::get_nir_src(nir_src src)
    if (src.is_ssa) {
       assert(src.ssa->parent_instr->type == nir_instr_type_load_const);
       nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr);
-      fs_reg reg = vgrf(src.ssa->num_components);
-      reg.type = BRW_REGISTER_TYPE_D;
+      fs_reg reg = bld.vgrf(BRW_REGISTER_TYPE_D, src.ssa->num_components);
 
       for (unsigned i = 0; i < src.ssa->num_components; ++i)
-         emit(MOV(offset(reg, i), fs_reg(load->value.i[i])));
+         bld.MOV(offset(reg, i), fs_reg(load->value.i[i]));
 
       return reg;
    } else {
@@ -1230,24 +1200,25 @@ fs_visitor::get_nir_dest(nir_dest dest)
 }
 
 void
-fs_visitor::emit_percomp(fs_inst *inst, unsigned wr_mask)
+fs_visitor::emit_percomp(const fs_builder &bld, const fs_inst &inst,
+                         unsigned wr_mask)
 {
    for (unsigned i = 0; i < 4; i++) {
       if (!((wr_mask >> i) & 1))
          continue;
 
-      fs_inst *new_inst = new(mem_ctx) fs_inst(*inst);
+      fs_inst *new_inst = new(mem_ctx) fs_inst(inst);
       new_inst->dst = offset(new_inst->dst, i);
       for (unsigned j = 0; j < new_inst->sources; j++)
-         if (inst->src[j].file == GRF)
+         if (new_inst->src[j].file == GRF)
             new_inst->src[j] = offset(new_inst->src[j], i);
 
-      emit(new_inst);
+      bld.emit(new_inst);
    }
 }
 
 void
-fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
+fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr)
 {
    fs_reg dest;
    if (nir_intrinsic_infos[instr->intrinsic].has_dest)
@@ -1265,12 +1236,12 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
        */
       fs_inst *cmp;
       if (instr->intrinsic == nir_intrinsic_discard_if) {
-         cmp = emit(CMP(reg_null_f, get_nir_src(instr->src[0]),
-                        fs_reg(0), BRW_CONDITIONAL_Z));
+         cmp = bld.CMP(bld.null_reg_f(), get_nir_src(instr->src[0]),
+                       fs_reg(0), BRW_CONDITIONAL_Z);
       } else {
          fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
                                        BRW_REGISTER_TYPE_UW));
-         cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ));
+         cmp = bld.CMP(bld.null_reg_f(), some_reg, some_reg, BRW_CONDITIONAL_NZ);
       }
       cmp->predicate = BRW_PREDICATE_NORMAL;
       cmp->flag_subreg = 1;
@@ -1307,8 +1278,8 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
    }
 
    case nir_intrinsic_load_front_face:
-      emit(MOV(retype(dest, BRW_REGISTER_TYPE_D),
-               *emit_frontfacing_interpolation()));
+      bld.MOV(retype(dest, BRW_REGISTER_TYPE_D),
+              *emit_frontfacing_interpolation());
       break;
 
    case nir_intrinsic_load_vertex_id:
@@ -1318,7 +1289,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       fs_reg vertex_id = nir_system_values[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE];
       assert(vertex_id.file != BAD_FILE);
       dest.type = vertex_id.type;
-      emit(MOV(dest, vertex_id));
+      bld.MOV(dest, vertex_id);
       break;
    }
 
@@ -1326,7 +1297,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       fs_reg base_vertex = nir_system_values[SYSTEM_VALUE_BASE_VERTEX];
       assert(base_vertex.file != BAD_FILE);
       dest.type = base_vertex.type;
-      emit(MOV(dest, base_vertex));
+      bld.MOV(dest, base_vertex);
       break;
    }
 
@@ -1334,7 +1305,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       fs_reg instance_id = nir_system_values[SYSTEM_VALUE_INSTANCE_ID];
       assert(instance_id.file != BAD_FILE);
       dest.type = instance_id.type;
-      emit(MOV(dest, instance_id));
+      bld.MOV(dest, instance_id);
       break;
    }
 
@@ -1342,7 +1313,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       fs_reg sample_mask_in = nir_system_values[SYSTEM_VALUE_SAMPLE_MASK_IN];
       assert(sample_mask_in.file != BAD_FILE);
       dest.type = sample_mask_in.type;
-      emit(MOV(dest, sample_mask_in));
+      bld.MOV(dest, sample_mask_in);
       break;
    }
 
@@ -1350,8 +1321,8 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       fs_reg sample_pos = nir_system_values[SYSTEM_VALUE_SAMPLE_POS];
       assert(sample_pos.file != BAD_FILE);
       dest.type = sample_pos.type;
-      emit(MOV(dest, sample_pos));
-      emit(MOV(offset(dest, 1), offset(sample_pos, 1)));
+      bld.MOV(dest, sample_pos);
+      bld.MOV(offset(dest, 1), offset(sample_pos, 1));
       break;
    }
 
@@ -1359,7 +1330,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       fs_reg sample_id = nir_system_values[SYSTEM_VALUE_SAMPLE_ID];
       assert(sample_id.file != BAD_FILE);
       dest.type = sample_id.type;
-      emit(MOV(dest, sample_id));
+      bld.MOV(dest, sample_id);
       break;
    }
 
@@ -1377,16 +1348,14 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          index -= num_direct_uniforms;
       }
 
-      for (int i = 0; i < instr->const_index[1]; i++) {
-         for (unsigned j = 0; j < instr->num_components; j++) {
-            fs_reg src = offset(retype(uniform_reg, dest.type), index);
-            if (has_indirect)
-               src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
-            index++;
+      for (unsigned j = 0; j < instr->num_components; j++) {
+         fs_reg src = offset(retype(uniform_reg, dest.type), index);
+         if (has_indirect)
+            src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
+         index++;
 
-            emit(MOV(dest, src));
-            dest = offset(dest, 1);
-         }
+         bld.MOV(dest, src);
+         dest = offset(dest, 1);
       }
       break;
    }
@@ -1417,9 +1386,9 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
           * from any live channel.
           */
          surf_index = vgrf(glsl_type::uint_type);
-         emit(ADD(surf_index, get_nir_src(instr->src[0]),
-                  fs_reg(stage_prog_data->binding_table.ubo_start)));
-         emit_uniformize(surf_index, surf_index);
+         bld.ADD(surf_index, get_nir_src(instr->src[0]),
+                 fs_reg(stage_prog_data->binding_table.ubo_start));
+         bld.emit_uniformize(surf_index, surf_index);
 
          /* Assume this may touch any UBO. It would be nice to provide
           * a tighter bound, but the array information is already lowered away.
@@ -1432,21 +1401,21 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       if (has_indirect) {
          /* Turn the byte offset into a dword offset. */
          fs_reg base_offset = vgrf(glsl_type::int_type);
-         emit(SHR(base_offset, retype(get_nir_src(instr->src[1]),
-                                 BRW_REGISTER_TYPE_D),
-                  fs_reg(2)));
+         bld.SHR(base_offset, retype(get_nir_src(instr->src[1]),
+                                     BRW_REGISTER_TYPE_D),
+                 fs_reg(2));
 
          unsigned vec4_offset = instr->const_index[0] / 4;
          for (int i = 0; i < instr->num_components; i++)
-            emit(VARYING_PULL_CONSTANT_LOAD(offset(dest, i), surf_index,
-                                            base_offset, vec4_offset + i));
+            VARYING_PULL_CONSTANT_LOAD(bld, offset(dest, i), surf_index,
+                                       base_offset, vec4_offset + i);
       } else {
          fs_reg packed_consts = vgrf(glsl_type::float_type);
          packed_consts.type = dest.type;
 
          fs_reg const_offset_reg((unsigned) instr->const_index[0] & ~15);
-         emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, packed_consts,
-              surf_index, const_offset_reg);
+         bld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, packed_consts,
+                  surf_index, const_offset_reg);
 
          for (unsigned i = 0; i < instr->num_components; i++) {
             packed_consts.set_smear(instr->const_index[0] % 16 / 4 + i);
@@ -1456,7 +1425,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
              */
             assert(packed_consts.subreg_offset < 32);
 
-            emit(MOV(dest, packed_consts));
+            bld.MOV(dest, packed_consts);
             dest = offset(dest, 1);
          }
       }
@@ -1468,17 +1437,15 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       /* fallthrough */
    case nir_intrinsic_load_input: {
       unsigned index = 0;
-      for (int i = 0; i < instr->const_index[1]; i++) {
-         for (unsigned j = 0; j < instr->num_components; j++) {
-            fs_reg src = offset(retype(nir_inputs, dest.type),
-                                instr->const_index[0] + index);
-            if (has_indirect)
-               src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
-            index++;
-
-            emit(MOV(dest, src));
-            dest = offset(dest, 1);
-         }
+      for (unsigned j = 0; j < instr->num_components; j++) {
+         fs_reg src = offset(retype(nir_inputs, dest.type),
+                             instr->const_index[0] + index);
+         if (has_indirect)
+            src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
+         index++;
+
+         bld.MOV(dest, src);
+         dest = offset(dest, 1);
       }
       break;
    }
@@ -1510,7 +1477,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
        */
       no16("interpolate_at_* not yet supported in SIMD16 mode.");
 
-      fs_reg dst_xy = vgrf(2);
+      fs_reg dst_xy = bld.vgrf(BRW_REGISTER_TYPE_F, 2);
 
       /* For most messages, we need one reg of ignored data; the hardware
        * requires mlen==1 even when there is no payload. in the per-slot
@@ -1522,7 +1489,8 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
 
       switch (instr->intrinsic) {
       case nir_intrinsic_interp_var_at_centroid:
-         inst = emit(FS_OPCODE_INTERPOLATE_AT_CENTROID, dst_xy, src, fs_reg(0u));
+         inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_CENTROID,
+                         dst_xy, src, fs_reg(0u));
          break;
 
       case nir_intrinsic_interp_var_at_sample: {
@@ -1530,8 +1498,8 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          nir_const_value *const_sample = nir_src_as_const_value(instr->src[0]);
          assert(const_sample);
          unsigned msg_data = const_sample ? const_sample->i[0] << 4 : 0;
-         inst = emit(FS_OPCODE_INTERPOLATE_AT_SAMPLE, dst_xy, src,
-                     fs_reg(msg_data));
+         inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_SAMPLE, dst_xy, src,
+                         fs_reg(msg_data));
          break;
       }
 
@@ -1542,17 +1510,17 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
             unsigned off_x = MIN2((int)(const_offset->f[0] * 16), 7) & 0xf;
             unsigned off_y = MIN2((int)(const_offset->f[1] * 16), 7) & 0xf;
 
-            inst = emit(FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET, dst_xy, src,
-                        fs_reg(off_x | (off_y << 4)));
+            inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET, dst_xy, src,
+                            fs_reg(off_x | (off_y << 4)));
          } else {
             src = vgrf(glsl_type::ivec2_type);
             fs_reg offset_src = retype(get_nir_src(instr->src[0]),
                                        BRW_REGISTER_TYPE_F);
             for (int i = 0; i < 2; i++) {
                fs_reg temp = vgrf(glsl_type::float_type);
-               emit(MUL(temp, offset(offset_src, i), fs_reg(16.0f)));
+               bld.MUL(temp, offset(offset_src, i), fs_reg(16.0f));
                fs_reg itemp = vgrf(glsl_type::int_type);
-               emit(MOV(itemp, temp));  /* float to int */
+               bld.MOV(itemp, temp);  /* float to int */
 
                /* Clamp the upper end of the range to +7/16.
                 * ARB_gpu_shader5 requires that we support a maximum offset
@@ -1569,14 +1537,13 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
                 * implementation-dependent constant
                 * FRAGMENT_INTERPOLATION_OFFSET_BITS"
                 */
-
-               emit(BRW_OPCODE_SEL, offset(src, i), itemp, fs_reg(7))
-                   ->conditional_mod = BRW_CONDITIONAL_L; /* min(src2, 7) */
+               set_condmod(BRW_CONDITIONAL_L,
+                           bld.SEL(offset(src, i), itemp, fs_reg(7)));
             }
 
             mlen = 2;
-            inst = emit(FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET, dst_xy, src,
-                        fs_reg(0u));
+            inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET, dst_xy, src,
+                            fs_reg(0u));
          }
          break;
       }
@@ -1594,7 +1561,7 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          fs_reg src = interp_reg(instr->variables[0]->var->data.location, j);
          src.type = dest.type;
 
-         emit(FS_OPCODE_LINTERP, dest, dst_xy, src);
+         bld.emit(FS_OPCODE_LINTERP, dest, dst_xy, src);
          dest = offset(dest, 1);
       }
       break;
@@ -1606,27 +1573,29 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
    case nir_intrinsic_store_output: {
       fs_reg src = get_nir_src(instr->src[0]);
       unsigned index = 0;
-      for (int i = 0; i < instr->const_index[1]; i++) {
-         for (unsigned j = 0; j < instr->num_components; j++) {
-            fs_reg new_dest = offset(retype(nir_outputs, src.type),
-                                     instr->const_index[0] + index);
-            if (has_indirect)
-               src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[1]));
-            index++;
-            emit(MOV(new_dest, src));
-            src = offset(src, 1);
-         }
+      for (unsigned j = 0; j < instr->num_components; j++) {
+         fs_reg new_dest = offset(retype(nir_outputs, src.type),
+                                  instr->const_index[0] + index);
+         if (has_indirect)
+            src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[1]));
+         index++;
+         bld.MOV(new_dest, src);
+         src = offset(src, 1);
       }
       break;
    }
 
+   case nir_intrinsic_barrier:
+      emit_barrier();
+      break;
+
    default:
       unreachable("unknown intrinsic");
    }
 }
 
 void
-fs_visitor::nir_emit_texture(nir_tex_instr *instr)
+fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr)
 {
    uint32_t set = instr->sampler_set;
    uint32_t binding = instr->sampler_index;
@@ -1650,7 +1619,8 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
    bool is_cube_array = instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE &&
                         instr->is_array;
 
-   int lod_components = 0, offset_components = 0;
+   int lod_components = 0;
+   int UNUSED offset_components = 0;
 
    fs_reg coordinate, shadow_comparitor, lod, lod2, sample_index, mcs, tex_offset;
 
@@ -1719,8 +1689,8 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
 
          /* Emit code to evaluate the actual indexing expression */
          sampler_reg = vgrf(glsl_type::uint_type);
-         emit(ADD(sampler_reg, src, fs_reg(sampler)));
-         emit_uniformize(sampler_reg, sampler_reg);
+         bld.ADD(sampler_reg, src, fs_reg(sampler));
+         bld.emit_uniformize(sampler_reg, sampler_reg);
          break;
       }
 
@@ -1789,18 +1759,19 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
    fs_reg dest = get_nir_dest(instr->dest);
    dest.type = this->result.type;
    unsigned num_components = nir_tex_instr_dest_size(instr);
-   emit_percomp(MOV(dest, this->result), (1 << num_components) - 1);
+   emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, dest, this->result),
+                (1 << num_components) - 1);
 }
 
 void
-fs_visitor::nir_emit_jump(nir_jump_instr *instr)
+fs_visitor::nir_emit_jump(const fs_builder &bld, nir_jump_instr *instr)
 {
    switch (instr->type) {
    case nir_jump_break:
-      emit(BRW_OPCODE_BREAK);
+      bld.emit(BRW_OPCODE_BREAK);
       break;
    case nir_jump_continue:
-      emit(BRW_OPCODE_CONTINUE);
+      bld.emit(BRW_OPCODE_CONTINUE);
       break;
    case nir_jump_return:
    default:
index cf3da7b18823799125c87745f67f6d3dbfc170dd..d92d4bbd81d376bdeca2b112de2b2aaa9046272f 100644 (file)
@@ -85,9 +85,9 @@ fs_visitor::opt_peephole_predicated_break()
        * instruction to set the flag register.
        */
       if (devinfo->gen == 6 && if_inst->conditional_mod) {
-         fs_inst *cmp_inst = CMP(reg_null_d, if_inst->src[0], if_inst->src[1],
-                                 if_inst->conditional_mod);
-         if_inst->insert_before(if_block, cmp_inst);
+         bld.at(if_block, if_inst)
+            .CMP(bld.null_reg_d(), if_inst->src[0], if_inst->src[1],
+                 if_inst->conditional_mod);
          jump_inst->predicate = BRW_PREDICATE_NORMAL;
       } else {
          jump_inst->predicate = if_inst->predicate;
index 582d0993f1c9096a7aad6b9fc6becdb10ef35916..364fc4a5ad26ef8b7a1cd0c56cc42c17be0443b6 100644 (file)
@@ -30,6 +30,8 @@
 #include "glsl/glsl_types.h"
 #include "glsl/ir_optimization.h"
 
+using namespace brw;
+
 static void
 assign_reg(unsigned *reg_hw_locations, fs_reg *reg)
 {
@@ -468,14 +470,14 @@ fs_visitor::setup_payload_interference(struct ra_graph *g,
  * see if we can actually use MRFs to do spills without overwriting normal MRF
  * contents.
  */
-void
-fs_visitor::get_used_mrfs(bool *mrf_used)
+static void
+get_used_mrfs(fs_visitor *v, bool *mrf_used)
 {
-   int reg_width = dispatch_width / 8;
+   int reg_width = v->dispatch_width / 8;
 
    memset(mrf_used, 0, BRW_MAX_MRF * sizeof(bool));
 
-   foreach_block_and_inst(block, fs_inst, inst, cfg) {
+   foreach_block_and_inst(block, fs_inst, inst, v->cfg) {
       if (inst->dst.file == MRF) {
          int reg = inst->dst.reg & ~BRW_MRF_COMPR4;
          mrf_used[reg] = true;
@@ -489,7 +491,7 @@ fs_visitor::get_used_mrfs(bool *mrf_used)
       }
 
       if (inst->mlen > 0) {
-        for (int i = 0; i < implied_mrf_writes(inst); i++) {
+        for (int i = 0; i < v->implied_mrf_writes(inst); i++) {
             mrf_used[inst->base_mrf + i] = true;
          }
       }
@@ -500,12 +502,14 @@ fs_visitor::get_used_mrfs(bool *mrf_used)
  * Sets interference between virtual GRFs and usage of the high GRFs for SEND
  * messages (treated as MRFs in code generation).
  */
-void
-fs_visitor::setup_mrf_hack_interference(struct ra_graph *g, int first_mrf_node)
+static void
+setup_mrf_hack_interference(fs_visitor *v, struct ra_graph *g,
+                            int first_mrf_node, int *first_used_mrf)
 {
    bool mrf_used[BRW_MAX_MRF];
-   get_used_mrfs(mrf_used);
+   get_used_mrfs(v, mrf_used);
 
+   *first_used_mrf = BRW_MAX_MRF;
    for (int i = 0; i < BRW_MAX_MRF; i++) {
       /* Mark each MRF reg node as being allocated to its physical register.
        *
@@ -518,7 +522,10 @@ fs_visitor::setup_mrf_hack_interference(struct ra_graph *g, int first_mrf_node)
        * that are used as conflicting with all virtual GRFs.
        */
       if (mrf_used[i]) {
-         for (unsigned j = 0; j < this->alloc.count; j++) {
+         if (i < *first_used_mrf)
+            *first_used_mrf = i;
+
+         for (unsigned j = 0; j < v->alloc.count; j++) {
             ra_add_node_interference(g, first_mrf_node + i, j);
          }
       }
@@ -528,7 +535,6 @@ fs_visitor::setup_mrf_hack_interference(struct ra_graph *g, int first_mrf_node)
 bool
 fs_visitor::assign_regs(bool allow_spilling)
 {
-   struct brw_compiler *compiler = brw->intelScreen->compiler;
    /* Most of this allocation was written for a reg_width of 1
     * (dispatch_width == 8).  In extending to SIMD16, the code was
     * left in place and it was converted to have the hardware
@@ -584,7 +590,9 @@ fs_visitor::assign_regs(bool allow_spilling)
 
    setup_payload_interference(g, payload_node_count, first_payload_node);
    if (devinfo->gen >= 7) {
-      setup_mrf_hack_interference(g, first_mrf_hack_node);
+      int first_used_mrf = BRW_MAX_MRF;
+      setup_mrf_hack_interference(this, g, first_mrf_hack_node,
+                                  &first_used_mrf);
 
       foreach_block_and_inst(block, fs_inst, inst, cfg) {
          /* When we do send-from-GRF for FB writes, we need to ensure that
@@ -600,6 +608,13 @@ fs_visitor::assign_regs(bool allow_spilling)
          if (inst->eot) {
             int size = alloc.sizes[inst->src[0].reg];
             int reg = compiler->fs_reg_sets[rsi].class_to_ra_reg_range[size] - 1;
+
+            /* If something happened to spill, we want to push the EOT send
+             * register early enough in the register file that we don't
+             * conflict with any used MRF hack registers.
+             */
+            reg -= BRW_MAX_MRF - first_used_mrf;
+
             ra_set_node_reg(g, inst->src[0].reg, reg);
             break;
          }
@@ -696,25 +711,24 @@ fs_visitor::emit_unspill(bblock_t *block, fs_inst *inst, fs_reg dst,
       dst.width = 16;
    }
 
+   const fs_builder ibld = bld.annotate(inst->annotation, inst->ir)
+                              .group(reg_size * 8, 0)
+                              .at(block, inst);
+
    for (int i = 0; i < count / reg_size; i++) {
       /* The gen7 descriptor-based offset is 12 bits of HWORD units. */
       bool gen7_read = devinfo->gen >= 7 && spill_offset < (1 << 12) * REG_SIZE;
-
-      fs_inst *unspill_inst =
-         new(mem_ctx) fs_inst(gen7_read ?
-                              SHADER_OPCODE_GEN7_SCRATCH_READ :
-                              SHADER_OPCODE_GEN4_SCRATCH_READ,
-                              dst);
+      fs_inst *unspill_inst = ibld.emit(gen7_read ?
+                                        SHADER_OPCODE_GEN7_SCRATCH_READ :
+                                        SHADER_OPCODE_GEN4_SCRATCH_READ,
+                                        dst);
       unspill_inst->offset = spill_offset;
-      unspill_inst->ir = inst->ir;
-      unspill_inst->annotation = inst->annotation;
       unspill_inst->regs_written = reg_size;
 
       if (!gen7_read) {
          unspill_inst->base_mrf = 14;
          unspill_inst->mlen = 1; /* header contains offset */
       }
-      inst->insert_before(block, unspill_inst);
 
       dst.reg_offset += reg_size;
       spill_offset += reg_size * REG_SIZE;
@@ -732,17 +746,17 @@ fs_visitor::emit_spill(bblock_t *block, fs_inst *inst, fs_reg src,
       reg_size = 2;
    }
 
+   const fs_builder ibld = bld.annotate(inst->annotation, inst->ir)
+                              .group(reg_size * 8, 0)
+                              .at(block, inst->next);
+
    for (int i = 0; i < count / reg_size; i++) {
       fs_inst *spill_inst =
-         new(mem_ctx) fs_inst(SHADER_OPCODE_GEN4_SCRATCH_WRITE,
-                              reg_size * 8, reg_null_f, src);
+         ibld.emit(SHADER_OPCODE_GEN4_SCRATCH_WRITE, bld.null_reg_f(), src);
       src.reg_offset += reg_size;
       spill_inst->offset = spill_offset + i * reg_size * REG_SIZE;
-      spill_inst->ir = inst->ir;
-      spill_inst->annotation = inst->annotation;
       spill_inst->mlen = 1 + reg_size; /* header, value */
       spill_inst->base_mrf = spill_base_mrf;
-      inst->insert_after(block, spill_inst);
    }
 }
 
@@ -839,7 +853,7 @@ fs_visitor::spill_reg(int spill_reg)
     */
    if (!spilled_any_registers) {
       bool mrf_used[BRW_MAX_MRF];
-      get_used_mrfs(mrf_used);
+      get_used_mrfs(this, mrf_used);
 
       for (int i = spill_base_mrf; i < BRW_MAX_MRF; i++) {
          if (mrf_used[i]) {
index 52aa5590c2e6b9a217f576f53cbe9527fd260c7c..8660ec08b8f2db9496c8488961f53a68e7afd782 100644 (file)
@@ -37,6 +37,8 @@
  */
 #define MAX_MOVS 8 /**< The maximum number of MOVs to attempt to match. */
 
+using namespace brw;
+
 /**
  * Scans forwards from an IF counting consecutive MOV instructions in the
  * "then" and "else" blocks of the if statement.
@@ -153,9 +155,6 @@ fs_visitor::opt_peephole_sel()
       if (movs == 0)
          continue;
 
-      fs_inst *sel_inst[MAX_MOVS] = { NULL };
-      fs_inst *mov_imm_inst[MAX_MOVS] = { NULL };
-
       enum brw_predicate predicate;
       bool predicate_inverse;
       if (devinfo->gen == 6 && if_inst->conditional_mod) {
@@ -188,9 +187,21 @@ fs_visitor::opt_peephole_sel()
             movs = i;
             break;
          }
+      }
+
+      if (movs == 0)
+         continue;
+
+      const fs_builder ibld = bld.at(block, if_inst);
 
+      /* Emit a CMP if our IF used the embedded comparison */
+      if (devinfo->gen == 6 && if_inst->conditional_mod)
+         ibld.CMP(ibld.null_reg_d(), if_inst->src[0], if_inst->src[1],
+                  if_inst->conditional_mod);
+
+      for (int i = 0; i < movs; i++) {
          if (then_mov[i]->src[0].equals(else_mov[i]->src[0])) {
-            sel_inst[i] = MOV(then_mov[i]->dst, then_mov[i]->src[0]);
+            ibld.MOV(then_mov[i]->dst, then_mov[i]->src[0]);
          } else {
             /* Only the last source register can be a constant, so if the MOV
              * in the "then" clause uses a constant, we need to put it in a
@@ -200,29 +211,13 @@ fs_visitor::opt_peephole_sel()
             if (src0.file == IMM) {
                src0 = vgrf(glsl_type::float_type);
                src0.type = then_mov[i]->src[0].type;
-               mov_imm_inst[i] = MOV(src0, then_mov[i]->src[0]);
+               ibld.MOV(src0, then_mov[i]->src[0]);
             }
 
-            sel_inst[i] = SEL(then_mov[i]->dst, src0, else_mov[i]->src[0]);
-            sel_inst[i]->predicate = predicate;
-            sel_inst[i]->predicate_inverse = predicate_inverse;
+            set_predicate_inv(predicate, predicate_inverse,
+                              ibld.SEL(then_mov[i]->dst, src0,
+                                       else_mov[i]->src[0]));
          }
-      }
-
-      if (movs == 0)
-         continue;
-
-      /* Emit a CMP if our IF used the embedded comparison */
-      if (devinfo->gen == 6 && if_inst->conditional_mod) {
-         fs_inst *cmp_inst = CMP(reg_null_d, if_inst->src[0], if_inst->src[1],
-                                 if_inst->conditional_mod);
-         if_inst->insert_before(block, cmp_inst);
-      }
-
-      for (int i = 0; i < movs; i++) {
-         if (mov_imm_inst[i])
-            if_inst->insert_before(block, mov_imm_inst[i]);
-         if_inst->insert_before(block, sel_inst[i]);
 
          then_mov[i]->remove(then_block);
          else_mov[i]->remove(else_block);
index e1f47d4ec44b0a32910a0b43f9ee71915b39cccc..9a4bad6bcf580f220565eacb6c2b70508d7ec9f3 100644 (file)
@@ -47,6 +47,7 @@
 #include "glsl/ir_optimization.h"
 #include "program/sampler.h"
 
+using namespace brw;
 
 fs_reg *
 fs_visitor::emit_vs_system_value(int location)
@@ -76,2918 +77,952 @@ fs_visitor::emit_vs_system_value(int location)
    return reg;
 }
 
-void
-fs_visitor::visit(ir_variable *ir)
+fs_inst *
+fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
+                              fs_reg coordinate, int coord_components,
+                              fs_reg shadow_c,
+                              fs_reg lod, fs_reg dPdy, int grad_components,
+                              uint32_t sampler)
 {
-   fs_reg *reg = NULL;
-
-   if (variable_storage(ir))
-      return;
+   int mlen;
+   int base_mrf = 1;
+   bool simd16 = false;
+   fs_reg orig_dst;
 
-   if (ir->data.mode == ir_var_shader_in) {
-      assert(ir->data.location != -1);
-      if (stage == MESA_SHADER_VERTEX) {
-         reg = new(this->mem_ctx)
-            fs_reg(ATTR, ir->data.location,
-                   brw_type_for_base_type(ir->type->get_scalar_type()));
-      } else if (ir->data.location == VARYING_SLOT_POS) {
-         reg = emit_fragcoord_interpolation(ir->data.pixel_center_integer,
-                                            ir->data.origin_upper_left);
-      } else if (ir->data.location == VARYING_SLOT_FACE) {
-        reg = emit_frontfacing_interpolation();
-      } else {
-         reg = new(this->mem_ctx) fs_reg(vgrf(ir->type));
-         emit_general_interpolation(*reg, ir->name, ir->type,
-                                    (glsl_interp_qualifier) ir->data.interpolation,
-                                    ir->data.location, ir->data.centroid,
-                                    ir->data.sample);
-      }
-      assert(reg);
-      hash_table_insert(this->variable_ht, reg, ir);
-      return;
-   } else if (ir->data.mode == ir_var_shader_out) {
-      reg = new(this->mem_ctx) fs_reg(vgrf(ir->type));
-
-      if (stage == MESA_SHADER_VERTEX) {
-        int vector_elements =
-           ir->type->is_array() ? ir->type->fields.array->vector_elements
-                                : ir->type->vector_elements;
-
-        for (int i = 0; i < (type_size(ir->type) + 3) / 4; i++) {
-           int output = ir->data.location + i;
-           this->outputs[output] = *reg;
-           this->outputs[output].reg_offset = i * 4;
-           this->output_components[output] = vector_elements;
-        }
+   /* g0 header. */
+   mlen = 1;
 
-      } else if (ir->data.index > 0) {
-        assert(ir->data.location == FRAG_RESULT_DATA0);
-        assert(ir->data.index == 1);
-        this->dual_src_output = *reg;
-         this->do_dual_src = true;
-      } else if (ir->data.location == FRAG_RESULT_COLOR) {
-        /* Writing gl_FragColor outputs to all color regions. */
-         assert(stage == MESA_SHADER_FRAGMENT);
-         brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
-        for (unsigned int i = 0; i < MAX2(key->nr_color_regions, 1); i++) {
-           this->outputs[i] = *reg;
-           this->output_components[i] = 4;
-        }
-      } else if (ir->data.location == FRAG_RESULT_DEPTH) {
-        this->frag_depth = *reg;
-      } else if (ir->data.location == FRAG_RESULT_SAMPLE_MASK) {
-         this->sample_mask = *reg;
-      } else {
-        /* gl_FragData or a user-defined FS output */
-        assert(ir->data.location >= FRAG_RESULT_DATA0 &&
-               ir->data.location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS);
-
-        int vector_elements =
-           ir->type->is_array() ? ir->type->fields.array->vector_elements
-                                : ir->type->vector_elements;
-
-        /* General color output. */
-        for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) {
-           int output = ir->data.location - FRAG_RESULT_DATA0 + i;
-           this->outputs[output] = offset(*reg, vector_elements * i);
-           this->output_components[output] = vector_elements;
-        }
+   if (shadow_c.file != BAD_FILE) {
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate);
+        coordinate = offset(coordinate, 1);
       }
-   } else if (ir->data.mode == ir_var_uniform) {
-      int param_index = uniforms;
 
-      /* Thanks to the lower_ubo_reference pass, we will see only
-       * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO
-       * variables, so no need for them to be in variable_ht.
-       *
-       * Some uniforms, such as samplers and atomic counters, have no actual
-       * storage, so we should ignore them.
+      /* gen4's SIMD8 sampler always has the slots for u,v,r present.
+       * the unused slots must be zeroed.
        */
-      if (ir->is_in_uniform_block() || type_size(ir->type) == 0)
-         return;
-
-      if (dispatch_width == 16) {
-        if (!variable_storage(ir)) {
-           fail("Failed to find uniform '%s' in SIMD16\n", ir->name);
-        }
-        return;
+      for (int i = coord_components; i < 3; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f));
       }
+      mlen += 3;
 
-      param_size[param_index] = type_size(ir->type);
-      if (!strncmp(ir->name, "gl_", 3)) {
-        setup_builtin_uniform_values(ir);
+      if (op == ir_tex) {
+        /* There's no plain shadow compare message, so we use shadow
+         * compare with a bias of 0.0.
+         */
+         bld.MOV(fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
+        mlen++;
+      } else if (op == ir_txb || op == ir_txl) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen), lod);
+        mlen++;
       } else {
-        setup_uniform_values(ir);
+         unreachable("Should not get here.");
       }
 
-      reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
-      reg->type = brw_type_for_base_type(ir->type);
-
-   } else if (ir->data.mode == ir_var_system_value) {
-      switch (ir->data.location) {
-      case SYSTEM_VALUE_BASE_VERTEX:
-      case SYSTEM_VALUE_VERTEX_ID:
-      case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
-      case SYSTEM_VALUE_INSTANCE_ID:
-         reg = emit_vs_system_value(ir->data.location);
-         break;
-      case SYSTEM_VALUE_SAMPLE_POS:
-        reg = emit_samplepos_setup();
-         break;
-      case SYSTEM_VALUE_SAMPLE_ID:
-        reg = emit_sampleid_setup();
-         break;
-      case SYSTEM_VALUE_SAMPLE_MASK_IN:
-         assert(devinfo->gen >= 7);
-         reg = new(mem_ctx)
-            fs_reg(retype(brw_vec8_grf(payload.sample_mask_in_reg, 0),
-                          BRW_REGISTER_TYPE_D));
-         break;
+      bld.MOV(fs_reg(MRF, base_mrf + mlen), shadow_c);
+      mlen++;
+   } else if (op == ir_tex) {
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate);
+        coordinate = offset(coordinate, 1);
       }
-   }
-
-   if (!reg)
-      reg = new(this->mem_ctx) fs_reg(vgrf(ir->type));
-
-   hash_table_insert(this->variable_ht, reg, ir);
-}
-
-void
-fs_visitor::visit(ir_dereference_variable *ir)
-{
-   fs_reg *reg = variable_storage(ir->var);
-
-   if (!reg) {
-      fail("Failed to find variable storage for %s\n", ir->var->name);
-      this->result = fs_reg(reg_null_d);
-      return;
-   }
-   this->result = *reg;
-}
-
-void
-fs_visitor::visit(ir_dereference_record *ir)
-{
-   const glsl_type *struct_type = ir->record->type;
-
-   ir->record->accept(this);
-
-   unsigned int off = 0;
-   for (unsigned int i = 0; i < struct_type->length; i++) {
-      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
-        break;
-      off += type_size(struct_type->fields.structure[i].type);
-   }
-   this->result = offset(this->result, off);
-   this->result.type = brw_type_for_base_type(ir->type);
-}
-
-void
-fs_visitor::visit(ir_dereference_array *ir)
-{
-   ir_constant *constant_index;
-   fs_reg src;
-   int element_size = type_size(ir->type);
+      /* zero the others. */
+      for (int i = coord_components; i<3; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f));
+      }
+      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
+      mlen += 3;
+   } else if (op == ir_txd) {
+      fs_reg &dPdx = lod;
 
-   constant_index = ir->array_index->as_constant();
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate);
+        coordinate = offset(coordinate, 1);
+      }
+      /* the slots for u and v are always present, but r is optional */
+      mlen += MAX2(coord_components, 2);
 
-   ir->array->accept(this);
-   src = this->result;
-   src.type = brw_type_for_base_type(ir->type);
+      /*  P   = u, v, r
+       * dPdx = dudx, dvdx, drdx
+       * dPdy = dudy, dvdy, drdy
+       *
+       * 1-arg: Does not exist.
+       *
+       * 2-arg: dudx   dvdx   dudy   dvdy
+       *        dPdx.x dPdx.y dPdy.x dPdy.y
+       *        m4     m5     m6     m7
+       *
+       * 3-arg: dudx   dvdx   drdx   dudy   dvdy   drdy
+       *        dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
+       *        m5     m6     m7     m8     m9     m10
+       */
+      for (int i = 0; i < grad_components; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen), dPdx);
+        dPdx = offset(dPdx, 1);
+      }
+      mlen += MAX2(grad_components, 2);
 
-   if (constant_index) {
-      if (src.file == ATTR) {
-         /* Attribute arrays get loaded as one vec4 per element.  In that case
-          * offset the source register.
-          */
-         src.reg += constant_index->value.i[0];
-      } else {
-         assert(src.file == UNIFORM || src.file == GRF || src.file == HW_REG);
-         src = offset(src, constant_index->value.i[0] * element_size);
+      for (int i = 0; i < grad_components; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen), dPdy);
+        dPdy = offset(dPdy, 1);
       }
+      mlen += MAX2(grad_components, 2);
+   } else if (op == ir_txs) {
+      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
+      simd16 = true;
+      bld.MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod);
+      mlen += 2;
    } else {
-      /* Variable index array dereference.  We attach the variable index
-       * component to the reg as a pointer to a register containing the
-       * offset.  Currently only uniform arrays are supported in this patch,
-       * and that reladdr pointer is resolved by
-       * move_uniform_array_access_to_pull_constants().  All other array types
-       * are lowered by lower_variable_index_to_cond_assign().
+      /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
+       * instructions.  We'll need to do SIMD16 here.
        */
-      ir->array_index->accept(this);
-
-      fs_reg index_reg;
-      index_reg = vgrf(glsl_type::int_type);
-      emit(BRW_OPCODE_MUL, index_reg, this->result, fs_reg(element_size));
+      simd16 = true;
+      assert(op == ir_txb || op == ir_txl || op == ir_txf);
 
-      if (src.reladdr) {
-         emit(BRW_OPCODE_ADD, index_reg, *src.reladdr, index_reg);
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type),
+                 coordinate);
+        coordinate = offset(coordinate, 1);
       }
 
-      src.reladdr = ralloc(mem_ctx, fs_reg);
-      memcpy(src.reladdr, &index_reg, sizeof(index_reg));
-   }
-   this->result = src;
-}
+      /* Initialize the rest of u/v/r with 0.0.  Empirically, this seems to
+       * be necessary for TXF (ld), but seems wise to do for all messages.
+       */
+      for (int i = coord_components; i < 3; i++) {
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f));
+      }
 
-fs_inst *
-fs_visitor::emit_lrp(const fs_reg &dst, const fs_reg &x, const fs_reg &y,
-                     const fs_reg &a)
-{
-   if (devinfo->gen < 6) {
-      /* We can't use the LRP instruction.  Emit x*(1-a) + y*a. */
-      fs_reg y_times_a           = vgrf(glsl_type::float_type);
-      fs_reg one_minus_a         = vgrf(glsl_type::float_type);
-      fs_reg x_times_one_minus_a = vgrf(glsl_type::float_type);
+      /* lod/bias appears after u/v/r. */
+      mlen += 6;
 
-      emit(MUL(y_times_a, y, a));
+      bld.MOV(fs_reg(MRF, base_mrf + mlen, lod.type), lod);
+      mlen++;
 
-      fs_reg negative_a = a;
-      negative_a.negate = !a.negate;
-      emit(ADD(one_minus_a, negative_a, fs_reg(1.0f)));
-      emit(MUL(x_times_one_minus_a, x, one_minus_a));
+      /* The unused upper half. */
+      mlen++;
+   }
 
-      return emit(ADD(dst, x_times_one_minus_a, y_times_a));
-   } else {
-      /* The LRP instruction actually does op1 * op0 + op2 * (1 - op0), so
-       * we need to reorder the operands.
+   if (simd16) {
+      /* Now, since we're doing simd16, the return is 2 interleaved
+       * vec4s where the odd-indexed ones are junk. We'll need to move
+       * this weirdness around to the expected layout.
        */
-      return emit(LRP(dst, a, y, x));
+      orig_dst = dst;
+      dst = fs_reg(GRF, alloc.allocate(8), orig_dst.type);
    }
-}
-
-void
-fs_visitor::emit_minmax(enum brw_conditional_mod conditionalmod, const fs_reg &dst,
-                        const fs_reg &src0, const fs_reg &src1)
-{
-   assert(conditionalmod == BRW_CONDITIONAL_GE ||
-          conditionalmod == BRW_CONDITIONAL_L);
 
-   fs_inst *inst;
-
-   if (devinfo->gen >= 6) {
-      inst = emit(BRW_OPCODE_SEL, dst, src0, src1);
-      inst->conditional_mod = conditionalmod;
-   } else {
-      emit(CMP(reg_null_d, src0, src1, conditionalmod));
-
-      inst = emit(BRW_OPCODE_SEL, dst, src0, src1);
-      inst->predicate = BRW_PREDICATE_NORMAL;
+   enum opcode opcode;
+   switch (op) {
+   case ir_tex: opcode = SHADER_OPCODE_TEX; break;
+   case ir_txb: opcode = FS_OPCODE_TXB; break;
+   case ir_txl: opcode = SHADER_OPCODE_TXL; break;
+   case ir_txd: opcode = SHADER_OPCODE_TXD; break;
+   case ir_txs: opcode = SHADER_OPCODE_TXS; break;
+   case ir_txf: opcode = SHADER_OPCODE_TXF; break;
+   default:
+      unreachable("not reached");
    }
-}
 
-void
-fs_visitor::emit_uniformize(const fs_reg &dst, const fs_reg &src)
-{
-   const fs_reg chan_index = vgrf(glsl_type::uint_type);
-
-   emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, component(chan_index, 0))
-      ->force_writemask_all = true;
-   emit(SHADER_OPCODE_BROADCAST, component(dst, 0),
-        src, component(chan_index, 0))
-      ->force_writemask_all = true;
-}
-
-bool
-fs_visitor::try_emit_saturate(ir_expression *ir)
-{
-   if (ir->operation != ir_unop_saturate)
-      return false;
-
-   ir_rvalue *sat_val = ir->operands[0];
-
-   fs_inst *pre_inst = (fs_inst *) this->instructions.get_tail();
-
-   sat_val->accept(this);
-   fs_reg src = this->result;
-
-   fs_inst *last_inst = (fs_inst *) this->instructions.get_tail();
+   fs_inst *inst = bld.emit(opcode, dst, reg_undef, fs_reg(sampler));
+   inst->base_mrf = base_mrf;
+   inst->mlen = mlen;
+   inst->header_size = 1;
+   inst->regs_written = simd16 ? 8 : 4;
 
-   /* If the last instruction from our accept() generated our
-    * src, just set the saturate flag instead of emmitting a separate mov.
-    */
-   fs_inst *modify = get_instruction_generating_reg(pre_inst, last_inst, src);
-   if (modify && modify->regs_written == modify->dst.width / 8 &&
-       modify->can_do_saturate()) {
-      modify->saturate = true;
-      this->result = src;
-      return true;
+   if (simd16) {
+      for (int i = 0; i < 4; i++) {
+         bld.MOV(orig_dst, dst);
+        orig_dst = offset(orig_dst, 1);
+        dst = offset(dst, 2);
+      }
    }
 
-   return false;
+   return inst;
 }
 
-bool
-fs_visitor::try_emit_line(ir_expression *ir)
+fs_inst *
+fs_visitor::emit_texture_gen4_simd16(ir_texture_opcode op, fs_reg dst,
+                                     fs_reg coordinate, int vector_elements,
+                                     fs_reg shadow_c, fs_reg lod,
+                                     uint32_t sampler)
 {
-   /* LINE's src0 must be of type float. */
-   if (ir->type != glsl_type::float_type)
-      return false;
+   fs_reg message(MRF, 2, BRW_REGISTER_TYPE_F, dispatch_width);
+   bool has_lod = op == ir_txl || op == ir_txb || op == ir_txf;
 
-   ir_rvalue *nonmul = ir->operands[1];
-   ir_expression *mul = ir->operands[0]->as_expression();
+   if (has_lod && shadow_c.file != BAD_FILE)
+      no16("TXB and TXL with shadow comparison unsupported in SIMD16.");
 
-   if (!mul || mul->operation != ir_binop_mul) {
-      nonmul = ir->operands[0];
-      mul = ir->operands[1]->as_expression();
+   if (op == ir_txd)
+      no16("textureGrad unsupported in SIMD16.");
 
-      if (!mul || mul->operation != ir_binop_mul)
-         return false;
+   /* Copy the coordinates. */
+   for (int i = 0; i < vector_elements; i++) {
+      bld.MOV(retype(offset(message, i), coordinate.type), coordinate);
+      coordinate = offset(coordinate, 1);
    }
 
-   ir_constant *const_add = nonmul->as_constant();
-   if (!const_add)
-      return false;
-
-   int add_operand_vf = brw_float_to_vf(const_add->value.f[0]);
-   if (add_operand_vf == -1)
-      return false;
-
-   ir_rvalue *non_const_mul = mul->operands[1];
-   ir_constant *const_mul = mul->operands[0]->as_constant();
-   if (!const_mul) {
-      const_mul = mul->operands[1]->as_constant();
+   fs_reg msg_end = offset(message, vector_elements);
 
-      if (!const_mul)
-         return false;
+   /* Messages other than sample and ld require all three components */
+   if (has_lod || shadow_c.file != BAD_FILE) {
+      for (int i = vector_elements; i < 3; i++) {
+         bld.MOV(offset(message, i), fs_reg(0.0f));
+      }
+   }
 
-      non_const_mul = mul->operands[0];
+   if (has_lod) {
+      fs_reg msg_lod = retype(offset(message, 3), op == ir_txf ?
+                              BRW_REGISTER_TYPE_UD : BRW_REGISTER_TYPE_F);
+      bld.MOV(msg_lod, lod);
+      msg_end = offset(msg_lod, 1);
    }
 
-   int mul_operand_vf = brw_float_to_vf(const_mul->value.f[0]);
-   if (mul_operand_vf == -1)
-      return false;
+   if (shadow_c.file != BAD_FILE) {
+      fs_reg msg_ref = offset(message, 3 + has_lod);
+      bld.MOV(msg_ref, shadow_c);
+      msg_end = offset(msg_ref, 1);
+   }
 
-   non_const_mul->accept(this);
-   fs_reg src1 = this->result;
+   enum opcode opcode;
+   switch (op) {
+   case ir_tex: opcode = SHADER_OPCODE_TEX; break;
+   case ir_txb: opcode = FS_OPCODE_TXB;     break;
+   case ir_txd: opcode = SHADER_OPCODE_TXD; break;
+   case ir_txl: opcode = SHADER_OPCODE_TXL; break;
+   case ir_txs: opcode = SHADER_OPCODE_TXS; break;
+   case ir_txf: opcode = SHADER_OPCODE_TXF; break;
+   default: unreachable("not reached");
+   }
 
-   fs_reg src0 = vgrf(ir->type);
-   emit(BRW_OPCODE_MOV, src0,
-        fs_reg((uint8_t)mul_operand_vf, 0, 0, (uint8_t)add_operand_vf));
+   fs_inst *inst = bld.emit(opcode, dst, reg_undef, fs_reg(sampler));
+   inst->base_mrf = message.reg - 1;
+   inst->mlen = msg_end.reg - inst->base_mrf;
+   inst->header_size = 1;
+   inst->regs_written = 8;
 
-   this->result = vgrf(ir->type);
-   emit(BRW_OPCODE_LINE, this->result, src0, src1);
-   return true;
+   return inst;
 }
 
-bool
-fs_visitor::try_emit_mad(ir_expression *ir)
+/* gen5's sampler has slots for u, v, r, array index, then optional
+ * parameters like shadow comparitor or LOD bias.  If optional
+ * parameters aren't present, those base slots are optional and don't
+ * need to be included in the message.
+ *
+ * We don't fill in the unnecessary slots regardless, which may look
+ * surprising in the disassembly.
+ */
+fs_inst *
+fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
+                              fs_reg coordinate, int vector_elements,
+                              fs_reg shadow_c,
+                              fs_reg lod, fs_reg lod2, int grad_components,
+                              fs_reg sample_index, uint32_t sampler,
+                              bool has_offset)
 {
-   /* 3-src instructions were introduced in gen6. */
-   if (devinfo->gen < 6)
-      return false;
+   int reg_width = dispatch_width / 8;
+   unsigned header_size = 0;
 
-   /* MAD can only handle floating-point data. */
-   if (ir->type != glsl_type::float_type)
-      return false;
-
-   ir_rvalue *nonmul;
-   ir_expression *mul;
-   bool mul_negate, mul_abs;
-
-   for (int i = 0; i < 2; i++) {
-      mul_negate = false;
-      mul_abs = false;
-
-      mul = ir->operands[i]->as_expression();
-      nonmul = ir->operands[1 - i];
-
-      if (mul && mul->operation == ir_unop_abs) {
-         mul = mul->operands[0]->as_expression();
-         mul_abs = true;
-      } else if (mul && mul->operation == ir_unop_neg) {
-         mul = mul->operands[0]->as_expression();
-         mul_negate = true;
-      }
+   fs_reg message(MRF, 2, BRW_REGISTER_TYPE_F, dispatch_width);
+   fs_reg msg_coords = message;
 
-      if (mul && mul->operation == ir_binop_mul)
-         break;
+   if (has_offset) {
+      /* The offsets set up by the ir_texture visitor are in the
+       * m1 header, so we can't go headerless.
+       */
+      header_size = 1;
+      message.reg--;
    }
 
-   if (!mul || mul->operation != ir_binop_mul)
-      return false;
-
-   nonmul->accept(this);
-   fs_reg src0 = this->result;
-
-   mul->operands[0]->accept(this);
-   fs_reg src1 = this->result;
-   src1.negate ^= mul_negate;
-   src1.abs = mul_abs;
-   if (mul_abs)
-      src1.negate = false;
-
-   mul->operands[1]->accept(this);
-   fs_reg src2 = this->result;
-   src2.abs = mul_abs;
-   if (mul_abs)
-      src2.negate = false;
-
-   this->result = vgrf(ir->type);
-   emit(BRW_OPCODE_MAD, this->result, src0, src1, src2);
-
-   return true;
-}
-
-bool
-fs_visitor::try_emit_b2f_of_comparison(ir_expression *ir)
-{
-   /* On platforms that do not natively generate 0u and ~0u for Boolean
-    * results, b2f expressions that look like
-    *
-    *     f = b2f(expr cmp 0)
-    *
-    * will generate better code by pretending the expression is
-    *
-    *     f = ir_triop_csel(0.0, 1.0, expr cmp 0)
-    *
-    * This is because the last instruction of "expr" can generate the
-    * condition code for the "cmp 0".  This avoids having to do the "-(b & 1)"
-    * trick to generate 0u or ~0u for the Boolean result.  This means code like
-    *
-    *     mov(16)         g16<1>F         1F
-    *     mul.ge.f0(16)   null            g6<8,8,1>F      g14<8,8,1>F
-    *     (+f0) sel(16)   m6<1>F          g16<8,8,1>F     0F
-    *
-    * will be generated instead of
-    *
-    *     mul(16)         g2<1>F          g12<8,8,1>F     g4<8,8,1>F
-    *     cmp.ge.f0(16)   g2<1>D          g4<8,8,1>F      0F
-    *     and(16)         g4<1>D          g2<8,8,1>D      1D
-    *     and(16)         m6<1>D          -g4<8,8,1>D     0x3f800000UD
-    *
-    * When the comparison is != 0.0 using the knowledge that the false case
-    * already results in zero would allow better code generation by possibly
-    * avoiding a load-immediate instruction.
-    */
-   ir_expression *cmp = ir->operands[0]->as_expression();
-   if (cmp == NULL)
-      return false;
-
-   if (cmp->operation == ir_binop_nequal) {
-      for (unsigned i = 0; i < 2; i++) {
-         ir_constant *c = cmp->operands[i]->as_constant();
-         if (c == NULL || !c->is_zero())
-            continue;
-
-         ir_expression *expr = cmp->operands[i ^ 1]->as_expression();
-         if (expr != NULL) {
-            fs_reg op[2];
-
-            for (unsigned j = 0; j < 2; j++) {
-               cmp->operands[j]->accept(this);
-               op[j] = this->result;
-
-               resolve_ud_negate(&op[j]);
-            }
-
-            emit_bool_to_cond_code_of_reg(cmp, op);
-
-            /* In this case we know when the condition is true, op[i ^ 1]
-             * contains zero.  Invert the predicate, use op[i ^ 1] as src0,
-             * and immediate 1.0f as src1.
-             */
-            this->result = vgrf(ir->type);
-            op[i ^ 1].type = BRW_REGISTER_TYPE_F;
-
-            fs_inst *inst = emit(SEL(this->result, op[i ^ 1], fs_reg(1.0f)));
-            inst->predicate = BRW_PREDICATE_NORMAL;
-            inst->predicate_inverse = true;
-            return true;
-         }
-      }
+   for (int i = 0; i < vector_elements; i++) {
+      bld.MOV(retype(offset(msg_coords, i), coordinate.type), coordinate);
+      coordinate = offset(coordinate, 1);
    }
+   fs_reg msg_end = offset(msg_coords, vector_elements);
+   fs_reg msg_lod = offset(msg_coords, 4);
 
-   emit_bool_to_cond_code(cmp);
-
-   fs_reg temp = vgrf(ir->type);
-   emit(MOV(temp, fs_reg(1.0f)));
-
-   this->result = vgrf(ir->type);
-   fs_inst *inst = emit(SEL(this->result, temp, fs_reg(0.0f)));
-   inst->predicate = BRW_PREDICATE_NORMAL;
-
-   return true;
-}
-
-static int
-pack_pixel_offset(float x)
-{
-   /* Clamp upper end of the range to +7/16. See explanation in non-constant
-    * offset case below. */
-   int n = MIN2((int)(x * 16), 7);
-   return n & 0xf;
-}
-
-void
-fs_visitor::emit_interpolate_expression(ir_expression *ir)
-{
-   /* in SIMD16 mode, the pixel interpolator returns coords interleaved
-    * 8 channels at a time, same as the barycentric coords presented in
-    * the FS payload. this requires a bit of extra work to support.
-    */
-   no16("interpolate_at_* not yet supported in SIMD16 mode.");
-
-   assert(stage == MESA_SHADER_FRAGMENT);
-   brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
-
-   ir_dereference * deref = ir->operands[0]->as_dereference();
-   ir_swizzle * swiz = NULL;
-   if (!deref) {
-      /* the api does not allow a swizzle here, but the varying packing code
-       * may have pushed one into here.
-       */
-      swiz = ir->operands[0]->as_swizzle();
-      assert(swiz);
-      deref = swiz->val->as_dereference();
+   if (shadow_c.file != BAD_FILE) {
+      fs_reg msg_shadow = msg_lod;
+      bld.MOV(msg_shadow, shadow_c);
+      msg_lod = offset(msg_shadow, 1);
+      msg_end = msg_lod;
    }
-   assert(deref);
-   ir_variable * var = deref->variable_referenced();
-   assert(var);
 
-   /* 1. collect interpolation factors */
-
-   fs_reg dst_xy = vgrf(glsl_type::get_instance(ir->type->base_type, 2, 1));
+   enum opcode opcode;
+   switch (op) {
+   case ir_tex:
+      opcode = SHADER_OPCODE_TEX;
+      break;
+   case ir_txb:
+      bld.MOV(msg_lod, lod);
+      msg_end = offset(msg_lod, 1);
 
-   /* for most messages, we need one reg of ignored data; the hardware requires mlen==1
-    * even when there is no payload. in the per-slot offset case, we'll replace this with
-    * the proper source data. */
-   fs_reg src = vgrf(glsl_type::float_type);
-   int mlen = 1;     /* one reg unless overriden */
-   int reg_width = dispatch_width / 8;
-   fs_inst *inst;
+      opcode = FS_OPCODE_TXB;
+      break;
+   case ir_txl:
+      bld.MOV(msg_lod, lod);
+      msg_end = offset(msg_lod, 1);
 
-   switch (ir->operation) {
-   case ir_unop_interpolate_at_centroid:
-      inst = emit(FS_OPCODE_INTERPOLATE_AT_CENTROID, dst_xy, src, fs_reg(0u));
+      opcode = SHADER_OPCODE_TXL;
       break;
+   case ir_txd: {
+      /**
+       *  P   =  u,    v,    r
+       * dPdx = dudx, dvdx, drdx
+       * dPdy = dudy, dvdy, drdy
+       *
+       * Load up these values:
+       * - dudx   dudy   dvdx   dvdy   drdx   drdy
+       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
+       */
+      msg_end = msg_lod;
+      for (int i = 0; i < grad_components; i++) {
+         bld.MOV(msg_end, lod);
+         lod = offset(lod, 1);
+         msg_end = offset(msg_end, 1);
 
-   case ir_binop_interpolate_at_sample: {
-      ir_constant *sample_num = ir->operands[1]->as_constant();
-      assert(sample_num || !"nonconstant sample number should have been lowered.");
+         bld.MOV(msg_end, lod2);
+         lod2 = offset(lod2, 1);
+         msg_end = offset(msg_end, 1);
+      }
 
-      unsigned msg_data = sample_num->value.i[0] << 4;
-      inst = emit(FS_OPCODE_INTERPOLATE_AT_SAMPLE, dst_xy, src, fs_reg(msg_data));
+      opcode = SHADER_OPCODE_TXD;
       break;
    }
+   case ir_txs:
+      msg_lod = retype(msg_end, BRW_REGISTER_TYPE_UD);
+      bld.MOV(msg_lod, lod);
+      msg_end = offset(msg_lod, 1);
 
-   case ir_binop_interpolate_at_offset: {
-      ir_constant *const_offset = ir->operands[1]->as_constant();
-      if (const_offset) {
-         unsigned msg_data = pack_pixel_offset(const_offset->value.f[0]) |
-                            (pack_pixel_offset(const_offset->value.f[1]) << 4);
-         inst = emit(FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET, dst_xy, src,
-                     fs_reg(msg_data));
-      } else {
-         /* pack the operands: hw wants offsets as 4 bit signed ints */
-         ir->operands[1]->accept(this);
-         src = vgrf(glsl_type::ivec2_type);
-         fs_reg src2 = src;
-         for (int i = 0; i < 2; i++) {
-            fs_reg temp = vgrf(glsl_type::float_type);
-            emit(MUL(temp, this->result, fs_reg(16.0f)));
-            emit(MOV(src2, temp));  /* float to int */
-
-            /* Clamp the upper end of the range to +7/16. ARB_gpu_shader5 requires
-             * that we support a maximum offset of +0.5, which isn't representable
-             * in a S0.4 value -- if we didn't clamp it, we'd end up with -8/16,
-             * which is the opposite of what the shader author wanted.
-             *
-             * This is legal due to ARB_gpu_shader5's quantization rules:
-             *
-             * "Not all values of <offset> may be supported; x and y offsets may
-             * be rounded to fixed-point values with the number of fraction bits
-             * given by the implementation-dependent constant
-             * FRAGMENT_INTERPOLATION_OFFSET_BITS"
-             */
-
-            fs_inst *inst = emit(BRW_OPCODE_SEL, src2, src2, fs_reg(7));
-            inst->conditional_mod = BRW_CONDITIONAL_L; /* min(src2, 7) */
+      opcode = SHADER_OPCODE_TXS;
+      break;
+   case ir_query_levels:
+      msg_lod = msg_end;
+      bld.MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u));
+      msg_end = offset(msg_lod, 1);
 
-            src2 = offset(src2, 1);
-            this->result = offset(this->result, 1);
-         }
+      opcode = SHADER_OPCODE_TXS;
+      break;
+   case ir_txf:
+      msg_lod = offset(msg_coords, 3);
+      bld.MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), lod);
+      msg_end = offset(msg_lod, 1);
 
-         mlen = 2 * reg_width;
-         inst = emit(FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET, dst_xy, src,
-                     fs_reg(0u));
-      }
+      opcode = SHADER_OPCODE_TXF;
       break;
-   }
+   case ir_txf_ms:
+      msg_lod = offset(msg_coords, 3);
+      /* lod */
+      bld.MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u));
+      /* sample index */
+      bld.MOV(retype(offset(msg_lod, 1), BRW_REGISTER_TYPE_UD), sample_index);
+      msg_end = offset(msg_lod, 2);
 
+      opcode = SHADER_OPCODE_TXF_CMS;
+      break;
+   case ir_lod:
+      opcode = SHADER_OPCODE_LOD;
+      break;
+   case ir_tg4:
+      opcode = SHADER_OPCODE_TG4;
+      break;
    default:
       unreachable("not reached");
    }
 
-   inst->mlen = mlen;
-   inst->regs_written = 2 * reg_width; /* 2 floats per slot returned */
-   inst->pi_noperspective = var->determine_interpolation_mode(key->flat_shade) ==
-         INTERP_QUALIFIER_NOPERSPECTIVE;
-
-   /* 2. emit linterp */
-
-   fs_reg res = vgrf(ir->type);
-   this->result = res;
+   fs_inst *inst = bld.emit(opcode, dst, reg_undef, fs_reg(sampler));
+   inst->base_mrf = message.reg;
+   inst->mlen = msg_end.reg - message.reg;
+   inst->header_size = header_size;
+   inst->regs_written = 4 * reg_width;
 
-   for (int i = 0; i < ir->type->vector_elements; i++) {
-      int ch = swiz ? ((*(int *)&swiz->mask) >> 2*i) & 3 : i;
-      emit(FS_OPCODE_LINTERP, res, dst_xy,
-           fs_reg(interp_reg(var->data.location, ch)));
-      res = offset(res, 1);
+   if (inst->mlen > MAX_SAMPLER_MESSAGE_SIZE) {
+      fail("Message length >" STRINGIFY(MAX_SAMPLER_MESSAGE_SIZE)
+           " disallowed by hardware\n");
    }
+
+   return inst;
 }
 
-void
-fs_visitor::visit(ir_expression *ir)
+static bool
+is_high_sampler(const struct brw_device_info *devinfo, fs_reg sampler)
 {
-   unsigned int operand;
-   fs_reg op[3], temp;
-   fs_inst *inst;
-   struct brw_wm_prog_key *fs_key = (struct brw_wm_prog_key *) this->key;
-
-   assert(ir->get_num_operands() <= 3);
-
-   if (try_emit_saturate(ir))
-      return;
-
-   /* Deal with the real oddball stuff first */
-   switch (ir->operation) {
-   case ir_binop_add:
-      if (devinfo->gen <= 5 && try_emit_line(ir))
-         return;
-      if (try_emit_mad(ir))
-         return;
-      break;
-
-   case ir_triop_csel:
-      ir->operands[1]->accept(this);
-      op[1] = this->result;
-      ir->operands[2]->accept(this);
-      op[2] = this->result;
-
-      emit_bool_to_cond_code(ir->operands[0]);
-
-      this->result = vgrf(ir->type);
-      inst = emit(SEL(this->result, op[1], op[2]));
-      inst->predicate = BRW_PREDICATE_NORMAL;
-      return;
+   if (devinfo->gen < 8 && !devinfo->is_haswell)
+      return false;
 
-   case ir_unop_b2f:
-      if (devinfo->gen <= 5 && try_emit_b2f_of_comparison(ir))
-         return;
-      break;
+   return sampler.file != IMM || sampler.fixed_hw_reg.dw1.ud >= 16;
+}
 
-   case ir_unop_interpolate_at_centroid:
-   case ir_binop_interpolate_at_offset:
-   case ir_binop_interpolate_at_sample:
-      emit_interpolate_expression(ir);
-      return;
+fs_inst *
+fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
+                              fs_reg coordinate, int coord_components,
+                              fs_reg shadow_c,
+                              fs_reg lod, fs_reg lod2, int grad_components,
+                              fs_reg sample_index, fs_reg mcs, fs_reg sampler,
+                              fs_reg offset_value)
+{
+   int reg_width = dispatch_width / 8;
+   unsigned header_size = 0;
 
-   default:
-      break;
+   fs_reg *sources = ralloc_array(mem_ctx, fs_reg, MAX_SAMPLER_MESSAGE_SIZE);
+   for (int i = 0; i < MAX_SAMPLER_MESSAGE_SIZE; i++) {
+      sources[i] = vgrf(glsl_type::float_type);
    }
+   int length = 0;
 
-   for (operand = 0; operand < ir->get_num_operands(); operand++) {
-      ir->operands[operand]->accept(this);
-      if (this->result.file == BAD_FILE) {
-        fail("Failed to get tree for expression operand:\n");
-        ir->operands[operand]->fprint(stderr);
-         fprintf(stderr, "\n");
-      }
-      assert(this->result.file == GRF ||
-             this->result.file == UNIFORM || this->result.file == ATTR);
-      op[operand] = this->result;
-
-      /* Matrix expression operands should have been broken down to vector
-       * operations already.
-       */
-      assert(!ir->operands[operand]->type->is_matrix());
-      /* And then those vector operands should have been broken down to scalar.
+   if (op == ir_tg4 || offset_value.file != BAD_FILE ||
+       is_high_sampler(devinfo, sampler)) {
+      /* For general texture offsets (no txf workaround), we need a header to
+       * put them in.  Note that for SIMD16 we're making space for two actual
+       * hardware registers here, so the emit will have to fix up for this.
+       *
+       * * ir4_tg4 needs to place its channel select in the header,
+       * for interaction with ARB_texture_swizzle
+       *
+       * The sampler index is only 4-bits, so for larger sampler numbers we
+       * need to offset the Sampler State Pointer in the header.
        */
-      assert(!ir->operands[operand]->type->is_vector());
+      header_size = 1;
+      sources[0] = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
+      length++;
+   }
+
+   if (shadow_c.file != BAD_FILE) {
+      bld.MOV(sources[length], shadow_c);
+      length++;
    }
 
-   /* Storage for our result.  If our result goes into an assignment, it will
-    * just get copy-propagated out, so no worries.
+   bool has_nonconstant_offset =
+      offset_value.file != BAD_FILE && offset_value.file != IMM;
+   bool coordinate_done = false;
+
+   /* The sampler can only meaningfully compute LOD for fragment shader
+    * messages. For all other stages, we change the opcode to ir_txl and
+    * hardcode the LOD to 0.
     */
-   this->result = vgrf(ir->type);
+   if (stage != MESA_SHADER_FRAGMENT && op == ir_tex) {
+      op = ir_txl;
+      lod = fs_reg(0.0f);
+   }
 
-   switch (ir->operation) {
-   case ir_unop_logic_not:
-      emit(NOT(this->result, op[0]));
+   /* Set up the LOD info */
+   switch (op) {
+   case ir_tex:
+   case ir_lod:
       break;
-   case ir_unop_neg:
-      op[0].negate = !op[0].negate;
-      emit(MOV(this->result, op[0]));
+   case ir_txb:
+      bld.MOV(sources[length], lod);
+      length++;
       break;
-   case ir_unop_abs:
-      op[0].abs = true;
-      op[0].negate = false;
-      emit(MOV(this->result, op[0]));
+   case ir_txl:
+      bld.MOV(sources[length], lod);
+      length++;
       break;
-   case ir_unop_sign:
-      if (ir->type->is_float()) {
-         /* AND(val, 0x80000000) gives the sign bit.
-          *
-          * Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
-          * zero.
-          */
-         emit(CMP(reg_null_f, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
-
-         op[0].type = BRW_REGISTER_TYPE_UD;
-         this->result.type = BRW_REGISTER_TYPE_UD;
-         emit(AND(this->result, op[0], fs_reg(0x80000000u)));
+   case ir_txd: {
+      no16("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
 
-         inst = emit(OR(this->result, this->result, fs_reg(0x3f800000u)));
-         inst->predicate = BRW_PREDICATE_NORMAL;
+      /* Load dPdx and the coordinate together:
+       * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
+       */
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(sources[length], coordinate);
+        coordinate = offset(coordinate, 1);
+        length++;
 
-         this->result.type = BRW_REGISTER_TYPE_F;
-      } else {
-         /*  ASR(val, 31) -> negative val generates 0xffffffff (signed -1).
-          *               -> non-negative val generates 0x00000000.
-          *  Predicated OR sets 1 if val is positive.
+         /* For cube map array, the coordinate is (u,v,r,ai) but there are
+          * only derivatives for (u, v, r).
           */
-         emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_G));
-
-         emit(ASR(this->result, op[0], fs_reg(31)));
+         if (i < grad_components) {
+            bld.MOV(sources[length], lod);
+            lod = offset(lod, 1);
+            length++;
 
-         inst = emit(OR(this->result, this->result, fs_reg(1)));
-         inst->predicate = BRW_PREDICATE_NORMAL;
+            bld.MOV(sources[length], lod2);
+            lod2 = offset(lod2, 1);
+            length++;
+         }
       }
-      break;
-   case ir_unop_rcp:
-      emit_math(SHADER_OPCODE_RCP, this->result, op[0]);
-      break;
 
-   case ir_unop_exp2:
-      emit_math(SHADER_OPCODE_EXP2, this->result, op[0]);
+      coordinate_done = true;
       break;
-   case ir_unop_log2:
-      emit_math(SHADER_OPCODE_LOG2, this->result, op[0]);
+   }
+   case ir_txs:
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), lod);
+      length++;
       break;
-   case ir_unop_exp:
-   case ir_unop_log:
-      unreachable("not reached: should be handled by ir_explog_to_explog2");
-   case ir_unop_sin:
-      emit_math(SHADER_OPCODE_SIN, this->result, op[0]);
+   case ir_query_levels:
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), fs_reg(0u));
+      length++;
       break;
-   case ir_unop_cos:
-      emit_math(SHADER_OPCODE_COS, this->result, op[0]);
-      break;
-
-   case ir_unop_dFdx:
-      /* Select one of the two opcodes based on the glHint value. */
-      if (fs_key->high_quality_derivatives)
-         emit(FS_OPCODE_DDX_FINE, this->result, op[0]);
-      else
-         emit(FS_OPCODE_DDX_COARSE, this->result, op[0]);
-      break;
-
-   case ir_unop_dFdx_coarse:
-      emit(FS_OPCODE_DDX_COARSE, this->result, op[0]);
-      break;
-
-   case ir_unop_dFdx_fine:
-      emit(FS_OPCODE_DDX_FINE, this->result, op[0]);
-      break;
-
-   case ir_unop_dFdy:
-      /* Select one of the two opcodes based on the glHint value. */
-      if (fs_key->high_quality_derivatives)
-         emit(FS_OPCODE_DDY_FINE, result, op[0], fs_reg(fs_key->render_to_fbo));
-      else
-         emit(FS_OPCODE_DDY_COARSE, result, op[0], fs_reg(fs_key->render_to_fbo));
-      break;
-
-   case ir_unop_dFdy_coarse:
-      emit(FS_OPCODE_DDY_COARSE, result, op[0], fs_reg(fs_key->render_to_fbo));
-      break;
-
-   case ir_unop_dFdy_fine:
-      emit(FS_OPCODE_DDY_FINE, result, op[0], fs_reg(fs_key->render_to_fbo));
-      break;
-
-   case ir_binop_add:
-      emit(ADD(this->result, op[0], op[1]));
-      break;
-   case ir_binop_sub:
-      unreachable("not reached: should be handled by ir_sub_to_add_neg");
-
-   case ir_binop_mul:
-      if (devinfo->gen < 8 && ir->type->is_integer()) {
-        /* For integer multiplication, the MUL uses the low 16 bits
-         * of one of the operands (src0 on gen6, src1 on gen7).  The
-         * MACH accumulates in the contribution of the upper 16 bits
-         * of that operand.
-          */
-         if (ir->operands[0]->is_uint16_constant()) {
-            if (devinfo->gen < 7)
-               emit(MUL(this->result, op[0], op[1]));
-            else
-               emit(MUL(this->result, op[1], op[0]));
-         } else if (ir->operands[1]->is_uint16_constant()) {
-            if (devinfo->gen < 7)
-               emit(MUL(this->result, op[1], op[0]));
-            else
-               emit(MUL(this->result, op[0], op[1]));
-         } else {
-            if (devinfo->gen >= 7)
-               no16("SIMD16 explicit accumulator operands unsupported\n");
-
-            struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
-                                        this->result.type);
-
-            emit(MUL(acc, op[0], op[1]));
-            emit(MACH(reg_null_d, op[0], op[1]));
-            emit(MOV(this->result, fs_reg(acc)));
-         }
-      } else {
-        emit(MUL(this->result, op[0], op[1]));
-      }
-      break;
-   case ir_binop_imul_high: {
-      if (devinfo->gen >= 7)
-         no16("SIMD16 explicit accumulator operands unsupported\n");
-
-      struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
-                                  this->result.type);
-
-      fs_inst *mul = emit(MUL(acc, op[0], op[1]));
-      emit(MACH(this->result, op[0], op[1]));
-
-      /* Until Gen8, integer multiplies read 32-bits from one source, and
-       * 16-bits from the other, and relying on the MACH instruction to
-       * generate the high bits of the result.
-       *
-       * On Gen8, the multiply instruction does a full 32x32-bit multiply,
-       * but in order to do a 64x64-bit multiply we have to simulate the
-       * previous behavior and then use a MACH instruction.
-       *
-       * FINISHME: Don't use source modifiers on src1.
+   case ir_txf:
+      /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r.
+       * On Gen9 they are u, v, lod, r
        */
-      if (devinfo->gen >= 8) {
-         assert(mul->src[1].type == BRW_REGISTER_TYPE_D ||
-                mul->src[1].type == BRW_REGISTER_TYPE_UD);
-         if (mul->src[1].type == BRW_REGISTER_TYPE_D) {
-            mul->src[1].type = BRW_REGISTER_TYPE_W;
-            mul->src[1].stride = 2;
-         } else {
-            mul->src[1].type = BRW_REGISTER_TYPE_UW;
-            mul->src[1].stride = 2;
-         }
-      }
-
-      break;
-   }
-   case ir_binop_div:
-      /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */
-      assert(ir->type->is_integer());
-      emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]);
-      break;
-   case ir_binop_carry: {
-      if (devinfo->gen >= 7)
-         no16("SIMD16 explicit accumulator operands unsupported\n");
-
-      struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
-                                  BRW_REGISTER_TYPE_UD);
-
-      emit(ADDC(reg_null_ud, op[0], op[1]));
-      emit(MOV(this->result, fs_reg(acc)));
-      break;
-   }
-   case ir_binop_borrow: {
-      if (devinfo->gen >= 7)
-         no16("SIMD16 explicit accumulator operands unsupported\n");
-
-      struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
-                                  BRW_REGISTER_TYPE_UD);
-
-      emit(SUBB(reg_null_ud, op[0], op[1]));
-      emit(MOV(this->result, fs_reg(acc)));
-      break;
-   }
-   case ir_binop_mod:
-      /* Floating point should be lowered by MOD_TO_FLOOR in the compiler. */
-      assert(ir->type->is_integer());
-      emit_math(SHADER_OPCODE_INT_REMAINDER, this->result, op[0], op[1]);
-      break;
-
-   case ir_binop_less:
-   case ir_binop_greater:
-   case ir_binop_lequal:
-   case ir_binop_gequal:
-   case ir_binop_equal:
-   case ir_binop_all_equal:
-   case ir_binop_nequal:
-   case ir_binop_any_nequal:
-      if (devinfo->gen <= 5) {
-         resolve_bool_comparison(ir->operands[0], &op[0]);
-         resolve_bool_comparison(ir->operands[1], &op[1]);
-      }
-
-      emit(CMP(this->result, op[0], op[1],
-               brw_conditional_for_comparison(ir->operation)));
-      break;
-
-   case ir_binop_logic_xor:
-      emit(XOR(this->result, op[0], op[1]));
-      break;
-
-   case ir_binop_logic_or:
-      emit(OR(this->result, op[0], op[1]));
-      break;
-
-   case ir_binop_logic_and:
-      emit(AND(this->result, op[0], op[1]));
-      break;
-
-   case ir_binop_dot:
-   case ir_unop_any:
-      unreachable("not reached: should be handled by brw_fs_channel_expressions");
-
-   case ir_unop_noise:
-      unreachable("not reached: should be handled by lower_noise");
-
-   case ir_quadop_vector:
-      unreachable("not reached: should be handled by lower_quadop_vector");
 
-   case ir_binop_vector_extract:
-      unreachable("not reached: should be handled by lower_vec_index_to_cond_assign()");
-
-   case ir_triop_vector_insert:
-      unreachable("not reached: should be handled by lower_vector_insert()");
-
-   case ir_binop_ldexp:
-      unreachable("not reached: should be handled by ldexp_to_arith()");
-
-   case ir_unop_sqrt:
-      emit_math(SHADER_OPCODE_SQRT, this->result, op[0]);
-      break;
-
-   case ir_unop_rsq:
-      emit_math(SHADER_OPCODE_RSQ, this->result, op[0]);
-      break;
-
-   case ir_unop_bitcast_i2f:
-   case ir_unop_bitcast_u2f:
-      op[0].type = BRW_REGISTER_TYPE_F;
-      this->result = op[0];
-      break;
-   case ir_unop_i2u:
-   case ir_unop_bitcast_f2u:
-      op[0].type = BRW_REGISTER_TYPE_UD;
-      this->result = op[0];
-      break;
-   case ir_unop_u2i:
-   case ir_unop_bitcast_f2i:
-      op[0].type = BRW_REGISTER_TYPE_D;
-      this->result = op[0];
-      break;
-   case ir_unop_i2f:
-   case ir_unop_u2f:
-   case ir_unop_f2i:
-   case ir_unop_f2u:
-      emit(MOV(this->result, op[0]));
-      break;
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
+      coordinate = offset(coordinate, 1);
+      length++;
 
-   case ir_unop_b2i:
-      emit(AND(this->result, op[0], fs_reg(1)));
-      break;
-   case ir_unop_b2f:
-      if (devinfo->gen <= 5) {
-         resolve_bool_comparison(ir->operands[0], &op[0]);
+      if (devinfo->gen >= 9) {
+         if (coord_components >= 2) {
+            bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
+            coordinate = offset(coordinate, 1);
+         }
+         length++;
       }
-      op[0].type = BRW_REGISTER_TYPE_D;
-      this->result.type = BRW_REGISTER_TYPE_D;
-      emit(AND(this->result, op[0], fs_reg(0x3f800000u)));
-      this->result.type = BRW_REGISTER_TYPE_F;
-      break;
 
-   case ir_unop_f2b:
-      emit(CMP(this->result, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
-      break;
-   case ir_unop_i2b:
-      emit(CMP(this->result, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
-      break;
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), lod);
+      length++;
 
-   case ir_unop_trunc:
-      emit(RNDZ(this->result, op[0]));
-      break;
-   case ir_unop_ceil: {
-         fs_reg tmp = vgrf(ir->type);
-         op[0].negate = !op[0].negate;
-         emit(RNDD(tmp, op[0]));
-         tmp.negate = true;
-         emit(MOV(this->result, tmp));
+      for (int i = devinfo->gen >= 9 ? 2 : 1; i < coord_components; i++) {
+         bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
+        coordinate = offset(coordinate, 1);
+        length++;
       }
-      break;
-   case ir_unop_floor:
-      emit(RNDD(this->result, op[0]));
-      break;
-   case ir_unop_fract:
-      emit(FRC(this->result, op[0]));
-      break;
-   case ir_unop_round_even:
-      emit(RNDE(this->result, op[0]));
-      break;
-
-   case ir_binop_min:
-   case ir_binop_max:
-      resolve_ud_negate(&op[0]);
-      resolve_ud_negate(&op[1]);
-      emit_minmax(ir->operation == ir_binop_min ?
-                  BRW_CONDITIONAL_L : BRW_CONDITIONAL_GE,
-                  this->result, op[0], op[1]);
-      break;
-   case ir_unop_pack_snorm_2x16:
-   case ir_unop_pack_snorm_4x8:
-   case ir_unop_pack_unorm_2x16:
-   case ir_unop_pack_unorm_4x8:
-   case ir_unop_unpack_snorm_2x16:
-   case ir_unop_unpack_snorm_4x8:
-   case ir_unop_unpack_unorm_2x16:
-   case ir_unop_unpack_unorm_4x8:
-   case ir_unop_unpack_half_2x16:
-   case ir_unop_pack_half_2x16:
-      unreachable("not reached: should be handled by lower_packing_builtins");
-   case ir_unop_unpack_half_2x16_split_x:
-      emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X, this->result, op[0]);
-      break;
-   case ir_unop_unpack_half_2x16_split_y:
-      emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y, this->result, op[0]);
-      break;
-   case ir_binop_pow:
-      emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]);
-      break;
-
-   case ir_unop_bitfield_reverse:
-      emit(BFREV(this->result, op[0]));
-      break;
-   case ir_unop_bit_count:
-      emit(CBIT(this->result, op[0]));
-      break;
-   case ir_unop_find_msb:
-      temp = vgrf(glsl_type::uint_type);
-      emit(FBH(temp, op[0]));
-
-      /* FBH counts from the MSB side, while GLSL's findMSB() wants the count
-       * from the LSB side. If FBH didn't return an error (0xFFFFFFFF), then
-       * subtract the result from 31 to convert the MSB count into an LSB count.
-       */
-
-      /* FBH only supports UD type for dst, so use a MOV to convert UD to D. */
-      emit(MOV(this->result, temp));
-      emit(CMP(reg_null_d, this->result, fs_reg(-1), BRW_CONDITIONAL_NZ));
-
-      temp.negate = true;
-      inst = emit(ADD(this->result, temp, fs_reg(31)));
-      inst->predicate = BRW_PREDICATE_NORMAL;
-      break;
-   case ir_unop_find_lsb:
-      emit(FBL(this->result, op[0]));
-      break;
-   case ir_unop_saturate:
-      inst = emit(MOV(this->result, op[0]));
-      inst->saturate = true;
-      break;
-   case ir_triop_bitfield_extract:
-      /* Note that the instruction's argument order is reversed from GLSL
-       * and the IR.
-       */
-      emit(BFE(this->result, op[2], op[1], op[0]));
-      break;
-   case ir_binop_bfm:
-      emit(BFI1(this->result, op[0], op[1]));
-      break;
-   case ir_triop_bfi:
-      emit(BFI2(this->result, op[0], op[1], op[2]));
-      break;
-   case ir_quadop_bitfield_insert:
-      unreachable("not reached: should be handled by "
-              "lower_instructions::bitfield_insert_to_bfm_bfi");
 
-   case ir_unop_bit_not:
-      emit(NOT(this->result, op[0]));
-      break;
-   case ir_binop_bit_and:
-      emit(AND(this->result, op[0], op[1]));
-      break;
-   case ir_binop_bit_xor:
-      emit(XOR(this->result, op[0], op[1]));
-      break;
-   case ir_binop_bit_or:
-      emit(OR(this->result, op[0], op[1]));
+      coordinate_done = true;
       break;
+   case ir_txf_ms:
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), sample_index);
+      length++;
 
-   case ir_binop_lshift:
-      emit(SHL(this->result, op[0], op[1]));
-      break;
+      /* data from the multisample control surface */
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), mcs);
+      length++;
 
-   case ir_binop_rshift:
-      if (ir->type->base_type == GLSL_TYPE_INT)
-        emit(ASR(this->result, op[0], op[1]));
-      else
-        emit(SHR(this->result, op[0], op[1]));
-      break;
-   case ir_binop_pack_half_2x16_split:
-      emit(FS_OPCODE_PACK_HALF_2x16_SPLIT, this->result, op[0], op[1]);
-      break;
-   case ir_binop_ubo_load: {
-      /* This IR node takes a constant uniform block and a constant or
-       * variable byte offset within the block and loads a vector from that.
+      /* there is no offsetting for this message; just copy in the integer
+       * texture coordinates
        */
-      ir_constant *const_uniform_block = ir->operands[0]->as_constant();
-      ir_constant *const_offset = ir->operands[1]->as_constant();
-      fs_reg surf_index;
-      uint32_t binding, set, index, set_index;
-
-      if (const_uniform_block) {
-         /* The block index is a constant, so just emit the binding table entry
-          * as an immediate.
-          */
-         index = const_uniform_block->value.u[0];
-         set = shader->base.UniformBlocks[index].Set;
-         set_index = shader->base.UniformBlocks[index].Binding;
-         binding = stage_prog_data->bind_map[set].index[set_index];
-         surf_index = fs_reg(binding);
-      } else {
-         assert(0 && "need more info from the ir for this.");
-
-         /* The block index is not a constant. Evaluate the index expression
-          * per-channel and add the base UBO index; we have to select a value
-          * from any live channel.
-          */
-         surf_index = vgrf(glsl_type::uint_type);
-         emit(ADD(surf_index, op[0],
-                  fs_reg(stage_prog_data->binding_table.ubo_start)));
-         emit_uniformize(surf_index, surf_index);
-
-         /* Assume this may touch any UBO. It would be nice to provide
-          * a tighter bound, but the array information is already lowered away.
-          */
-         brw_mark_surface_used(prog_data,
-                               stage_prog_data->binding_table.ubo_start +
-                               shader_prog->NumUniformBlocks - 1);
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
+         coordinate = offset(coordinate, 1);
+         length++;
       }
 
-      if (const_offset) {
-         fs_reg packed_consts = vgrf(glsl_type::float_type);
-         packed_consts.type = result.type;
-
-         fs_reg const_offset_reg = fs_reg(const_offset->value.u[0] & ~15);
-         emit(new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, 8,
-                                   packed_consts, surf_index, const_offset_reg));
-
-         for (int i = 0; i < ir->type->vector_elements; i++) {
-            packed_consts.set_smear(const_offset->value.u[0] % 16 / 4 + i);
-
-            /* The std140 packing rules don't allow vectors to cross 16-byte
-             * boundaries, and a reg is 32 bytes.
-             */
-            assert(packed_consts.subreg_offset < 32);
-
-            /* UBO bools are any nonzero value.  We consider bools to be
-             * values with the low bit set to 1.  Convert them using CMP.
-             */
-            if (ir->type->base_type == GLSL_TYPE_BOOL) {
-               emit(CMP(result, packed_consts, fs_reg(0u), BRW_CONDITIONAL_NZ));
-            } else {
-               emit(MOV(result, packed_consts));
-            }
+      coordinate_done = true;
+      break;
+   case ir_tg4:
+      if (has_nonconstant_offset) {
+         if (shadow_c.file != BAD_FILE)
+            no16("Gen7 does not support gather4_po_c in SIMD16 mode.");
 
-            result = offset(result, 1);
+         /* More crazy intermixing */
+         for (int i = 0; i < 2; i++) { /* u, v */
+            bld.MOV(sources[length], coordinate);
+            coordinate = offset(coordinate, 1);
+            length++;
          }
-      } else {
-         /* Turn the byte offset into a dword offset. */
-         fs_reg base_offset = vgrf(glsl_type::int_type);
-         emit(SHR(base_offset, op[1], fs_reg(2)));
-
-         for (int i = 0; i < ir->type->vector_elements; i++) {
-            emit(VARYING_PULL_CONSTANT_LOAD(result, surf_index,
-                                            base_offset, i));
 
-            if (ir->type->base_type == GLSL_TYPE_BOOL)
-               emit(CMP(result, result, fs_reg(0), BRW_CONDITIONAL_NZ));
-
-            result = offset(result, 1);
+         for (int i = 0; i < 2; i++) { /* offu, offv */
+            bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), offset_value);
+            offset_value = offset(offset_value, 1);
+            length++;
          }
-      }
-
-      result.reg_offset = 0;
-      break;
-   }
-
-   case ir_triop_fma:
-      /* Note that the instruction's argument order is reversed from GLSL
-       * and the IR.
-       */
-      emit(MAD(this->result, op[2], op[1], op[0]));
-      break;
-
-   case ir_triop_lrp:
-      emit_lrp(this->result, op[0], op[1], op[2]);
-      break;
-
-   case ir_triop_csel:
-   case ir_unop_interpolate_at_centroid:
-   case ir_binop_interpolate_at_offset:
-   case ir_binop_interpolate_at_sample:
-      unreachable("already handled above");
-      break;
-
-   case ir_unop_d2f:
-   case ir_unop_f2d:
-   case ir_unop_d2i:
-   case ir_unop_i2d:
-   case ir_unop_d2u:
-   case ir_unop_u2d:
-   case ir_unop_d2b:
-   case ir_unop_pack_double_2x32:
-   case ir_unop_unpack_double_2x32:
-   case ir_unop_frexp_sig:
-   case ir_unop_frexp_exp:
-      unreachable("fp64 todo");
-      break;
-   }
-}
-
-void
-fs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
-                                  const glsl_type *type, bool predicated)
-{
-   switch (type->base_type) {
-   case GLSL_TYPE_FLOAT:
-   case GLSL_TYPE_UINT:
-   case GLSL_TYPE_INT:
-   case GLSL_TYPE_BOOL:
-      for (unsigned int i = 0; i < type->components(); i++) {
-        l.type = brw_type_for_base_type(type);
-        r.type = brw_type_for_base_type(type);
-
-        if (predicated || !l.equals(r)) {
-           fs_inst *inst = emit(MOV(l, r));
-           inst->predicate = predicated ? BRW_PREDICATE_NORMAL : BRW_PREDICATE_NONE;
-        }
 
-        l = offset(l, 1);
-        r = offset(r, 1);
-      }
-      break;
-   case GLSL_TYPE_ARRAY:
-      for (unsigned int i = 0; i < type->length; i++) {
-        emit_assignment_writes(l, r, type->fields.array, predicated);
-      }
-      break;
+         if (coord_components == 3) { /* r if present */
+            bld.MOV(sources[length], coordinate);
+            coordinate = offset(coordinate, 1);
+            length++;
+         }
 
-   case GLSL_TYPE_STRUCT:
-      for (unsigned int i = 0; i < type->length; i++) {
-        emit_assignment_writes(l, r, type->fields.structure[i].type,
-                               predicated);
+         coordinate_done = true;
       }
       break;
-
-   case GLSL_TYPE_SAMPLER:
-   case GLSL_TYPE_IMAGE:
-   case GLSL_TYPE_ATOMIC_UINT:
-      break;
-
-   case GLSL_TYPE_DOUBLE:
-   case GLSL_TYPE_VOID:
-   case GLSL_TYPE_ERROR:
-   case GLSL_TYPE_INTERFACE:
-   case GLSL_TYPE_FUNCTION:
-      unreachable("not reached");
-   }
-}
-
-/* If the RHS processing resulted in an instruction generating a
- * temporary value, and it would be easy to rewrite the instruction to
- * generate its result right into the LHS instead, do so.  This ends
- * up reliably removing instructions where it can be tricky to do so
- * later without real UD chain information.
- */
-bool
-fs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir,
-                                   fs_reg dst,
-                                   fs_reg src,
-                                   fs_inst *pre_rhs_inst,
-                                   fs_inst *last_rhs_inst)
-{
-   /* Only attempt if we're doing a direct assignment. */
-   if (ir->condition ||
-       !(ir->lhs->type->is_scalar() ||
-        (ir->lhs->type->is_vector() &&
-         ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1)))
-      return false;
-
-   /* Make sure the last instruction generated our source reg. */
-   fs_inst *modify = get_instruction_generating_reg(pre_rhs_inst,
-                                                   last_rhs_inst,
-                                                   src);
-   if (!modify)
-      return false;
-
-   /* If last_rhs_inst wrote a different number of components than our LHS,
-    * we can't safely rewrite it.
-    */
-   if (alloc.sizes[dst.reg] != modify->regs_written)
-      return false;
-
-   /* Success!  Rewrite the instruction. */
-   modify->dst = dst;
-
-   return true;
-}
-
-void
-fs_visitor::visit(ir_assignment *ir)
-{
-   fs_reg l, r;
-   fs_inst *inst;
-
-   /* FINISHME: arrays on the lhs */
-   ir->lhs->accept(this);
-   l = this->result;
-
-   fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail();
-
-   ir->rhs->accept(this);
-   r = this->result;
-
-   fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail();
-
-   assert(l.file != BAD_FILE);
-   assert(r.file != BAD_FILE);
-
-   if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst))
-      return;
-
-   if (ir->condition) {
-      emit_bool_to_cond_code(ir->condition);
    }
 
-   if (ir->lhs->type->is_scalar() ||
-       ir->lhs->type->is_vector()) {
-      for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
-        if (ir->write_mask & (1 << i)) {
-           inst = emit(MOV(l, r));
-           if (ir->condition)
-              inst->predicate = BRW_PREDICATE_NORMAL;
-           r = offset(r, 1);
-        }
-        l = offset(l, 1);
+   /* Set up the coordinate (except for cases where it was done above) */
+   if (!coordinate_done) {
+      for (int i = 0; i < coord_components; i++) {
+         bld.MOV(sources[length], coordinate);
+         coordinate = offset(coordinate, 1);
+         length++;
       }
-   } else {
-      emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL);
    }
-}
 
-fs_inst *
-fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
-                              fs_reg coordinate, int coord_components,
-                              fs_reg shadow_c,
-                              fs_reg lod, fs_reg dPdy, int grad_components,
-                              uint32_t sampler)
-{
    int mlen;
-   int base_mrf = 1;
-   bool simd16 = false;
-   fs_reg orig_dst;
-
-   /* g0 header. */
-   mlen = 1;
+   if (reg_width == 2)
+      mlen = length * reg_width - header_size;
+   else
+      mlen = length * reg_width;
 
-   if (shadow_c.file != BAD_FILE) {
-      for (int i = 0; i < coord_components; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate));
-        coordinate = offset(coordinate, 1);
-      }
-
-      /* gen4's SIMD8 sampler always has the slots for u,v,r present.
-       * the unused slots must be zeroed.
-       */
-      for (int i = coord_components; i < 3; i++) {
-         emit(MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f)));
-      }
-      mlen += 3;
-
-      if (op == ir_tex) {
-        /* There's no plain shadow compare message, so we use shadow
-         * compare with a bias of 0.0.
-         */
-        emit(MOV(fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f)));
-        mlen++;
-      } else if (op == ir_txb || op == ir_txl) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
-        mlen++;
-      } else {
-         unreachable("Should not get here.");
-      }
-
-      emit(MOV(fs_reg(MRF, base_mrf + mlen), shadow_c));
-      mlen++;
-   } else if (op == ir_tex) {
-      for (int i = 0; i < coord_components; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate));
-        coordinate = offset(coordinate, 1);
-      }
-      /* zero the others. */
-      for (int i = coord_components; i<3; i++) {
-         emit(MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f)));
-      }
-      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
-      mlen += 3;
-   } else if (op == ir_txd) {
-      fs_reg &dPdx = lod;
-
-      for (int i = 0; i < coord_components; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate));
-        coordinate = offset(coordinate, 1);
-      }
-      /* the slots for u and v are always present, but r is optional */
-      mlen += MAX2(coord_components, 2);
-
-      /*  P   = u, v, r
-       * dPdx = dudx, dvdx, drdx
-       * dPdy = dudy, dvdy, drdy
-       *
-       * 1-arg: Does not exist.
-       *
-       * 2-arg: dudx   dvdx   dudy   dvdy
-       *        dPdx.x dPdx.y dPdy.x dPdy.y
-       *        m4     m5     m6     m7
-       *
-       * 3-arg: dudx   dvdx   drdx   dudy   dvdy   drdy
-       *        dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
-       *        m5     m6     m7     m8     m9     m10
-       */
-      for (int i = 0; i < grad_components; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen), dPdx));
-        dPdx = offset(dPdx, 1);
-      }
-      mlen += MAX2(grad_components, 2);
-
-      for (int i = 0; i < grad_components; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen), dPdy));
-        dPdy = offset(dPdy, 1);
-      }
-      mlen += MAX2(grad_components, 2);
-   } else if (op == ir_txs) {
-      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
-      simd16 = true;
-      emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod));
-      mlen += 2;
-   } else {
-      /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
-       * instructions.  We'll need to do SIMD16 here.
-       */
-      simd16 = true;
-      assert(op == ir_txb || op == ir_txl || op == ir_txf);
-
-      for (int i = 0; i < coord_components; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type),
-                  coordinate));
-        coordinate = offset(coordinate, 1);
-      }
-
-      /* Initialize the rest of u/v/r with 0.0.  Empirically, this seems to
-       * be necessary for TXF (ld), but seems wise to do for all messages.
-       */
-      for (int i = coord_components; i < 3; i++) {
-        emit(MOV(fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f)));
-      }
-
-      /* lod/bias appears after u/v/r. */
-      mlen += 6;
-
-      emit(MOV(fs_reg(MRF, base_mrf + mlen, lod.type), lod));
-      mlen++;
-
-      /* The unused upper half. */
-      mlen++;
-   }
-
-   if (simd16) {
-      /* Now, since we're doing simd16, the return is 2 interleaved
-       * vec4s where the odd-indexed ones are junk. We'll need to move
-       * this weirdness around to the expected layout.
-       */
-      orig_dst = dst;
-      dst = fs_reg(GRF, alloc.allocate(8), orig_dst.type);
-   }
+   fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
+                               BRW_REGISTER_TYPE_F, dispatch_width);
+   bld.LOAD_PAYLOAD(src_payload, sources, length, header_size);
 
+   /* Generate the SEND */
    enum opcode opcode;
    switch (op) {
    case ir_tex: opcode = SHADER_OPCODE_TEX; break;
    case ir_txb: opcode = FS_OPCODE_TXB; break;
    case ir_txl: opcode = SHADER_OPCODE_TXL; break;
    case ir_txd: opcode = SHADER_OPCODE_TXD; break;
-   case ir_txs: opcode = SHADER_OPCODE_TXS; break;
    case ir_txf: opcode = SHADER_OPCODE_TXF; break;
+   case ir_txf_ms: opcode = SHADER_OPCODE_TXF_CMS; break;
+   case ir_txs: opcode = SHADER_OPCODE_TXS; break;
+   case ir_query_levels: opcode = SHADER_OPCODE_TXS; break;
+   case ir_lod: opcode = SHADER_OPCODE_LOD; break;
+   case ir_tg4:
+      if (has_nonconstant_offset)
+         opcode = SHADER_OPCODE_TG4_OFFSET;
+      else
+         opcode = SHADER_OPCODE_TG4;
+      break;
    default:
       unreachable("not reached");
    }
-
-   fs_inst *inst = emit(opcode, dst, reg_undef, fs_reg(sampler));
-   inst->base_mrf = base_mrf;
-   inst->mlen = mlen;
-   inst->header_size = 1;
-   inst->regs_written = simd16 ? 8 : 4;
-
-   if (simd16) {
-      for (int i = 0; i < 4; i++) {
-        emit(MOV(orig_dst, dst));
-        orig_dst = offset(orig_dst, 1);
-        dst = offset(dst, 2);
-      }
-   }
-
-   return inst;
-}
-
-fs_inst *
-fs_visitor::emit_texture_gen4_simd16(ir_texture_opcode op, fs_reg dst,
-                                     fs_reg coordinate, int vector_elements,
-                                     fs_reg shadow_c, fs_reg lod,
-                                     uint32_t sampler)
-{
-   fs_reg message(MRF, 2, BRW_REGISTER_TYPE_F, dispatch_width);
-   bool has_lod = op == ir_txl || op == ir_txb || op == ir_txf;
-
-   if (has_lod && shadow_c.file != BAD_FILE)
-      no16("TXB and TXL with shadow comparison unsupported in SIMD16.");
-
-   if (op == ir_txd)
-      no16("textureGrad unsupported in SIMD16.");
-
-   /* Copy the coordinates. */
-   for (int i = 0; i < vector_elements; i++) {
-      emit(MOV(retype(offset(message, i), coordinate.type), coordinate));
-      coordinate = offset(coordinate, 1);
-   }
-
-   fs_reg msg_end = offset(message, vector_elements);
-
-   /* Messages other than sample and ld require all three components */
-   if (has_lod || shadow_c.file != BAD_FILE) {
-      for (int i = vector_elements; i < 3; i++) {
-         emit(MOV(offset(message, i), fs_reg(0.0f)));
-      }
-   }
-
-   if (has_lod) {
-      fs_reg msg_lod = retype(offset(message, 3), op == ir_txf ?
-                              BRW_REGISTER_TYPE_UD : BRW_REGISTER_TYPE_F);
-      emit(MOV(msg_lod, lod));
-      msg_end = offset(msg_lod, 1);
-   }
-
-   if (shadow_c.file != BAD_FILE) {
-      fs_reg msg_ref = offset(message, 3 + has_lod);
-      emit(MOV(msg_ref, shadow_c));
-      msg_end = offset(msg_ref, 1);
-   }
-
-   enum opcode opcode;
-   switch (op) {
-   case ir_tex: opcode = SHADER_OPCODE_TEX; break;
-   case ir_txb: opcode = FS_OPCODE_TXB;     break;
-   case ir_txd: opcode = SHADER_OPCODE_TXD; break;
-   case ir_txl: opcode = SHADER_OPCODE_TXL; break;
-   case ir_txs: opcode = SHADER_OPCODE_TXS; break;
-   case ir_txf: opcode = SHADER_OPCODE_TXF; break;
-   default: unreachable("not reached");
-   }
-
-   fs_inst *inst = emit(opcode, dst, reg_undef, fs_reg(sampler));
-   inst->base_mrf = message.reg - 1;
-   inst->mlen = msg_end.reg - inst->base_mrf;
-   inst->header_size = 1;
-   inst->regs_written = 8;
-
-   return inst;
-}
-
-/* gen5's sampler has slots for u, v, r, array index, then optional
- * parameters like shadow comparitor or LOD bias.  If optional
- * parameters aren't present, those base slots are optional and don't
- * need to be included in the message.
- *
- * We don't fill in the unnecessary slots regardless, which may look
- * surprising in the disassembly.
- */
-fs_inst *
-fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
-                              fs_reg coordinate, int vector_elements,
-                              fs_reg shadow_c,
-                              fs_reg lod, fs_reg lod2, int grad_components,
-                              fs_reg sample_index, uint32_t sampler,
-                              bool has_offset)
-{
-   int reg_width = dispatch_width / 8;
-   unsigned header_size = 0;
-
-   fs_reg message(MRF, 2, BRW_REGISTER_TYPE_F, dispatch_width);
-   fs_reg msg_coords = message;
-
-   if (has_offset) {
-      /* The offsets set up by the ir_texture visitor are in the
-       * m1 header, so we can't go headerless.
-       */
-      header_size = 1;
-      message.reg--;
-   }
-
-   for (int i = 0; i < vector_elements; i++) {
-      emit(MOV(retype(offset(msg_coords, i), coordinate.type), coordinate));
-      coordinate = offset(coordinate, 1);
-   }
-   fs_reg msg_end = offset(msg_coords, vector_elements);
-   fs_reg msg_lod = offset(msg_coords, 4);
-
-   if (shadow_c.file != BAD_FILE) {
-      fs_reg msg_shadow = msg_lod;
-      emit(MOV(msg_shadow, shadow_c));
-      msg_lod = offset(msg_shadow, 1);
-      msg_end = msg_lod;
-   }
-
-   enum opcode opcode;
-   switch (op) {
-   case ir_tex:
-      opcode = SHADER_OPCODE_TEX;
-      break;
-   case ir_txb:
-      emit(MOV(msg_lod, lod));
-      msg_end = offset(msg_lod, 1);
-
-      opcode = FS_OPCODE_TXB;
-      break;
-   case ir_txl:
-      emit(MOV(msg_lod, lod));
-      msg_end = offset(msg_lod, 1);
-
-      opcode = SHADER_OPCODE_TXL;
-      break;
-   case ir_txd: {
-      /**
-       *  P   =  u,    v,    r
-       * dPdx = dudx, dvdx, drdx
-       * dPdy = dudy, dvdy, drdy
-       *
-       * Load up these values:
-       * - dudx   dudy   dvdx   dvdy   drdx   drdy
-       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
-       */
-      msg_end = msg_lod;
-      for (int i = 0; i < grad_components; i++) {
-         emit(MOV(msg_end, lod));
-         lod = offset(lod, 1);
-         msg_end = offset(msg_end, 1);
-
-         emit(MOV(msg_end, lod2));
-         lod2 = offset(lod2, 1);
-         msg_end = offset(msg_end, 1);
-      }
-
-      opcode = SHADER_OPCODE_TXD;
-      break;
-   }
-   case ir_txs:
-      msg_lod = retype(msg_end, BRW_REGISTER_TYPE_UD);
-      emit(MOV(msg_lod, lod));
-      msg_end = offset(msg_lod, 1);
-
-      opcode = SHADER_OPCODE_TXS;
-      break;
-   case ir_query_levels:
-      msg_lod = msg_end;
-      emit(MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u)));
-      msg_end = offset(msg_lod, 1);
-
-      opcode = SHADER_OPCODE_TXS;
-      break;
-   case ir_txf:
-      msg_lod = offset(msg_coords, 3);
-      emit(MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), lod));
-      msg_end = offset(msg_lod, 1);
-
-      opcode = SHADER_OPCODE_TXF;
-      break;
-   case ir_txf_ms:
-      msg_lod = offset(msg_coords, 3);
-      /* lod */
-      emit(MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u)));
-      /* sample index */
-      emit(MOV(retype(offset(msg_lod, 1), BRW_REGISTER_TYPE_UD), sample_index));
-      msg_end = offset(msg_lod, 2);
-
-      opcode = SHADER_OPCODE_TXF_CMS;
-      break;
-   case ir_lod:
-      opcode = SHADER_OPCODE_LOD;
-      break;
-   case ir_tg4:
-      opcode = SHADER_OPCODE_TG4;
-      break;
-   default:
-      unreachable("not reached");
-   }
-
-   fs_inst *inst = emit(opcode, dst, reg_undef, fs_reg(sampler));
-   inst->base_mrf = message.reg;
-   inst->mlen = msg_end.reg - message.reg;
-   inst->header_size = header_size;
-   inst->regs_written = 4 * reg_width;
-
-   if (inst->mlen > MAX_SAMPLER_MESSAGE_SIZE) {
-      fail("Message length >" STRINGIFY(MAX_SAMPLER_MESSAGE_SIZE)
-           " disallowed by hardware\n");
-   }
-
-   return inst;
-}
-
-static bool
-is_high_sampler(const struct brw_device_info *devinfo, fs_reg sampler)
-{
-   if (devinfo->gen < 8 && !devinfo->is_haswell)
-      return false;
-
-   return sampler.file != IMM || sampler.fixed_hw_reg.dw1.ud >= 16;
-}
-
-fs_inst *
-fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
-                              fs_reg coordinate, int coord_components,
-                              fs_reg shadow_c,
-                              fs_reg lod, fs_reg lod2, int grad_components,
-                              fs_reg sample_index, fs_reg mcs, fs_reg sampler,
-                              fs_reg offset_value)
-{
-   int reg_width = dispatch_width / 8;
-   unsigned header_size = 0;
-
-   fs_reg *sources = ralloc_array(mem_ctx, fs_reg, MAX_SAMPLER_MESSAGE_SIZE);
-   for (int i = 0; i < MAX_SAMPLER_MESSAGE_SIZE; i++) {
-      sources[i] = vgrf(glsl_type::float_type);
-   }
-   int length = 0;
-
-   if (op == ir_tg4 || offset_value.file != BAD_FILE ||
-       is_high_sampler(devinfo, sampler)) {
-      /* For general texture offsets (no txf workaround), we need a header to
-       * put them in.  Note that for SIMD16 we're making space for two actual
-       * hardware registers here, so the emit will have to fix up for this.
-       *
-       * * ir4_tg4 needs to place its channel select in the header,
-       * for interaction with ARB_texture_swizzle
-       *
-       * The sampler index is only 4-bits, so for larger sampler numbers we
-       * need to offset the Sampler State Pointer in the header.
-       */
-      header_size = 1;
-      sources[0] = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-      length++;
-   }
-
-   if (shadow_c.file != BAD_FILE) {
-      emit(MOV(sources[length], shadow_c));
-      length++;
-   }
-
-   bool has_nonconstant_offset =
-      offset_value.file != BAD_FILE && offset_value.file != IMM;
-   bool coordinate_done = false;
-
-   /* The sampler can only meaningfully compute LOD for fragment shader
-    * messages. For all other stages, we change the opcode to ir_txl and
-    * hardcode the LOD to 0.
-    */
-   if (stage != MESA_SHADER_FRAGMENT && op == ir_tex) {
-      op = ir_txl;
-      lod = fs_reg(0.0f);
-   }
-
-   /* Set up the LOD info */
-   switch (op) {
-   case ir_tex:
-   case ir_lod:
-      break;
-   case ir_txb:
-      emit(MOV(sources[length], lod));
-      length++;
-      break;
-   case ir_txl:
-      emit(MOV(sources[length], lod));
-      length++;
-      break;
-   case ir_txd: {
-      no16("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
-
-      /* Load dPdx and the coordinate together:
-       * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
-       */
-      for (int i = 0; i < coord_components; i++) {
-        emit(MOV(sources[length], coordinate));
-        coordinate = offset(coordinate, 1);
-        length++;
-
-         /* For cube map array, the coordinate is (u,v,r,ai) but there are
-          * only derivatives for (u, v, r).
-          */
-         if (i < grad_components) {
-            emit(MOV(sources[length], lod));
-            lod = offset(lod, 1);
-            length++;
-
-            emit(MOV(sources[length], lod2));
-            lod2 = offset(lod2, 1);
-            length++;
-         }
-      }
-
-      coordinate_done = true;
-      break;
-   }
-   case ir_txs:
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), lod));
-      length++;
-      break;
-   case ir_query_levels:
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), fs_reg(0u)));
-      length++;
-      break;
-   case ir_txf:
-      /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r.
-       * On Gen9 they are u, v, lod, r
-       */
-
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
-      coordinate = offset(coordinate, 1);
-      length++;
-
-      if (devinfo->gen >= 9) {
-         if (coord_components >= 2) {
-            emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
-            coordinate = offset(coordinate, 1);
-         }
-         length++;
-      }
-
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), lod));
-      length++;
-
-      for (int i = devinfo->gen >= 9 ? 2 : 1; i < coord_components; i++) {
-        emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
-        coordinate = offset(coordinate, 1);
-        length++;
-      }
-
-      coordinate_done = true;
-      break;
-   case ir_txf_ms:
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), sample_index));
-      length++;
-
-      /* data from the multisample control surface */
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), mcs));
-      length++;
-
-      /* there is no offsetting for this message; just copy in the integer
-       * texture coordinates
-       */
-      for (int i = 0; i < coord_components; i++) {
-         emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
-         coordinate = offset(coordinate, 1);
-         length++;
-      }
-
-      coordinate_done = true;
-      break;
-   case ir_tg4:
-      if (has_nonconstant_offset) {
-         if (shadow_c.file != BAD_FILE)
-            no16("Gen7 does not support gather4_po_c in SIMD16 mode.");
-
-         /* More crazy intermixing */
-         for (int i = 0; i < 2; i++) { /* u, v */
-            emit(MOV(sources[length], coordinate));
-            coordinate = offset(coordinate, 1);
-            length++;
-         }
-
-         for (int i = 0; i < 2; i++) { /* offu, offv */
-            emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), offset_value));
-            offset_value = offset(offset_value, 1);
-            length++;
-         }
-
-         if (coord_components == 3) { /* r if present */
-            emit(MOV(sources[length], coordinate));
-            coordinate = offset(coordinate, 1);
-            length++;
-         }
-
-         coordinate_done = true;
-      }
-      break;
-   }
-
-   /* Set up the coordinate (except for cases where it was done above) */
-   if (!coordinate_done) {
-      for (int i = 0; i < coord_components; i++) {
-         emit(MOV(sources[length], coordinate));
-         coordinate = offset(coordinate, 1);
-         length++;
-      }
-   }
-
-   int mlen;
-   if (reg_width == 2)
-      mlen = length * reg_width - header_size;
-   else
-      mlen = length * reg_width;
-
-   fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
-                               BRW_REGISTER_TYPE_F, dispatch_width);
-   emit(LOAD_PAYLOAD(src_payload, sources, length, header_size));
-
-   /* Generate the SEND */
-   enum opcode opcode;
-   switch (op) {
-   case ir_tex: opcode = SHADER_OPCODE_TEX; break;
-   case ir_txb: opcode = FS_OPCODE_TXB; break;
-   case ir_txl: opcode = SHADER_OPCODE_TXL; break;
-   case ir_txd: opcode = SHADER_OPCODE_TXD; break;
-   case ir_txf: opcode = SHADER_OPCODE_TXF; break;
-   case ir_txf_ms: opcode = SHADER_OPCODE_TXF_CMS; break;
-   case ir_txs: opcode = SHADER_OPCODE_TXS; break;
-   case ir_query_levels: opcode = SHADER_OPCODE_TXS; break;
-   case ir_lod: opcode = SHADER_OPCODE_LOD; break;
-   case ir_tg4:
-      if (has_nonconstant_offset)
-         opcode = SHADER_OPCODE_TG4_OFFSET;
-      else
-         opcode = SHADER_OPCODE_TG4;
-      break;
-   default:
-      unreachable("not reached");
-   }
-   fs_inst *inst = emit(opcode, dst, src_payload, sampler);
-   inst->base_mrf = -1;
-   inst->mlen = mlen;
-   inst->header_size = header_size;
-   inst->regs_written = 4 * reg_width;
-
-   if (inst->mlen > MAX_SAMPLER_MESSAGE_SIZE) {
-      fail("Message length >" STRINGIFY(MAX_SAMPLER_MESSAGE_SIZE)
-           " disallowed by hardware\n");
-   }
-
-   return inst;
-}
-
-fs_reg
-fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components,
-                             bool is_rect, uint32_t sampler, int texunit)
-{
-   fs_inst *inst = NULL;
-   bool needs_gl_clamp = true;
-   fs_reg scale_x, scale_y;
-
-   /* The 965 requires the EU to do the normalization of GL rectangle
-    * texture coordinates.  We use the program parameter state
-    * tracking to get the scaling factor.
-    */
-   if (is_rect &&
-       (devinfo->gen < 6 ||
-        (devinfo->gen >= 6 && (key_tex->gl_clamp_mask[0] & (1 << sampler) ||
-                               key_tex->gl_clamp_mask[1] & (1 << sampler))))) {
-      struct gl_program_parameter_list *params = prog->Parameters;
-      int tokens[STATE_LENGTH] = {
-        STATE_INTERNAL,
-        STATE_TEXRECT_SCALE,
-        texunit,
-        0,
-        0
-      };
-
-      no16("rectangle scale uniform setup not supported on SIMD16\n");
-      if (dispatch_width == 16) {
-        return coordinate;
-      }
-
-      GLuint index = _mesa_add_state_reference(params,
-                                              (gl_state_index *)tokens);
-      /* Try to find existing copies of the texrect scale uniforms. */
-      for (unsigned i = 0; i < uniforms; i++) {
-         if (stage_prog_data->param[i] ==
-             &prog->Parameters->ParameterValues[index][0]) {
-            scale_x = fs_reg(UNIFORM, i);
-            scale_y = fs_reg(UNIFORM, i + 1);
-            break;
-         }
-      }
-
-      /* If we didn't already set them up, do so now. */
-      if (scale_x.file == BAD_FILE) {
-         scale_x = fs_reg(UNIFORM, uniforms);
-         scale_y = fs_reg(UNIFORM, uniforms + 1);
-
-         stage_prog_data->param[uniforms++] =
-            &prog->Parameters->ParameterValues[index][0];
-         stage_prog_data->param[uniforms++] =
-            &prog->Parameters->ParameterValues[index][1];
-      }
-   }
-
-   /* The 965 requires the EU to do the normalization of GL rectangle
-    * texture coordinates.  We use the program parameter state
-    * tracking to get the scaling factor.
-    */
-   if (devinfo->gen < 6 && is_rect) {
-      fs_reg dst = fs_reg(GRF, alloc.allocate(coord_components));
-      fs_reg src = coordinate;
-      coordinate = dst;
-
-      emit(MUL(dst, src, scale_x));
-      dst = offset(dst, 1);
-      src = offset(src, 1);
-      emit(MUL(dst, src, scale_y));
-   } else if (is_rect) {
-      /* On gen6+, the sampler handles the rectangle coordinates
-       * natively, without needing rescaling.  But that means we have
-       * to do GL_CLAMP clamping at the [0, width], [0, height] scale,
-       * not [0, 1] like the default case below.
-       */
-      needs_gl_clamp = false;
-
-      for (int i = 0; i < 2; i++) {
-        if (key_tex->gl_clamp_mask[i] & (1 << sampler)) {
-           fs_reg chan = coordinate;
-           chan = offset(chan, i);
-
-           inst = emit(BRW_OPCODE_SEL, chan, chan, fs_reg(0.0f));
-           inst->conditional_mod = BRW_CONDITIONAL_GE;
-
-           /* Our parameter comes in as 1.0/width or 1.0/height,
-            * because that's what people normally want for doing
-            * texture rectangle handling.  We need width or height
-            * for clamping, but we don't care enough to make a new
-            * parameter type, so just invert back.
-            */
-           fs_reg limit = vgrf(glsl_type::float_type);
-           emit(MOV(limit, i == 0 ? scale_x : scale_y));
-           emit(SHADER_OPCODE_RCP, limit, limit);
-
-           inst = emit(BRW_OPCODE_SEL, chan, chan, limit);
-           inst->conditional_mod = BRW_CONDITIONAL_L;
-        }
-      }
-   }
-
-   if (coord_components > 0 && needs_gl_clamp) {
-      for (int i = 0; i < MIN2(coord_components, 3); i++) {
-        if (key_tex->gl_clamp_mask[i] & (1 << sampler)) {
-           fs_reg chan = coordinate;
-           chan = offset(chan, i);
-
-           fs_inst *inst = emit(MOV(chan, chan));
-           inst->saturate = true;
-        }
-      }
-   }
-   return coordinate;
-}
-
-/* Sample from the MCS surface attached to this multisample texture. */
-fs_reg
-fs_visitor::emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler)
-{
-   int reg_width = dispatch_width / 8;
-   fs_reg payload = fs_reg(GRF, alloc.allocate(components * reg_width),
-                           BRW_REGISTER_TYPE_F, dispatch_width);
-   fs_reg dest = vgrf(glsl_type::uvec4_type);
-   fs_reg *sources = ralloc_array(mem_ctx, fs_reg, components);
-
-   /* parameters are: u, v, r; missing parameters are treated as zero */
-   for (int i = 0; i < components; i++) {
-      sources[i] = vgrf(glsl_type::float_type);
-      emit(MOV(retype(sources[i], BRW_REGISTER_TYPE_D), coordinate));
-      coordinate = offset(coordinate, 1);
-   }
-
-   emit(LOAD_PAYLOAD(payload, sources, components, 0));
-
-   fs_inst *inst = emit(SHADER_OPCODE_TXF_MCS, dest, payload, sampler);
+   fs_inst *inst = bld.emit(opcode, dst, src_payload, sampler);
    inst->base_mrf = -1;
-   inst->mlen = components * reg_width;
-   inst->header_size = 0;
-   inst->regs_written = 4 * reg_width; /* we only care about one reg of
-                                        * response, but the sampler always
-                                        * writes 4/8
-                                        */
-
-   return dest;
-}
-
-void
-fs_visitor::emit_texture(ir_texture_opcode op,
-                         const glsl_type *dest_type,
-                         fs_reg coordinate, int coord_components,
-                         fs_reg shadow_c,
-                         fs_reg lod, fs_reg lod2, int grad_components,
-                         fs_reg sample_index,
-                         fs_reg offset_value,
-                         fs_reg mcs,
-                         int gather_component,
-                         bool is_cube_array,
-                         bool is_rect,
-                         uint32_t sampler,
-                         fs_reg sampler_reg, int texunit)
-{
-   fs_inst *inst = NULL;
-
-   if (op == ir_tg4) {
-      /* When tg4 is used with the degenerate ZERO/ONE swizzles, don't bother
-       * emitting anything other than setting up the constant result.
-       */
-      int swiz = GET_SWZ(key_tex->swizzles[sampler], gather_component);
-      if (swiz == SWIZZLE_ZERO || swiz == SWIZZLE_ONE) {
-
-         fs_reg res = vgrf(glsl_type::vec4_type);
-         this->result = res;
-
-         for (int i=0; i<4; i++) {
-            emit(MOV(res, fs_reg(swiz == SWIZZLE_ZERO ? 0.0f : 1.0f)));
-            res = offset(res, 1);
-         }
-         return;
-      }
-   }
-
-   if (coordinate.file != BAD_FILE) {
-      /* FINISHME: Texture coordinate rescaling doesn't work with non-constant
-       * samplers.  This should only be a problem with GL_CLAMP on Gen7.
-       */
-      coordinate = rescale_texcoord(coordinate, coord_components, is_rect,
-                                    sampler, texunit);
-   }
-
-   /* Writemasking doesn't eliminate channels on SIMD8 texture
-    * samples, so don't worry about them.
-    */
-   fs_reg dst = vgrf(glsl_type::get_instance(dest_type->base_type, 4, 1));
-
-   if (devinfo->gen >= 7) {
-      inst = emit_texture_gen7(op, dst, coordinate, coord_components,
-                               shadow_c, lod, lod2, grad_components,
-                               sample_index, mcs, sampler_reg,
-                               offset_value);
-   } else if (devinfo->gen >= 5) {
-      inst = emit_texture_gen5(op, dst, coordinate, coord_components,
-                               shadow_c, lod, lod2, grad_components,
-                               sample_index, sampler,
-                               offset_value.file != BAD_FILE);
-   } else if (dispatch_width == 16) {
-      inst = emit_texture_gen4_simd16(op, dst, coordinate, coord_components,
-                                      shadow_c, lod, sampler);
-   } else {
-      inst = emit_texture_gen4(op, dst, coordinate, coord_components,
-                               shadow_c, lod, lod2, grad_components,
-                               sampler);
-   }
-
-   if (shadow_c.file != BAD_FILE)
-      inst->shadow_compare = true;
-
-   if (offset_value.file == IMM)
-      inst->offset = offset_value.fixed_hw_reg.dw1.ud;
-
-   if (op == ir_tg4) {
-      inst->offset |=
-         gather_channel(gather_component, sampler) << 16; /* M0.2:16-17 */
-
-      if (devinfo->gen == 6)
-         emit_gen6_gather_wa(key_tex->gen6_gather_wa[sampler], dst);
-   }
-
-   /* fixup #layers for cube map arrays */
-   if (op == ir_txs && is_cube_array) {
-      fs_reg depth = offset(dst, 2);
-      fs_reg fixed_depth = vgrf(glsl_type::int_type);
-      emit_math(SHADER_OPCODE_INT_QUOTIENT, fixed_depth, depth, fs_reg(6));
-
-      fs_reg *fixed_payload = ralloc_array(mem_ctx, fs_reg, inst->regs_written);
-      int components = inst->regs_written / (dst.width / 8);
-      for (int i = 0; i < components; i++) {
-         if (i == 2) {
-            fixed_payload[i] = fixed_depth;
-         } else {
-            fixed_payload[i] = offset(dst, i);
-         }
-      }
-      emit(LOAD_PAYLOAD(dst, fixed_payload, components, 0));
-   }
-
-   swizzle_result(op, dest_type->vector_elements, dst, sampler);
-}
-
-void
-fs_visitor::visit(ir_texture *ir)
-{
-   uint32_t sampler;
-
-   ir_dereference_variable *deref_var = ir->sampler->as_dereference_variable();
-   assert(deref_var);
-   ir_variable *var = deref_var->var;
-
-   sampler = stage_prog_data->bind_map[var->data.set].index[var->data.index];
-
-   ir_rvalue *nonconst_sampler_index =
-      _mesa_get_sampler_array_nonconst_index(ir->sampler);
-
-   /* Handle non-constant sampler array indexing */
-   fs_reg sampler_reg;
-   if (nonconst_sampler_index) {
-      /* The highest sampler which may be used by this operation is
-       * the last element of the array. Mark it here, because the generator
-       * doesn't have enough information to determine the bound.
-       */
-      uint32_t array_size = ir->sampler->as_dereference_array()
-         ->array->type->array_size();
-
-      uint32_t max_used = sampler + array_size - 1;
-      if (ir->op == ir_tg4 && devinfo->gen < 8) {
-         max_used += stage_prog_data->binding_table.gather_texture_start;
-      } else {
-         max_used += stage_prog_data->binding_table.texture_start;
-      }
-
-      brw_mark_surface_used(prog_data, max_used);
-
-      /* Emit code to evaluate the actual indexing expression */
-      nonconst_sampler_index->accept(this);
-      fs_reg temp = vgrf(glsl_type::uint_type);
-      emit(ADD(temp, this->result, fs_reg(sampler)));
-      emit_uniformize(temp, temp);
-
-      sampler_reg = temp;
-   } else {
-      /* Single sampler, or constant array index; the indexing expression
-       * is just an immediate.
-       */
-      sampler_reg = fs_reg(sampler);
-   }
-
-   /* FINISHME: We're failing to recompile our programs when the sampler is
-    * updated.  This only matters for the texture rectangle scale parameters
-    * (pre-gen6, or gen6+ with GL_CLAMP).
-    */
-   int texunit = prog->SamplerUnits[sampler];
-
-   /* Should be lowered by do_lower_texture_projection */
-   assert(!ir->projector);
-
-   /* Should be lowered */
-   assert(!ir->offset || !ir->offset->type->is_array());
-
-   /* Generate code to compute all the subexpression trees.  This has to be
-    * done before loading any values into MRFs for the sampler message since
-    * generating these values may involve SEND messages that need the MRFs.
-    */
-   fs_reg coordinate;
-   int coord_components = 0;
-   if (ir->coordinate) {
-      coord_components = ir->coordinate->type->vector_elements;
-      ir->coordinate->accept(this);
-      coordinate = this->result;
-   }
-
-   fs_reg shadow_comparitor;
-   if (ir->shadow_comparitor) {
-      ir->shadow_comparitor->accept(this);
-      shadow_comparitor = this->result;
-   }
-
-   fs_reg offset_value;
-   if (ir->offset) {
-      ir_constant *const_offset = ir->offset->as_constant();
-      if (const_offset) {
-         /* Store the header bitfield in an IMM register.  This allows us to
-          * use offset_value.file to distinguish between no offset, a constant
-          * offset, and a non-constant offset.
-          */
-         offset_value =
-            fs_reg(brw_texture_offset(const_offset->value.i,
-                                      const_offset->type->vector_elements));
-      } else {
-         ir->offset->accept(this);
-         offset_value = this->result;
-      }
-   }
-
-   fs_reg lod, lod2, sample_index, mcs;
-   int grad_components = 0;
-   switch (ir->op) {
-   case ir_tex:
-   case ir_lod:
-   case ir_tg4:
-   case ir_query_levels:
-      break;
-   case ir_txb:
-      ir->lod_info.bias->accept(this);
-      lod = this->result;
-      break;
-   case ir_txd:
-      ir->lod_info.grad.dPdx->accept(this);
-      lod = this->result;
-
-      ir->lod_info.grad.dPdy->accept(this);
-      lod2 = this->result;
-
-      grad_components = ir->lod_info.grad.dPdx->type->vector_elements;
-      break;
-   case ir_txf:
-   case ir_txl:
-   case ir_txs:
-      ir->lod_info.lod->accept(this);
-      lod = this->result;
-      break;
-   case ir_txf_ms:
-      ir->lod_info.sample_index->accept(this);
-      sample_index = this->result;
-
-      if (devinfo->gen >= 7 &&
-          key_tex->compressed_multisample_layout_mask & (1 << sampler)) {
-         mcs = emit_mcs_fetch(coordinate, ir->coordinate->type->vector_elements,
-                              sampler_reg);
-      } else {
-         mcs = fs_reg(0u);
-      }
-      break;
-   default:
-      unreachable("Unrecognized texture opcode");
-   };
-
-   int gather_component = 0;
-   if (ir->op == ir_tg4)
-      gather_component = ir->lod_info.component->as_constant()->value.i[0];
-
-   bool is_rect =
-      ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT;
-
-   bool is_cube_array =
-      ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE &&
-      ir->sampler->type->sampler_array;
-
-   emit_texture(ir->op, ir->type, coordinate, coord_components,
-                shadow_comparitor, lod, lod2, grad_components,
-                sample_index, offset_value, mcs,
-                gather_component, is_cube_array, is_rect, sampler,
-                sampler_reg, texunit);
-}
-
-/**
- * Apply workarounds for Gen6 gather with UINT/SINT
- */
-void
-fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst)
-{
-   if (!wa)
-      return;
-
-   int width = (wa & WA_8BIT) ? 8 : 16;
-
-   for (int i = 0; i < 4; i++) {
-      fs_reg dst_f = retype(dst, BRW_REGISTER_TYPE_F);
-      /* Convert from UNORM to UINT */
-      emit(MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1))));
-      emit(MOV(dst, dst_f));
-
-      if (wa & WA_SIGN) {
-         /* Reinterpret the UINT value as a signed INT value by
-          * shifting the sign bit into place, then shifting back
-          * preserving sign.
-          */
-         emit(SHL(dst, dst, fs_reg(32 - width)));
-         emit(ASR(dst, dst, fs_reg(32 - width)));
-      }
-
-      dst = offset(dst, 1);
-   }
-}
-
-/**
- * Set up the gather channel based on the swizzle, for gather4.
- */
-uint32_t
-fs_visitor::gather_channel(int orig_chan, uint32_t sampler)
-{
-   int swiz = GET_SWZ(key_tex->swizzles[sampler], orig_chan);
-   switch (swiz) {
-      case SWIZZLE_X: return 0;
-      case SWIZZLE_Y:
-         /* gather4 sampler is broken for green channel on RG32F --
-          * we must ask for blue instead.
-          */
-         if (key_tex->gather_channel_quirk_mask & (1 << sampler))
-            return 2;
-         return 1;
-      case SWIZZLE_Z: return 2;
-      case SWIZZLE_W: return 3;
-      default:
-         unreachable("Not reached"); /* zero, one swizzles handled already */
+   inst->mlen = mlen;
+   inst->header_size = header_size;
+   inst->regs_written = 4 * reg_width;
+
+   if (inst->mlen > MAX_SAMPLER_MESSAGE_SIZE) {
+      fail("Message length >" STRINGIFY(MAX_SAMPLER_MESSAGE_SIZE)
+           " disallowed by hardware\n");
    }
+
+   return inst;
 }
 
-/**
- * Swizzle the result of a texture result.  This is necessary for
- * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
- */
-void
-fs_visitor::swizzle_result(ir_texture_opcode op, int dest_components,
-                           fs_reg orig_val, uint32_t sampler)
+fs_reg
+fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components,
+                             bool is_rect, uint32_t sampler, int texunit)
 {
-   if (op == ir_query_levels) {
-      /* # levels is in .w */
-      this->result = offset(orig_val, 3);
-      return;
-   }
-
-   this->result = orig_val;
+   bool needs_gl_clamp = true;
+   fs_reg scale_x, scale_y;
 
-   /* txs,lod don't actually sample the texture, so swizzling the result
-    * makes no sense.
+   /* The 965 requires the EU to do the normalization of GL rectangle
+    * texture coordinates.  We use the program parameter state
+    * tracking to get the scaling factor.
     */
-   if (op == ir_txs || op == ir_lod || op == ir_tg4)
-      return;
-
-   if (dest_components == 1) {
-      /* Ignore DEPTH_TEXTURE_MODE swizzling. */
-   } else if (key_tex->swizzles[sampler] != SWIZZLE_NOOP) {
-      fs_reg swizzled_result = vgrf(glsl_type::vec4_type);
-      swizzled_result.type = orig_val.type;
-
-      for (int i = 0; i < 4; i++) {
-        int swiz = GET_SWZ(key_tex->swizzles[sampler], i);
-        fs_reg l = swizzled_result;
-        l = offset(l, i);
+   if (is_rect &&
+       (devinfo->gen < 6 ||
+        (devinfo->gen >= 6 && (key_tex->gl_clamp_mask[0] & (1 << sampler) ||
+                               key_tex->gl_clamp_mask[1] & (1 << sampler))))) {
+      struct gl_program_parameter_list *params = prog->Parameters;
+      int tokens[STATE_LENGTH] = {
+        STATE_INTERNAL,
+        STATE_TEXRECT_SCALE,
+        texunit,
+        0,
+        0
+      };
 
-        if (swiz == SWIZZLE_ZERO) {
-           emit(MOV(l, fs_reg(0.0f)));
-        } else if (swiz == SWIZZLE_ONE) {
-           emit(MOV(l, fs_reg(1.0f)));
-        } else {
-            emit(MOV(l, offset(orig_val,
-                               GET_SWZ(key_tex->swizzles[sampler], i))));
-        }
+      no16("rectangle scale uniform setup not supported on SIMD16\n");
+      if (dispatch_width == 16) {
+        return coordinate;
       }
-      this->result = swizzled_result;
-   }
-}
 
-void
-fs_visitor::visit(ir_swizzle *ir)
-{
-   ir->val->accept(this);
-   fs_reg val = this->result;
+      GLuint index = _mesa_add_state_reference(params,
+                                              (gl_state_index *)tokens);
+      /* Try to find existing copies of the texrect scale uniforms. */
+      for (unsigned i = 0; i < uniforms; i++) {
+         if (stage_prog_data->param[i] ==
+             &prog->Parameters->ParameterValues[index][0]) {
+            scale_x = fs_reg(UNIFORM, i);
+            scale_y = fs_reg(UNIFORM, i + 1);
+            break;
+         }
+      }
 
-   if (ir->type->vector_elements == 1) {
-      this->result = offset(this->result, ir->mask.x);
-      return;
-   }
+      /* If we didn't already set them up, do so now. */
+      if (scale_x.file == BAD_FILE) {
+         scale_x = fs_reg(UNIFORM, uniforms);
+         scale_y = fs_reg(UNIFORM, uniforms + 1);
 
-   fs_reg result = vgrf(ir->type);
-   this->result = result;
-
-   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
-      fs_reg channel = val;
-      int swiz = 0;
-
-      switch (i) {
-      case 0:
-        swiz = ir->mask.x;
-        break;
-      case 1:
-        swiz = ir->mask.y;
-        break;
-      case 2:
-        swiz = ir->mask.z;
-        break;
-      case 3:
-        swiz = ir->mask.w;
-        break;
+         stage_prog_data->param[uniforms++] =
+            &prog->Parameters->ParameterValues[index][0];
+         stage_prog_data->param[uniforms++] =
+            &prog->Parameters->ParameterValues[index][1];
       }
-
-      emit(MOV(result, offset(channel, swiz)));
-      result = offset(result, 1);
    }
-}
 
-void
-fs_visitor::visit(ir_discard *ir)
-{
-   /* We track our discarded pixels in f0.1.  By predicating on it, we can
-    * update just the flag bits that aren't yet discarded.  If there's no
-    * condition, we emit a CMP of g0 != g0, so all currently executing
-    * channels will get turned off.
+   /* The 965 requires the EU to do the normalization of GL rectangle
+    * texture coordinates.  We use the program parameter state
+    * tracking to get the scaling factor.
     */
-   fs_inst *cmp;
-   if (ir->condition) {
-      emit_bool_to_cond_code(ir->condition);
-      cmp = (fs_inst *) this->instructions.get_tail();
-      cmp->conditional_mod = brw_negate_cmod(cmp->conditional_mod);
-   } else {
-      fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
-                                      BRW_REGISTER_TYPE_UW));
-      cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ));
-   }
-   cmp->predicate = BRW_PREDICATE_NORMAL;
-   cmp->flag_subreg = 1;
+   if (devinfo->gen < 6 && is_rect) {
+      fs_reg dst = fs_reg(GRF, alloc.allocate(coord_components));
+      fs_reg src = coordinate;
+      coordinate = dst;
 
-   if (devinfo->gen >= 6) {
-      emit_discard_jump();
-   }
-}
+      bld.MUL(dst, src, scale_x);
+      dst = offset(dst, 1);
+      src = offset(src, 1);
+      bld.MUL(dst, src, scale_y);
+   } else if (is_rect) {
+      /* On gen6+, the sampler handles the rectangle coordinates
+       * natively, without needing rescaling.  But that means we have
+       * to do GL_CLAMP clamping at the [0, width], [0, height] scale,
+       * not [0, 1] like the default case below.
+       */
+      needs_gl_clamp = false;
 
-void
-fs_visitor::visit(ir_constant *ir)
-{
-   /* Set this->result to reg at the bottom of the function because some code
-    * paths will cause this visitor to be applied to other fields.  This will
-    * cause the value stored in this->result to be modified.
-    *
-    * Make reg constant so that it doesn't get accidentally modified along the
-    * way.  Yes, I actually had this problem. :(
-    */
-   const fs_reg reg = vgrf(ir->type);
-   fs_reg dst_reg = reg;
+      for (int i = 0; i < 2; i++) {
+        if (key_tex->gl_clamp_mask[i] & (1 << sampler)) {
+           fs_reg chan = coordinate;
+           chan = offset(chan, i);
 
-   if (ir->type->is_array()) {
-      const unsigned size = type_size(ir->type->fields.array);
+            set_condmod(BRW_CONDITIONAL_GE,
+                        bld.emit(BRW_OPCODE_SEL, chan, chan, fs_reg(0.0f)));
 
-      for (unsigned i = 0; i < ir->type->length; i++) {
-        ir->array_elements[i]->accept(this);
-        fs_reg src_reg = this->result;
+           /* Our parameter comes in as 1.0/width or 1.0/height,
+            * because that's what people normally want for doing
+            * texture rectangle handling.  We need width or height
+            * for clamping, but we don't care enough to make a new
+            * parameter type, so just invert back.
+            */
+           fs_reg limit = vgrf(glsl_type::float_type);
+            bld.MOV(limit, i == 0 ? scale_x : scale_y);
+            bld.emit(SHADER_OPCODE_RCP, limit, limit);
 
-        dst_reg.type = src_reg.type;
-        for (unsigned j = 0; j < size; j++) {
-           emit(MOV(dst_reg, src_reg));
-           src_reg = offset(src_reg, 1);
-           dst_reg = offset(dst_reg, 1);
+            set_condmod(BRW_CONDITIONAL_L,
+                        bld.emit(BRW_OPCODE_SEL, chan, chan, limit));
         }
       }
-   } else if (ir->type->is_record()) {
-      foreach_in_list(ir_constant, field, &ir->components) {
-        const unsigned size = type_size(field->type);
-
-        field->accept(this);
-        fs_reg src_reg = this->result;
-
-        dst_reg.type = src_reg.type;
-        for (unsigned j = 0; j < size; j++) {
-           emit(MOV(dst_reg, src_reg));
-           src_reg = offset(src_reg, 1);
-           dst_reg = offset(dst_reg, 1);
-        }
-      }
-   } else {
-      const unsigned size = type_size(ir->type);
-
-      for (unsigned i = 0; i < size; i++) {
-        switch (ir->type->base_type) {
-        case GLSL_TYPE_FLOAT:
-           emit(MOV(dst_reg, fs_reg(ir->value.f[i])));
-           break;
-        case GLSL_TYPE_UINT:
-           emit(MOV(dst_reg, fs_reg(ir->value.u[i])));
-           break;
-        case GLSL_TYPE_INT:
-           emit(MOV(dst_reg, fs_reg(ir->value.i[i])));
-           break;
-        case GLSL_TYPE_BOOL:
-            emit(MOV(dst_reg, fs_reg(ir->value.b[i] != 0 ? ~0 : 0)));
-           break;
-        default:
-           unreachable("Non-float/uint/int/bool constant");
+   }
+
+   if (coord_components > 0 && needs_gl_clamp) {
+      for (int i = 0; i < MIN2(coord_components, 3); i++) {
+        if (key_tex->gl_clamp_mask[i] & (1 << sampler)) {
+           fs_reg chan = coordinate;
+           chan = offset(chan, i);
+            set_saturate(true, bld.MOV(chan, chan));
         }
-        dst_reg = offset(dst_reg, 1);
       }
    }
-
-   this->result = reg;
+   return coordinate;
 }
 
-void
-fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
+/* Sample from the MCS surface attached to this multisample texture. */
+fs_reg
+fs_visitor::emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler)
 {
-   ir_expression *expr = ir->as_expression();
-
-   if (!expr || expr->operation == ir_binop_ubo_load) {
-      ir->accept(this);
+   int reg_width = dispatch_width / 8;
+   fs_reg payload = fs_reg(GRF, alloc.allocate(components * reg_width),
+                           BRW_REGISTER_TYPE_F, dispatch_width);
+   fs_reg dest = vgrf(glsl_type::uvec4_type);
+   fs_reg *sources = ralloc_array(mem_ctx, fs_reg, components);
 
-      fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1)));
-      inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      return;
+   /* parameters are: u, v, r; missing parameters are treated as zero */
+   for (int i = 0; i < components; i++) {
+      sources[i] = vgrf(glsl_type::float_type);
+      bld.MOV(retype(sources[i], BRW_REGISTER_TYPE_D), coordinate);
+      coordinate = offset(coordinate, 1);
    }
 
-   fs_reg op[3];
-
-   assert(expr->get_num_operands() <= 3);
-   for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
-      assert(expr->operands[i]->type->is_scalar());
+   bld.LOAD_PAYLOAD(payload, sources, components, 0);
 
-      expr->operands[i]->accept(this);
-      op[i] = this->result;
-
-      resolve_ud_negate(&op[i]);
-   }
+   fs_inst *inst = bld.emit(SHADER_OPCODE_TXF_MCS, dest, payload, sampler);
+   inst->base_mrf = -1;
+   inst->mlen = components * reg_width;
+   inst->header_size = 0;
+   inst->regs_written = 4 * reg_width; /* we only care about one reg of
+                                        * response, but the sampler always
+                                        * writes 4/8
+                                        */
 
-   emit_bool_to_cond_code_of_reg(expr, op);
+   return dest;
 }
 
 void
-fs_visitor::emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3])
+fs_visitor::emit_texture(ir_texture_opcode op,
+                         const glsl_type *dest_type,
+                         fs_reg coordinate, int coord_components,
+                         fs_reg shadow_c,
+                         fs_reg lod, fs_reg lod2, int grad_components,
+                         fs_reg sample_index,
+                         fs_reg offset_value,
+                         fs_reg mcs,
+                         int gather_component,
+                         bool is_cube_array,
+                         bool is_rect,
+                         uint32_t sampler,
+                         fs_reg sampler_reg, int texunit)
 {
-   fs_inst *inst;
+   fs_inst *inst = NULL;
 
-   switch (expr->operation) {
-   case ir_unop_logic_not:
-      inst = emit(AND(reg_null_d, op[0], fs_reg(1)));
-      inst->conditional_mod = BRW_CONDITIONAL_Z;
-      break;
+   if (op == ir_tg4) {
+      /* When tg4 is used with the degenerate ZERO/ONE swizzles, don't bother
+       * emitting anything other than setting up the constant result.
+       */
+      int swiz = GET_SWZ(key_tex->swizzles[sampler], gather_component);
+      if (swiz == SWIZZLE_ZERO || swiz == SWIZZLE_ONE) {
 
-   case ir_binop_logic_xor:
-      if (devinfo->gen <= 5) {
-         fs_reg temp = vgrf(expr->type);
-         emit(XOR(temp, op[0], op[1]));
-         inst = emit(AND(reg_null_d, temp, fs_reg(1)));
-      } else {
-         inst = emit(XOR(reg_null_d, op[0], op[1]));
-      }
-      inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      break;
+         fs_reg res = vgrf(glsl_type::vec4_type);
+         this->result = res;
 
-   case ir_binop_logic_or:
-      if (devinfo->gen <= 5) {
-         fs_reg temp = vgrf(expr->type);
-         emit(OR(temp, op[0], op[1]));
-         inst = emit(AND(reg_null_d, temp, fs_reg(1)));
-      } else {
-         inst = emit(OR(reg_null_d, op[0], op[1]));
+         for (int i=0; i<4; i++) {
+            bld.MOV(res, fs_reg(swiz == SWIZZLE_ZERO ? 0.0f : 1.0f));
+            res = offset(res, 1);
+         }
+         return;
       }
-      inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      break;
+   }
 
-   case ir_binop_logic_and:
-      if (devinfo->gen <= 5) {
-         fs_reg temp = vgrf(expr->type);
-         emit(AND(temp, op[0], op[1]));
-         inst = emit(AND(reg_null_d, temp, fs_reg(1)));
-      } else {
-         inst = emit(AND(reg_null_d, op[0], op[1]));
-      }
-      inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      break;
+   if (coordinate.file != BAD_FILE) {
+      /* FINISHME: Texture coordinate rescaling doesn't work with non-constant
+       * samplers.  This should only be a problem with GL_CLAMP on Gen7.
+       */
+      coordinate = rescale_texcoord(coordinate, coord_components, is_rect,
+                                    sampler, texunit);
+   }
 
-   case ir_unop_f2b:
-      if (devinfo->gen >= 6) {
-         emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
-      } else {
-         inst = emit(MOV(reg_null_f, op[0]));
-         inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      }
-      break;
+   /* Writemasking doesn't eliminate channels on SIMD8 texture
+    * samples, so don't worry about them.
+    */
+   fs_reg dst = vgrf(glsl_type::get_instance(dest_type->base_type, 4, 1));
 
-   case ir_unop_i2b:
-      if (devinfo->gen >= 6) {
-         emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
-      } else {
-         inst = emit(MOV(reg_null_d, op[0]));
-         inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      }
-      break;
+   if (devinfo->gen >= 7) {
+      inst = emit_texture_gen7(op, dst, coordinate, coord_components,
+                               shadow_c, lod, lod2, grad_components,
+                               sample_index, mcs, sampler_reg,
+                               offset_value);
+   } else if (devinfo->gen >= 5) {
+      inst = emit_texture_gen5(op, dst, coordinate, coord_components,
+                               shadow_c, lod, lod2, grad_components,
+                               sample_index, sampler,
+                               offset_value.file != BAD_FILE);
+   } else if (dispatch_width == 16) {
+      inst = emit_texture_gen4_simd16(op, dst, coordinate, coord_components,
+                                      shadow_c, lod, sampler);
+   } else {
+      inst = emit_texture_gen4(op, dst, coordinate, coord_components,
+                               shadow_c, lod, lod2, grad_components,
+                               sampler);
+   }
 
-   case ir_binop_greater:
-   case ir_binop_gequal:
-   case ir_binop_less:
-   case ir_binop_lequal:
-   case ir_binop_equal:
-   case ir_binop_all_equal:
-   case ir_binop_nequal:
-   case ir_binop_any_nequal:
-      if (devinfo->gen <= 5) {
-         resolve_bool_comparison(expr->operands[0], &op[0]);
-         resolve_bool_comparison(expr->operands[1], &op[1]);
-      }
+   if (shadow_c.file != BAD_FILE)
+      inst->shadow_compare = true;
 
-      emit(CMP(reg_null_d, op[0], op[1],
-               brw_conditional_for_comparison(expr->operation)));
-      break;
+   if (offset_value.file == IMM)
+      inst->offset = offset_value.fixed_hw_reg.dw1.ud;
+
+   if (op == ir_tg4) {
+      inst->offset |=
+         gather_channel(gather_component, sampler) << 16; /* M0.2:16-17 */
 
-   case ir_triop_csel: {
-      /* Expand the boolean condition into the flag register. */
-      inst = emit(MOV(reg_null_d, op[0]));
-      inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      if (devinfo->gen == 6)
+         emit_gen6_gather_wa(key_tex->gen6_gather_wa[sampler], dst);
+   }
 
-      /* Select which boolean to return. */
-      fs_reg temp = vgrf(expr->operands[1]->type);
-      inst = emit(SEL(temp, op[1], op[2]));
-      inst->predicate = BRW_PREDICATE_NORMAL;
+   /* fixup #layers for cube map arrays */
+   if (op == ir_txs && is_cube_array) {
+      fs_reg depth = offset(dst, 2);
+      fs_reg fixed_depth = vgrf(glsl_type::int_type);
+      bld.emit(SHADER_OPCODE_INT_QUOTIENT, fixed_depth, depth, fs_reg(6));
 
-      /* Expand the result to a condition code. */
-      inst = emit(MOV(reg_null_d, temp));
-      inst->conditional_mod = BRW_CONDITIONAL_NZ;
-      break;
+      fs_reg *fixed_payload = ralloc_array(mem_ctx, fs_reg, inst->regs_written);
+      int components = inst->regs_written / (dst.width / 8);
+      for (int i = 0; i < components; i++) {
+         if (i == 2) {
+            fixed_payload[i] = fixed_depth;
+         } else {
+            fixed_payload[i] = offset(dst, i);
+         }
+      }
+      bld.LOAD_PAYLOAD(dst, fixed_payload, components, 0);
    }
 
-   default:
-      unreachable("not reached");
-   }
+   swizzle_result(op, dest_type->vector_elements, dst, sampler);
 }
 
 /**
- * Emit a gen6 IF statement with the comparison folded into the IF
- * instruction.
+ * Apply workarounds for Gen6 gather with UINT/SINT
  */
 void
-fs_visitor::emit_if_gen6(ir_if *ir)
+fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst)
 {
-   ir_expression *expr = ir->condition->as_expression();
-
-   if (expr && expr->operation != ir_binop_ubo_load) {
-      fs_reg op[3];
-      fs_inst *inst;
-      fs_reg temp;
-
-      assert(expr->get_num_operands() <= 3);
-      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
-        assert(expr->operands[i]->type->is_scalar());
-
-        expr->operands[i]->accept(this);
-        op[i] = this->result;
-      }
-
-      switch (expr->operation) {
-      case ir_unop_logic_not:
-         emit(IF(op[0], fs_reg(0), BRW_CONDITIONAL_Z));
-         return;
-
-      case ir_binop_logic_xor:
-         emit(IF(op[0], op[1], BRW_CONDITIONAL_NZ));
-         return;
-
-      case ir_binop_logic_or:
-         temp = vgrf(glsl_type::bool_type);
-         emit(OR(temp, op[0], op[1]));
-         emit(IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ));
-         return;
-
-      case ir_binop_logic_and:
-         temp = vgrf(glsl_type::bool_type);
-         emit(AND(temp, op[0], op[1]));
-         emit(IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ));
-         return;
-
-      case ir_unop_f2b:
-        inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0));
-        inst->conditional_mod = BRW_CONDITIONAL_NZ;
-        return;
-
-      case ir_unop_i2b:
-        emit(IF(op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
-        return;
-
-      case ir_binop_greater:
-      case ir_binop_gequal:
-      case ir_binop_less:
-      case ir_binop_lequal:
-      case ir_binop_equal:
-      case ir_binop_all_equal:
-      case ir_binop_nequal:
-      case ir_binop_any_nequal:
-         if (devinfo->gen <= 5) {
-            resolve_bool_comparison(expr->operands[0], &op[0]);
-            resolve_bool_comparison(expr->operands[1], &op[1]);
-         }
-
-        emit(IF(op[0], op[1],
-                 brw_conditional_for_comparison(expr->operation)));
-        return;
+   if (!wa)
+      return;
 
-      case ir_triop_csel: {
-         /* Expand the boolean condition into the flag register. */
-         fs_inst *inst = emit(MOV(reg_null_d, op[0]));
-         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+   int width = (wa & WA_8BIT) ? 8 : 16;
 
-         /* Select which boolean to use as the result. */
-         fs_reg temp = vgrf(expr->operands[1]->type);
-         inst = emit(SEL(temp, op[1], op[2]));
-         inst->predicate = BRW_PREDICATE_NORMAL;
+   for (int i = 0; i < 4; i++) {
+      fs_reg dst_f = retype(dst, BRW_REGISTER_TYPE_F);
+      /* Convert from UNORM to UINT */
+      bld.MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1)));
+      bld.MOV(dst, dst_f);
 
-        emit(IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ));
-        return;
+      if (wa & WA_SIGN) {
+         /* Reinterpret the UINT value as a signed INT value by
+          * shifting the sign bit into place, then shifting back
+          * preserving sign.
+          */
+         bld.SHL(dst, dst, fs_reg(32 - width));
+         bld.ASR(dst, dst, fs_reg(32 - width));
       }
 
-      default:
-        unreachable("not reached");
-      }
+      dst = offset(dst, 1);
    }
-
-   ir->condition->accept(this);
-   emit(IF(this->result, fs_reg(0), BRW_CONDITIONAL_NZ));
 }
 
-bool
-fs_visitor::try_opt_frontfacing_ternary(ir_if *ir)
+/**
+ * Set up the gather channel based on the swizzle, for gather4.
+ */
+uint32_t
+fs_visitor::gather_channel(int orig_chan, uint32_t sampler)
 {
-   ir_dereference_variable *deref = ir->condition->as_dereference_variable();
-   if (!deref || strcmp(deref->var->name, "gl_FrontFacing") != 0)
-      return false;
-
-   if (ir->then_instructions.length() != 1 ||
-       ir->else_instructions.length() != 1)
-      return false;
-
-   ir_assignment *then_assign =
-         ((ir_instruction *)ir->then_instructions.head)->as_assignment();
-   ir_assignment *else_assign =
-         ((ir_instruction *)ir->else_instructions.head)->as_assignment();
-
-   if (!then_assign || then_assign->condition ||
-       !else_assign || else_assign->condition ||
-       then_assign->write_mask != else_assign->write_mask ||
-       !then_assign->lhs->equals(else_assign->lhs))
-      return false;
-
-   ir_constant *then_rhs = then_assign->rhs->as_constant();
-   ir_constant *else_rhs = else_assign->rhs->as_constant();
-
-   if (!then_rhs || !else_rhs)
-      return false;
-
-   if (then_rhs->type->base_type != GLSL_TYPE_FLOAT)
-      return false;
-
-   if ((then_rhs->is_one() && else_rhs->is_negative_one()) ||
-       (else_rhs->is_one() && then_rhs->is_negative_one())) {
-      then_assign->lhs->accept(this);
-      fs_reg dst = this->result;
-      dst.type = BRW_REGISTER_TYPE_D;
-      fs_reg tmp = vgrf(glsl_type::int_type);
-
-      if (devinfo->gen >= 6) {
-         /* Bit 15 of g0.0 is 0 if the polygon is front facing. */
-         fs_reg g0 = fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_W));
-
-         /* For (gl_FrontFacing ? 1.0 : -1.0), emit:
-          *
-          *    or(8)  tmp.1<2>W  g0.0<0,1,0>W  0x00003f80W
-          *    and(8) dst<1>D    tmp<8,8,1>D   0xbf800000D
-          *
-          * and negate g0.0<0,1,0>W for (gl_FrontFacing ? -1.0 : 1.0).
+   int swiz = GET_SWZ(key_tex->swizzles[sampler], orig_chan);
+   switch (swiz) {
+      case SWIZZLE_X: return 0;
+      case SWIZZLE_Y:
+         /* gather4 sampler is broken for green channel on RG32F --
+          * we must ask for blue instead.
           */
+         if (key_tex->gather_channel_quirk_mask & (1 << sampler))
+            return 2;
+         return 1;
+      case SWIZZLE_Z: return 2;
+      case SWIZZLE_W: return 3;
+      default:
+         unreachable("Not reached"); /* zero, one swizzles handled already */
+   }
+}
 
-         if (then_rhs->is_negative_one()) {
-            assert(else_rhs->is_one());
-            g0.negate = true;
-         }
+/**
+ * Swizzle the result of a texture result.  This is necessary for
+ * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
+ */
+void
+fs_visitor::swizzle_result(ir_texture_opcode op, int dest_components,
+                           fs_reg orig_val, uint32_t sampler)
+{
+   if (op == ir_query_levels) {
+      /* # levels is in .w */
+      this->result = offset(orig_val, 3);
+      return;
+   }
 
-         tmp.type = BRW_REGISTER_TYPE_W;
-         tmp.subreg_offset = 2;
-         tmp.stride = 2;
+   this->result = orig_val;
 
-         fs_inst *or_inst = emit(OR(tmp, g0, fs_reg(0x3f80)));
-         or_inst->src[1].type = BRW_REGISTER_TYPE_UW;
+   /* txs,lod don't actually sample the texture, so swizzling the result
+    * makes no sense.
+    */
+   if (op == ir_txs || op == ir_lod || op == ir_tg4)
+      return;
 
-         tmp.type = BRW_REGISTER_TYPE_D;
-         tmp.subreg_offset = 0;
-         tmp.stride = 1;
-      } else {
-         /* Bit 31 of g1.6 is 0 if the polygon is front facing. */
-         fs_reg g1_6 = fs_reg(retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_D));
-
-         /* For (gl_FrontFacing ? 1.0 : -1.0), emit:
-          *
-          *    or(8)  tmp<1>D  g1.6<0,1,0>D  0x3f800000D
-          *    and(8) dst<1>D  tmp<8,8,1>D   0xbf800000D
-          *
-          * and negate g1.6<0,1,0>D for (gl_FrontFacing ? -1.0 : 1.0).
-          */
+   if (dest_components == 1) {
+      /* Ignore DEPTH_TEXTURE_MODE swizzling. */
+   } else if (key_tex->swizzles[sampler] != SWIZZLE_NOOP) {
+      fs_reg swizzled_result = vgrf(glsl_type::vec4_type);
+      swizzled_result.type = orig_val.type;
 
-         if (then_rhs->is_negative_one()) {
-            assert(else_rhs->is_one());
-            g1_6.negate = true;
-         }
+      for (int i = 0; i < 4; i++) {
+        int swiz = GET_SWZ(key_tex->swizzles[sampler], i);
+        fs_reg l = swizzled_result;
+        l = offset(l, i);
 
-         emit(OR(tmp, g1_6, fs_reg(0x3f800000)));
+        if (swiz == SWIZZLE_ZERO) {
+            bld.MOV(l, fs_reg(0.0f));
+        } else if (swiz == SWIZZLE_ONE) {
+            bld.MOV(l, fs_reg(1.0f));
+        } else {
+            bld.MOV(l, offset(orig_val,
+                              GET_SWZ(key_tex->swizzles[sampler], i)));
+        }
       }
-      emit(AND(dst, tmp, fs_reg(0xbf800000)));
-      return true;
+      this->result = swizzled_result;
    }
-
-   return false;
 }
 
 /**
@@ -3056,21 +1091,21 @@ fs_visitor::try_replace_with_sel()
       if (src0.file == IMM) {
          src0 = vgrf(glsl_type::float_type);
          src0.type = then_mov->src[0].type;
-         emit(MOV(src0, then_mov->src[0]));
+         bld.MOV(src0, then_mov->src[0]);
       }
 
-      fs_inst *sel;
       if (if_inst->conditional_mod) {
          /* Sandybridge-specific IF with embedded comparison */
-         emit(CMP(reg_null_d, if_inst->src[0], if_inst->src[1],
-                  if_inst->conditional_mod));
-         sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]);
-         sel->predicate = BRW_PREDICATE_NORMAL;
+         bld.CMP(bld.null_reg_d(), if_inst->src[0], if_inst->src[1],
+                 if_inst->conditional_mod);
+         set_predicate(BRW_PREDICATE_NORMAL,
+                       bld.emit(BRW_OPCODE_SEL, then_mov->dst,
+                                src0, else_mov->src[0]));
       } else {
          /* Separate CMP and IF instructions */
-         sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]);
-         sel->predicate = if_inst->predicate;
-         sel->predicate_inverse = if_inst->predicate_inverse;
+         set_predicate_inv(if_inst->predicate, if_inst->predicate_inverse,
+                           bld.emit(BRW_OPCODE_SEL, then_mov->dst,
+                                    src0, else_mov->src[0]));
       }
 
       return true;
@@ -3079,178 +1114,6 @@ fs_visitor::try_replace_with_sel()
    return false;
 }
 
-void
-fs_visitor::visit(ir_if *ir)
-{
-   if (try_opt_frontfacing_ternary(ir))
-      return;
-
-   /* Don't point the annotation at the if statement, because then it plus
-    * the then and else blocks get printed.
-    */
-   this->base_ir = ir->condition;
-
-   if (devinfo->gen == 6) {
-      emit_if_gen6(ir);
-   } else {
-      emit_bool_to_cond_code(ir->condition);
-
-      emit(IF(BRW_PREDICATE_NORMAL));
-   }
-
-   foreach_in_list(ir_instruction, ir_, &ir->then_instructions) {
-      this->base_ir = ir_;
-      ir_->accept(this);
-   }
-
-   if (!ir->else_instructions.is_empty()) {
-      emit(BRW_OPCODE_ELSE);
-
-      foreach_in_list(ir_instruction, ir_, &ir->else_instructions) {
-        this->base_ir = ir_;
-        ir_->accept(this);
-      }
-   }
-
-   emit(BRW_OPCODE_ENDIF);
-
-   if (!try_replace_with_sel() && devinfo->gen < 6) {
-      no16("Can't support (non-uniform) control flow on SIMD16\n");
-   }
-}
-
-void
-fs_visitor::visit(ir_loop *ir)
-{
-   if (devinfo->gen < 6) {
-      no16("Can't support (non-uniform) control flow on SIMD16\n");
-   }
-
-   this->base_ir = NULL;
-   emit(BRW_OPCODE_DO);
-
-   foreach_in_list(ir_instruction, ir_, &ir->body_instructions) {
-      this->base_ir = ir_;
-      ir_->accept(this);
-   }
-
-   this->base_ir = NULL;
-   emit(BRW_OPCODE_WHILE);
-}
-
-void
-fs_visitor::visit(ir_loop_jump *ir)
-{
-   switch (ir->mode) {
-   case ir_loop_jump::jump_break:
-      emit(BRW_OPCODE_BREAK);
-      break;
-   case ir_loop_jump::jump_continue:
-      emit(BRW_OPCODE_CONTINUE);
-      break;
-   }
-}
-
-void
-fs_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
-{
-   ir_dereference *deref = static_cast<ir_dereference *>(
-      ir->actual_parameters.get_head());
-   ir_variable *location = deref->variable_referenced();
-   unsigned surf_index = (stage_prog_data->binding_table.abo_start +
-                          location->data.binding);
-
-   /* Calculate the surface offset */
-   fs_reg offset = vgrf(glsl_type::uint_type);
-   ir_dereference_array *deref_array = deref->as_dereference_array();
-
-   if (deref_array) {
-      deref_array->array_index->accept(this);
-
-      fs_reg tmp = vgrf(glsl_type::uint_type);
-      emit(MUL(tmp, this->result, fs_reg(ATOMIC_COUNTER_SIZE)));
-      emit(ADD(offset, tmp, fs_reg(location->data.atomic.offset)));
-   } else {
-      offset = fs_reg(location->data.atomic.offset);
-   }
-
-   /* Emit the appropriate machine instruction */
-   const char *callee = ir->callee->function_name();
-   ir->return_deref->accept(this);
-   fs_reg dst = this->result;
-
-   if (!strcmp("__intrinsic_atomic_read", callee)) {
-      emit_untyped_surface_read(surf_index, dst, offset);
-
-   } else if (!strcmp("__intrinsic_atomic_increment", callee)) {
-      emit_untyped_atomic(BRW_AOP_INC, surf_index, dst, offset,
-                          fs_reg(), fs_reg());
-
-   } else if (!strcmp("__intrinsic_atomic_predecrement", callee)) {
-      emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dst, offset,
-                          fs_reg(), fs_reg());
-   }
-}
-
-void
-fs_visitor::visit(ir_call *ir)
-{
-   const char *callee = ir->callee->function_name();
-
-   if (!strcmp("__intrinsic_atomic_read", callee) ||
-       !strcmp("__intrinsic_atomic_increment", callee) ||
-       !strcmp("__intrinsic_atomic_predecrement", callee)) {
-      visit_atomic_counter_intrinsic(ir);
-   } else {
-      unreachable("Unsupported intrinsic.");
-   }
-}
-
-void
-fs_visitor::visit(ir_return *)
-{
-   unreachable("FINISHME");
-}
-
-void
-fs_visitor::visit(ir_function *ir)
-{
-   /* Ignore function bodies other than main() -- we shouldn't see calls to
-    * them since they should all be inlined before we get to ir_to_mesa.
-    */
-   if (strcmp(ir->name, "main") == 0) {
-      const ir_function_signature *sig;
-      exec_list empty;
-
-      sig = ir->matching_signature(NULL, &empty, false);
-
-      assert(sig);
-
-      foreach_in_list(ir_instruction, ir_, &sig->body) {
-        this->base_ir = ir_;
-        ir_->accept(this);
-      }
-   }
-}
-
-void
-fs_visitor::visit(ir_function_signature *)
-{
-   unreachable("not reached");
-}
-
-void
-fs_visitor::visit(ir_emit_vertex *)
-{
-   unreachable("not reached");
-}
-
-void
-fs_visitor::visit(ir_end_primitive *)
-{
-   unreachable("not reached");
-}
-
 void
 fs_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
                                 fs_reg dst, fs_reg offset, fs_reg src0,
@@ -3263,17 +1126,16 @@ fs_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
 
    sources[0] = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
    /* Initialize the sample mask in the message header. */
-   emit(MOV(sources[0], fs_reg(0u)))
-      ->force_writemask_all = true;
+   bld.exec_all().MOV(sources[0], fs_reg(0u));
 
    if (stage == MESA_SHADER_FRAGMENT) {
       if (((brw_wm_prog_data*)this->prog_data)->uses_kill) {
-         emit(MOV(component(sources[0], 7), brw_flag_reg(0, 1)))
-            ->force_writemask_all = true;
+         bld.exec_all()
+            .MOV(component(sources[0], 7), brw_flag_reg(0, 1));
       } else {
-         emit(MOV(component(sources[0], 7),
-                  retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD)))
-            ->force_writemask_all = true;
+         bld.exec_all()
+            .MOV(component(sources[0], 7),
+                 retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD));
       }
    } else {
       /* The execution mask is part of the side-band information sent together with
@@ -3282,37 +1144,37 @@ fs_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
        * the atomic operation.
        */
       assert(stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_COMPUTE);
-      emit(MOV(component(sources[0], 7),
-               fs_reg(0xffffu)))->force_writemask_all = true;
+      bld.exec_all()
+         .MOV(component(sources[0], 7), fs_reg(0xffffu));
    }
    length++;
 
    /* Set the atomic operation offset. */
    sources[1] = vgrf(glsl_type::uint_type);
-   emit(MOV(sources[1], offset));
+   bld.MOV(sources[1], offset);
    length++;
 
    /* Set the atomic operation arguments. */
    if (src0.file != BAD_FILE) {
       sources[length] = vgrf(glsl_type::uint_type);
-      emit(MOV(sources[length], src0));
+      bld.MOV(sources[length], src0);
       length++;
    }
 
    if (src1.file != BAD_FILE) {
       sources[length] = vgrf(glsl_type::uint_type);
-      emit(MOV(sources[length], src1));
+      bld.MOV(sources[length], src1);
       length++;
    }
 
    int mlen = 1 + (length - 1) * reg_width;
    fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
                                BRW_REGISTER_TYPE_UD, dispatch_width);
-   emit(LOAD_PAYLOAD(src_payload, sources, length, 1));
+   bld.LOAD_PAYLOAD(src_payload, sources, length, 1);
 
    /* Emit the instruction. */
-   fs_inst *inst = emit(SHADER_OPCODE_UNTYPED_ATOMIC, dst, src_payload,
-                        fs_reg(surf_index), fs_reg(atomic_op));
+   fs_inst *inst = bld.emit(SHADER_OPCODE_UNTYPED_ATOMIC, dst, src_payload,
+                            fs_reg(surf_index), fs_reg(atomic_op));
    inst->mlen = mlen;
 }
 
@@ -3326,17 +1188,17 @@ fs_visitor::emit_untyped_surface_read(unsigned surf_index, fs_reg dst,
 
    sources[0] = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
    /* Initialize the sample mask in the message header. */
-   emit(MOV(sources[0], fs_reg(0u)))
-      ->force_writemask_all = true;
+   bld.exec_all()
+      .MOV(sources[0], fs_reg(0u));
 
    if (stage == MESA_SHADER_FRAGMENT) {
       if (((brw_wm_prog_data*)this->prog_data)->uses_kill) {
-         emit(MOV(component(sources[0], 7), brw_flag_reg(0, 1)))
-            ->force_writemask_all = true;
+         bld.exec_all()
+            .MOV(component(sources[0], 7), brw_flag_reg(0, 1));
       } else {
-         emit(MOV(component(sources[0], 7),
-                  retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD)))
-            ->force_writemask_all = true;
+         bld.exec_all()
+            .MOV(component(sources[0], 7),
+                 retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD));
       }
    } else {
       /* The execution mask is part of the side-band information sent together with
@@ -3345,48 +1207,25 @@ fs_visitor::emit_untyped_surface_read(unsigned surf_index, fs_reg dst,
        * the atomic operation.
        */
       assert(stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_COMPUTE);
-      emit(MOV(component(sources[0], 7),
-               fs_reg(0xffffu)))->force_writemask_all = true;
+      bld.exec_all()
+         .MOV(component(sources[0], 7), fs_reg(0xffffu));
    }
 
    /* Set the surface read offset. */
    sources[1] = vgrf(glsl_type::uint_type);
-   emit(MOV(sources[1], offset));
+   bld.MOV(sources[1], offset);
 
    int mlen = 1 + reg_width;
    fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
                                BRW_REGISTER_TYPE_UD, dispatch_width);
-   fs_inst *inst = emit(LOAD_PAYLOAD(src_payload, sources, 2, 1));
+   fs_inst *inst = bld.LOAD_PAYLOAD(src_payload, sources, 2, 1);
 
    /* Emit the instruction. */
-   inst = emit(SHADER_OPCODE_UNTYPED_SURFACE_READ, dst, src_payload,
-               fs_reg(surf_index), fs_reg(1));
+   inst = bld.emit(SHADER_OPCODE_UNTYPED_SURFACE_READ, dst, src_payload,
+                   fs_reg(surf_index), fs_reg(1));
    inst->mlen = mlen;
 }
 
-fs_inst *
-fs_visitor::emit(fs_inst *inst)
-{
-   if (dispatch_width == 16 && inst->exec_size == 8)
-      inst->force_uncompressed = true;
-
-   inst->annotation = this->current_annotation;
-   inst->ir = this->base_ir;
-
-   this->instructions.push_tail(inst);
-
-   return inst;
-}
-
-void
-fs_visitor::emit(exec_list list)
-{
-   foreach_in_list_safe(fs_inst, inst, &list) {
-      inst->exec_node::remove();
-      emit(inst);
-   }
-}
-
 /** Emits a dummy fragment shader consisting of magenta for bringup purposes. */
 void
 fs_visitor::emit_dummy_fs()
@@ -3396,12 +1235,12 @@ fs_visitor::emit_dummy_fs()
    /* Everyone's favorite color. */
    const float color[4] = { 1.0, 0.0, 1.0, 0.0 };
    for (int i = 0; i < 4; i++) {
-      emit(MOV(fs_reg(MRF, 2 + i * reg_width, BRW_REGISTER_TYPE_F,
-                      dispatch_width), fs_reg(color[i])));
+      bld.MOV(fs_reg(MRF, 2 + i * reg_width, BRW_REGISTER_TYPE_F,
+                     dispatch_width), fs_reg(color[i]));
    }
 
    fs_inst *write;
-   write = emit(FS_OPCODE_FB_WRITE);
+   write = bld.emit(FS_OPCODE_FB_WRITE);
    write->eot = true;
    if (devinfo->gen >= 6) {
       write->base_mrf = 2;
@@ -3454,19 +1293,19 @@ fs_visitor::emit_interpolation_setup_gen4()
 {
    struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
 
-   this->current_annotation = "compute pixel centers";
+   fs_builder abld = bld.annotate("compute pixel centers");
    this->pixel_x = vgrf(glsl_type::uint_type);
    this->pixel_y = vgrf(glsl_type::uint_type);
    this->pixel_x.type = BRW_REGISTER_TYPE_UW;
    this->pixel_y.type = BRW_REGISTER_TYPE_UW;
-   emit(ADD(this->pixel_x,
+   abld.ADD(this->pixel_x,
             fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
-            fs_reg(brw_imm_v(0x10101010))));
-   emit(ADD(this->pixel_y,
+            fs_reg(brw_imm_v(0x10101010)));
+   abld.ADD(this->pixel_y,
             fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
-            fs_reg(brw_imm_v(0x11001100))));
+            fs_reg(brw_imm_v(0x11001100)));
 
-   this->current_annotation = "compute pixel deltas from v0";
+   abld = bld.annotate("compute pixel deltas from v0");
 
    this->delta_xy[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
       vgrf(glsl_type::vec2_type);
@@ -3475,27 +1314,27 @@ fs_visitor::emit_interpolation_setup_gen4()
    const fs_reg ystart(negate(brw_vec1_grf(1, 1)));
 
    if (devinfo->has_pln && dispatch_width == 16) {
-      emit(ADD(half(offset(delta_xy, 0), 0), half(this->pixel_x, 0), xstart));
-      emit(ADD(half(offset(delta_xy, 0), 1), half(this->pixel_y, 0), ystart));
-      emit(ADD(half(offset(delta_xy, 1), 0), half(this->pixel_x, 1), xstart))
-         ->force_sechalf = true;
-      emit(ADD(half(offset(delta_xy, 1), 1), half(this->pixel_y, 1), ystart))
-         ->force_sechalf = true;
+      for (unsigned i = 0; i < 2; i++) {
+         abld.half(i).ADD(half(offset(delta_xy, i), 0),
+                          half(this->pixel_x, i), xstart);
+         abld.half(i).ADD(half(offset(delta_xy, i), 1),
+                          half(this->pixel_y, i), ystart);
+      }
    } else {
-      emit(ADD(offset(delta_xy, 0), this->pixel_x, xstart));
-      emit(ADD(offset(delta_xy, 1), this->pixel_y, ystart));
+      abld.ADD(offset(delta_xy, 0), this->pixel_x, xstart);
+      abld.ADD(offset(delta_xy, 1), this->pixel_y, ystart);
    }
 
-   this->current_annotation = "compute pos.w and 1/pos.w";
+   abld = bld.annotate("compute pos.w and 1/pos.w");
    /* Compute wpos.w.  It's always in our setup, since it's needed to
     * interpolate the other attributes.
     */
    this->wpos_w = vgrf(glsl_type::float_type);
-   emit(FS_OPCODE_LINTERP, wpos_w, delta_xy, interp_reg(VARYING_SLOT_POS, 3));
+   abld.emit(FS_OPCODE_LINTERP, wpos_w, delta_xy,
+             interp_reg(VARYING_SLOT_POS, 3));
    /* Compute the pixel 1/W value from wpos.w. */
    this->pixel_w = vgrf(glsl_type::float_type);
-   emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
-   this->current_annotation = NULL;
+   abld.emit(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
 }
 
 /** Emits the interpolation for the varying inputs. */
@@ -3504,8 +1343,8 @@ fs_visitor::emit_interpolation_setup_gen6()
 {
    struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
 
-   this->current_annotation = "compute pixel centers";
-   if (brw->gen >= 8 || dispatch_width == 8) {
+   fs_builder abld = bld.annotate("compute pixel centers");
+   if (devinfo->gen >= 8 || dispatch_width == 8) {
       /* The "Register Region Restrictions" page says for BDW (and newer,
        * presumably):
        *
@@ -3518,15 +1357,15 @@ fs_visitor::emit_interpolation_setup_gen6()
        */
       fs_reg int_pixel_xy(GRF, alloc.allocate(dispatch_width / 8),
                           BRW_REGISTER_TYPE_UW, dispatch_width * 2);
-      emit(ADD(int_pixel_xy,
+      abld.exec_all()
+          .ADD(int_pixel_xy,
                fs_reg(stride(suboffset(g1_uw, 4), 1, 4, 0)),
-               fs_reg(brw_imm_v(0x11001010))))
-         ->force_writemask_all = true;
+               fs_reg(brw_imm_v(0x11001010)));
 
       this->pixel_x = vgrf(glsl_type::float_type);
       this->pixel_y = vgrf(glsl_type::float_type);
-      emit(FS_OPCODE_PIXEL_X, this->pixel_x, int_pixel_xy);
-      emit(FS_OPCODE_PIXEL_Y, this->pixel_y, int_pixel_xy);
+      abld.emit(FS_OPCODE_PIXEL_X, this->pixel_x, int_pixel_xy);
+      abld.emit(FS_OPCODE_PIXEL_Y, this->pixel_y, int_pixel_xy);
    } else {
       /* The "Register Region Restrictions" page says for SNB, IVB, HSW:
        *
@@ -3540,12 +1379,12 @@ fs_visitor::emit_interpolation_setup_gen6()
       fs_reg int_pixel_y = vgrf(glsl_type::uint_type);
       int_pixel_x.type = BRW_REGISTER_TYPE_UW;
       int_pixel_y.type = BRW_REGISTER_TYPE_UW;
-      emit(ADD(int_pixel_x,
+      abld.ADD(int_pixel_x,
                fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
-               fs_reg(brw_imm_v(0x10101010))));
-      emit(ADD(int_pixel_y,
+               fs_reg(brw_imm_v(0x10101010)));
+      abld.ADD(int_pixel_y,
                fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
-               fs_reg(brw_imm_v(0x11001100))));
+               fs_reg(brw_imm_v(0x11001100)));
 
       /* As of gen6, we can no longer mix float and int sources.  We have
        * to turn the integer pixel centers into floats for their actual
@@ -3553,21 +1392,19 @@ fs_visitor::emit_interpolation_setup_gen6()
        */
       this->pixel_x = vgrf(glsl_type::float_type);
       this->pixel_y = vgrf(glsl_type::float_type);
-      emit(MOV(this->pixel_x, int_pixel_x));
-      emit(MOV(this->pixel_y, int_pixel_y));
+      abld.MOV(this->pixel_x, int_pixel_x);
+      abld.MOV(this->pixel_y, int_pixel_y);
    }
 
-   this->current_annotation = "compute pos.w";
+   abld = bld.annotate("compute pos.w");
    this->pixel_w = fs_reg(brw_vec8_grf(payload.source_w_reg, 0));
    this->wpos_w = vgrf(glsl_type::float_type);
-   emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w);
+   abld.emit(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w);
 
    for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) {
       uint8_t reg = payload.barycentric_coord_reg[i];
       this->delta_xy[i] = fs_reg(brw_vec16_grf(reg, 0));
    }
-
-   this->current_annotation = NULL;
 }
 
 void
@@ -3581,7 +1418,7 @@ fs_visitor::setup_color_payload(fs_reg *dst, fs_reg color, unsigned components,
       fs_reg tmp = vgrf(glsl_type::vec4_type);
       assert(color.type == BRW_REGISTER_TYPE_F);
       for (unsigned i = 0; i < components; i++) {
-         inst = emit(MOV(offset(tmp, i), offset(color, i)));
+         inst = bld.MOV(offset(tmp, i), offset(color, i));
          inst->saturate = true;
       }
       color = tmp;
@@ -3627,7 +1464,7 @@ fs_visitor::emit_alpha_test()
 {
    assert(stage == MESA_SHADER_FRAGMENT);
    brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
-   this->current_annotation = "Alpha test";
+   const fs_builder abld = bld.annotate("Alpha test");
 
    fs_inst *cmp;
    if (key->alpha_test_func == GL_ALWAYS)
@@ -3637,30 +1474,29 @@ fs_visitor::emit_alpha_test()
       /* f0.1 = 0 */
       fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
                                       BRW_REGISTER_TYPE_UW));
-      cmp = emit(CMP(reg_null_f, some_reg, some_reg,
-                     BRW_CONDITIONAL_NEQ));
+      cmp = abld.CMP(bld.null_reg_f(), some_reg, some_reg,
+                     BRW_CONDITIONAL_NEQ);
    } else {
       /* RT0 alpha */
       fs_reg color = offset(outputs[0], 3);
 
       /* f0.1 &= func(color, ref) */
-      cmp = emit(CMP(reg_null_f, color, fs_reg(key->alpha_test_ref),
-                     cond_for_alpha_func(key->alpha_test_func)));
+      cmp = abld.CMP(bld.null_reg_f(), color, fs_reg(key->alpha_test_ref),
+                     cond_for_alpha_func(key->alpha_test_func));
    }
    cmp->predicate = BRW_PREDICATE_NORMAL;
    cmp->flag_subreg = 1;
 }
 
 fs_inst *
-fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
+fs_visitor::emit_single_fb_write(const fs_builder &bld,
+                                 fs_reg color0, fs_reg color1,
                                  fs_reg src0_alpha, unsigned components,
                                  unsigned exec_size, bool use_2nd_half)
 {
    assert(stage == MESA_SHADER_FRAGMENT);
    brw_wm_prog_data *prog_data = (brw_wm_prog_data*) this->prog_data;
    brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
-
-   this->current_annotation = "FB write header";
    int header_size = 2, payload_header_size;
 
    /* We can potentially have a message length of up to 15, so we have to set
@@ -3691,22 +1527,23 @@ fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
 
    if (payload.aa_dest_stencil_reg) {
       sources[length] = fs_reg(GRF, alloc.allocate(1));
-      emit(MOV(sources[length],
-               fs_reg(brw_vec8_grf(payload.aa_dest_stencil_reg, 0))));
+      bld.exec_all().annotate("FB write stencil/AA alpha")
+         .MOV(sources[length],
+              fs_reg(brw_vec8_grf(payload.aa_dest_stencil_reg, 0)));
       length++;
    }
 
    prog_data->uses_omask =
       prog->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
    if (prog_data->uses_omask) {
-      this->current_annotation = "FB write oMask";
       assert(this->sample_mask.file != BAD_FILE);
       /* Hand over gl_SampleMask. Only lower 16 bits are relevant.  Since
        * it's unsinged single words, one vgrf is always 16-wide.
        */
       sources[length] = fs_reg(GRF, alloc.allocate(1),
                                BRW_REGISTER_TYPE_UW, 16);
-      emit(FS_OPCODE_SET_OMASK, sources[length], this->sample_mask);
+      bld.exec_all().annotate("FB write oMask")
+         .emit(FS_OPCODE_SET_OMASK, sources[length], this->sample_mask);
       length++;
    }
 
@@ -3752,7 +1589,11 @@ fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
       if (prog->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
         /* Hand over gl_FragDepth. */
         assert(this->frag_depth.file != BAD_FILE);
-         sources[length] = this->frag_depth;
+         if (exec_size < dispatch_width) {
+            sources[length] = half(this->frag_depth, use_2nd_half);
+         } else {
+            sources[length] = this->frag_depth;
+         }
       } else {
         /* Pass through the payload depth. */
          sources[length] = fs_reg(brw_vec8_grf(payload.source_depth_reg, 0));
@@ -3763,28 +1604,29 @@ fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
    if (payload.dest_depth_reg)
       sources[length++] = fs_reg(brw_vec8_grf(payload.dest_depth_reg, 0));
 
+   const fs_builder ubld = bld.group(exec_size, use_2nd_half);
    fs_inst *load;
    fs_inst *write;
    if (devinfo->gen >= 7) {
       /* Send from the GRF */
       fs_reg payload = fs_reg(GRF, -1, BRW_REGISTER_TYPE_F, exec_size);
-      load = emit(LOAD_PAYLOAD(payload, sources, length, payload_header_size));
+      load = ubld.LOAD_PAYLOAD(payload, sources, length, payload_header_size);
       payload.reg = alloc.allocate(load->regs_written);
       load->dst = payload;
-      write = emit(FS_OPCODE_FB_WRITE, reg_undef, payload);
+      write = ubld.emit(FS_OPCODE_FB_WRITE, reg_undef, payload);
       write->base_mrf = -1;
    } else {
       /* Send from the MRF */
-      load = emit(LOAD_PAYLOAD(fs_reg(MRF, 1, BRW_REGISTER_TYPE_F, exec_size),
-                               sources, length, payload_header_size));
+      load = ubld.LOAD_PAYLOAD(fs_reg(MRF, 1, BRW_REGISTER_TYPE_F, exec_size),
+                               sources, length, payload_header_size);
 
       /* On pre-SNB, we have to interlace the color values.  LOAD_PAYLOAD
        * will do this for us if we just give it a COMPR4 destination.
        */
-      if (brw->gen < 6 && exec_size == 16)
+      if (devinfo->gen < 6 && exec_size == 16)
          load->dst.reg |= BRW_MRF_COMPR4;
 
-      write = emit(FS_OPCODE_FB_WRITE);
+      write = ubld.emit(FS_OPCODE_FB_WRITE);
       write->exec_size = exec_size;
       write->base_mrf = 1;
    }
@@ -3807,10 +1649,10 @@ fs_visitor::emit_fb_writes()
 
    fs_inst *inst = NULL;
    if (do_dual_src) {
-      this->current_annotation = ralloc_asprintf(this->mem_ctx,
-                                                "FB dual-source write");
-      inst = emit_single_fb_write(this->outputs[0], this->dual_src_output,
-                                  reg_undef, 4, 8);
+      const fs_builder abld = bld.annotate("FB dual-source write");
+
+      inst = emit_single_fb_write(abld, this->outputs[0],
+                                  this->dual_src_output, reg_undef, 4, 8);
       inst->target = 0;
 
       /* SIMD16 dual source blending requires to send two SIMD8 dual source
@@ -3831,8 +1673,9 @@ fs_visitor::emit_fb_writes()
        * m + 3: a1
        */
       if (dispatch_width == 16) {
-         inst = emit_single_fb_write(this->outputs[0], this->dual_src_output,
-                                     reg_undef, 4, 8, true);
+         inst = emit_single_fb_write(abld, this->outputs[0],
+                                     this->dual_src_output, reg_undef, 4, 8,
+                                     true);
          inst->target = 0;
       }
 
@@ -3843,14 +1686,14 @@ fs_visitor::emit_fb_writes()
          if (this->outputs[target].file == BAD_FILE)
             continue;
 
-         this->current_annotation = ralloc_asprintf(this->mem_ctx,
-                                                    "FB write target %d",
-                                                    target);
+         const fs_builder abld = bld.annotate(
+            ralloc_asprintf(this->mem_ctx, "FB write target %d", target));
+
          fs_reg src0_alpha;
          if (devinfo->gen >= 6 && key->replicate_alpha && target != 0)
             src0_alpha = offset(outputs[0], 3);
 
-         inst = emit_single_fb_write(this->outputs[target], reg_undef,
+         inst = emit_single_fb_write(abld, this->outputs[target], reg_undef,
                                      src0_alpha,
                                      this->output_components[target],
                                      dispatch_width);
@@ -3863,19 +1706,17 @@ fs_visitor::emit_fb_writes()
        * alpha out the pipeline to our null renderbuffer to support
        * alpha-testing, alpha-to-coverage, and so on.
        */
-      inst = emit_single_fb_write(reg_undef, reg_undef, reg_undef, 0,
+      inst = emit_single_fb_write(bld, reg_undef, reg_undef, reg_undef, 0,
                                   dispatch_width);
       inst->target = 0;
    }
 
    inst->eot = true;
-   this->current_annotation = NULL;
 }
 
 void
-fs_visitor::setup_uniform_clipplane_values()
+fs_visitor::setup_uniform_clipplane_values(gl_clip_plane *clip_planes)
 {
-   gl_clip_plane *clip_planes = brw_select_clip_planes(ctx);
    const struct brw_vue_prog_key *key =
       (const struct brw_vue_prog_key *) this->key;
 
@@ -3889,7 +1730,7 @@ fs_visitor::setup_uniform_clipplane_values()
    }
 }
 
-void fs_visitor::compute_clip_distance()
+void fs_visitor::compute_clip_distance(gl_clip_plane *clip_planes)
 {
    struct brw_vue_prog_data *vue_prog_data =
       (struct brw_vue_prog_data *) prog_data;
@@ -3918,9 +1759,9 @@ void fs_visitor::compute_clip_distance()
    if (outputs[clip_vertex].file == BAD_FILE)
       return;
 
-   setup_uniform_clipplane_values();
+   setup_uniform_clipplane_values(clip_planes);
 
-   current_annotation = "user clip distances";
+   const fs_builder abld = bld.annotate("user clip distances");
 
    this->outputs[VARYING_SLOT_CLIP_DIST0] = vgrf(glsl_type::vec4_type);
    this->outputs[VARYING_SLOT_CLIP_DIST1] = vgrf(glsl_type::vec4_type);
@@ -3930,16 +1771,16 @@ void fs_visitor::compute_clip_distance()
       fs_reg output = outputs[VARYING_SLOT_CLIP_DIST0 + i / 4];
       output.reg_offset = i & 3;
 
-      emit(MUL(output, outputs[clip_vertex], u));
+      abld.MUL(output, outputs[clip_vertex], u);
       for (int j = 1; j < 4; j++) {
          u.reg = userplane[i].reg + j;
-         emit(MAD(output, output, offset(outputs[clip_vertex], j), u));
+         abld.MAD(output, output, offset(outputs[clip_vertex], j), u);
       }
    }
 }
 
 void
-fs_visitor::emit_urb_writes()
+fs_visitor::emit_urb_writes(gl_clip_plane *clip_planes)
 {
    int slot, urb_offset, length;
    struct brw_vs_prog_data *vs_prog_data =
@@ -3954,18 +1795,17 @@ fs_visitor::emit_urb_writes()
 
    /* Lower legacy ff and ClipVertex clipping to clip distances */
    if (key->base.userclip_active && !prog->UsesClipDistanceOut)
-      compute_clip_distance();
+      compute_clip_distance(clip_planes);
 
    /* If we don't have any valid slots to write, just do a minimal urb write
     * send to terminate the shader. */
    if (vue_map->slots_valid == 0) {
 
       fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-      fs_inst *inst = emit(MOV(payload, fs_reg(retype(brw_vec8_grf(1, 0),
-                                                      BRW_REGISTER_TYPE_UD))));
-      inst->force_writemask_all = true;
+      bld.exec_all().MOV(payload, fs_reg(retype(brw_vec8_grf(1, 0),
+                                                BRW_REGISTER_TYPE_UD)));
 
-      inst = emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
+      fs_inst *inst = bld.emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
       inst->eot = true;
       inst->mlen = 1;
       inst->offset = 1;
@@ -3994,7 +1834,7 @@ fs_visitor::emit_urb_writes()
          }
 
          zero = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-         emit(MOV(zero, fs_reg(0u)));
+         bld.MOV(zero, fs_reg(0u));
 
          sources[length++] = zero;
          if (vue_map->slots_valid & VARYING_BIT_LAYER)
@@ -4049,8 +1889,7 @@ fs_visitor::emit_urb_writes()
             for (int i = 0; i < 4; i++) {
                reg = fs_reg(GRF, alloc.allocate(1), outputs[varying].type);
                src = offset(this->outputs[varying], i);
-               fs_inst *inst = emit(MOV(reg, src));
-               inst->saturate = true;
+               set_saturate(true, bld.MOV(reg, src));
                sources[length++] = reg;
             }
          } else {
@@ -4060,7 +1899,7 @@ fs_visitor::emit_urb_writes()
          break;
       }
 
-      current_annotation = "URB write";
+      const fs_builder abld = bld.annotate("URB write");
 
       /* If we've queued up 8 registers of payload (2 VUE slots), if this is
        * the last slot or if we need to flush (see BAD_FILE varying case
@@ -4073,22 +1912,14 @@ fs_visitor::emit_urb_writes()
          fs_reg *payload_sources = ralloc_array(mem_ctx, fs_reg, length + 1);
          fs_reg payload = fs_reg(GRF, alloc.allocate(length + 1),
                                  BRW_REGISTER_TYPE_F, dispatch_width);
-
-         /* We need WE_all on the MOV for the message header (the URB handles)
-          * so do a MOV to a dummy register and set force_writemask_all on the
-          * MOV.  LOAD_PAYLOAD will preserve that.
-          */
-         fs_reg dummy = fs_reg(GRF, alloc.allocate(1),
-                               BRW_REGISTER_TYPE_UD);
-         fs_inst *inst = emit(MOV(dummy, fs_reg(retype(brw_vec8_grf(1, 0),
-                                                       BRW_REGISTER_TYPE_UD))));
-         inst->force_writemask_all = true;
-         payload_sources[0] = dummy;
+         payload_sources[0] =
+            fs_reg(retype(brw_vec8_grf(1, 0), BRW_REGISTER_TYPE_UD));
 
          memcpy(&payload_sources[1], sources, length * sizeof sources[0]);
-         emit(LOAD_PAYLOAD(payload, payload_sources, length + 1, 1));
+         abld.LOAD_PAYLOAD(payload, payload_sources, length + 1, 1);
 
-         inst = emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
+         fs_inst *inst =
+            abld.emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
          inst->eot = last;
          inst->mlen = length + 1;
          inst->offset = urb_offset;
@@ -4099,22 +1930,10 @@ fs_visitor::emit_urb_writes()
    }
 }
 
-void
-fs_visitor::resolve_ud_negate(fs_reg *reg)
-{
-   if (reg->type != BRW_REGISTER_TYPE_UD ||
-       !reg->negate)
-      return;
-
-   fs_reg temp = vgrf(glsl_type::uint_type);
-   emit(MOV(temp, *reg));
-   *reg = temp;
-}
-
 void
 fs_visitor::emit_cs_terminate()
 {
-   assert(brw->gen >= 7);
+   assert(devinfo->gen >= 7);
 
    /* We are getting the thread ID from the compute shader header */
    assert(stage == MESA_SHADER_COMPUTE);
@@ -4125,94 +1944,53 @@ fs_visitor::emit_cs_terminate()
     */
    struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD);
    fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-   fs_inst *inst = emit(MOV(payload, g0));
-   inst->force_writemask_all = true;
+   bld.exec_all().MOV(payload, g0);
 
    /* Send a message to the thread spawner to terminate the thread. */
-   inst = emit(CS_OPCODE_CS_TERMINATE, reg_undef, payload);
+   fs_inst *inst = bld.exec_all()
+                      .emit(CS_OPCODE_CS_TERMINATE, reg_undef, payload);
    inst->eot = true;
 }
 
-/**
- * Resolve the result of a Gen4-5 CMP instruction to a proper boolean.
- *
- * CMP on Gen4-5 only sets the LSB of the result; the rest are undefined.
- * If we need a proper boolean value, we have to fix it up to be 0 or ~0.
- */
 void
-fs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg)
+fs_visitor::emit_barrier()
 {
-   assert(devinfo->gen <= 5);
+   assert(devinfo->gen >= 7);
 
-   if (rvalue->type != glsl_type::bool_type)
-      return;
+   /* We are getting the barrier ID from the compute shader header */
+   assert(stage == MESA_SHADER_COMPUTE);
 
-   fs_reg and_result = vgrf(glsl_type::bool_type);
-   fs_reg neg_result = vgrf(glsl_type::bool_type);
-   emit(AND(and_result, *reg, fs_reg(1)));
-   emit(MOV(neg_result, negate(and_result)));
-   *reg = neg_result;
-}
+   fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
 
-fs_visitor::fs_visitor(struct brw_context *brw,
-                       void *mem_ctx,
-                       const struct brw_wm_prog_key *key,
-                       struct brw_wm_prog_data *prog_data,
-                       struct gl_shader_program *shader_prog,
-                       struct gl_fragment_program *fp,
-                       unsigned dispatch_width)
-   : backend_visitor(brw, shader_prog, &fp->Base, &prog_data->base,
-                     MESA_SHADER_FRAGMENT),
-     reg_null_f(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_F)),
-     reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
-     reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
-     key(key), prog_data(&prog_data->base),
-     dispatch_width(dispatch_width), promoted_constants(0)
-{
-   this->mem_ctx = mem_ctx;
-   init();
-}
+   /* Clear the message payload */
+   bld.exec_all().MOV(payload, fs_reg(0u));
 
-fs_visitor::fs_visitor(struct brw_context *brw,
-                       void *mem_ctx,
-                       const struct brw_vs_prog_key *key,
-                       struct brw_vs_prog_data *prog_data,
-                       struct gl_shader_program *shader_prog,
-                       struct gl_vertex_program *cp,
-                       unsigned dispatch_width)
-   : backend_visitor(brw, shader_prog, &cp->Base, &prog_data->base.base,
-                     MESA_SHADER_VERTEX),
-     reg_null_f(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_F)),
-     reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
-     reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
-     key(key), prog_data(&prog_data->base.base),
-     dispatch_width(dispatch_width), promoted_constants(0)
-{
-   this->mem_ctx = mem_ctx;
-   init();
+   /* Copy bits 27:24 of r0.2 (barrier id) to the message payload reg.2 */
+   fs_reg r0_2 = fs_reg(retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_UD));
+   bld.exec_all().AND(component(payload, 2), r0_2, fs_reg(0x0f000000u));
+
+   /* Emit a gateway "barrier" message using the payload we set up, followed
+    * by a wait instruction.
+    */
+   bld.exec_all().emit(SHADER_OPCODE_BARRIER, reg_undef, payload);
 }
 
-fs_visitor::fs_visitor(struct brw_context *brw,
+fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data,
                        void *mem_ctx,
-                       const struct brw_cs_prog_key *key,
-                       struct brw_cs_prog_data *prog_data,
+                       gl_shader_stage stage,
+                       const void *key,
+                       struct brw_stage_prog_data *prog_data,
                        struct gl_shader_program *shader_prog,
-                       struct gl_compute_program *cp,
-                       unsigned dispatch_width)
-   : backend_visitor(brw, shader_prog, &cp->Base, &prog_data->base,
-                     MESA_SHADER_COMPUTE),
-     reg_null_f(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_F)),
-     reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
-     reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
-     key(key), prog_data(&prog_data->base),
-     dispatch_width(dispatch_width)
-{
-   this->mem_ctx = mem_ctx;
-   init();
-}
-
-void
-fs_visitor::init()
+                       struct gl_program *prog,
+                       unsigned dispatch_width,
+                       int shader_time_index)
+   : backend_shader(compiler, log_data, mem_ctx,
+                    shader_prog, prog, prog_data, stage),
+     key(key), prog_data(prog_data),
+     dispatch_width(dispatch_width),
+     shader_time_index(shader_time_index),
+     promoted_constants(0),
+     bld(fs_builder(this, dispatch_width).at_end())
 {
    switch (stage) {
    case MESA_SHADER_FRAGMENT:
@@ -4232,9 +2010,6 @@ fs_visitor::init()
    this->failed = false;
    this->simd16_unsupported = false;
    this->no16_msg = NULL;
-   this->variable_ht = hash_table_ctor(0,
-                                       hash_table_pointer_hash,
-                                       hash_table_pointer_compare);
 
    this->nir_locals = NULL;
    this->nir_globals = NULL;
@@ -4247,9 +2022,6 @@ fs_visitor::init()
    this->first_non_payload_grf = 0;
    this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
 
-   this->current_annotation = NULL;
-   this->base_ir = NULL;
-
    this->virtual_grf_start = NULL;
    this->virtual_grf_end = NULL;
    this->live_intervals = NULL;
@@ -4269,5 +2041,4 @@ fs_visitor::init()
 
 fs_visitor::~fs_visitor()
 {
-   hash_table_dtor(this->variable_ht);
 }
index a323e4d903198c4acb03360fddf8e1d8410981cd..0b8bfc3d9bdd6a79ff48289784baad84908a50ec 100644 (file)
@@ -47,11 +47,12 @@ brw_upload_gs_pull_constants(struct brw_context *brw)
       return;
 
    /* BRW_NEW_GS_PROG_DATA */
-   const struct brw_stage_prog_data *prog_data = &brw->gs.prog_data->base.base;
+   const struct brw_vue_prog_data *prog_data = &brw->gs.prog_data->base;
+   const bool dword_pitch = prog_data->dispatch_mode == DISPATCH_MODE_SIMD8;
 
    /* _NEW_PROGRAM_CONSTANTS */
    brw_upload_pull_constants(brw, BRW_NEW_GS_CONSTBUF, &gp->program.Base,
-                             stage_state, prog_data, false);
+                             stage_state, &prog_data->base, dword_pitch);
 }
 
 const struct brw_tracked_state brw_gs_pull_constants = {
@@ -77,8 +78,11 @@ brw_upload_gs_ubo_surfaces(struct brw_context *brw)
       return;
 
    /* BRW_NEW_GS_PROG_DATA */
+   struct brw_vue_prog_data *prog_data = &brw->gs.prog_data->base;
+   bool dword_pitch = prog_data->dispatch_mode == DISPATCH_MODE_SIMD8;
+
    brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
-                          &brw->gs.base, &brw->gs.prog_data->base.base, false);
+                          &brw->gs.base, &prog_data->base, dword_pitch);
 }
 
 const struct brw_tracked_state brw_gs_ubo_surfaces = {
index e347c51834829fa9b36561594a031464bba458f3..7a8c210118cd3066dc8fe4fdfe97729882478785 100644 (file)
@@ -322,6 +322,9 @@ FJ(gen4_jump_count, 111,  96, devinfo->gen < 6)
 FC(gen4_pop_count,  115, 112, devinfo->gen < 6)
 /** @} */
 
+/* Message descriptor bits */
+#define MD(x) ((x) + 96)
+
 /**
  * Fields for SEND messages:
  *  @{
@@ -347,6 +350,7 @@ FF(header_present,
    /* 6:   */ 115, 115,
    /* 7:   */ 115, 115,
    /* 8:   */ 115, 115)
+F(gateway_notify, MD(16), MD(15))
 FF(function_control,
    /* 4:   */ 111,  96,
    /* 4.5: */ 111,  96,
@@ -354,6 +358,13 @@ FF(function_control,
    /* 6:   */ 114,  96,
    /* 7:   */ 114,  96,
    /* 8:   */ 114,  96)
+FF(gateway_subfuncid,
+   /* 4:   */ MD(1), MD(0),
+   /* 4.5: */ MD(1), MD(0),
+   /* 5:   */ MD(1), MD(0), /* 2:0, but bit 2 is reserved MBZ */
+   /* 6:   */ MD(2), MD(0),
+   /* 7:   */ MD(2), MD(0),
+   /* 8:   */ MD(2), MD(0))
 FF(sfid,
    /* 4:   */ 123, 120, /* called msg_target */
    /* 4.5  */ 123, 120,
@@ -364,9 +375,6 @@ FF(sfid,
 FC(base_mrf,   27,  24, devinfo->gen < 6);
 /** @} */
 
-/* Message descriptor bits */
-#define MD(x) (x + 96)
-
 /**
  * URB message function control bits:
  *  @{
index f3dfe790f348e53b6a4ce293c02dcb1a7f3543f1..96dc20da3cf13a94442a3b7fea0ee083484ef171 100644 (file)
@@ -131,14 +131,15 @@ horiz_offset(fs_reg reg, unsigned delta)
 static inline fs_reg
 offset(fs_reg reg, unsigned delta)
 {
-   assert(reg.stride > 0);
    switch (reg.file) {
    case BAD_FILE:
       break;
    case GRF:
    case MRF:
    case ATTR:
-      return byte_offset(reg, delta * reg.width * reg.stride * type_sz(reg.type));
+      return byte_offset(reg,
+                         delta * MAX2(reg.width * reg.stride, 1) *
+                         type_sz(reg.type));
    case UNIFORM:
       reg.reg_offset += delta;
       break;
@@ -155,6 +156,7 @@ component(fs_reg reg, unsigned idx)
    assert(idx < reg.width);
    reg.subreg_offset = idx * type_sz(reg.type);
    reg.width = 1;
+   reg.stride = 0;
    return reg;
 }
 
@@ -254,9 +256,62 @@ public:
    uint8_t exec_size;
 
    bool eot:1;
-   bool force_uncompressed:1;
    bool force_sechalf:1;
    bool pi_noperspective:1;   /**< Pixel interpolator noperspective flag */
 };
 
+/**
+ * Set second-half quarter control on \p inst.
+ */
+static inline fs_inst *
+set_sechalf(fs_inst *inst)
+{
+   inst->force_sechalf = true;
+   return inst;
+}
+
+/**
+ * Make the execution of \p inst dependent on the evaluation of a possibly
+ * inverted predicate.
+ */
+static inline fs_inst *
+set_predicate_inv(enum brw_predicate pred, bool inverse,
+                  fs_inst *inst)
+{
+   inst->predicate = pred;
+   inst->predicate_inverse = inverse;
+   return inst;
+}
+
+/**
+ * Make the execution of \p inst dependent on the evaluation of a predicate.
+ */
+static inline fs_inst *
+set_predicate(enum brw_predicate pred, fs_inst *inst)
+{
+   return set_predicate_inv(pred, false, inst);
+}
+
+/**
+ * Write the result of evaluating the condition given by \p mod to a flag
+ * register.
+ */
+static inline fs_inst *
+set_condmod(enum brw_conditional_mod mod, fs_inst *inst)
+{
+   inst->conditional_mod = mod;
+   return inst;
+}
+
+/**
+ * Clamp the result of \p inst to the saturation range of its destination
+ * datatype.
+ */
+static inline fs_inst *
+set_saturate(bool saturate, fs_inst *inst)
+{
+   inst->saturate = saturate;
+   return inst;
+}
+
 #endif
index a56fdd6fce91fe40eac242612b9c6b328d252f36..fceacae0e5141bc6c5525df6e3b3ddb85e90acef 100644 (file)
@@ -190,6 +190,50 @@ public:
    }
 };
 
+/**
+ * Make the execution of \p inst dependent on the evaluation of a possibly
+ * inverted predicate.
+ */
+inline vec4_instruction *
+set_predicate_inv(enum brw_predicate pred, bool inverse,
+                  vec4_instruction *inst)
+{
+   inst->predicate = pred;
+   inst->predicate_inverse = inverse;
+   return inst;
+}
+
+/**
+ * Make the execution of \p inst dependent on the evaluation of a predicate.
+ */
+inline vec4_instruction *
+set_predicate(enum brw_predicate pred, vec4_instruction *inst)
+{
+   return set_predicate_inv(pred, false, inst);
+}
+
+/**
+ * Write the result of evaluating the condition given by \p mod to a flag
+ * register.
+ */
+inline vec4_instruction *
+set_condmod(enum brw_conditional_mod mod, vec4_instruction *inst)
+{
+   inst->conditional_mod = mod;
+   return inst;
+}
+
+/**
+ * Clamp the result of \p inst to the saturation range of its destination
+ * datatype.
+ */
+inline vec4_instruction *
+set_saturate(bool saturate, vec4_instruction *inst)
+{
+   inst->saturate = saturate;
+   return inst;
+}
+
 } /* namespace brw */
 
 #endif
index 0424003ffd504948cb6bbacb30d9ab961130ce36..7a5f9834423e86b114c89d06e24269d00c65546e 100644 (file)
@@ -89,19 +89,18 @@ txs_type(const glsl_type *type)
 ir_visitor_status
 lower_texture_grad_visitor::visit_leave(ir_texture *ir)
 {
-   /* Only lower textureGrad with shadow samplers */
-   if (ir->op != ir_txd || !ir->shadow_comparitor)
+   /* Only lower textureGrad with cube maps or shadow samplers */
+   if (ir->op != ir_txd ||
+      (ir->sampler->type->sampler_dimensionality != GLSL_SAMPLER_DIM_CUBE &&
+       !ir->shadow_comparitor))
       return visit_continue;
 
-   /* Lower textureGrad() with samplerCubeShadow even if we have the sample_d_c
+   /* Lower textureGrad() with samplerCube* even if we have the sample_d_c
     * message.  GLSL provides gradients for the 'r' coordinate.  Unfortunately:
     *
     * From the Ivybridge PRM, Volume 4, Part 1, sample_d message description:
     * "The r coordinate contains the faceid, and the r gradients are ignored
     *  by hardware."
-    *
-    * We likely need to do a similar treatment for samplerCube and
-    * samplerCubeArray, but we have insufficient testing for that at the moment.
     */
    bool need_lowering = !has_sample_d_c ||
       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE;
@@ -155,9 +154,20 @@ lower_texture_grad_visitor::visit_leave(ir_texture *ir)
                               expr(ir_unop_sqrt, dot(dPdy, dPdy)));
    }
 
-   /* lambda_base = log2(rho).  We're ignoring GL state biases for now. */
+   /* lambda_base = log2(rho).  We're ignoring GL state biases for now.
+    *
+    * For cube maps the result of these formulas is giving us a value of rho
+    * that is twice the value we should use, so divide it by 2 or,
+    * alternatively, remove one unit from the result of the log2 computation.
+    */
    ir->op = ir_txl;
-   ir->lod_info.lod = expr(ir_unop_log2, rho);
+   if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
+      ir->lod_info.lod = expr(ir_binop_add,
+                              expr(ir_unop_log2, rho),
+                              new(mem_ctx) ir_constant(-1.0f));
+   } else {
+      ir->lod_info.lod = expr(ir_unop_log2, rho);
+   }
 
    progress = true;
    return visit_continue;
index 06916e28cbdef683881168bc07ecc0c9791db890..49f2e3e498cecb55d6986babfbc01948ba391cb3 100644 (file)
@@ -339,8 +339,13 @@ is_color_fast_clear_compatible(struct brw_context *brw,
                                mesa_format format,
                                const union gl_color_union *color)
 {
-   if (_mesa_is_format_integer_color(format))
+   if (_mesa_is_format_integer_color(format)) {
+      if (brw->gen >= 8) {
+         perf_debug("Integer fast clear not enabled for (%s)",
+                    _mesa_get_format_name(format));
+      }
       return false;
+   }
 
    for (int i = 0; i < 4; i++) {
       if (color->f[i] != 0.0 && color->f[i] != 1.0 &&
@@ -466,7 +471,8 @@ brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb,
        *      linear (untiled) memory is UNDEFINED."
        */
       if (irb->mt->tiling == I915_TILING_NONE) {
-         perf_debug("falling back to plain clear because buffers are untiled\n");
+         perf_debug("Falling back to plain clear because %dx%d buffer is untiled\n",
+                    irb->mt->logical_width0, irb->mt->logical_height0);
          clear_type = PLAIN_CLEAR;
       }
 
@@ -477,7 +483,8 @@ brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       for (int i = 0; i < 4; i++) {
          if (_mesa_format_has_color_component(irb->mt->format, i) &&
              !color_mask[i]) {
-            perf_debug("falling back to plain clear because of color mask\n");
+            perf_debug("Falling back to plain clear on %dx%d buffer because of color mask\n",
+                       irb->mt->logical_width0, irb->mt->logical_height0);
             clear_type = PLAIN_CLEAR;
          }
       }
index fc7018d15b9cfcefea78af02b66b166fd1325668..d079197a2a952a667edac6b1ce17835164c1241c 100644 (file)
@@ -414,6 +414,12 @@ brw_meta_stencil_blit(struct brw_context *brw,
    GLenum target;
 
    _mesa_meta_fb_tex_blit_begin(ctx, &blit);
+   /* XXX: Pretend to support stencil textures so _mesa_base_tex_format()
+    * returns a valid format.  When we properly support the extension, we
+    * should remove this.
+    */
+   assert(ctx->Extensions.ARB_texture_stencil8 == false);
+   ctx->Extensions.ARB_texture_stencil8 = true;
 
    _mesa_GenFramebuffers(1, &fbo);
    /* Force the surface to be configured for level zero. */
@@ -451,6 +457,7 @@ brw_meta_stencil_blit(struct brw_context *brw,
    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 error:
+   ctx->Extensions.ARB_texture_stencil8 = false;
    _mesa_meta_fb_tex_blit_end(ctx, target, &blit);
    _mesa_meta_end(ctx);
 
index 67a693b5ec16b755dd9d4d34fbe5b69ab9380cde..5a4515b582dbe14ec2fb84186b76ed4dbaa7d32f 100644 (file)
@@ -39,6 +39,7 @@
 #include "brw_state.h"
 #include "brw_defines.h"
 
+#include "main/framebuffer.h"
 #include "main/fbobject.h"
 #include "main/glformats.h"
 
 static void upload_drawing_rect(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
+   const struct gl_framebuffer *fb = ctx->DrawBuffer;
+   const unsigned int fb_width = _mesa_geometric_width(fb);
+   const unsigned int fb_height = _mesa_geometric_height(fb);
 
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2));
    OUT_BATCH(0); /* xmin, ymin */
-   OUT_BATCH(((ctx->DrawBuffer->Width - 1) & 0xffff) |
-           ((ctx->DrawBuffer->Height - 1) << 16));
+   OUT_BATCH(((fb_width - 1) & 0xffff) | ((fb_height - 1) << 16));
    OUT_BATCH(0);
    ADVANCE_BATCH();
 }
@@ -767,7 +770,7 @@ static void upload_polygon_stipple_offset(struct brw_context *brw)
     * works just fine, and there's no window system to worry about.
     */
    if (_mesa_is_winsys_fbo(ctx->DrawBuffer))
-      OUT_BATCH((32 - (ctx->DrawBuffer->Height & 31)) & 31);
+      OUT_BATCH((32 - (_mesa_geometric_height(ctx->DrawBuffer) & 31)) & 31);
    else
       OUT_BATCH(0);
    ADVANCE_BATCH();
index e4119b1aa3f475657d305728577270424f145d72..b7bb2315b97d6ac979c63b1ff49c8dbdad315a59 100644 (file)
@@ -122,18 +122,9 @@ brw_create_nir(struct brw_context *brw,
    /* Get rid of split copies */
    nir_optimize(nir);
 
-   if (shader_prog) {
-      nir_assign_var_locations_scalar_direct_first(nir, &nir->uniforms,
-                                                   &nir->num_direct_uniforms,
-                                                   &nir->num_uniforms);
-   } else {
-      /* ARB programs generally create a giant array of "uniform" data, and allow
-       * indirect addressing without any boundaries.  In the absence of bounds
-       * analysis, it's all or nothing.  num_direct_uniforms is only useful when
-       * we have some direct and some indirect access; it doesn't matter here.
-       */
-      nir->num_direct_uniforms = 0;
-   }
+   nir_assign_var_locations_scalar_direct_first(nir, &nir->uniforms,
+                                                &nir->num_direct_uniforms,
+                                                &nir->num_uniforms);
    nir_assign_var_locations_scalar(&nir->inputs, &nir->num_inputs);
    nir_assign_var_locations_scalar(&nir->outputs, &nir->num_outputs);
 
@@ -176,6 +167,12 @@ brw_create_nir(struct brw_context *brw,
    nir_validate_shader(nir);
 
    if (unlikely(debug_enabled)) {
+      /* Re-index SSA defs so we print more sensible numbers. */
+      nir_foreach_overload(nir, overload) {
+         if (overload->impl)
+            nir_index_ssa_defs(overload->impl);
+      }
+
       fprintf(stderr, "NIR (SSA form) for %s shader:\n",
               _mesa_shader_stage_to_string(stage));
       nir_print_shader(nir, stderr);
index b056fbfc4275018b3f6e04894139de060302be9c..ea128ccb670d511044e6fb06e201b126df6c427c 100644 (file)
@@ -88,7 +88,7 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx,
         return NULL;
    }
 
-   case MESA_GEOMETRY_PROGRAM: {
+   case GL_GEOMETRY_PROGRAM_NV: {
       struct brw_geometry_program *prog = CALLOC_STRUCT(brw_geometry_program);
       if (prog) {
          prog->id = get_new_program_id(brw->intelScreen);
@@ -287,18 +287,24 @@ void brwInitFragProgFuncs( struct dd_function_table *functions )
    functions->MemoryBarrier = brw_memory_barrier;
 }
 
+struct shader_times {
+   uint64_t time;
+   uint64_t written;
+   uint64_t reset;
+};
+
 void
 brw_init_shader_time(struct brw_context *brw)
 {
-   const int max_entries = 4096;
-   brw->shader_time.bo = drm_intel_bo_alloc(brw->bufmgr, "shader time",
-                                            max_entries * SHADER_TIME_STRIDE,
-                                            4096);
+   const int max_entries = 2048;
+   brw->shader_time.bo =
+      drm_intel_bo_alloc(brw->bufmgr, "shader time",
+                         max_entries * SHADER_TIME_STRIDE * 3, 4096);
    brw->shader_time.names = rzalloc_array(brw, const char *, max_entries);
    brw->shader_time.ids = rzalloc_array(brw, int, max_entries);
    brw->shader_time.types = rzalloc_array(brw, enum shader_time_shader_type,
                                           max_entries);
-   brw->shader_time.cumulative = rzalloc_array(brw, uint64_t,
+   brw->shader_time.cumulative = rzalloc_array(brw, struct shader_times,
                                                max_entries);
    brw->shader_time.max_entries = max_entries;
 }
@@ -318,27 +324,6 @@ compare_time(const void *a, const void *b)
       return 1;
 }
 
-static void
-get_written_and_reset(struct brw_context *brw, int i,
-                      uint64_t *written, uint64_t *reset)
-{
-   enum shader_time_shader_type type = brw->shader_time.types[i];
-   assert(type == ST_VS || type == ST_GS || type == ST_FS8 ||
-          type == ST_FS16 || type == ST_CS);
-
-   /* Find where we recorded written and reset. */
-   int wi, ri;
-
-   for (wi = i; brw->shader_time.types[wi] != type + 1; wi++)
-      ;
-
-   for (ri = i; brw->shader_time.types[ri] != type + 2; ri++)
-      ;
-
-   *written = brw->shader_time.cumulative[wi];
-   *reset = brw->shader_time.cumulative[ri];
-}
-
 static void
 print_shader_time_line(const char *stage, const char *name,
                        int shader_num, uint64_t time, uint64_t total)
@@ -374,26 +359,13 @@ brw_report_shader_time(struct brw_context *brw)
       sorted[i] = &scaled[i];
 
       switch (type) {
-      case ST_VS_WRITTEN:
-      case ST_VS_RESET:
-      case ST_GS_WRITTEN:
-      case ST_GS_RESET:
-      case ST_FS8_WRITTEN:
-      case ST_FS8_RESET:
-      case ST_FS16_WRITTEN:
-      case ST_FS16_RESET:
-      case ST_CS_WRITTEN:
-      case ST_CS_RESET:
-         /* We'll handle these when along with the time. */
-         scaled[i] = 0;
-         continue;
-
       case ST_VS:
       case ST_GS:
       case ST_FS8:
       case ST_FS16:
       case ST_CS:
-         get_written_and_reset(brw, i, &written, &reset);
+         written = brw->shader_time.cumulative[i].written;
+         reset = brw->shader_time.cumulative[i].reset;
          break;
 
       default:
@@ -405,7 +377,7 @@ brw_report_shader_time(struct brw_context *brw)
          break;
       }
 
-      uint64_t time = brw->shader_time.cumulative[i];
+      uint64_t time = brw->shader_time.cumulative[i].time;
       if (written) {
          scaled[i] = time / written * (written + reset);
       } else {
@@ -491,16 +463,19 @@ brw_collect_shader_time(struct brw_context *brw)
     * overhead compared to the cost of tracking the time in the first place.
     */
    drm_intel_bo_map(brw->shader_time.bo, true);
-
-   uint32_t *times = brw->shader_time.bo->virtual;
+   void *bo_map = brw->shader_time.bo->virtual;
 
    for (int i = 0; i < brw->shader_time.num_entries; i++) {
-      brw->shader_time.cumulative[i] += times[i * SHADER_TIME_STRIDE / 4];
+      uint32_t *times = bo_map + i * 3 * SHADER_TIME_STRIDE;
+
+      brw->shader_time.cumulative[i].time += times[SHADER_TIME_STRIDE * 0 / 4];
+      brw->shader_time.cumulative[i].written += times[SHADER_TIME_STRIDE * 1 / 4];
+      brw->shader_time.cumulative[i].reset += times[SHADER_TIME_STRIDE * 2 / 4];
    }
 
    /* Zero the BO out to clear it out for our next collection.
     */
-   memset(times, 0, brw->shader_time.bo->size);
+   memset(bo_map, 0, brw->shader_time.bo->size);
    drm_intel_bo_unmap(brw->shader_time.bo);
 }
 
index 667c90093047748d09b106f1a06d6fcf44842bf9..aea4d9b77d340d894768bef6fca5f447a0bc72dd 100644 (file)
@@ -66,10 +66,20 @@ brw_write_timestamp(struct brw_context *brw, drm_intel_bo *query_bo, int idx)
 void
 brw_write_depth_count(struct brw_context *brw, drm_intel_bo *query_bo, int idx)
 {
-   brw_emit_pipe_control_write(brw,
-                               PIPE_CONTROL_WRITE_DEPTH_COUNT
-                               | PIPE_CONTROL_DEPTH_STALL,
-                               query_bo, idx * sizeof(uint64_t), 0, 0);
+   uint32_t flags;
+
+   flags = (PIPE_CONTROL_WRITE_DEPTH_COUNT |
+            PIPE_CONTROL_DEPTH_STALL);
+
+   /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM
+    * command when loading the values into the predicate source registers for
+    * conditional rendering.
+    */
+   if (brw->predicate.supported)
+      flags |= PIPE_CONTROL_FLUSH_ENABLE;
+
+   brw_emit_pipe_control_write(brw, flags, query_bo,
+                               idx * sizeof(uint64_t), 0, 0);
 }
 
 /**
index c03a8aed7961fc4c59edeac9795a77da794761c5..c8b134103bba3cd1b83eb9654fe50b825a8dab22 100644 (file)
@@ -764,6 +764,22 @@ brw_ip_reg(void)
                   WRITEMASK_XYZW); /* NOTE! */
 }
 
+static inline struct brw_reg
+brw_notification_reg(void)
+{
+   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+                  BRW_ARF_NOTIFICATION_COUNT,
+                  0,
+                  0,
+                  0,
+                  BRW_REGISTER_TYPE_UD,
+                  BRW_VERTICAL_STRIDE_0,
+                  BRW_WIDTH_1,
+                  BRW_HORIZONTAL_STRIDE_0,
+                  BRW_SWIZZLE_XXXX,
+                  WRITEMASK_X);
+}
+
 static inline struct brw_reg
 brw_acc_reg(unsigned width)
 {
@@ -778,7 +794,11 @@ brw_flag_reg(int reg, int subreg)
                       BRW_ARF_FLAG + reg, subreg);
 }
 
-
+/**
+ * Return the mask register present in Gen4-5, or the related register present
+ * in Gen7.5 and later hardware referred to as "channel enable" register in
+ * the documentation.
+ */
 static inline struct brw_reg
 brw_mask_reg(unsigned subnr)
 {
index 34f75fdd8144a35db951d959d50f808d0a66f3bc..ee0add5d765ada519c7e09d10e20bf1709caec33 100644 (file)
@@ -399,10 +399,10 @@ schedule_node::set_latency_gen7(bool is_haswell)
 
 class instruction_scheduler {
 public:
-   instruction_scheduler(backend_visitor *v, int grf_count,
+   instruction_scheduler(backend_shader *s, int grf_count,
                          instruction_scheduler_mode mode)
    {
-      this->bv = v;
+      this->bs = s;
       this->mem_ctx = ralloc_context(NULL);
       this->grf_count = grf_count;
       this->instructions.make_empty();
@@ -455,7 +455,7 @@ public:
    int grf_count;
    int time;
    exec_list instructions;
-   backend_visitor *bv;
+   backend_shader *bs;
 
    instruction_scheduler_mode mode;
 
@@ -606,7 +606,7 @@ vec4_instruction_scheduler::get_register_pressure_benefit(backend_instruction *b
 schedule_node::schedule_node(backend_instruction *inst,
                              instruction_scheduler *sched)
 {
-   const struct brw_device_info *devinfo = sched->bv->devinfo;
+   const struct brw_device_info *devinfo = sched->bs->devinfo;
 
    this->inst = inst;
    this->child_array_size = 0;
@@ -1384,7 +1384,7 @@ vec4_instruction_scheduler::issue_time(backend_instruction *inst)
 void
 instruction_scheduler::schedule_instructions(bblock_t *block)
 {
-   const struct brw_device_info *devinfo = bv->devinfo;
+   const struct brw_device_info *devinfo = bs->devinfo;
    backend_instruction *inst = block->end();
    time = 0;
 
@@ -1419,7 +1419,7 @@ instruction_scheduler::schedule_instructions(bblock_t *block)
 
       if (debug) {
          fprintf(stderr, "clock %4d, scheduled: ", time);
-         bv->dump_instruction(chosen->inst);
+         bs->dump_instruction(chosen->inst);
       }
 
       /* Now that we've scheduled a new instruction, some of its
@@ -1435,7 +1435,7 @@ instruction_scheduler::schedule_instructions(bblock_t *block)
 
          if (debug) {
             fprintf(stderr, "\tchild %d, %d parents: ", i, child->parent_count);
-            bv->dump_instruction(child->inst);
+            bs->dump_instruction(child->inst);
          }
 
          child->cand_generation = cand_generation;
@@ -1474,7 +1474,7 @@ instruction_scheduler::run(cfg_t *cfg)
    if (debug) {
       fprintf(stderr, "\nInstructions before scheduling (reg_alloc %d)\n",
               post_reg_alloc);
-      bv->dump_instructions();
+      bs->dump_instructions();
    }
 
    /* Populate the remaining GRF uses array to improve the pre-regalloc
@@ -1504,7 +1504,7 @@ instruction_scheduler::run(cfg_t *cfg)
    if (debug) {
       fprintf(stderr, "\nInstructions after scheduling (reg_alloc %d)\n",
               post_reg_alloc);
-      bv->dump_instructions();
+      bs->dump_instructions();
    }
 }
 
index 014b43448ad72d4bb483be4d02c304eb060796fd..5d9892214a935c6cef3bf06c2d45b32883d27c92 100644 (file)
@@ -52,6 +52,12 @@ static void upload_sf_vp(struct brw_context *brw)
                         sizeof(*sfv), 32, &brw->sf.vp_offset);
    memset(sfv, 0, sizeof(*sfv));
 
+   /* Accessing the fields Width and Height of gl_framebuffer to produce the
+    * values to program the viewport and scissor is fine as long as the
+    * gl_framebuffer has atleast one attachment.
+    */
+   assert(ctx->DrawBuffer->_HasAttachments);
+
    if (render_to_fbo) {
       y_scale = 1.0;
       y_bias = 0;
index ebfb49acf8d70747f230baf9dfcd933fc87cd07f..06393c8ff2bb61343bcb56e77dfb3d8259fabec9 100644 (file)
 #include "glsl/glsl_parser_extras.h"
 #include "main/shaderapi.h"
 
+static void
+shader_debug_log_mesa(void *data, const char *fmt, ...)
+{
+   struct brw_context *brw = (struct brw_context *)data;
+   va_list args;
+
+   va_start(args, fmt);
+   GLuint msg_id = 0;
+   _mesa_gl_vdebug(&brw->ctx, &msg_id,
+                   MESA_DEBUG_SOURCE_SHADER_COMPILER,
+                   MESA_DEBUG_TYPE_OTHER,
+                   MESA_DEBUG_SEVERITY_NOTIFICATION, fmt, args);
+   va_end(args);
+}
+
+static void
+shader_perf_log_mesa(void *data, const char *fmt, ...)
+{
+   struct brw_context *brw = (struct brw_context *)data;
+
+   va_list args;
+   va_start(args, fmt);
+
+   if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
+      va_list args_copy;
+      va_copy(args_copy, args);
+      vfprintf(stderr, fmt, args_copy);
+      va_end(args_copy);
+   }
+
+   if (brw->perf_debug) {
+      GLuint msg_id = 0;
+      _mesa_gl_vdebug(&brw->ctx, &msg_id,
+                      MESA_DEBUG_SOURCE_SHADER_COMPILER,
+                      MESA_DEBUG_TYPE_PERFORMANCE,
+                      MESA_DEBUG_SEVERITY_MEDIUM, fmt, args);
+   }
+   va_end(args);
+}
+
 struct brw_compiler *
 brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)
 {
    struct brw_compiler *compiler = rzalloc(mem_ctx, struct brw_compiler);
 
    compiler->devinfo = devinfo;
+   compiler->shader_debug_log = shader_debug_log_mesa;
+   compiler->shader_perf_log = shader_perf_log_mesa;
 
    brw_fs_alloc_reg_sets(compiler);
    brw_vec4_alloc_reg_set(compiler);
 
+   if (devinfo->gen >= 8 && !(INTEL_DEBUG & DEBUG_VEC4VS))
+      compiler->scalar_vs = true;
+
+   nir_shader_compiler_options *nir_options =
+      rzalloc(compiler, nir_shader_compiler_options);
+   nir_options->native_integers = true;
+   /* In order to help allow for better CSE at the NIR level we tell NIR
+    * to split all ffma instructions during opt_algebraic and we then
+    * re-combine them as a later step.
+    */
+   nir_options->lower_ffma = true;
+   nir_options->lower_sub = true;
+
+   /* We want the GLSL compiler to emit code that uses condition codes */
+   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
+      compiler->glsl_compiler_options[i].MaxUnrollIterations = 32;
+      compiler->glsl_compiler_options[i].MaxIfDepth =
+         devinfo->gen < 6 ? 16 : UINT_MAX;
+
+      compiler->glsl_compiler_options[i].EmitCondCodes = true;
+      compiler->glsl_compiler_options[i].EmitNoNoise = true;
+      compiler->glsl_compiler_options[i].EmitNoMainReturn = true;
+      compiler->glsl_compiler_options[i].EmitNoIndirectInput = true;
+      compiler->glsl_compiler_options[i].EmitNoIndirectOutput =
+        (i == MESA_SHADER_FRAGMENT);
+      compiler->glsl_compiler_options[i].EmitNoIndirectTemp =
+        (i == MESA_SHADER_FRAGMENT);
+      compiler->glsl_compiler_options[i].EmitNoIndirectUniform = false;
+      compiler->glsl_compiler_options[i].LowerClipDistance = true;
+   }
+
+   compiler->glsl_compiler_options[MESA_SHADER_VERTEX].OptimizeForAOS = true;
+   compiler->glsl_compiler_options[MESA_SHADER_GEOMETRY].OptimizeForAOS = true;
+
+   if (compiler->scalar_vs) {
+      /* If we're using the scalar backend for vertex shaders, we need to
+       * configure these accordingly.
+       */
+      compiler->glsl_compiler_options[MESA_SHADER_VERTEX].EmitNoIndirectOutput = true;
+      compiler->glsl_compiler_options[MESA_SHADER_VERTEX].EmitNoIndirectTemp = true;
+      compiler->glsl_compiler_options[MESA_SHADER_VERTEX].OptimizeForAOS = false;
+
+      compiler->glsl_compiler_options[MESA_SHADER_VERTEX].NirOptions = nir_options;
+   }
+
+   compiler->glsl_compiler_options[MESA_SHADER_FRAGMENT].NirOptions = nir_options;
+   compiler->glsl_compiler_options[MESA_SHADER_COMPUTE].NirOptions = nir_options;
+
    return compiler;
 }
 
@@ -97,7 +187,7 @@ is_scalar_shader_stage(struct brw_context *brw, int stage)
    case MESA_SHADER_FRAGMENT:
       return true;
    case MESA_SHADER_VERTEX:
-      return brw->scalar_vs;
+      return brw->intelScreen->compiler->scalar_vs;
    default:
       return false;
    }
@@ -632,6 +722,8 @@ brw_instruction_name(enum opcode op)
       return "gs_ff_sync_set_primitives";
    case CS_OPCODE_CS_TERMINATE:
       return "cs_terminate";
+   case SHADER_OPCODE_BARRIER:
+      return "barrier";
    }
 
    unreachable("not reached");
@@ -755,19 +847,22 @@ brw_abs_immediate(enum brw_reg_type type, struct brw_reg *reg)
    return false;
 }
 
-backend_visitor::backend_visitor(struct brw_context *brw,
-                                 struct gl_shader_program *shader_prog,
-                                 struct gl_program *prog,
-                                 struct brw_stage_prog_data *stage_prog_data,
-                                 gl_shader_stage stage)
-   : brw(brw),
-     devinfo(brw->intelScreen->devinfo),
-     ctx(&brw->ctx),
+backend_shader::backend_shader(const struct brw_compiler *compiler,
+                               void *log_data,
+                               void *mem_ctx,
+                               struct gl_shader_program *shader_prog,
+                               struct gl_program *prog,
+                               struct brw_stage_prog_data *stage_prog_data,
+                               gl_shader_stage stage)
+   : compiler(compiler),
+     log_data(log_data),
+     devinfo(compiler->devinfo),
      shader(shader_prog ?
         (struct brw_shader *)shader_prog->_LinkedShaders[stage] : NULL),
      shader_prog(shader_prog),
      prog(prog),
      stage_prog_data(stage_prog_data),
+     mem_ctx(mem_ctx),
      cfg(NULL),
      stage(stage)
 {
@@ -950,7 +1045,6 @@ backend_instruction::can_do_saturate() const
    case BRW_OPCODE_LINE:
    case BRW_OPCODE_LRP:
    case BRW_OPCODE_MAC:
-   case BRW_OPCODE_MACH:
    case BRW_OPCODE_MAD:
    case BRW_OPCODE_MATH:
    case BRW_OPCODE_MOV:
@@ -1060,6 +1154,7 @@ backend_instruction::has_side_effects() const
    case SHADER_OPCODE_MEMORY_FENCE:
    case SHADER_OPCODE_URB_WRITE_SIMD8:
    case FS_OPCODE_FB_WRITE:
+   case SHADER_OPCODE_BARRIER:
       return true;
    default:
       return false;
@@ -1148,13 +1243,13 @@ backend_instruction::remove(bblock_t *block)
 }
 
 void
-backend_visitor::dump_instructions()
+backend_shader::dump_instructions()
 {
    dump_instructions(NULL);
 }
 
 void
-backend_visitor::dump_instructions(const char *name)
+backend_shader::dump_instructions(const char *name)
 {
    FILE *file = stderr;
    if (name && geteuid() != 0) {
@@ -1183,7 +1278,7 @@ backend_visitor::dump_instructions(const char *name)
 }
 
 void
-backend_visitor::calculate_cfg()
+backend_shader::calculate_cfg()
 {
    if (this->cfg)
       return;
@@ -1191,7 +1286,7 @@ backend_visitor::calculate_cfg()
 }
 
 void
-backend_visitor::invalidate_cfg()
+backend_shader::invalidate_cfg()
 {
    ralloc_free(this->cfg);
    this->cfg = NULL;
@@ -1206,7 +1301,7 @@ backend_visitor::invalidate_cfg()
  * trigger some of our asserts that surface indices are < BRW_MAX_SURFACES.
  */
 void
-backend_visitor::assign_common_binding_table_offsets(uint32_t next_binding_table_offset)
+backend_shader::assign_common_binding_table_offsets(uint32_t next_binding_table_offset)
 {
    int num_textures = _mesa_fls(prog->SamplersUsed);
 
index 59a0eff824ee30b34ae2da1bd59d12372fbec1f2..b2c1a0b8d699e59cbc6aa38184ed7250731caf14 100644 (file)
@@ -86,6 +86,12 @@ struct brw_compiler {
        */
       int aligned_pairs_class;
    } fs_reg_sets[2];
+
+   void (*shader_debug_log)(void *, const char *str, ...) PRINTFLIKE(2, 3);
+   void (*shader_perf_log)(void *, const char *str, ...) PRINTFLIKE(2, 3);
+
+   bool scalar_vs;
+   struct gl_shader_compiler_options glsl_compiler_options[MESA_SHADER_STAGES];
 };
 
 enum PACKED register_file {
@@ -211,20 +217,23 @@ enum instruction_scheduler_mode {
    SCHEDULE_POST,
 };
 
-class backend_visitor : public ir_visitor {
+class backend_shader {
 protected:
 
-   backend_visitor(struct brw_context *brw,
-                   struct gl_shader_program *shader_prog,
-                   struct gl_program *prog,
-                   struct brw_stage_prog_data *stage_prog_data,
-                   gl_shader_stage stage);
+   backend_shader(const struct brw_compiler *compiler,
+                  void *log_data,
+                  void *mem_ctx,
+                  struct gl_shader_program *shader_prog,
+                  struct gl_program *prog,
+                  struct brw_stage_prog_data *stage_prog_data,
+                  gl_shader_stage stage);
 
 public:
 
-   struct brw_context * const brw;
+   const struct brw_compiler *compiler;
+   void *log_data; /* Passed to compiler->*_log functions */
+
    const struct brw_device_info * const devinfo;
-   struct gl_context * const ctx;
    struct brw_shader * const shader;
    struct gl_shader_program * const shader_prog;
    struct gl_program * const prog;
index 26fdae64ea4432364aa3e2028b56dd04077fbe7e..987672f881592dbc15943367bfbe8b84f3ac2db6 100644 (file)
@@ -229,11 +229,14 @@ void brw_destroy_caches( struct brw_context *brw );
 #define BRW_BATCH_STRUCT(brw, s) \
    intel_batchbuffer_data(brw, (s), sizeof(*(s)), RENDER_RING)
 
-void *brw_state_batch(struct brw_context *brw,
-                     enum aub_state_struct_type type,
-                     int size,
-                     int alignment,
-                     uint32_t *out_offset);
+void *__brw_state_batch(struct brw_context *brw,
+                        enum aub_state_struct_type type,
+                        int size,
+                        int alignment,
+                        int index,
+                        uint32_t *out_offset);
+#define brw_state_batch(brw, type, size, alignment, out_offset) \
+   __brw_state_batch(brw, type, size, alignment, 0, out_offset)
 
 /* brw_wm_surface_state.c */
 void gen4_init_vtable_surface_functions(struct brw_context *brw);
@@ -246,6 +249,7 @@ void brw_configure_w_tiled(const struct intel_mipmap_tree *mt,
                            unsigned *pitch, uint32_t *tiling,
                            unsigned *format);
 
+const char *brw_surface_format_name(unsigned format);
 uint32_t brw_format_for_mesa_format(mesa_format mesa_format);
 
 GLuint translate_tex_target(GLenum target);
index 45dca69823fd385ab9e65a380b1fd9e83a2dcf14..a405a80ef6e3204284f3ea371ea7b03eb52d4308 100644 (file)
@@ -38,7 +38,8 @@ static void
 brw_track_state_batch(struct brw_context *brw,
                      enum aub_state_struct_type type,
                      uint32_t offset,
-                     int size)
+                      int size,
+                      int index)
 {
    struct intel_batchbuffer *batch = &brw->batch;
 
@@ -53,6 +54,7 @@ brw_track_state_batch(struct brw_context *brw,
    brw->state_batch_list[brw->state_batch_count].offset = offset;
    brw->state_batch_list[brw->state_batch_count].size = size;
    brw->state_batch_list[brw->state_batch_count].type = type;
+   brw->state_batch_list[brw->state_batch_count].index = index;
    brw->state_batch_count++;
 }
 
@@ -108,18 +110,20 @@ brw_annotate_aub(struct brw_context *brw)
  * margin (4096 bytes, even if the object is just a 20-byte surface
  * state), and more buffers to walk and count for aperture size checking.
  *
- * However, due to the restrictions inposed by the aperture size
+ * However, due to the restrictions imposed by the aperture size
  * checking performance hacks, we can't have the batch point at a
  * separate indirect state buffer, because once the batch points at
  * it, no more relocations can be added to it.  So, we sneak these
  * buffers in at the top of the batchbuffer.
  */
 void *
-brw_state_batch(struct brw_context *brw,
-               enum aub_state_struct_type type,
-               int size,
-               int alignment,
-               uint32_t *out_offset)
+__brw_state_batch(struct brw_context *brw,
+                  enum aub_state_struct_type type,
+                  int size,
+                  int alignment,
+                  int index,
+                  uint32_t *out_offset)
+
 {
    struct intel_batchbuffer *batch = &brw->batch;
    uint32_t offset;
@@ -140,7 +144,7 @@ brw_state_batch(struct brw_context *brw,
    batch->state_batch_offset = offset;
 
    if (unlikely(INTEL_DEBUG & (DEBUG_BATCH | DEBUG_AUB)))
-      brw_track_state_batch(brw, type, offset, size);
+      brw_track_state_batch(brw, type, offset, size, index);
 
    *out_offset = offset;
    return batch->map + (offset>>2);
index 530f5a8b76e1c3842d64affa0d7cdc8157635e34..b6f4d598e1df2dcfa2ce1a2a46e90c942ac8ea33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright Â© 2007 Intel Corporation
+ * Copyright Â© 2007-2015 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "brw_context.h"
 #include "brw_defines.h"
 #include "brw_eu.h"
+#include "brw_state.h"
+
+static const char *sampler_mip_filter[] = {
+   "NONE",
+   "NEAREST",
+   "RSVD",
+   "LINEAR"
+};
+
+static const char *sampler_mag_filter[] = {
+   "NEAREST",
+   "LINEAR",
+   "ANISOTROPIC",
+   "FLEXIBLE (GEN8+)",
+   "RSVD", "RSVD",
+   "MONO",
+   "RSVD"
+};
+
+static const char *sampler_addr_mode[] = {
+   "WRAP",
+   "MIRROR",
+   "CLAMP",
+   "CUBE",
+   "CLAMP_BORDER",
+   "MIRROR_ONCE",
+   "HALF_BORDER"
+};
+
+static const char *surface_tiling[] = {
+   "LINEAR",
+   "W-tiled",
+   "X-tiled",
+   "Y-tiled"
+};
 
 static void
 batch_out(struct brw_context *brw, const char *name, uint32_t offset,
@@ -50,6 +85,25 @@ batch_out(struct brw_context *brw, const char *name, uint32_t offset,
    va_end(va);
 }
 
+static void
+batch_out64(struct brw_context *brw, const char *name, uint32_t offset,
+            int index, char *fmt, ...)
+{
+   uint32_t *tmp = brw->batch.bo->virtual + offset;
+
+   /* Swap the dwords since we want to handle this as a 64b value, but the data
+    * is typically emitted as dwords.
+    */
+   uint64_t data = ((uint64_t)tmp[index + 1]) << 32 | tmp[index];
+   va_list va;
+
+   fprintf(stderr, "0x%08x:      0x%016" PRIx64 ": %8s: ",
+          offset + index * 4, data, name);
+   va_start(va, fmt);
+   vfprintf(stderr, fmt, va);
+   va_end(va);
+}
+
 static const char *
 get_965_surfacetype(unsigned int surfacetype)
 {
@@ -64,19 +118,6 @@ get_965_surfacetype(unsigned int surfacetype)
     }
 }
 
-static const char *
-get_965_surface_format(unsigned int surface_format)
-{
-    switch (surface_format) {
-    case 0x000: return "r32g32b32a32_float";
-    case 0x0c1: return "b8g8r8a8_unorm";
-    case 0x100: return "b5g6r5_unorm";
-    case 0x102: return "b5g5r5a1_unorm";
-    case 0x104: return "b4g4r4a4_unorm";
-    default: return "unknown";
-    }
-}
-
 static void dump_vs_state(struct brw_context *brw, uint32_t offset)
 {
    const char *name = "VS_STATE";
@@ -176,7 +217,7 @@ static void dump_surface_state(struct brw_context *brw, uint32_t offset)
 
    batch_out(brw, name, offset, 0, "%s %s\n",
             get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
-            get_965_surface_format(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)));
+             brw_surface_format_name(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)));
    batch_out(brw, name, offset, 1, "offset\n");
    batch_out(brw, name, offset, 2, "%dx%d size, %d mips\n",
             GET_FIELD(surf[2], BRW_SURFACE_WIDTH) + 1,
@@ -200,7 +241,7 @@ static void dump_gen7_surface_state(struct brw_context *brw, uint32_t offset)
 
    batch_out(brw, name, offset, 0, "%s %s %s\n",
              get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
-             get_965_surface_format(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)),
+             brw_surface_format_name(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)),
              (surf[0] & GEN7_SURFACE_IS_ARRAY) ? "array" : "");
    batch_out(brw, name, offset, 1, "offset\n");
    batch_out(brw, name, offset, 2, "%dx%d size, %d mips, %d slices\n",
@@ -222,6 +263,87 @@ static void dump_gen7_surface_state(struct brw_context *brw, uint32_t offset)
    batch_out(brw, name, offset, 7, "\n");
 }
 
+static float q_to_float(uint32_t data, int integer_end, int integer_start,
+                        int fractional_end, int fractional_start)
+{
+   /* Convert the number to floating point. */
+   float n = GET_BITS(data, integer_start, fractional_end);
+
+   /* Multiply by 2^-n */
+   return n * exp2(-(fractional_end - fractional_start + 1));
+}
+
+static void
+dump_gen8_surface_state(struct brw_context *brw, uint32_t offset, int index)
+{
+   uint32_t *surf = brw->batch.bo->virtual + offset;
+   int aux_mode = surf[6] & INTEL_MASK(2, 0);
+   const char *aux_str;
+   char *name;
+
+   if (brw->gen >= 9 && (aux_mode == 1 || aux_mode == 5)) {
+      bool msrt = GET_BITS(surf[4], 5, 3) > 0;
+      bool compression = GET_FIELD(surf[7], GEN9_SURFACE_RT_COMPRESSION) == 1;
+      aux_str = ralloc_asprintf(NULL, "AUX_CCS_%c (%s, MULTISAMPLE_COUNT%c1)",
+                                (aux_mode == 1) ? 'D' : 'E',
+                                compression ? "Compressed RT" : "Uncompressed",
+                                msrt ? '>' : '=');
+   } else {
+      static const char *surface_aux_mode[] = { "AUX_NONE", "AUX_MCS",
+                                                "AUX_APPEND", "AUX_HIZ",
+                                                "RSVD", "RSVD"};
+      aux_str = ralloc_asprintf(NULL, "%s", surface_aux_mode[aux_mode]);
+   }
+
+   name = ralloc_asprintf(NULL, "SURF%03d", index);
+   batch_out(brw, name, offset, 0, "%s %s %s VALIGN%d HALIGN%d %s\n",
+             get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
+             brw_surface_format_name(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)),
+             (surf[0] & GEN7_SURFACE_IS_ARRAY) ? "array" : "",
+             1 << (GET_BITS(surf[0], 17, 16) + 1), /* VALIGN */
+             1 << (GET_BITS(surf[0], 15, 14) + 1), /* HALIGN */
+             surface_tiling[GET_BITS(surf[0], 13, 12)]);
+   batch_out(brw, name, offset, 1, "MOCS: 0x%x Base MIP: %.1f (%u mips) Surface QPitch: %d\n",
+             GET_FIELD(surf[1], GEN8_SURFACE_MOCS),
+             q_to_float(surf[1], 23, 20, 19, 19),
+             surf[5] & INTEL_MASK(3, 0),
+             GET_FIELD(surf[1], GEN8_SURFACE_QPITCH) << 2);
+   batch_out(brw, name, offset, 2, "%dx%d [%s]\n",
+             GET_FIELD(surf[2], GEN7_SURFACE_WIDTH) + 1,
+             GET_FIELD(surf[2], GEN7_SURFACE_HEIGHT) + 1,
+             aux_str);
+   batch_out(brw, name, offset, 3, "%d slices (depth), pitch: %d\n",
+             GET_FIELD(surf[3], BRW_SURFACE_DEPTH) + 1,
+             (surf[3] & INTEL_MASK(17, 0)) + 1);
+   batch_out(brw, name, offset, 4, "min array element: %d, array extent %d, MULTISAMPLE_%d\n",
+             GET_FIELD(surf[4], GEN7_SURFACE_MIN_ARRAY_ELEMENT),
+             GET_FIELD(surf[4], GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT) + 1,
+             1 << GET_BITS(surf[4], 5, 3));
+   batch_out(brw, name, offset, 5, "x,y offset: %d,%d, min LOD: %d\n",
+             GET_FIELD(surf[5], BRW_SURFACE_X_OFFSET),
+             GET_FIELD(surf[5], BRW_SURFACE_Y_OFFSET),
+             GET_FIELD(surf[5], GEN7_SURFACE_MIN_LOD));
+   batch_out(brw, name, offset, 6, "AUX pitch: %d qpitch: %d\n",
+             GET_FIELD(surf[6], GEN8_SURFACE_AUX_QPITCH) << 2,
+             GET_FIELD(surf[6], GEN8_SURFACE_AUX_PITCH) << 2);
+   if (brw->gen >= 9) {
+      batch_out(brw, name, offset, 7, "Clear color: R(%x)G(%x)B(%x)A(%x)\n",
+                surf[12], surf[13], surf[14], surf[15]);
+   } else {
+      batch_out(brw, name, offset, 7, "Clear color: %c%c%c%c\n",
+                GET_BITS(surf[7], 31, 31) ? 'R' : '-',
+                GET_BITS(surf[7], 30, 30) ? 'G' : '-',
+                GET_BITS(surf[7], 29, 29) ? 'B' : '-',
+                GET_BITS(surf[7], 28, 28) ? 'A' : '-');
+   }
+
+   for (int i = 8; i < 12; i++)
+      batch_out(brw, name, offset, i, "0x%08x\n", surf[i]);
+
+   ralloc_free((void *)aux_str);
+   ralloc_free(name);
+}
+
 static void
 dump_sdc(struct brw_context *brw, uint32_t offset)
 {
@@ -229,7 +351,7 @@ dump_sdc(struct brw_context *brw, uint32_t offset)
 
    if (brw->gen >= 5 && brw->gen <= 6) {
       struct gen5_sampler_default_color *sdc = (brw->batch.bo->virtual +
-                                               offset);
+                                                offset);
       batch_out(brw, name, offset, 0, "unorm rgba\n");
       batch_out(brw, name, offset, 1, "r %f\n", sdc->f[0]);
       batch_out(brw, name, offset, 2, "b %f\n", sdc->f[1]);
@@ -271,6 +393,45 @@ static void dump_sampler_state(struct brw_context *brw,
    }
 }
 
+static void gen7_dump_sampler_state(struct brw_context *brw,
+                                    uint32_t offset, uint32_t size)
+{
+   const uint32_t *samp = brw->batch.bo->virtual + offset;
+   char name[20];
+
+   for (int i = 0; i < size / 16; i++) {
+      sprintf(name, "SAMPLER_STATE %d", i);
+      batch_out(brw, name, offset, i,
+                "Disabled = %s, Base Mip: %u.%u, Mip/Mag/Min Filter: %s/%s/%s, LOD Bias: %d.%d\n",
+                GET_BITS(samp[0], 31, 31) ? "yes" : "no",
+                GET_BITS(samp[0], 26, 23),
+                GET_BITS(samp[0], 22, 22),
+                sampler_mip_filter[GET_FIELD(samp[0], BRW_SAMPLER_MIP_FILTER)],
+                sampler_mag_filter[GET_FIELD(samp[0], BRW_SAMPLER_MAG_FILTER)],
+                /* min filter defs are the same as mag */
+                sampler_mag_filter[GET_FIELD(samp[0], BRW_SAMPLER_MIN_FILTER)],
+                GET_BITS(samp[0], 13, 10),
+                GET_BITS(samp[0], 9, 1)
+               );
+      batch_out(brw, name, offset, i+1, "Min LOD: %u.%u, Max LOD: %u.%u\n",
+                GET_BITS(samp[1], 31, 28),
+                GET_BITS(samp[1], 27, 20),
+                GET_BITS(samp[1], 19, 16),
+                GET_BITS(samp[1], 15, 8)
+               );
+      batch_out(brw, name, offset, i+2, "Border Color\n"); /* FINISHME: gen8+ */
+      batch_out(brw, name, offset, i+3, "Max aniso: RATIO %d:1, TC[XYZ] Address Control: %s|%s|%s\n",
+                (GET_FIELD(samp[3], BRW_SAMPLER_MAX_ANISOTROPY) + 1) * 2,
+                sampler_addr_mode[GET_FIELD(samp[3], BRW_SAMPLER_TCX_WRAP_MODE)],
+                sampler_addr_mode[GET_FIELD(samp[3], BRW_SAMPLER_TCY_WRAP_MODE)],
+                sampler_addr_mode[GET_FIELD(samp[3], BRW_SAMPLER_TCZ_WRAP_MODE)]
+               );
+
+      samp += 4;
+      offset += 4 * sizeof(uint32_t);
+   }
+}
+
 static void dump_sf_viewport_state(struct brw_context *brw,
                                   uint32_t offset)
 {
@@ -320,10 +481,17 @@ static void dump_sf_clip_viewport_state(struct brw_context *brw,
    batch_out(brw, name, offset, 3, "m30 = %f\n", vp->viewport.m30);
    batch_out(brw, name, offset, 4, "m31 = %f\n", vp->viewport.m31);
    batch_out(brw, name, offset, 5, "m32 = %f\n", vp->viewport.m32);
-   batch_out(brw, name, offset, 6, "guardband xmin = %f\n", vp->guardband.xmin);
-   batch_out(brw, name, offset, 7, "guardband xmax = %f\n", vp->guardband.xmax);
-   batch_out(brw, name, offset, 8, "guardband ymin = %f\n", vp->guardband.ymin);
-   batch_out(brw, name, offset, 9, "guardband ymax = %f\n", vp->guardband.ymax);
+   batch_out(brw, name, offset, 8, "guardband xmin = %f\n", vp->guardband.xmin);
+   batch_out(brw, name, offset, 9, "guardband xmax = %f\n", vp->guardband.xmax);
+   batch_out(brw, name, offset, 9, "guardband ymin = %f\n", vp->guardband.ymin);
+   batch_out(brw, name, offset, 10, "guardband ymax = %f\n", vp->guardband.ymax);
+   if (brw->gen >= 8) {
+      float *cc_vp = brw->batch.bo->virtual + offset;
+      batch_out(brw, name, offset, 12, "Min extents: %.2fx%.2f\n",
+                cc_vp[12], cc_vp[14]);
+      batch_out(brw, name, offset, 14, "Max extents: %.2fx%.2f\n",
+                cc_vp[13], cc_vp[15]);
+   }
 }
 
 
@@ -397,6 +565,92 @@ static void dump_blend_state(struct brw_context *brw, uint32_t offset)
    batch_out(brw, name, offset, 1, "\n");
 }
 
+static void
+gen8_dump_blend_state(struct brw_context *brw, uint32_t offset, uint32_t size)
+{
+   const uint32_t *blend = brw->batch.bo->virtual + offset;
+   const char *logicop[] =
+   {
+        "LOGICOP_CLEAR (BLACK)",
+        "LOGICOP_NOR",
+        "LOGICOP_AND_INVERTED",
+        "LOGICOP_COPY_INVERTED",
+        "LOGICOP_AND_REVERSE",
+        "LOGICOP_INVERT",
+        "LOGICOP_XOR",
+        "LOGICOP_NAND",
+        "LOGICOP_AND",
+        "LOGICOP_EQUIV",
+        "LOGICOP_NOOP",
+        "LOGICOP_OR_INVERTED",
+        "LOGICOP_COPY",
+        "LOGICOP_OR_REVERSE",
+        "LOGICOP_OR",
+        "LOGICOP_SET (WHITE)"
+   };
+
+   const char *blend_function[] =
+   { "ADD", "SUBTRACT", "REVERSE_SUBTRACT", "MIN", "MAX};" };
+
+   const char *blend_factor[0x1b] =
+   {
+      "RSVD",
+      "ONE",
+      "SRC_COLOR", "SRC_ALPHA",
+      "DST_ALPHA", "DST_COLOR",
+      "SRC_ALPHA_SATURATE",
+      "CONST_COLOR", "CONST_ALPHA",
+      "SRC1_COLOR", "SRC1_ALPHA",
+      "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", "RSVD",
+      "ZERO",
+      "INV_SRC_COLOR", "INV_SRC_ALPHA",
+      "INV_DST_ALPHA", "INV_DST_COLOR",
+      "RSVD",
+      "INV_CONST_COLOR", "INV_CONST_ALPHA",
+      "INV_SRC1_COLOR", "INV_SRC1_ALPHA"
+   };
+
+   batch_out(brw, "BLEND", offset, 0, "Alpha blend/test\n");
+
+   if (((size) % 2) != 0)
+      fprintf(stderr, "Invalid blend state size %d\n", size);
+
+   for (int i = 1; i < size / 4; i += 2) {
+      char name[sizeof("BLEND_ENTRYXXX")];
+      sprintf(name, "BLEND_ENTRY%02d", (i - 1) / 2);
+      if (blend[i + 1] & GEN8_BLEND_LOGIC_OP_ENABLE) {
+         batch_out(brw, name, offset, i + 1, "%s\n",
+                   logicop[GET_FIELD(blend[i + 1],
+                                     GEN8_BLEND_LOGIC_OP_FUNCTION)]);
+      } else if (blend[i] & GEN8_BLEND_COLOR_BUFFER_BLEND_ENABLE) {
+         batch_out64(brw, name, offset, i,
+                   "\n\t\t\tColor Buffer Blend factor %s,%s,%s,%s (src,dst,src alpha, dst alpha)"
+                   "\n\t\t\tfunction %s,%s (color, alpha), Disables: %c%c%c%c\n",
+                   blend_factor[GET_FIELD(blend[i],
+                                          GEN8_BLEND_SRC_BLEND_FACTOR)],
+                   blend_factor[GET_FIELD(blend[i],
+                                          GEN8_BLEND_DST_BLEND_FACTOR)],
+                   blend_factor[GET_FIELD(blend[i],
+                                          GEN8_BLEND_SRC_ALPHA_BLEND_FACTOR)],
+                   blend_factor[GET_FIELD(blend[i],
+                                          GEN8_BLEND_DST_ALPHA_BLEND_FACTOR)],
+                   blend_function[GET_FIELD(blend[i],
+                                            GEN8_BLEND_COLOR_BLEND_FUNCTION)],
+                   blend_function[GET_FIELD(blend[i],
+                                            GEN8_BLEND_ALPHA_BLEND_FUNCTION)],
+                   blend[i] & GEN8_BLEND_WRITE_DISABLE_RED ? 'R' : '-',
+                   blend[i] & GEN8_BLEND_WRITE_DISABLE_GREEN ? 'G' : '-',
+                   blend[i] & GEN8_BLEND_WRITE_DISABLE_BLUE ? 'B' : '-',
+                   blend[i] & GEN8_BLEND_WRITE_DISABLE_ALPHA ? 'A' : '-'
+                   );
+      } else if (!blend[i] && (blend[i + 1] == 0xb)) {
+         batch_out64(brw, name, offset, i, "NOP blend state\n");
+      } else {
+         batch_out64(brw, name, offset, i, "????\n");
+      }
+   }
+}
+
 static void
 dump_scissor(struct brw_context *brw, uint32_t offset)
 {
@@ -555,20 +809,29 @@ dump_state_batch(struct brw_context *brw)
            dump_cc_state_gen4(brw, offset);
         break;
       case AUB_TRACE_BLEND_STATE:
-        dump_blend_state(brw, offset);
+         if (brw->gen >= 8)
+            gen8_dump_blend_state(brw, offset, size);
+         else
+            dump_blend_state(brw, offset);
         break;
       case AUB_TRACE_BINDING_TABLE:
         dump_binding_table(brw, offset, size);
         break;
       case AUB_TRACE_SURFACE_STATE:
-        if (brw->gen < 7) {
-           dump_surface_state(brw, offset);
-        } else {
+         if (brw->gen >= 8) {
+            dump_gen8_surface_state(brw, offset,
+                                    brw->state_batch_list[i].index);
+         } else if (brw->gen >= 7) {
            dump_gen7_surface_state(brw, offset);
-        }
+         } else {
+            dump_surface_state(brw, offset);
+         }
         break;
       case AUB_TRACE_SAMPLER_STATE:
-         dump_sampler_state(brw, offset, size);
+         if (brw->gen >= 7)
+            gen7_dump_sampler_state(brw, offset, size);
+         else
+            dump_sampler_state(brw, offset, size);
         break;
       case AUB_TRACE_SAMPLER_DEFAULT_COLOR:
         dump_sdc(brw, offset);
index 84b0861aaad9276d4b090da21c6a89e5eb6d3a22..08d1ac288858c630f32507831b8c404399230535 100644 (file)
@@ -41,6 +41,7 @@
 #include "brw_gs.h"
 #include "brw_wm.h"
 #include "brw_cs.h"
+#include "main/framebuffer.h"
 
 static const struct brw_tracked_state *gen4_atoms[] =
 {
@@ -660,6 +661,7 @@ brw_upload_pipeline_state(struct brw_context *brw,
    int i;
    static int dirty_count = 0;
    struct brw_state_flags state = brw->state.pipelines[pipeline];
+   unsigned int fb_samples = _mesa_geometric_samples(ctx->DrawBuffer);
 
    brw_select_pipeline(brw, pipeline);
 
@@ -696,8 +698,8 @@ brw_upload_pipeline_state(struct brw_context *brw,
       brw->ctx.NewDriverState |= BRW_NEW_META_IN_PROGRESS;
    }
 
-   if (brw->num_samples != ctx->DrawBuffer->Visual.samples) {
-      brw->num_samples = ctx->DrawBuffer->Visual.samples;
+   if (brw->num_samples != fb_samples) {
+      brw->num_samples = fb_samples;
       brw->ctx.NewDriverState |= BRW_NEW_NUM_SAMPLES;
    }
 
index 016f87a4c2a0000424a3d2c73205dfd8aa4072b3..05016067bba58693fc6b0b3e77ab43e075bbece6 100644 (file)
@@ -39,13 +39,14 @@ struct surface_format_info {
    int input_vb;
    int streamed_output_vb;
    int color_processing;
+   const char *name;
 };
 
 /* This macro allows us to write the table almost as it appears in the PRM,
  * while restructuring it to turn it into the C code we want.
  */
 #define SF(sampl, filt, shad, ck, rt, ab, vb, so, color, sf) \
-   [sf] = { true, sampl, filt, shad, ck, rt, ab, vb, so, color },
+   [BRW_SURFACEFORMAT_##sf] = { true, sampl, filt, shad, ck, rt, ab, vb, so, color, #sf},
 
 #define Y 0
 #define x 999
@@ -73,6 +74,7 @@ struct surface_format_info {
  * VB    - Input Vertex Buffer
  * SO    - Steamed Output Vertex Buffers (transform feedback)
  * color - Color Processing
+ * sf    - Surface Format
  *
  * See page 88 of the Sandybridge PRM VOL4_Part1 PDF.
  *
@@ -85,230 +87,236 @@ struct surface_format_info {
  */
 const struct surface_format_info surface_formats[] = {
 /* smpl filt shad CK  RT  AB  VB  SO  color */
-   SF( Y, 50,  x,  x,  Y,  Y,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32B32A32_FLOAT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32B32A32_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32B32A32_UINT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32A32_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32A32_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R64G64_FLOAT)
-   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R32G32B32X32_FLOAT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32A32_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32A32_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R32G32B32A32_SFIXED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R64G64_PASSTHRU)
-   SF( Y, 50,  x,  x,  x,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32B32_FLOAT)
-   SF( Y,  x,  x,  x,  x,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32B32_SINT)
-   SF( Y,  x,  x,  x,  x,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32B32_UINT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32B32_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R32G32B32_SFIXED)
-   SF( Y,  Y,  x,  x,  Y, 45,  Y,  x, 60, BRW_SURFACEFORMAT_R16G16B16A16_UNORM)
-   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16A16_SNORM)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16A16_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16A16_UINT)
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16A16_FLOAT)
-   SF( Y, 50,  x,  x,  Y,  Y,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32_FLOAT)
-   SF( Y, 70,  x,  x,  Y,  Y,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32_FLOAT_LD)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32G32_UINT)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS)
-   SF( Y,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT)
-   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L32A32_FLOAT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R64_FLOAT)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R16G16B16X16_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R16G16B16X16_FLOAT)
-   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A32X32_FLOAT)
-   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L32X32_FLOAT)
-   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I32X32_FLOAT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16A16_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16A16_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32G32_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R32G32_SFIXED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R64_PASSTHRU)
-   SF( Y,  Y,  x,  Y,  Y,  Y,  Y,  x, 60, BRW_SURFACEFORMAT_B8G8R8A8_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB)
+   SF( Y, 50,  x,  x,  Y,  Y,  Y,  Y,  x, R32G32B32A32_FLOAT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32G32B32A32_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32G32B32A32_UINT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32A32_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32A32_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R64G64_FLOAT)
+   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, R32G32B32X32_FLOAT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32A32_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32A32_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R32G32B32A32_SFIXED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R64G64_PASSTHRU)
+   SF( Y, 50,  x,  x,  x,  x,  Y,  Y,  x, R32G32B32_FLOAT)
+   SF( Y,  x,  x,  x,  x,  x,  Y,  Y,  x, R32G32B32_SINT)
+   SF( Y,  x,  x,  x,  x,  x,  Y,  Y,  x, R32G32B32_UINT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32B32_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R32G32B32_SFIXED)
+   SF( Y,  Y,  x,  x,  Y, 45,  Y,  x, 60, R16G16B16A16_UNORM)
+   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, R16G16B16A16_SNORM)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R16G16B16A16_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R16G16B16A16_UINT)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, R16G16B16A16_FLOAT)
+   SF( Y, 50,  x,  x,  Y,  Y,  Y,  Y,  x, R32G32_FLOAT)
+   SF( Y, 70,  x,  x,  Y,  Y,  Y,  Y,  x, R32G32_FLOAT_LD)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32G32_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32G32_UINT)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, R32_FLOAT_X8X24_TYPELESS)
+   SF( Y,  x,  x,  x,  x,  x,  x,  x,  x, X32_TYPELESS_G8X24_UINT)
+   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, L32A32_FLOAT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R64_FLOAT)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, R16G16B16X16_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, R16G16B16X16_FLOAT)
+   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, A32X32_FLOAT)
+   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, L32X32_FLOAT)
+   SF( Y, 50,  x,  x,  x,  x,  x,  x,  x, I32X32_FLOAT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16B16A16_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16B16A16_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32G32_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R32G32_SFIXED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R64_PASSTHRU)
+   SF( Y,  Y,  x,  Y,  Y,  Y,  Y,  x, 60, B8G8R8A8_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, B8G8R8A8_UNORM_SRGB)
 /* smpl filt shad CK  RT  AB  VB  SO  color */
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x, 60, BRW_SURFACEFORMAT_R10G10B10A2_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x, 60, BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R10G10B10A2_UINT)
-   SF( Y,  Y,  x,  x,  x,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x, 60, BRW_SURFACEFORMAT_R8G8B8A8_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x, 60, BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8A8_SNORM)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8A8_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8A8_UINT)
-   SF( Y,  Y,  x,  x,  Y, 45,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_UNORM)
-   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_SNORM)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_UINT)
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_FLOAT)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x, 60, BRW_SURFACEFORMAT_B10G10R10A2_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x, 60, BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R11G11B10_FLOAT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, BRW_SURFACEFORMAT_R32_UINT)
-   SF( Y, 50,  Y,  x,  Y,  Y,  Y,  Y,  x, BRW_SURFACEFORMAT_R32_FLOAT)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS)
-   SF( Y,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L16A16_UNORM)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I24X8_UNORM)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L24X8_UNORM)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A24X8_UNORM)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I32_FLOAT)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L32_FLOAT)
-   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A32_FLOAT)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x, 60, BRW_SURFACEFORMAT_B8G8R8X8_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8X8_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B10G10R10X2_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L16A16_FLOAT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32_SNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x, 60, R10G10B10A2_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x, 60, R10G10B10A2_UNORM_SRGB)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R10G10B10A2_UINT)
+   SF( Y,  Y,  x,  x,  x,  Y,  Y,  x,  x, R10G10B10_SNORM_A2_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x, 60, R8G8B8A8_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x, 60, R8G8B8A8_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, R8G8B8A8_SNORM)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R8G8B8A8_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R8G8B8A8_UINT)
+   SF( Y,  Y,  x,  x,  Y, 45,  Y,  x,  x, R16G16_UNORM)
+   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, R16G16_SNORM)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R16G16_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R16G16_UINT)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, R16G16_FLOAT)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x, 60, B10G10R10A2_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x, 60, B10G10R10A2_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, R11G11B10_FLOAT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32_UINT)
+   SF( Y, 50,  Y,  x,  Y,  Y,  Y,  Y,  x, R32_FLOAT)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, R24_UNORM_X8_TYPELESS)
+   SF( Y,  x,  x,  x,  x,  x,  x,  x,  x, X24_TYPELESS_G8_UINT)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, L16A16_UNORM)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, I24X8_UNORM)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, L24X8_UNORM)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, A24X8_UNORM)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, I32_FLOAT)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, L32_FLOAT)
+   SF( Y, 50,  Y,  x,  x,  x,  x,  x,  x, A32_FLOAT)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x, 60, B8G8R8X8_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, B8G8R8X8_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, R8G8B8X8_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, R8G8B8X8_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, R9G9B9E5_SHAREDEXP)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, B10G10R10X2_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, L16A16_FLOAT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32_SNORM)
 /* smpl filt shad CK  RT  AB  VB  SO  color */
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R10G10B10X2_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8A8_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8A8_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R32_USCALED)
-   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B5G6R5_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB)
-   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B5G5R5A1_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB)
-   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B4G4R4A4_UNORM)
-   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8_UNORM)
-   SF( Y,  Y,  x,  Y,  Y, 60,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8_SNORM)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8_UINT)
-   SF( Y,  Y,  Y,  x,  Y, 45,  Y,  x, 70, BRW_SURFACEFORMAT_R16_UNORM)
-   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, BRW_SURFACEFORMAT_R16_SNORM)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16_UINT)
-   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R16_FLOAT)
-   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A8P8_UNORM_PALETTE0)
-   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A8P8_UNORM_PALETTE1)
-   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I16_UNORM)
-   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L16_UNORM)
-   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A16_UNORM)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8A8_UNORM)
-   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I16_FLOAT)
-   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L16_FLOAT)
-   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A16_FLOAT)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8A8_UNORM_SRGB)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM)
-   SF( x,  x,  x,  x,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B5G5R5X1_UNORM)
-   SF( x,  x,  x,  x,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R10G10B10X2_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8B8A8_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8B8A8_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R32_USCALED)
+   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, B5G6R5_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, B5G6R5_UNORM_SRGB)
+   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, B5G5R5A1_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, B5G5R5A1_UNORM_SRGB)
+   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, B4G4R4A4_UNORM)
+   SF( Y,  Y,  x,  x,  Y,  Y,  x,  x,  x, B4G4R4A4_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, R8G8_UNORM)
+   SF( Y,  Y,  x,  Y,  Y, 60,  Y,  x,  x, R8G8_SNORM)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R8G8_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R8G8_UINT)
+   SF( Y,  Y,  Y,  x,  Y, 45,  Y,  x, 70, R16_UNORM)
+   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, R16_SNORM)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R16_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R16_UINT)
+   SF( Y,  Y,  x,  x,  Y,  Y,  Y,  x,  x, R16_FLOAT)
+   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, A8P8_UNORM_PALETTE0)
+   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, A8P8_UNORM_PALETTE1)
+   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, I16_UNORM)
+   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, L16_UNORM)
+   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, A16_UNORM)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, L8A8_UNORM)
+   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, I16_FLOAT)
+   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, L16_FLOAT)
+   SF( Y,  Y,  Y,  x,  x,  x,  x,  x,  x, A16_FLOAT)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, L8A8_UNORM_SRGB)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, R5G5_SNORM_B6_UNORM)
+   SF( x,  x,  x,  x,  Y,  Y,  x,  x,  x, B5G5R5X1_UNORM)
+   SF( x,  x,  x,  x,  Y,  Y,  x,  x,  x, B5G5R5X1_UNORM_SRGB)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8_USCALED)
 /* smpl filt shad CK  RT  AB  VB  SO  color */
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16_USCALED)
-   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P8A8_UNORM_PALETTE0)
-   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P8A8_UNORM_PALETTE1)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A1B5G5R5_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A4B4G4R4_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8A8_UINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8A8_SINT)
-   SF( Y,  Y,  x, 45,  Y,  Y,  Y,  x,  x, BRW_SURFACEFORMAT_R8_UNORM)
-   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, BRW_SURFACEFORMAT_R8_SNORM)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8_SINT)
-   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8_UINT)
-   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, BRW_SURFACEFORMAT_A8_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I8_UNORM)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P4A4_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A4P4_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8_USCALED)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P8_UNORM_PALETTE0)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8_UNORM_SRGB)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P8_UNORM_PALETTE1)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P4A4_UNORM_PALETTE1)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_A4P4_UNORM_PALETTE1)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_Y8_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8_UINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_L8_SINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I8_UINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_I8_SINT)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_DXT1_RGB_SRGB)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R1_UINT)
-   SF( Y,  Y,  x,  Y,  Y,  x,  x,  x, 60, BRW_SURFACEFORMAT_YCRCB_NORMAL)
-   SF( Y,  Y,  x,  Y,  Y,  x,  x,  x, 60, BRW_SURFACEFORMAT_YCRCB_SWAPUVY)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P2_UNORM_PALETTE0)
-   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_P2_UNORM_PALETTE1)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC1_UNORM)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC2_UNORM)
-   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC3_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC4_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC5_UNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC1_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC2_UNORM_SRGB)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC3_UNORM_SRGB)
-   SF( Y,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_MONO8)
-   SF( Y,  Y,  x,  x,  Y,  x,  x,  x, 60, BRW_SURFACEFORMAT_YCRCB_SWAPUV)
-   SF( Y,  Y,  x,  x,  Y,  x,  x,  x, 60, BRW_SURFACEFORMAT_YCRCB_SWAPY)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_DXT1_RGB)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16_USCALED)
+   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, P8A8_UNORM_PALETTE0)
+   SF(50, 50,  x,  x,  x,  x,  x,  x,  x, P8A8_UNORM_PALETTE1)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, A1B5G5R5_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, A4B4G4R4_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, L8A8_UINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, L8A8_SINT)
+   SF( Y,  Y,  x, 45,  Y,  Y,  Y,  x,  x, R8_UNORM)
+   SF( Y,  Y,  x,  x,  Y, 60,  Y,  x,  x, R8_SNORM)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R8_SINT)
+   SF( Y,  x,  x,  x,  Y,  x,  Y,  x,  x, R8_UINT)
+   SF( Y,  Y,  x,  Y,  Y,  Y,  x,  x,  x, A8_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, I8_UNORM)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, L8_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, P4A4_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, A4P4_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8_USCALED)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, P8_UNORM_PALETTE0)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, L8_UNORM_SRGB)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, P8_UNORM_PALETTE1)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, P4A4_UNORM_PALETTE1)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, A4P4_UNORM_PALETTE1)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, Y8_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, L8_UINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, L8_SINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, I8_UINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, I8_SINT)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, DXT1_RGB_SRGB)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, R1_UINT)
+   SF( Y,  Y,  x,  Y,  Y,  x,  x,  x, 60, YCRCB_NORMAL)
+   SF( Y,  Y,  x,  Y,  Y,  x,  x,  x, 60, YCRCB_SWAPUVY)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, P2_UNORM_PALETTE0)
+   SF(45, 45,  x,  x,  x,  x,  x,  x,  x, P2_UNORM_PALETTE1)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BC1_UNORM)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BC2_UNORM)
+   SF( Y,  Y,  x,  Y,  x,  x,  x,  x,  x, BC3_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC4_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC5_UNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC1_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC2_UNORM_SRGB)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC3_UNORM_SRGB)
+   SF( Y,  x,  x,  x,  x,  x,  x,  x,  x, MONO8)
+   SF( Y,  Y,  x,  x,  Y,  x,  x,  x, 60, YCRCB_SWAPUV)
+   SF( Y,  Y,  x,  x,  Y,  x,  x,  x, 60, YCRCB_SWAPY)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, DXT1_RGB)
 /* smpl filt shad CK  RT  AB  VB  SO  color */
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_FXT1)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R8G8B8_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R64G64B64A64_FLOAT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R64G64B64_FLOAT)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC4_SNORM)
-   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC5_SNORM)
-   SF(50, 50,  x,  x,  x,  x, 60,  x,  x, BRW_SURFACEFORMAT_R16G16B16_FLOAT)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16_UNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, BRW_SURFACEFORMAT_R16G16B16_USCALED)
-   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC6H_SF16)
-   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC7_UNORM)
-   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC7_UNORM_SRGB)
-   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_BC6H_UF16)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_PLANAR_420_8)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8_UNORM_SRGB)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC1_RGB8)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC2_RGB8)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_EAC_R11)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_EAC_RG11)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_EAC_SIGNED_R11)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_EAC_SIGNED_RG11)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC2_SRGB8)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R16G16B16_UINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R16G16B16_SINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R32_SFIXED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R10G10B10A2_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R10G10B10A2_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R10G10B10A2_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R10G10B10A2_SINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B10G10R10A2_SNORM)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B10G10R10A2_USCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B10G10R10A2_SSCALED)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B10G10R10A2_UINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_B10G10R10A2_SINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R64G64B64A64_PASSTHRU)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R64G64B64_PASSTHRU)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC2_RGB8_PTA)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC2_SRGB8_PTA)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC2_EAC_RGBA8)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_ETC2_EAC_SRGB8_A8)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8_UINT)
-   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8_SINT)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, FXT1)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8B8_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8B8_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8B8_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R8G8B8_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R64G64B64A64_FLOAT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R64G64B64_FLOAT)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC4_SNORM)
+   SF( Y,  Y,  x,  x,  x,  x,  x,  x,  x, BC5_SNORM)
+   SF(50, 50,  x,  x,  x,  x, 60,  x,  x, R16G16B16_FLOAT)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16B16_UNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16B16_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16B16_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  Y,  x,  x, R16G16B16_USCALED)
+   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BC6H_SF16)
+   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BC7_UNORM)
+   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BC7_UNORM_SRGB)
+   SF(70, 70,  x,  x,  x,  x,  x,  x,  x, BC6H_UF16)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, PLANAR_420_8)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R8G8B8_UNORM_SRGB)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC1_RGB8)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC2_RGB8)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, EAC_R11)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, EAC_RG11)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, EAC_SIGNED_R11)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, EAC_SIGNED_RG11)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC2_SRGB8)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R16G16B16_UINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R16G16B16_SINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R32_SFIXED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R10G10B10A2_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R10G10B10A2_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R10G10B10A2_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R10G10B10A2_SINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, B10G10R10A2_SNORM)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, B10G10R10A2_USCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, B10G10R10A2_SSCALED)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, B10G10R10A2_UINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, B10G10R10A2_SINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R64G64B64A64_PASSTHRU)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R64G64B64_PASSTHRU)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC2_RGB8_PTA)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC2_SRGB8_PTA)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC2_EAC_RGBA8)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, ETC2_EAC_SRGB8_A8)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R8G8B8_UINT)
+   SF( x,  x,  x,  x,  x,  x,  x,  x,  x, R8G8B8_SINT)
 };
 #undef x
 #undef Y
 
+const char *
+brw_surface_format_name(unsigned format)
+{
+   return surface_formats[format].name;
+}
+
 uint32_t
 brw_format_for_mesa_format(mesa_format mesa_format)
 {
index 72b02a2cf0a0d261bc65b1fb1fe9d4f017e7a088..998d8c427704ca418a543d2c87c631a46b8b5130 100644 (file)
 
 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
 
+static unsigned int
+tr_mode_horizontal_texture_alignment(const struct brw_context *brw,
+                                     const struct intel_mipmap_tree *mt)
+{
+   const unsigned *align_yf, *align_ys;
+   const unsigned bpp = _mesa_get_format_bytes(mt->format) * 8;
+   unsigned ret_align, divisor;
+
+   /* Horizontal alignment tables for TRMODE_{YF,YS}. Value in below
+    * tables specifies the horizontal alignment requirement in elements
+    * for the surface. An element is defined as a pixel in uncompressed
+    * surface formats, and as a compression block in compressed surface
+    * formats. For MSFMT_DEPTH_STENCIL type multisampled surfaces, an
+    * element is a sample.
+    */
+   const unsigned align_1d_yf[] = {4096, 2048, 1024, 512, 256};
+   const unsigned align_1d_ys[] = {65536, 32768, 16384, 8192, 4096};
+   const unsigned align_2d_yf[] = {64, 64, 32, 32, 16};
+   const unsigned align_2d_ys[] = {256, 256, 128, 128, 64};
+   const unsigned align_3d_yf[] = {16, 8, 8, 8, 4};
+   const unsigned align_3d_ys[] = {64, 32, 32, 32, 16};
+   int i = 0;
+
+   /* Alignment computations below assume bpp >= 8 and a power of 2. */
+   assert (bpp >= 8 && bpp <= 128 && is_power_of_two(bpp));
+
+   switch(mt->target) {
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_1D_ARRAY:
+      align_yf = align_1d_yf;
+      align_ys = align_1d_ys;
+      break;
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_RECTANGLE:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_CUBE_MAP:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      align_yf = align_2d_yf;
+      align_ys = align_2d_ys;
+      break;
+   case GL_TEXTURE_3D:
+      align_yf = align_3d_yf;
+      align_ys = align_3d_ys;
+      break;
+   default:
+      unreachable("not reached");
+   }
+
+   /* Compute array index. */
+   i = ffs(bpp/8) - 1;
+
+   ret_align = mt->tr_mode == INTEL_MIPTREE_TRMODE_YF ?
+               align_yf[i] : align_ys[i];
+
+   assert(is_power_of_two(mt->num_samples));
+
+   switch (mt->num_samples) {
+   case 2:
+   case 4:
+      divisor = 2;
+      break;
+   case 8:
+   case 16:
+      divisor = 4;
+      break;
+   default:
+      divisor = 1;
+      break;
+   }
+   return ret_align / divisor;
+}
+
+
 static unsigned int
 intel_horizontal_texture_alignment_unit(struct brw_context *brw,
-                                        struct intel_mipmap_tree *mt)
+                                        struct intel_mipmap_tree *mt,
+                                        uint32_t layout_flags)
 {
+   if (layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16)
+      return 16;
+
    /**
     * From the "Alignment Unit Size" section of various specs, namely:
     * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
@@ -88,18 +167,85 @@ intel_horizontal_texture_alignment_unit(struct brw_context *brw,
    if (mt->format == MESA_FORMAT_S_UINT8)
       return 8;
 
+   if (brw->gen >= 9 && mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE) {
+      uint32_t align = tr_mode_horizontal_texture_alignment(brw, mt);
+      /* XY_FAST_COPY_BLT doesn't support horizontal alignment < 32. */
+      return align < 32 ? 32 : align;
+   }
+
    if (brw->gen >= 7 && mt->format == MESA_FORMAT_Z_UNORM16)
       return 8;
 
-   if (brw->gen == 8 && mt->mcs_mt && mt->num_samples <= 1)
-      return 16;
-
    return 4;
 }
 
+static unsigned int
+tr_mode_vertical_texture_alignment(const struct brw_context *brw,
+                                   const struct intel_mipmap_tree *mt)
+{
+   const unsigned *align_yf, *align_ys;
+   const unsigned bpp = _mesa_get_format_bytes(mt->format) * 8;
+   unsigned ret_align, divisor;
+
+   /* Vertical alignment tables for TRMODE_YF and TRMODE_YS. */
+   const unsigned align_2d_yf[] = {64, 32, 32, 16, 16};
+   const unsigned align_2d_ys[] = {256, 128, 128, 64, 64};
+   const unsigned align_3d_yf[] = {16, 16, 16, 8, 8};
+   const unsigned align_3d_ys[] = {32, 32, 32, 16, 16};
+   int i = 0;
+
+   assert(brw->gen >= 9 &&
+          mt->target != GL_TEXTURE_1D &&
+          mt->target != GL_TEXTURE_1D_ARRAY);
+
+   /* Alignment computations below assume bpp >= 8 and a power of 2. */
+   assert (bpp >= 8 && bpp <= 128 && is_power_of_two(bpp)) ;
+
+   switch(mt->target) {
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_RECTANGLE:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_CUBE_MAP:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      align_yf = align_2d_yf;
+      align_ys = align_2d_ys;
+      break;
+   case GL_TEXTURE_3D:
+      align_yf = align_3d_yf;
+      align_ys = align_3d_ys;
+      break;
+   default:
+      unreachable("not reached");
+   }
+
+   /* Compute array index. */
+   i = ffs(bpp / 8) - 1;
+
+   ret_align = mt->tr_mode == INTEL_MIPTREE_TRMODE_YF ?
+               align_yf[i] : align_ys[i];
+
+   assert(is_power_of_two(mt->num_samples));
+
+   switch (mt->num_samples) {
+   case 4:
+   case 8:
+      divisor = 2;
+      break;
+   case 16:
+      divisor = 4;
+      break;
+   default:
+      divisor = 1;
+      break;
+   }
+   return ret_align / divisor;
+}
+
 static unsigned int
 intel_vertical_texture_alignment_unit(struct brw_context *brw,
-                                      mesa_format format, bool multisampled)
+                                      const struct intel_mipmap_tree *mt)
 {
    /**
     * From the "Alignment Unit Size" section of various specs, namely:
@@ -124,23 +270,29 @@ intel_vertical_texture_alignment_unit(struct brw_context *brw,
     * Where "*" means either VALIGN_2 or VALIGN_4 depending on the setting of
     * the SURFACE_STATE "Surface Vertical Alignment" field.
     */
-   if (_mesa_is_format_compressed(format))
+   if (_mesa_is_format_compressed(mt->format))
       /* See comment above for the horizontal alignment */
       return brw->gen >= 9 ? 16 : 4;
 
-   if (format == MESA_FORMAT_S_UINT8)
+   if (mt->format == MESA_FORMAT_S_UINT8)
       return brw->gen >= 7 ? 8 : 4;
 
+   if (mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE) {
+      uint32_t align = tr_mode_vertical_texture_alignment(brw, mt);
+      /* XY_FAST_COPY_BLT doesn't support vertical alignment < 64 */
+      return align < 64 ? 64 : align;
+   }
+
    /* Broadwell only supports VALIGN of 4, 8, and 16.  The BSpec says 4
     * should always be used, except for stencil buffers, which should be 8.
     */
    if (brw->gen >= 8)
       return 4;
 
-   if (multisampled)
+   if (mt->num_samples > 1)
       return 4;
 
-   GLenum base_format = _mesa_get_format_base_format(format);
+   GLenum base_format = _mesa_get_format_base_format(mt->format);
 
    if (brw->gen >= 6 &&
        (base_format == GL_DEPTH_COMPONENT ||
@@ -161,7 +313,7 @@ intel_vertical_texture_alignment_unit(struct brw_context *brw,
        *
        *     VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
        */
-      if (base_format == GL_YCBCR_MESA || format == MESA_FORMAT_RGB_FLOAT32)
+      if (base_format == GL_YCBCR_MESA || mt->format == MESA_FORMAT_RGB_FLOAT32)
          return 2;
 
       return 4;
@@ -348,9 +500,9 @@ align_cube(struct intel_mipmap_tree *mt)
       mt->total_height += 2;
 }
 
-static bool
-use_linear_1d_layout(struct brw_context *brw,
-                     struct intel_mipmap_tree *mt)
+bool
+gen9_use_linear_1d_layout(const struct brw_context *brw,
+                          const struct intel_mipmap_tree *mt)
 {
    /* On Gen9+ the mipmap levels of a 1D surface are all laid out in a
     * horizontal line. This isn't done for depth/stencil buffers however
@@ -375,7 +527,7 @@ brw_miptree_layout_texture_array(struct brw_context *brw,
                                 struct intel_mipmap_tree *mt)
 {
    unsigned height = mt->physical_height0;
-   bool layout_1d = use_linear_1d_layout(brw, mt);
+   bool layout_1d = gen9_use_linear_1d_layout(brw, mt);
    int physical_qpitch;
 
    if (layout_1d)
@@ -458,46 +610,111 @@ brw_miptree_layout_texture_3d(struct brw_context *brw,
    align_cube(mt);
 }
 
-void
-brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
+/**
+ * \brief Helper function for intel_miptree_create().
+ */
+static uint32_t
+brw_miptree_choose_tiling(struct brw_context *brw,
+                          enum intel_miptree_tiling_mode requested,
+                          const struct intel_mipmap_tree *mt)
 {
-   bool multisampled = mt->num_samples > 1;
-   bool gen6_hiz_or_stencil = false;
+   if (mt->format == MESA_FORMAT_S_UINT8) {
+      /* The stencil buffer is W tiled. However, we request from the kernel a
+       * non-tiled buffer because the GTT is incapable of W fencing.
+       */
+      return I915_TILING_NONE;
+   }
 
-   if (brw->gen == 6 && mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
-      const GLenum base_format = _mesa_get_format_base_format(mt->format);
-      gen6_hiz_or_stencil = _mesa_is_depth_or_stencil_format(base_format);
+   /* Some usages may want only one type of tiling, like depth miptrees (Y
+    * tiled), or temporary BOs for uploading data once (linear).
+    */
+   switch (requested) {
+   case INTEL_MIPTREE_TILING_ANY:
+      break;
+   case INTEL_MIPTREE_TILING_Y:
+      return I915_TILING_Y;
+   case INTEL_MIPTREE_TILING_NONE:
+      return I915_TILING_NONE;
    }
 
-   if (gen6_hiz_or_stencil) {
-      /* On gen6, we use ALL_SLICES_AT_EACH_LOD for stencil/hiz because the
-       * hardware doesn't support multiple mip levels on stencil/hiz.
+   if (mt->num_samples > 1) {
+      /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
+       * Surface"):
        *
-       * PRM Vol 2, Part 1, 7.5.3 Hierarchical Depth Buffer:
-       * "The hierarchical depth buffer does not support the LOD field"
+       *   [DevSNB+]: For multi-sample render targets, this field must be
+       *   1. MSRTs can only be tiled.
        *
-       * PRM Vol 2, Part 1, 7.5.4.1 Separate Stencil Buffer:
-       * "The stencil depth buffer does not support the LOD field"
+       * Our usual reason for preferring X tiling (fast blits using the
+       * blitting engine) doesn't apply to MSAA, since we'll generally be
+       * downsampling or upsampling when blitting between the MSAA buffer
+       * and another buffer, and the blitting engine doesn't support that.
+       * So use Y tiling, since it makes better use of the cache.
        */
-      if (mt->format == MESA_FORMAT_S_UINT8) {
-         /* Stencil uses W tiling, so we force W tiling alignment for the
-          * ALL_SLICES_AT_EACH_LOD miptree layout.
-          */
-         mt->align_w = 64;
-         mt->align_h = 64;
-      } else {
-         /* Depth uses Y tiling, so we force need Y tiling alignment for the
-          * ALL_SLICES_AT_EACH_LOD miptree layout.
-          */
-         mt->align_w = 128 / mt->cpp;
-         mt->align_h = 32;
-      }
-   } else {
-      mt->align_w = intel_horizontal_texture_alignment_unit(brw, mt);
-      mt->align_h =
-         intel_vertical_texture_alignment_unit(brw, mt->format, multisampled);
+      return I915_TILING_Y;
+   }
+
+   GLenum base_format = _mesa_get_format_base_format(mt->format);
+   if (base_format == GL_DEPTH_COMPONENT ||
+       base_format == GL_DEPTH_STENCIL_EXT)
+      return I915_TILING_Y;
+
+   /* 1D textures (and 1D array textures) don't get any benefit from tiling,
+    * in fact it leads to a less efficient use of memory space and bandwidth
+    * due to tile alignment.
+    */
+   if (mt->logical_height0 == 1)
+      return I915_TILING_NONE;
+
+   int minimum_pitch = mt->total_width * mt->cpp;
+
+   /* If the width is much smaller than a tile, don't bother tiling. */
+   if (minimum_pitch < 64)
+      return I915_TILING_NONE;
+
+   if (ALIGN(minimum_pitch, 512) >= 32768 ||
+       mt->total_width >= 32768 || mt->total_height >= 32768) {
+      perf_debug("%dx%d miptree too large to blit, falling back to untiled",
+                 mt->total_width, mt->total_height);
+      return I915_TILING_NONE;
+   }
+
+   /* Pre-gen6 doesn't have BLORP to handle Y-tiling, so use X-tiling. */
+   if (brw->gen < 6)
+      return I915_TILING_X;
+
+   /* From the Sandybridge PRM, Volume 1, Part 2, page 32:
+    * "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either TileX
+    *  or Linear."
+    * 128 bits per pixel translates to 16 bytes per pixel. This is necessary
+    * all the way back to 965, but is permitted on Gen7+.
+    */
+   if (brw->gen < 7 && mt->cpp >= 16)
+      return I915_TILING_X;
+
+   /* From the Ivy Bridge PRM, Vol4 Part1 2.12.2.1 (SURFACE_STATE for most
+    * messages), on p64, under the heading "Surface Vertical Alignment":
+    *
+    *     This field must be set to VALIGN_4 for all tiled Y Render Target
+    *     surfaces.
+    *
+    * So if the surface is renderable and uses a vertical alignment of 2,
+    * force it to be X tiled.  This is somewhat conservative (it's possible
+    * that the client won't ever render to this surface), but it's difficult
+    * to know that ahead of time.  And besides, since we use a vertical
+    * alignment of 4 as often as we can, this shouldn't happen very often.
+    */
+   if (brw->gen == 7 && mt->align_h == 2 &&
+       brw->format_supported_as_render_target[mt->format]) {
+      return I915_TILING_X;
    }
 
+   return I915_TILING_Y | I915_TILING_X;
+}
+
+static void
+intel_miptree_set_total_width_height(struct brw_context *brw,
+                                     struct intel_mipmap_tree *mt)
+{
    switch (mt->target) {
    case GL_TEXTURE_CUBE_MAP:
       if (brw->gen == 4) {
@@ -532,7 +749,7 @@ brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
          break;
       case INTEL_MSAA_LAYOUT_NONE:
       case INTEL_MSAA_LAYOUT_IMS:
-         if (use_linear_1d_layout(brw, mt))
+         if (gen9_use_linear_1d_layout(brw, mt))
             gen9_miptree_layout_1d(mt);
          else
             brw_miptree_layout_2d(mt);
@@ -540,8 +757,62 @@ brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
       }
       break;
    }
+
    DBG("%s: %dx%dx%d\n", __func__,
        mt->total_width, mt->total_height, mt->cpp);
+}
+
+void
+brw_miptree_layout(struct brw_context *brw,
+                   struct intel_mipmap_tree *mt,
+                   enum intel_miptree_tiling_mode requested,
+                   uint32_t layout_flags)
+{
+   bool gen6_hiz_or_stencil = false;
+
+   mt->tr_mode = INTEL_MIPTREE_TRMODE_NONE;
+
+   if (brw->gen == 6 && mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
+      const GLenum base_format = _mesa_get_format_base_format(mt->format);
+      gen6_hiz_or_stencil = _mesa_is_depth_or_stencil_format(base_format);
+   }
+
+   if (gen6_hiz_or_stencil) {
+      /* On gen6, we use ALL_SLICES_AT_EACH_LOD for stencil/hiz because the
+       * hardware doesn't support multiple mip levels on stencil/hiz.
+       *
+       * PRM Vol 2, Part 1, 7.5.3 Hierarchical Depth Buffer:
+       * "The hierarchical depth buffer does not support the LOD field"
+       *
+       * PRM Vol 2, Part 1, 7.5.4.1 Separate Stencil Buffer:
+       * "The stencil depth buffer does not support the LOD field"
+       */
+      if (mt->format == MESA_FORMAT_S_UINT8) {
+         /* Stencil uses W tiling, so we force W tiling alignment for the
+          * ALL_SLICES_AT_EACH_LOD miptree layout.
+          */
+         mt->align_w = 64;
+         mt->align_h = 64;
+         assert((layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16) == 0);
+      } else {
+         /* Depth uses Y tiling, so we force need Y tiling alignment for the
+          * ALL_SLICES_AT_EACH_LOD miptree layout.
+          */
+         mt->align_w = 128 / mt->cpp;
+         mt->align_h = 32;
+      }
+   } else {
+      mt->align_w =
+         intel_horizontal_texture_alignment_unit(brw, mt, layout_flags);
+      mt->align_h = intel_vertical_texture_alignment_unit(brw, mt);
+   }
+
+   intel_miptree_set_total_width_height(brw, mt);
+
+   if (!mt->total_width || !mt->total_height) {
+      intel_miptree_release(&mt);
+      return;
+   }
 
    /* On Gen9+ the alignment values are expressed in multiples of the block
     * size
@@ -552,5 +823,8 @@ brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
       mt->align_w /= i;
       mt->align_h /= j;
    }
+
+   if ((layout_flags & MIPTREE_LAYOUT_FOR_BO) == 0)
+      mt->tiling = brw_miptree_choose_tiling(brw, requested, mt);
 }
 
index b548d234538043885b67dde8e9eaf2e97b83e91b..04e4e944118ecae7d80cad371fe7d1523f3e71c3 100644 (file)
 
 #include "main/mtypes.h"
 #include "main/imports.h"
+#include "brw_context.h"
 
 extern GLuint brw_translate_blend_factor( GLenum factor );
 extern GLuint brw_translate_blend_equation( GLenum mode );
 extern GLenum brw_fix_xRGB_alpha(GLenum function);
 
+static inline uint32_t
+brw_get_line_width(struct brw_context *brw)
+{
+   /* From the OpenGL 4.4 spec:
+    *
+    * "The actual width of non-antialiased lines is determined by rounding
+    * the supplied width to the nearest integer, then clamping it to the
+    * implementation-dependent maximum non-antialiased line width."
+    */
+   float line_width =
+      CLAMP(!brw->ctx.Multisample._Enabled && !brw->ctx.Line.SmoothFlag
+            ? roundf(brw->ctx.Line.Width) : brw->ctx.Line.Width,
+            0.0, brw->ctx.Const.MaxLineWidth);
+   uint32_t line_width_u3_7 = U_FIXED(line_width, 7);
+
+   /* Line width of 0 is not allowed when MSAA enabled */
+   if (brw->ctx.Multisample._Enabled) {
+      if (line_width_u3_7 == 0)
+         line_width_u3_7 = 1;
+   } else if (brw->ctx.Line.SmoothFlag && line_width < 1.5) {
+      /* For 1 pixel line thickness or less, the general
+       * anti-aliasing algorithm gives up, and a garbage line is
+       * generated.  Setting a Line Width of 0.0 specifies the
+       * rasterization of the "thinnest" (one-pixel-wide),
+       * non-antialiased lines.
+       *
+       * Lines rendered with zero Line Width are rasterized using
+       * Grid Intersection Quantization rules as specified by
+       * bspec section 6.3.12.1 Zero-Width (Cosmetic) Line
+       * Rasterization.
+       */
+      line_width_u3_7 = 0;
+   }
+
+   return line_width_u3_7;
+}
+
 #endif
index 2841d983ad567d14fb117998442dfd203e800a38..a5c686ceaaff1666ab786a85abb7aff3db0f28a1 100644 (file)
@@ -35,6 +35,7 @@ extern "C" {
 #include "program/prog_print.h"
 #include "program/prog_parameter.h"
 }
+#include "main/context.h"
 
 #define MAX_INSTRUCTION (1 << 30)
 
@@ -1676,20 +1677,16 @@ vec4_visitor::emit_shader_time_end()
     */
    emit(ADD(diff, src_reg(diff), src_reg(-2u)));
 
-   emit_shader_time_write(st_base, src_reg(diff));
-   emit_shader_time_write(st_written, src_reg(1u));
+   emit_shader_time_write(0, src_reg(diff));
+   emit_shader_time_write(1, src_reg(1u));
    emit(BRW_OPCODE_ELSE);
-   emit_shader_time_write(st_reset, src_reg(1u));
+   emit_shader_time_write(2, src_reg(1u));
    emit(BRW_OPCODE_ENDIF);
 }
 
 void
-vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type,
-                                     src_reg value)
+vec4_visitor::emit_shader_time_write(int shader_time_subindex, src_reg value)
 {
-   int shader_time_index =
-      brw_get_shader_time_index(brw, shader_prog, prog, type);
-
    dst_reg dst =
       dst_reg(this, glsl_type::get_array_instance(glsl_type::vec4_type, 2));
 
@@ -1698,7 +1695,8 @@ vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type,
    time.reg_offset++;
 
    offset.type = BRW_REGISTER_TYPE_UD;
-   emit(MOV(offset, src_reg(shader_time_index * SHADER_TIME_STRIDE)));
+   int index = shader_time_index * 3 + shader_time_subindex;
+   emit(MOV(offset, src_reg(index * SHADER_TIME_STRIDE)));
 
    time.type = BRW_REGISTER_TYPE_UD;
    emit(MOV(time, src_reg(value)));
@@ -1709,11 +1707,11 @@ vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type,
 }
 
 bool
-vec4_visitor::run()
+vec4_visitor::run(gl_clip_plane *clip_planes)
 {
    sanity_param_count = prog->Parameters->NumParameters;
 
-   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+   if (shader_time_index >= 0)
       emit_shader_time_begin();
 
    assign_binding_table_offsets();
@@ -1731,7 +1729,7 @@ vec4_visitor::run()
    base_ir = NULL;
 
    if (key->userclip_active && !prog->UsesClipDistanceOut)
-      setup_uniform_clipplane_values();
+      setup_uniform_clipplane_values(clip_planes);
 
    emit_thread_end();
 
@@ -1768,7 +1766,7 @@ vec4_visitor::run()
          snprintf(filename, 64, "%s-%04d-%02d-%02d-" #pass,            \
                   stage_abbrev, shader_prog ? shader_prog->Name : 0, iteration, pass_num); \
                                                                        \
-         backend_visitor::dump_instructions(filename);                 \
+         backend_shader::dump_instructions(filename);                  \
       }                                                                \
                                                                        \
       progress = progress || this_progress;                            \
@@ -1781,7 +1779,7 @@ vec4_visitor::run()
       snprintf(filename, 64, "%s-%04d-00-start",
                stage_abbrev, shader_prog ? shader_prog->Name : 0);
 
-      backend_visitor::dump_instructions(filename);
+      backend_shader::dump_instructions(filename);
    }
 
    bool progress;
@@ -1868,8 +1866,6 @@ brw_vs_emit(struct brw_context *brw,
    bool start_busy = false;
    double start_time = 0;
    const unsigned *assembly = NULL;
-   bool use_nir =
-      brw->ctx.Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].NirOptions != NULL;
 
    if (unlikely(brw->perf_debug)) {
       start_busy = (brw->batch.last_bo &&
@@ -1881,22 +1877,33 @@ brw_vs_emit(struct brw_context *brw,
    if (prog)
       shader = (brw_shader *) prog->_LinkedShaders[MESA_SHADER_VERTEX];
 
+   int st_index = -1;
+   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+      st_index = brw_get_shader_time_index(brw, prog, &c->vp->program.Base,
+                                           ST_VS);
+
    if (unlikely(INTEL_DEBUG & DEBUG_VS))
       brw_dump_ir("vertex", prog, &shader->base, &c->vp->program.Base);
 
-   if (use_nir && !c->vp->program.Base.nir) {
-      /* Normally we generate NIR in LinkShader() or ProgramStringNotify(), but
-       * Mesa's fixed-function vertex program handling doesn't notify the driver
-       * at all.  Just do it here, at the last minute, even though it's lame.
-       */
-      assert(c->vp->program.Base.Id == 0 && prog == NULL);
-      c->vp->program.Base.nir =
-         brw_create_nir(brw, NULL, &c->vp->program.Base, MESA_SHADER_VERTEX);
-   }
+   if (brw->intelScreen->compiler->scalar_vs) {
+      if (!c->vp->program.Base.nir) {
+         /* Normally we generate NIR in LinkShader() or
+          * ProgramStringNotify(), but Mesa's fixed-function vertex program
+          * handling doesn't notify the driver at all.  Just do it here, at
+          * the last minute, even though it's lame.
+          */
+         assert(c->vp->program.Base.Id == 0 && prog == NULL);
+         c->vp->program.Base.nir =
+            brw_create_nir(brw, NULL, &c->vp->program.Base, MESA_SHADER_VERTEX);
+      }
 
-   if (brw->scalar_vs && (prog || use_nir)) {
-      fs_visitor v(brw, mem_ctx, &c->key, prog_data, prog, &c->vp->program, 8);
-      if (!v.run_vs()) {
+      prog_data->base.dispatch_mode = DISPATCH_MODE_SIMD8;
+
+      fs_visitor v(brw->intelScreen->compiler, brw,
+                   mem_ctx, MESA_SHADER_VERTEX, &c->key,
+                   &prog_data->base.base, prog, &c->vp->program.Base,
+                   8, st_index);
+      if (!v.run_vs(brw_select_clip_planes(&brw->ctx))) {
          if (prog) {
             prog->LinkStatus = false;
             ralloc_strcat(&prog->InfoLog, v.fail_msg);
@@ -1908,7 +1915,8 @@ brw_vs_emit(struct brw_context *brw,
          return NULL;
       }
 
-      fs_generator g(brw, mem_ctx, (void *) &c->key, &prog_data->base.base,
+      fs_generator g(brw->intelScreen->compiler, brw,
+                     mem_ctx, (void *) &c->key, &prog_data->base.base,
                      &c->vp->program.Base, v.promoted_constants,
                      v.runtime_check_aads_emit, "VS");
       if (INTEL_DEBUG & DEBUG_VS) {
@@ -1926,13 +1934,16 @@ brw_vs_emit(struct brw_context *brw,
       g.generate_code(v.cfg, 8);
       assembly = g.get_assembly(final_assembly_size);
 
-      prog_data->base.simd8 = true;
       c->base.last_scratch = v.last_scratch;
    }
 
    if (!assembly) {
-      vec4_vs_visitor v(brw, c, prog_data, prog, mem_ctx);
-      if (!v.run()) {
+      prog_data->base.dispatch_mode = DISPATCH_MODE_4X2_DUAL_OBJECT;
+
+      vec4_vs_visitor v(brw->intelScreen->compiler,
+                        c, prog_data, prog, mem_ctx, st_index,
+                        !_mesa_is_gles3(&brw->ctx));
+      if (!v.run(brw_select_clip_planes(&brw->ctx))) {
          if (prog) {
             prog->LinkStatus = false;
             ralloc_strcat(&prog->InfoLog, v.fail_msg);
@@ -1944,7 +1955,8 @@ brw_vs_emit(struct brw_context *brw,
          return NULL;
       }
 
-      vec4_generator g(brw, prog, &c->vp->program.Base, &prog_data->base,
+      vec4_generator g(brw->intelScreen->compiler, brw,
+                       prog, &c->vp->program.Base, &prog_data->base,
                        mem_ctx, INTEL_DEBUG & DEBUG_VS, "vertex", "VS");
       assembly = g.generate_assembly(v.cfg, final_assembly_size);
    }
index 628c6313cc9e254c31b1658f1ead27961e58d69f..2ac169321897d4a7a8b5627cd5e5773e8f9c18eb 100644 (file)
@@ -73,10 +73,10 @@ class vec4_live_variables;
  * Translates either GLSL IR or Mesa IR (for ARB_vertex_program and
  * fixed-function) into VS IR.
  */
-class vec4_visitor : public backend_visitor
+class vec4_visitor : public backend_shader, public ir_visitor
 {
 public:
-   vec4_visitor(struct brw_context *brw,
+   vec4_visitor(const struct brw_compiler *compiler,
                 struct brw_vec4_compile *c,
                 struct gl_program *prog,
                 const struct brw_vue_prog_key *key,
@@ -85,9 +85,7 @@ public:
                 gl_shader_stage stage,
                void *mem_ctx,
                 bool no_spills,
-                shader_time_shader_type st_base,
-                shader_time_shader_type st_written,
-                shader_time_shader_type st_reset);
+                int shader_time_index);
    ~vec4_visitor();
 
    dst_reg dst_null_f()
@@ -160,6 +158,7 @@ public:
    virtual void visit(ir_if *);
    virtual void visit(ir_emit_vertex *);
    virtual void visit(ir_end_primitive *);
+   virtual void visit(ir_barrier *);
    /*@}*/
 
    src_reg result;
@@ -178,10 +177,10 @@ public:
 
    struct hash_table *variable_ht;
 
-   bool run(void);
+   bool run(gl_clip_plane *clip_planes);
    void fail(const char *msg, ...);
 
-   void setup_uniform_clipplane_values();
+   void setup_uniform_clipplane_values(gl_clip_plane *clip_planes);
    void setup_uniform_values(ir_variable *ir);
    void setup_builtin_uniform_values(ir_variable *ir);
    int setup_uniforms(int payload_reg);
@@ -344,8 +343,7 @@ public:
 
    void emit_shader_time_begin();
    void emit_shader_time_end();
-   void emit_shader_time_write(enum shader_time_shader_type type,
-                               src_reg value);
+   void emit_shader_time_write(int shader_time_subindex, src_reg value);
 
    void emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
                             dst_reg dst, src_reg offset, src_reg src0,
@@ -412,9 +410,7 @@ private:
     */
    const bool no_spills;
 
-   const shader_time_shader_type st_base;
-   const shader_time_shader_type st_written;
-   const shader_time_shader_type st_reset;
+   int shader_time_index;
 };
 
 
@@ -426,7 +422,7 @@ private:
 class vec4_generator
 {
 public:
-   vec4_generator(struct brw_context *brw,
+   vec4_generator(const struct brw_compiler *compiler, void *log_data,
                   struct gl_shader_program *shader_prog,
                   struct gl_program *prog,
                   struct brw_vue_prog_data *prog_data,
@@ -508,7 +504,9 @@ private:
                                          struct brw_reg dst);
    void generate_unpack_flags(struct brw_reg dst);
 
-   struct brw_context *brw;
+   const struct brw_compiler *compiler;
+   void *log_data; /* Passed to compiler->*_log functions */
+
    const struct brw_device_info *devinfo;
 
    struct brw_codegen *p;
index 9147c3cbb793e0a89d5d2909449b57b39df88944..c9fe0cebf2757bef1deefa7a821bce2d35f7d308 100644 (file)
@@ -114,8 +114,16 @@ instructions_match(vec4_instruction *a, vec4_instruction *b)
 {
    return a->opcode == b->opcode &&
           a->saturate == b->saturate &&
+          a->predicate == b->predicate &&
+          a->predicate_inverse == b->predicate_inverse &&
           a->conditional_mod == b->conditional_mod &&
+          a->flag_subreg == b->flag_subreg &&
           a->dst.type == b->dst.type &&
+          a->offset == b->offset &&
+          a->mlen == b->mlen &&
+          a->base_mrf == b->base_mrf &&
+          a->header_size == b->header_size &&
+          a->shadow_compare == b->shadow_compare &&
           a->dst.writemask == b->dst.writemask &&
           a->force_writemask_all == b->force_writemask_all &&
           a->regs_written == b->regs_written &&
index ef77b8df05148afafd06fe87e17d6be1ca3d4da8..d2de2f0be25cfa5cbfbcb10974685e2227cc97ea 100644 (file)
@@ -134,7 +134,8 @@ vec4_instruction::get_src(const struct brw_vue_prog_data *prog_data, int i)
    return brw_reg;
 }
 
-vec4_generator::vec4_generator(struct brw_context *brw,
+vec4_generator::vec4_generator(const struct brw_compiler *compiler,
+                               void *log_data,
                                struct gl_shader_program *shader_prog,
                                struct gl_program *prog,
                                struct brw_vue_prog_data *prog_data,
@@ -142,13 +143,13 @@ vec4_generator::vec4_generator(struct brw_context *brw,
                                bool debug_flag,
                                const char *stage_name,
                                const char *stage_abbrev)
-   : brw(brw), devinfo(brw->intelScreen->devinfo),
+   : compiler(compiler), log_data(log_data), devinfo(compiler->devinfo),
      shader_prog(shader_prog), prog(prog), prog_data(prog_data),
      mem_ctx(mem_ctx), stage_name(stage_name), stage_abbrev(stage_abbrev),
      debug_flag(debug_flag)
 {
    p = rzalloc(mem_ctx, struct brw_codegen);
-   brw_init_codegen(brw->intelScreen->devinfo, p, mem_ctx);
+   brw_init_codegen(devinfo, p, mem_ctx);
 }
 
 vec4_generator::~vec4_generator()
@@ -398,30 +399,25 @@ vec4_generator::generate_tex(vec4_instruction *inst,
       brw_mark_surface_used(&prog_data->base, sampler + base_binding_table_index);
    } else {
       /* Non-constant sampler index. */
-      /* Note: this clobbers `dst` as a temporary before emitting the send */
 
       struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD));
-      struct brw_reg temp = vec1(retype(dst, BRW_REGISTER_TYPE_UD));
-
       struct brw_reg sampler_reg = vec1(retype(sampler_index, BRW_REGISTER_TYPE_UD));
 
       brw_push_insn_state(p);
       brw_set_default_mask_control(p, BRW_MASK_DISABLE);
       brw_set_default_access_mode(p, BRW_ALIGN_1);
 
-      /* Some care required: `sampler` and `temp` may alias:
-       *    addr = sampler & 0xff
-       *    temp = (sampler << 8) & 0xf00
-       *    addr = addr | temp
-       */
-      brw_ADD(p, addr, sampler_reg, brw_imm_ud(base_binding_table_index));
-      brw_SHL(p, temp, sampler_reg, brw_imm_ud(8u));
-      brw_AND(p, temp, temp, brw_imm_ud(0x0f00));
-      brw_AND(p, addr, addr, brw_imm_ud(0x0ff));
-      brw_OR(p, addr, addr, temp);
+      /* addr = ((sampler * 0x101) + base_binding_table_index) & 0xfff */
+      brw_MUL(p, addr, sampler_reg, brw_imm_uw(0x101));
+      if (base_binding_table_index)
+         brw_ADD(p, addr, addr, brw_imm_ud(base_binding_table_index));
+      brw_AND(p, addr, addr, brw_imm_ud(0xfff));
 
       brw_pop_insn_state(p);
 
+      if (inst->base_mrf != -1)
+         gen6_resolve_implied_move(p, &src, inst->base_mrf);
+
       /* dst = send(offset, a0.0 | <descriptor>) */
       brw_inst *insn = brw_send_indirect_message(
          p, BRW_SFID_SAMPLER, dst, src, addr);
@@ -1631,16 +1627,11 @@ vec4_generator::generate_code(const cfg_t *cfg)
       ralloc_free(annotation.ann);
    }
 
-   static GLuint msg_id = 0;
-   _mesa_gl_debug(&brw->ctx, &msg_id,
-                  MESA_DEBUG_SOURCE_SHADER_COMPILER,
-                  MESA_DEBUG_TYPE_OTHER,
-                  MESA_DEBUG_SEVERITY_NOTIFICATION,
-                  "%s vec4 shader: %d inst, %d loops, "
-                  "compacted %d to %d bytes.\n",
-                  stage_abbrev,
-                  before_size / 16, loop_count,
-                  before_size, after_size);
+   compiler->shader_debug_log(log_data,
+                              "%s vec4 shader: %d inst, %d loops, "
+                              "compacted %d to %d bytes.\n",
+                              stage_abbrev, before_size / 16, loop_count,
+                              before_size, after_size);
 }
 
 const unsigned *
index 363e30e34e4155efd7f4d2bbd152f91e2b7e88b1..69bcf5afc51353374b131b713acc991af2775f7f 100644 (file)
@@ -34,15 +34,15 @@ const unsigned MAX_GS_INPUT_VERTICES = 6;
 
 namespace brw {
 
-vec4_gs_visitor::vec4_gs_visitor(struct brw_context *brw,
+vec4_gs_visitor::vec4_gs_visitor(const struct brw_compiler *compiler,
                                  struct brw_gs_compile *c,
                                  struct gl_shader_program *prog,
                                  void *mem_ctx,
-                                 bool no_spills)
-   : vec4_visitor(brw, &c->base, &c->gp->program.Base, &c->key.base,
+                                 bool no_spills,
+                                 int shader_time_index)
+   : vec4_visitor(compiler, &c->base, &c->gp->program.Base, &c->key.base,
                   &c->prog_data.base, prog, MESA_SHADER_GEOMETRY, mem_ctx,
-                  no_spills,
-                  ST_GS, ST_GS_WRITTEN, ST_GS_RESET),
+                  no_spills, shader_time_index),
      c(c)
 {
 }
@@ -106,7 +106,7 @@ vec4_gs_visitor::setup_payload()
     * to be interleaved, so one register contains two attribute slots.
     */
    int attributes_per_reg =
-      c->prog_data.dispatch_mode == GEN7_GS_DISPATCH_MODE_DUAL_OBJECT ? 1 : 2;
+      c->prog_data.base.dispatch_mode == DISPATCH_MODE_4X2_DUAL_OBJECT ? 1 : 2;
 
    /* If a geometry shader tries to read from an input that wasn't written by
     * the vertex shader, that produces undefined results, but it shouldn't
@@ -629,7 +629,8 @@ generate_assembly(struct brw_context *brw,
                   const cfg_t *cfg,
                   unsigned *final_assembly_size)
 {
-   vec4_generator g(brw, shader_prog, prog, prog_data, mem_ctx,
+   vec4_generator g(brw->intelScreen->compiler, brw,
+                    shader_prog, prog, prog_data, mem_ctx,
                     INTEL_DEBUG & DEBUG_GS, "geometry", "GS");
    return g.generate_assembly(cfg, final_assembly_size);
 }
@@ -648,6 +649,10 @@ brw_gs_emit(struct brw_context *brw,
       brw_dump_ir("geometry", prog, &shader->base, NULL);
    }
 
+   int st_index = -1;
+   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
+      st_index = brw_get_shader_time_index(brw, prog, NULL, ST_GS);
+
    if (brw->gen >= 7) {
       /* Compile the geometry shader in DUAL_OBJECT dispatch mode, if we can do
        * so without spilling. If the GS invocations count > 1, then we can't use
@@ -655,10 +660,11 @@ brw_gs_emit(struct brw_context *brw,
        */
       if (c->prog_data.invocations <= 1 &&
           likely(!(INTEL_DEBUG & DEBUG_NO_DUAL_OBJECT_GS))) {
-         c->prog_data.dispatch_mode = GEN7_GS_DISPATCH_MODE_DUAL_OBJECT;
+         c->prog_data.base.dispatch_mode = DISPATCH_MODE_4X2_DUAL_OBJECT;
 
-         vec4_gs_visitor v(brw, c, prog, mem_ctx, true /* no_spills */);
-         if (v.run()) {
+         vec4_gs_visitor v(brw->intelScreen->compiler,
+                           c, prog, mem_ctx, true /* no_spills */, st_index);
+         if (v.run(NULL /* clip planes */)) {
             return generate_assembly(brw, prog, &c->gp->program.Base,
                                      &c->prog_data.base, mem_ctx, v.cfg,
                                      final_assembly_size);
@@ -690,19 +696,23 @@ brw_gs_emit(struct brw_context *brw,
     * SINGLE mode.
     */
    if (c->prog_data.invocations <= 1 || brw->gen < 7)
-      c->prog_data.dispatch_mode = GEN7_GS_DISPATCH_MODE_SINGLE;
+      c->prog_data.base.dispatch_mode = DISPATCH_MODE_4X1_SINGLE;
    else
-      c->prog_data.dispatch_mode = GEN7_GS_DISPATCH_MODE_DUAL_INSTANCE;
+      c->prog_data.base.dispatch_mode = DISPATCH_MODE_4X2_DUAL_INSTANCE;
 
    vec4_gs_visitor *gs = NULL;
    const unsigned *ret = NULL;
 
    if (brw->gen >= 7)
-      gs = new vec4_gs_visitor(brw, c, prog, mem_ctx, false /* no_spills */);
+      gs = new vec4_gs_visitor(brw->intelScreen->compiler,
+                               c, prog, mem_ctx, false /* no_spills */,
+                               st_index);
    else
-      gs = new gen6_gs_visitor(brw, c, prog, mem_ctx, false /* no_spills */);
+      gs = new gen6_gs_visitor(brw->intelScreen->compiler,
+                               c, prog, mem_ctx, false /* no_spills */,
+                               st_index);
 
-   if (!gs->run()) {
+   if (!gs->run(NULL /* clip planes */)) {
       prog->LinkStatus = false;
       ralloc_strcat(&prog->InfoLog, gs->fail_msg);
    } else {
index bcb5a2bcfc1a392fc4c8c8f93d49939349a61919..e693c56b58f5412113075905d1204c0e1e1fba24 100644 (file)
@@ -68,11 +68,12 @@ namespace brw {
 class vec4_gs_visitor : public vec4_visitor
 {
 public:
-   vec4_gs_visitor(struct brw_context *brw,
+   vec4_gs_visitor(const struct brw_compiler *compiler,
                    struct brw_gs_compile *c,
                    struct gl_shader_program *prog,
                    void *mem_ctx,
-                   bool no_spills);
+                   bool no_spills,
+                   int shader_time_index);
 
 protected:
    virtual dst_reg *make_reg_for_system_value(ir_variable *ir);
index 5368a75bc0f735d64fbc7380387702d677140a51..555c42e2f24790666fb9880a3f05a73f6e714f49 100644 (file)
@@ -191,7 +191,6 @@ vec4_visitor::setup_payload_interference(struct ra_graph *g,
 bool
 vec4_visitor::reg_allocate()
 {
-   struct brw_compiler *compiler = brw->intelScreen->compiler;
    unsigned int hw_reg_mapping[alloc.count];
    int payload_reg_count = this->first_non_payload_grf;
 
index e51c140c0f28924b906e5bd0988c7c7d9b495758..236fa51f92c0f282fd0287ce318d40b479b7cea1 100644 (file)
@@ -684,9 +684,12 @@ vec4_visitor::setup_uniform_values(ir_variable *ir)
     * order we'd walk the type, so walk the list of storage and find anything
     * with our name, or the prefix of a component that starts with our name.
     */
-   for (unsigned u = 0; u < shader_prog->NumUserUniformStorage; u++) {
+   for (unsigned u = 0; u < shader_prog->NumUniformStorage; u++) {
       struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
 
+      if (storage->builtin)
+         continue;
+
       if (strncmp(ir->name, storage->name, namelen) != 0 ||
           (storage->name[namelen] != 0 &&
            storage->name[namelen] != '.' &&
@@ -718,10 +721,8 @@ vec4_visitor::setup_uniform_values(ir_variable *ir)
 }
 
 void
-vec4_visitor::setup_uniform_clipplane_values()
+vec4_visitor::setup_uniform_clipplane_values(gl_clip_plane *clip_planes)
 {
-   gl_clip_plane *clip_planes = brw_select_clip_planes(ctx);
-
    for (int i = 0; i < key->nr_userclip_plane_consts; ++i) {
       assert(this->uniforms < uniform_array_size);
       this->uniform_vector_size[this->uniforms] = 4;
@@ -2461,11 +2462,27 @@ vec4_visitor::emit_mcs_fetch(ir_texture *ir, src_reg coordinate, src_reg sampler
       new(mem_ctx) vec4_instruction(SHADER_OPCODE_TXF_MCS,
                                     dst_reg(this, glsl_type::uvec4_type));
    inst->base_mrf = 2;
-   inst->mlen = 1;
    inst->src[1] = sampler;
 
+   int param_base;
+
+   if (devinfo->gen >= 9) {
+      /* Gen9+ needs a message header in order to use SIMD4x2 mode */
+      vec4_instruction *header_inst = new(mem_ctx)
+         vec4_instruction(VS_OPCODE_SET_SIMD4X2_HEADER_GEN9,
+                          dst_reg(MRF, inst->base_mrf));
+
+      emit(header_inst);
+
+      inst->mlen = 2;
+      inst->header_size = 1;
+      param_base = inst->base_mrf + 1;
+   } else {
+      inst->mlen = 1;
+      param_base = inst->base_mrf;
+   }
+
    /* parameters are: u, v, r, lod; lod will always be zero due to api restrictions */
-   int param_base = inst->base_mrf;
    int coord_mask = (1 << ir->coordinate->type->vector_elements) - 1;
    int zero_mask = 0xf & ~coord_mask;
 
@@ -2948,6 +2965,12 @@ vec4_visitor::visit(ir_end_primitive *)
    unreachable("not reached");
 }
 
+void
+vec4_visitor::visit(ir_barrier *)
+{
+   unreachable("not reached");
+}
+
 void
 vec4_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
                                   dst_reg dst, src_reg offset,
@@ -3655,7 +3678,7 @@ vec4_visitor::resolve_bool_comparison(ir_rvalue *rvalue, src_reg *reg)
    *reg = neg_result;
 }
 
-vec4_visitor::vec4_visitor(struct brw_context *brw,
+vec4_visitor::vec4_visitor(const struct brw_compiler *compiler,
                            struct brw_vec4_compile *c,
                            struct gl_program *prog,
                            const struct brw_vue_prog_key *key,
@@ -3664,10 +3687,9 @@ vec4_visitor::vec4_visitor(struct brw_context *brw,
                            gl_shader_stage stage,
                           void *mem_ctx,
                            bool no_spills,
-                           shader_time_shader_type st_base,
-                           shader_time_shader_type st_written,
-                           shader_time_shader_type st_reset)
-   : backend_visitor(brw, shader_prog, prog, &prog_data->base, stage),
+                           int shader_time_index)
+   : backend_shader(compiler, NULL, mem_ctx,
+                    shader_prog, prog, &prog_data->base, stage),
      c(c),
      key(key),
      prog_data(prog_data),
@@ -3676,11 +3698,8 @@ vec4_visitor::vec4_visitor(struct brw_context *brw,
      first_non_payload_grf(0),
      need_all_constants_in_pull_buffer(false),
      no_spills(no_spills),
-     st_base(st_base),
-     st_written(st_written),
-     st_reset(st_reset)
+     shader_time_index(shader_time_index)
 {
-   this->mem_ctx = mem_ctx;
    this->failed = false;
 
    this->base_ir = NULL;
index 92d108598a2790e6854af293a1e34ba8b2f5d426..dcbd2405078d667b9d556c75a2b9d80ff2886666 100644 (file)
@@ -381,8 +381,7 @@ vec4_vs_visitor::emit_program_code()
          break;
 
       default:
-         _mesa_problem(ctx, "Unsupported opcode %s in vertex program\n",
-                       _mesa_opcode_string(vpi->Opcode));
+         assert(!"Unsupported opcode in vertex program");
       }
 
       /* Copy the temporary back into the actual destination register. */
@@ -574,15 +573,13 @@ vec4_vs_visitor::get_vp_src_reg(const prog_src_register &src)
          break;
 
       default:
-         _mesa_problem(ctx, "bad uniform src register file: %s\n",
-                       _mesa_register_file_name((gl_register_file)src.File));
+         assert(!"Bad uniform in src register file");
          return src_reg(this, glsl_type::vec4_type);
       }
       break;
 
    default:
-      _mesa_problem(ctx, "bad src register file: %s\n",
-                    _mesa_register_file_name((gl_register_file)src.File));
+      assert(!"Bad src register file");
       return src_reg(this, glsl_type::vec4_type);
    }
 
index 4baf73ebde17e6eb373a3d377a8b422c31200607..f93062b46d04c33d9ab25983576ec4bd415efdab 100644 (file)
@@ -23,7 +23,6 @@
 
 
 #include "brw_vs.h"
-#include "main/context.h"
 
 
 namespace brw {
@@ -78,7 +77,7 @@ vec4_vs_visitor::emit_prolog()
             /* ES 3.0 has different rules for converting signed normalized
              * fixed-point numbers than desktop GL.
              */
-            if (_mesa_is_gles3(ctx) && (wa_flags & BRW_ATTRIB_WA_SIGN)) {
+            if ((wa_flags & BRW_ATTRIB_WA_SIGN) && !use_legacy_snorm_formula) {
                /* According to equation 2.2 of the ES 3.0 specification,
                 * signed normalization conversion is done by:
                 *
@@ -212,18 +211,21 @@ vec4_vs_visitor::emit_thread_end()
 }
 
 
-vec4_vs_visitor::vec4_vs_visitor(struct brw_context *brw,
+vec4_vs_visitor::vec4_vs_visitor(const struct brw_compiler *compiler,
                                  struct brw_vs_compile *vs_compile,
                                  struct brw_vs_prog_data *vs_prog_data,
                                  struct gl_shader_program *prog,
-                                 void *mem_ctx)
-   : vec4_visitor(brw, &vs_compile->base, &vs_compile->vp->program.Base,
+                                 void *mem_ctx,
+                                 int shader_time_index,
+                                 bool use_legacy_snorm_formula)
+   : vec4_visitor(compiler, &vs_compile->base, &vs_compile->vp->program.Base,
                   &vs_compile->key.base, &vs_prog_data->base, prog,
                   MESA_SHADER_VERTEX,
                   mem_ctx, false /* no_spills */,
-                  ST_VS, ST_VS_WRITTEN, ST_VS_RESET),
+                  shader_time_index),
      vs_compile(vs_compile),
-     vs_prog_data(vs_prog_data)
+     vs_prog_data(vs_prog_data),
+     use_legacy_snorm_formula(use_legacy_snorm_formula)
 {
 }
 
index d03567e33b8a8c103d4393a4f8c6e82f1ff0ceb5..6e9848fb1e90c2d47f69bb1adcb9f2a34e290f3e 100644 (file)
 
 #include "util/ralloc.h"
 
-static inline void assign_vue_slot(struct brw_vue_map *vue_map,
-                                   int varying)
-{
-   /* Make sure this varying hasn't been assigned a slot already */
-   assert (vue_map->varying_to_slot[varying] == -1);
-
-   vue_map->varying_to_slot[varying] = vue_map->num_slots;
-   vue_map->slot_to_varying[vue_map->num_slots++] = varying;
-}
-
-/**
- * Compute the VUE map for vertex shader program.
- */
-void
-brw_compute_vue_map(const struct brw_device_info *devinfo,
-                    struct brw_vue_map *vue_map,
-                    GLbitfield64 slots_valid)
-{
-   vue_map->slots_valid = slots_valid;
-   int i;
-
-   /* gl_Layer and gl_ViewportIndex don't get their own varying slots -- they
-    * are stored in the first VUE slot (VARYING_SLOT_PSIZ).
-    */
-   slots_valid &= ~(VARYING_BIT_LAYER | VARYING_BIT_VIEWPORT);
-
-   /* Make sure that the values we store in vue_map->varying_to_slot and
-    * vue_map->slot_to_varying won't overflow the signed chars that are used
-    * to store them.  Note that since vue_map->slot_to_varying sometimes holds
-    * values equal to BRW_VARYING_SLOT_COUNT, we need to ensure that
-    * BRW_VARYING_SLOT_COUNT is <= 127, not 128.
-    */
-   STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 127);
-
-   vue_map->num_slots = 0;
-   for (i = 0; i < BRW_VARYING_SLOT_COUNT; ++i) {
-      vue_map->varying_to_slot[i] = -1;
-      vue_map->slot_to_varying[i] = BRW_VARYING_SLOT_COUNT;
-   }
-
-   /* VUE header: format depends on chip generation and whether clipping is
-    * enabled.
-    */
-   if (devinfo->gen < 6) {
-      /* There are 8 dwords in VUE header pre-Ironlake:
-       * dword 0-3 is indices, point width, clip flags.
-       * dword 4-7 is ndc position
-       * dword 8-11 is the first vertex data.
-       *
-       * On Ironlake the VUE header is nominally 20 dwords, but the hardware
-       * will accept the same header layout as Gen4 [and should be a bit faster]
-       */
-      assign_vue_slot(vue_map, VARYING_SLOT_PSIZ);
-      assign_vue_slot(vue_map, BRW_VARYING_SLOT_NDC);
-      assign_vue_slot(vue_map, VARYING_SLOT_POS);
-   } else {
-      /* There are 8 or 16 DWs (D0-D15) in VUE header on Sandybridge:
-       * dword 0-3 of the header is indices, point width, clip flags.
-       * dword 4-7 is the 4D space position
-       * dword 8-15 of the vertex header is the user clip distance if
-       * enabled.
-       * dword 8-11 or 16-19 is the first vertex element data we fill.
-       */
-      assign_vue_slot(vue_map, VARYING_SLOT_PSIZ);
-      assign_vue_slot(vue_map, VARYING_SLOT_POS);
-      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0))
-         assign_vue_slot(vue_map, VARYING_SLOT_CLIP_DIST0);
-      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1))
-         assign_vue_slot(vue_map, VARYING_SLOT_CLIP_DIST1);
-
-      /* front and back colors need to be consecutive so that we can use
-       * ATTRIBUTE_SWIZZLE_INPUTATTR_FACING to swizzle them when doing
-       * two-sided color.
-       */
-      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_COL0))
-         assign_vue_slot(vue_map, VARYING_SLOT_COL0);
-      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_BFC0))
-         assign_vue_slot(vue_map, VARYING_SLOT_BFC0);
-      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_COL1))
-         assign_vue_slot(vue_map, VARYING_SLOT_COL1);
-      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_BFC1))
-         assign_vue_slot(vue_map, VARYING_SLOT_BFC1);
-   }
-
-   /* The hardware doesn't care about the rest of the vertex outputs, so just
-    * assign them contiguously.  Don't reassign outputs that already have a
-    * slot.
-    *
-    * We generally don't need to assign a slot for VARYING_SLOT_CLIP_VERTEX,
-    * since it's encoded as the clip distances by emit_clip_distances().
-    * However, it may be output by transform feedback, and we'd rather not
-    * recompute state when TF changes, so we just always include it.
-    */
-   for (int i = 0; i < VARYING_SLOT_MAX; ++i) {
-      if ((slots_valid & BITFIELD64_BIT(i)) &&
-          vue_map->varying_to_slot[i] == -1) {
-         assign_vue_slot(vue_map, i);
-      }
-   }
-}
-
-
 /**
  * Decide which set of clip planes should be used when clipping via
  * gl_Position or gl_ClipVertex.
index 6157ae6ffa9d225136e387777d681f04be1af8fd..61f9b006a58e7c73b16074d2a0b324fc3211e7a4 100644 (file)
@@ -90,11 +90,13 @@ namespace brw {
 class vec4_vs_visitor : public vec4_visitor
 {
 public:
-   vec4_vs_visitor(struct brw_context *brw,
+   vec4_vs_visitor(const struct brw_compiler *compiler,
                    struct brw_vs_compile *vs_compile,
                    struct brw_vs_prog_data *vs_prog_data,
                    struct gl_shader_program *prog,
-                   void *mem_ctx);
+                   void *mem_ctx,
+                   int shader_time_index,
+                   bool use_legacy_snorm_formula);
 
 protected:
    virtual dst_reg *make_reg_for_system_value(ir_variable *ir);
@@ -115,6 +117,8 @@ private:
    struct brw_vs_prog_data * const vs_prog_data;
    src_reg *vp_temp_regs;
    src_reg vp_addr_reg;
+
+   bool use_legacy_snorm_formula;
 };
 
 } /* namespace brw */
index f82a62b4851c8eb53ef6408c4da3a3cf3fcc5a28..b2f91bd412bbb43e1b119cd8ec8e838dde8484c8 100644 (file)
@@ -121,7 +121,7 @@ brw_upload_vs_pull_constants(struct brw_context *brw)
    /* BRW_NEW_VS_PROG_DATA */
    const struct brw_stage_prog_data *prog_data = &brw->vs.prog_data->base.base;
 
-   dword_pitch = brw->vs.prog_data->base.simd8;
+   dword_pitch = brw->vs.prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8;
 
    /* _NEW_PROGRAM_CONSTANTS */
    brw_upload_pull_constants(brw, BRW_NEW_VS_CONSTBUF, &vp->program.Base,
@@ -151,7 +151,7 @@ brw_upload_vs_ubo_surfaces(struct brw_context *brw)
       return;
 
    /* BRW_NEW_VS_PROG_DATA */
-   dword_pitch = brw->vs.prog_data->base.simd8;
+   dword_pitch = brw->vs.prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8;
    brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_VERTEX],
                            &brw->vs.base, &brw->vs.prog_data->base.base,
                            dword_pitch);
diff --git a/src/mesa/drivers/dri/i965/brw_vue_map.c b/src/mesa/drivers/dri/i965/brw_vue_map.c
new file mode 100644 (file)
index 0000000..7687578
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright Â© 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * @file brw_vue_map.c
+ *
+ * This file computes the "VUE map" for a (non-fragment) shader stage, which
+ * describes the layout of its output varyings.  The VUE map is used to match
+ * outputs from one stage with the inputs of the next.
+ *
+ * Largely, varyings can be placed however we like - producers/consumers simply
+ * have to agree on the layout.  However, there is also a "VUE Header" that
+ * prescribes a fixed-layout for items that interact with fixed function
+ * hardware, such as the clipper and rasterizer.
+ *
+ * Authors:
+ *   Paul Berry <stereotype441@gmail.com>
+ *   Chris Forbes <chrisf@ijw.co.nz>
+ *   Eric Anholt <eric@anholt.net>
+ */
+
+
+#include "main/compiler.h"
+#include "brw_context.h"
+
+static inline void
+assign_vue_slot(struct brw_vue_map *vue_map, int varying)
+{
+   /* Make sure this varying hasn't been assigned a slot already */
+   assert (vue_map->varying_to_slot[varying] == -1);
+
+   vue_map->varying_to_slot[varying] = vue_map->num_slots;
+   vue_map->slot_to_varying[vue_map->num_slots++] = varying;
+}
+
+/**
+ * Compute the VUE map for a shader stage.
+ */
+void
+brw_compute_vue_map(const struct brw_device_info *devinfo,
+                    struct brw_vue_map *vue_map,
+                    GLbitfield64 slots_valid)
+{
+   vue_map->slots_valid = slots_valid;
+   int i;
+
+   /* gl_Layer and gl_ViewportIndex don't get their own varying slots -- they
+    * are stored in the first VUE slot (VARYING_SLOT_PSIZ).
+    */
+   slots_valid &= ~(VARYING_BIT_LAYER | VARYING_BIT_VIEWPORT);
+
+   /* Make sure that the values we store in vue_map->varying_to_slot and
+    * vue_map->slot_to_varying won't overflow the signed chars that are used
+    * to store them.  Note that since vue_map->slot_to_varying sometimes holds
+    * values equal to BRW_VARYING_SLOT_COUNT, we need to ensure that
+    * BRW_VARYING_SLOT_COUNT is <= 127, not 128.
+    */
+   STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 127);
+
+   vue_map->num_slots = 0;
+   for (i = 0; i < BRW_VARYING_SLOT_COUNT; ++i) {
+      vue_map->varying_to_slot[i] = -1;
+      vue_map->slot_to_varying[i] = BRW_VARYING_SLOT_COUNT;
+   }
+
+   /* VUE header: format depends on chip generation and whether clipping is
+    * enabled.
+    *
+    * See the Sandybridge PRM, Volume 2 Part 1, section 1.5.1 (page 30),
+    * "Vertex URB Entry (VUE) Formats" which describes the VUE header layout.
+    */
+   if (devinfo->gen < 6) {
+      /* There are 8 dwords in VUE header pre-Ironlake:
+       * dword 0-3 is indices, point width, clip flags.
+       * dword 4-7 is ndc position
+       * dword 8-11 is the first vertex data.
+       *
+       * On Ironlake the VUE header is nominally 20 dwords, but the hardware
+       * will accept the same header layout as Gen4 [and should be a bit faster]
+       */
+      assign_vue_slot(vue_map, VARYING_SLOT_PSIZ);
+      assign_vue_slot(vue_map, BRW_VARYING_SLOT_NDC);
+      assign_vue_slot(vue_map, VARYING_SLOT_POS);
+   } else {
+      /* There are 8 or 16 DWs (D0-D15) in VUE header on Sandybridge:
+       * dword 0-3 of the header is indices, point width, clip flags.
+       * dword 4-7 is the 4D space position
+       * dword 8-15 of the vertex header is the user clip distance if
+       * enabled.
+       * dword 8-11 or 16-19 is the first vertex element data we fill.
+       */
+      assign_vue_slot(vue_map, VARYING_SLOT_PSIZ);
+      assign_vue_slot(vue_map, VARYING_SLOT_POS);
+      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0))
+         assign_vue_slot(vue_map, VARYING_SLOT_CLIP_DIST0);
+      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1))
+         assign_vue_slot(vue_map, VARYING_SLOT_CLIP_DIST1);
+
+      /* front and back colors need to be consecutive so that we can use
+       * ATTRIBUTE_SWIZZLE_INPUTATTR_FACING to swizzle them when doing
+       * two-sided color.
+       */
+      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_COL0))
+         assign_vue_slot(vue_map, VARYING_SLOT_COL0);
+      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_BFC0))
+         assign_vue_slot(vue_map, VARYING_SLOT_BFC0);
+      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_COL1))
+         assign_vue_slot(vue_map, VARYING_SLOT_COL1);
+      if (slots_valid & BITFIELD64_BIT(VARYING_SLOT_BFC1))
+         assign_vue_slot(vue_map, VARYING_SLOT_BFC1);
+   }
+
+   /* The hardware doesn't care about the rest of the vertex outputs, so just
+    * assign them contiguously.  Don't reassign outputs that already have a
+    * slot.
+    *
+    * We generally don't need to assign a slot for VARYING_SLOT_CLIP_VERTEX,
+    * since it's encoded as the clip distances by emit_clip_distances().
+    * However, it may be output by transform feedback, and we'd rather not
+    * recompute state when TF changes, so we just always include it.
+    */
+   for (int i = 0; i < VARYING_SLOT_MAX; ++i) {
+      if ((slots_valid & BITFIELD64_BIT(i)) &&
+          vue_map->varying_to_slot[i] == -1) {
+         assign_vue_slot(vue_map, i);
+      }
+   }
+}
index 5496225a6c70da8420787541278f9531291cbce7..4619ce1080d1eb059e5a4937536cfe8dfd2b2e84 100644 (file)
@@ -36,6 +36,7 @@
 #include "main/formats.h"
 #include "main/fbobject.h"
 #include "main/samplerobj.h"
+#include "main/framebuffer.h"
 #include "program/prog_parameter.h"
 #include "program/program.h"
 #include "intel_mipmap_tree.h"
@@ -462,7 +463,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    GLuint lookup = 0;
    GLuint line_aa;
    bool program_uses_dfdy = fp->program.UsesDFdy;
-   bool multisample_fbo = ctx->DrawBuffer->Visual.samples > 1;
+   const bool multisample_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
 
    memset(key, 0, sizeof(*key));
 
@@ -561,7 +562,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
     * drawable height in order to invert the Y axis.
     */
    if (fp->program.Base.InputsRead & VARYING_BIT_POS) {
-      key->drawable_height = ctx->DrawBuffer->Height;
+      key->drawable_height = _mesa_geometric_height(ctx->DrawBuffer);
    }
 
    if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
@@ -580,7 +581,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    key->persample_shading =
       _mesa_get_min_invocations_per_fragment(ctx, &fp->program, true) > 1;
    if (key->persample_shading)
-      key->persample_2x = ctx->DrawBuffer->Visual.samples == 2;
+      key->persample_2x = _mesa_geometric_samples(ctx->DrawBuffer) == 2;
 
    key->compute_pos_offset =
       _mesa_get_min_invocations_per_fragment(ctx, &fp->program, false) > 1 &&
index 160dd2f6c624a7054523b2ad19f08ec5f893a373..72aad96bb6a7cda9ba4bd705f8a25b4466e70e73 100644 (file)
@@ -35,6 +35,7 @@
 #include "main/mtypes.h"
 #include "main/samplerobj.h"
 #include "program/prog_parameter.h"
+#include "main/framebuffer.h"
 
 #include "intel_mipmap_tree.h"
 #include "intel_batchbuffer.h"
@@ -738,6 +739,9 @@ brw_update_renderbuffer_surfaces(struct brw_context *brw,
                                  uint32_t *surf_offset)
 {
    GLuint i;
+   const unsigned int w = _mesa_geometric_width(fb);
+   const unsigned int h = _mesa_geometric_height(fb);
+   const unsigned int s = _mesa_geometric_samples(fb);
 
    /* Update surfaces for drawing buffers */
    if (fb->_NumColorDrawBuffers >= 1) {
@@ -748,17 +752,15 @@ brw_update_renderbuffer_surfaces(struct brw_context *brw,
             surf_offset[surf_index] = 
                brw->vtbl.update_renderbuffer_surface(
                   brw, fb->_ColorDrawBuffers[i],
-                  fb->MaxNumLayers > 0, i, surf_index);
+                  _mesa_geometric_layers(fb) > 0, i, surf_index);
         } else {
-            brw->vtbl.emit_null_surface_state(
-               brw, fb->Width, fb->Height, fb->Visual.samples,
+            brw->vtbl.emit_null_surface_state(brw, w, h, s,
                &surf_offset[surf_index]);
         }
       }
    } else {
       const uint32_t surf_index = render_target_start;
-      brw->vtbl.emit_null_surface_state(
-         brw, fb->Width, fb->Height, fb->Visual.samples,
+      brw->vtbl.emit_null_surface_state(brw, w, h, s,
          &surf_offset[surf_index]);
    }
 }
index aaf90df2b9c49a6a854f05f4a41e4304fe692071..9a29366f0e0de8bfa83df326f8bdf5b4703b5977 100644 (file)
@@ -31,6 +31,7 @@
 #include "brw_util.h"
 #include "intel_batchbuffer.h"
 #include "main/fbobject.h"
+#include "main/framebuffer.h"
 
 static void
 upload_clip_state(struct brw_context *brw)
@@ -145,11 +146,14 @@ upload_clip_state(struct brw_context *brw)
     * the viewport, so we can ignore this restriction.
     */
    if (brw->gen < 8) {
+      const float fb_width = (float)_mesa_geometric_width(fb);
+      const float fb_height = (float)_mesa_geometric_height(fb);
+
       for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
          if (ctx->ViewportArray[i].X != 0 ||
              ctx->ViewportArray[i].Y != 0 ||
-             ctx->ViewportArray[i].Width != (float) fb->Width ||
-             ctx->ViewportArray[i].Height != (float) fb->Height) {
+             ctx->ViewportArray[i].Width != fb_width ||
+             ctx->ViewportArray[i].Height != fb_height) {
             dw2 &= ~GEN6_CLIP_GB_TEST;
             break;
          }
@@ -179,7 +183,7 @@ upload_clip_state(struct brw_context *brw)
             dw2);
    OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT |
              U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT |
-             (fb->MaxNumLayers > 0 ? 0 : GEN6_CLIP_FORCE_ZERO_RTAINDEX) |
+             (_mesa_geometric_layers(fb) > 0 ? 0 : GEN6_CLIP_FORCE_ZERO_RTAINDEX) |
              ((ctx->Const.MaxViewports - 1) & GEN6_CLIP_MAX_VP_INDEX_MASK));
    ADVANCE_BATCH();
 }
index 28f23c9e4f7686db8998a65993db030b8efdbf28..27254ebb7279fb7625e2c9c7c91d0b489d2c3842 100644 (file)
@@ -35,12 +35,13 @@ namespace brw {
 class gen6_gs_visitor : public vec4_gs_visitor
 {
 public:
-   gen6_gs_visitor(struct brw_context *brw,
+   gen6_gs_visitor(const struct brw_compiler *comp,
                    struct brw_gs_compile *c,
                    struct gl_shader_program *prog,
                    void *mem_ctx,
-                   bool no_spills) :
-      vec4_gs_visitor(brw, c, prog, mem_ctx, no_spills) {}
+                   bool no_spills,
+                   int shader_time_index) :
+      vec4_gs_visitor(comp, c, prog, mem_ctx, no_spills, shader_time_index) {}
 
 protected:
    virtual void assign_binding_table_offsets();
index ec46479ff75b1043371377728758d651a41970fc..36734f598fe4fd86c3618aaaf0fa38133ed01a52 100644 (file)
@@ -26,6 +26,7 @@
 #include "brw_context.h"
 #include "brw_defines.h"
 #include "brw_multisample_state.h"
+#include "main/framebuffer.h"
 
 void
 gen6_get_sample_position(struct gl_context *ctx,
@@ -34,7 +35,7 @@ gen6_get_sample_position(struct gl_context *ctx,
 {
    uint8_t bits;
 
-   switch (fb->Visual.samples) {
+   switch (_mesa_geometric_samples(fb)) {
    case 1:
       result[0] = result[1] = 0.5f;
       return;
index 6431ed56d818b848928275904abfad9c16dc9cd5..ba5c944fb3d2c250bca10642ab53c501820ffaee 100644 (file)
@@ -246,7 +246,7 @@ gen6_queryobj_get_results(struct gl_context *ctx,
        * and correctly emitted the number of pixel shader invocations, but,
        * whomever forgot to undo the multiply by 4.
        */
-      if (brw->gen >= 8 || brw->is_haswell)
+      if (brw->gen == 8 || brw->is_haswell)
          query->Base.Result /= 4;
       break;
 
index 0111f152ef65817cfb1b5f98cd7aa847e4dc32ab..17b4a7fba96b7172340537f6d09fa2280882d215 100644 (file)
@@ -39,6 +39,8 @@ gen6_upload_scissor_state(struct brw_context *brw)
    const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
    struct gen6_scissor_rect *scissor;
    uint32_t scissor_state_offset;
+   const unsigned int fb_width= _mesa_geometric_width(ctx->DrawBuffer);
+   const unsigned int fb_height = _mesa_geometric_height(ctx->DrawBuffer);
 
    scissor = brw_state_batch(brw, AUB_TRACE_SCISSOR_STATE,
                             sizeof(*scissor) * ctx->Const.MaxViewports, 32,
@@ -56,7 +58,11 @@ gen6_upload_scissor_state(struct brw_context *brw)
    for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
       int bbox[4];
 
-      _mesa_scissor_bounding_box(ctx, ctx->DrawBuffer, i, bbox);
+      bbox[0] = 0;
+      bbox[1] = fb_width;
+      bbox[2] = 0;
+      bbox[3] = fb_height;
+      _mesa_intersect_scissor_bounding_box(ctx, i, bbox);
 
       if (bbox[0] == bbox[1] || bbox[2] == bbox[3]) {
          /* If the scissor was out of bounds and got clamped to 0 width/height
@@ -80,8 +86,8 @@ gen6_upload_scissor_state(struct brw_context *brw)
          /* memory: Y=0=top */
          scissor[i].xmin = bbox[0];
          scissor[i].xmax = bbox[1] - 1;
-         scissor[i].ymin = ctx->DrawBuffer->Height - bbox[3];
-         scissor[i].ymax = ctx->DrawBuffer->Height - bbox[2] - 1;
+         scissor[i].ymin = fb_height - bbox[3];
+         scissor[i].ymax = fb_height - bbox[2] - 1;
       }
    }
    BEGIN_BATCH(2);
index e445ce256000cc016d76de546e55c50f9b78dbb8..b00517ed81ef7e02e0ffa5c60b3efa1a6b0acd27 100644 (file)
@@ -31,6 +31,7 @@
 #include "brw_util.h"
 #include "main/macros.h"
 #include "main/fbobject.h"
+#include "main/framebuffer.h"
 #include "intel_batchbuffer.h"
 
 /**
@@ -273,7 +274,7 @@ upload_sf_state(struct brw_context *brw)
    int i;
    /* _NEW_BUFFER */
    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
+   const bool multisampled_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
 
    const int urb_entry_read_offset = BRW_SF_URB_ENTRY_READ_OFFSET;
    float point_size;
@@ -361,31 +362,7 @@ upload_sf_state(struct brw_context *brw)
 
    /* _NEW_LINE */
    {
-      /* OpenGL dictates that line width should be rounded to the nearest
-       * integer
-       */
-      float line_width =
-         roundf(CLAMP(ctx->Line.Width, 0.0, ctx->Const.MaxLineWidth));
-      uint32_t line_width_u3_7 = U_FIXED(line_width, 7);
-
-      /* Line width of 0 is not allowed when MSAA enabled */
-      if (ctx->Multisample._Enabled) {
-         if (line_width_u3_7 == 0)
-             line_width_u3_7 = 1;
-      } else if (ctx->Line.SmoothFlag && ctx->Line.Width < 1.5) {
-         /* For 1 pixel line thickness or less, the general
-          * anti-aliasing algorithm gives up, and a garbage line is
-          * generated.  Setting a Line Width of 0.0 specifies the
-          * rasterization of the "thinnest" (one-pixel-wide),
-          * non-antialiased lines.
-          *
-          * Lines rendered with zero Line Width are rasterized using
-          * Grid Intersection Quantization rules as specified by
-          * bspec section 6.3.12.1 Zero-Width (Cosmetic) Line
-          * Rasterization.
-          */
-         line_width_u3_7 = 0;
-      }
+      uint32_t line_width_u3_7 = brw_get_line_width(brw);
       dw3 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT;
    }
    if (ctx->Line.SmoothFlag) {
index 2fb0182c56e89704a34075df72a15cca300670c6..7c8d8849f4e1d354c8cb39c34a23f9eaef65da17 100644 (file)
@@ -30,6 +30,7 @@
 #include "brw_defines.h"
 #include "intel_batchbuffer.h"
 #include "main/fbobject.h"
+#include "main/framebuffer.h"
 #include "main/viewport.h"
 
 /* The clip VP defines the guardband region where expensive clipping is skipped
@@ -93,10 +94,10 @@ gen6_upload_sf_vp(struct brw_context *brw)
    /* _NEW_BUFFERS */
    if (render_to_fbo) {
       y_scale = 1.0;
-      y_bias = 0;
+      y_bias = 0.0;
    } else {
       y_scale = -1.0;
-      y_bias = ctx->DrawBuffer->Height;
+      y_bias = (float)_mesa_geometric_height(ctx->DrawBuffer);
    }
 
    for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
index 7081eb734288b455b0cbb697339a4e50da665268..d1748ba74578555b75f68db6cd0660cb55507a1e 100644 (file)
@@ -33,6 +33,7 @@
 #include "program/program.h"
 #include "program/prog_parameter.h"
 #include "program/prog_statevars.h"
+#include "main/framebuffer.h"
 #include "intel_batchbuffer.h"
 
 static void
@@ -284,7 +285,7 @@ upload_wm_state(struct brw_context *brw)
    const struct brw_wm_prog_data *prog_data = brw->wm.prog_data;
 
    /* _NEW_BUFFERS */
-   const bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
+   const bool multisampled_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
 
    /* In case of non 1x per sample shading, only one of SIMD8 and SIMD16
     * should be enabled. We do 'SIMD16 only' dispatch if a SIMD16 shader
index e1c4f8b5d14faf8322f5e590ecd98f9c390cfd00..8d6d3fe1d34ae2ae0e4f5017dbe1e45e5522df32 100644 (file)
@@ -112,7 +112,7 @@ upload_gs_state(struct brw_context *brw)
           GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) |
          ((brw->gs.prog_data->invocations - 1) <<
           GEN7_GS_INSTANCE_CONTROL_SHIFT) |
-         brw->gs.prog_data->dispatch_mode |
+         SET_FIELD(prog_data->dispatch_mode, GEN7_GS_DISPATCH_MODE) |
          GEN6_GS_STATISTICS_ENABLE |
          (brw->gs.prog_data->include_primitive_id ?
           GEN7_GS_INCLUDE_PRIMITIVE_ID : 0) |
index 58e33370c57b169ba28fcf44aafbdd3684f9dda5..4fa46a8eb9783a91d2ee2994c4bd0f70dcb4b9c7 100644 (file)
@@ -27,6 +27,7 @@
 #include "brw_util.h"
 #include "main/macros.h"
 #include "main/fbobject.h"
+#include "main/framebuffer.h"
 #include "intel_batchbuffer.h"
 
 static void
@@ -109,7 +110,7 @@ upload_sf_state(struct brw_context *brw)
    float point_size;
    /* _NEW_BUFFERS */
    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
+   const bool multisampled_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
 
    dw1 = GEN6_SF_STATISTICS_ENABLE;
 
@@ -192,30 +193,7 @@ upload_sf_state(struct brw_context *brw)
 
    /* _NEW_LINE */
    {
-      /* OpenGL dictates that line width should be rounded to the nearest
-       * integer
-       */
-      float line_width =
-         roundf(CLAMP(ctx->Line.Width, 0.0, ctx->Const.MaxLineWidth));
-      uint32_t line_width_u3_7 = U_FIXED(line_width, 7);
-      /* Line width of 0 is not allowed when MSAA enabled */
-      if (ctx->Multisample._Enabled) {
-         if (line_width_u3_7 == 0)
-             line_width_u3_7 = 1;
-      } else if (ctx->Line.SmoothFlag && ctx->Line.Width < 1.5) {
-         /* For 1 pixel line thickness or less, the general
-          * anti-aliasing algorithm gives up, and a garbage line is
-          * generated.  Setting a Line Width of 0.0 specifies the
-          * rasterization of the "thinnest" (one-pixel-wide),
-          * non-antialiased lines.
-          *
-          * Lines rendered with zero Line Width are rasterized using
-          * Grid Intersection Quantization rules as specified by
-          * bspec section 6.3.12.1 Zero-Width (Cosmetic) Line
-          * Rasterization.
-          */
-         line_width_u3_7 = 0;
-      }
+      uint32_t line_width_u3_7 = brw_get_line_width(brw);
       dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT;
    }
    if (ctx->Line.SmoothFlag) {
index eb596845b72a865e3093fda5cbfdaf1ee0d8042f..b655205ec35810412686d4aac0d10d456b976604 100644 (file)
@@ -26,6 +26,7 @@
 #include "brw_defines.h"
 #include "intel_batchbuffer.h"
 #include "main/fbobject.h"
+#include "main/framebuffer.h"
 #include "main/viewport.h"
 
 static void
@@ -45,10 +46,10 @@ gen7_upload_sf_clip_viewport(struct brw_context *brw)
    /* _NEW_BUFFERS */
    if (render_to_fbo) {
       y_scale = 1.0;
-      y_bias = 0;
+      y_bias = 0.0;
    } else {
       y_scale = -1.0;
-      y_bias = ctx->DrawBuffer->Height;
+      y_bias = (float)_mesa_geometric_height(ctx->DrawBuffer);
    }
 
    for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
index 278b3ec6d215cc5b93a902c133608c90852a8a5d..4b17d06fa83da8c2dfc2c3964dd389535823bb52 100644 (file)
@@ -43,18 +43,52 @@ gen7_upload_constant_state(struct brw_context *brw,
    int dwords = brw->gen >= 8 ? 11 : 7;
    BEGIN_BATCH(dwords);
    OUT_BATCH(opcode << 16 | (dwords - 2));
-   OUT_BATCH(active ? stage_state->push_const_size : 0);
-   OUT_BATCH(0);
+
+   /* Workaround for SKL+ (we use option #2 until we have a need for more
+    * constant buffers). This comes from the documentation for 3DSTATE_CONSTANT_*
+    *
+    * The driver must ensure The following case does not occur without a flush
+    * to the 3D engine: 3DSTATE_CONSTANT_* with buffer 3 read length equal to
+    * zero committed followed by a 3DSTATE_CONSTANT_* with buffer 0 read length
+    * not equal to zero committed. Possible ways to avoid this condition
+    * include:
+    *     1. always force buffer 3 to have a non zero read length
+    *     2. always force buffer 0 to a zero read length
+    */
+   if (brw->gen >= 9 && active) {
+      OUT_BATCH(0);
+      OUT_BATCH(stage_state->push_const_size);
+   } else {
+      OUT_BATCH(active ? stage_state->push_const_size : 0);
+      OUT_BATCH(0);
+   }
    /* Pointer to the constant buffer.  Covered by the set of state flags
     * from gen6_prepare_wm_contants
     */
-   OUT_BATCH(active ? (stage_state->push_const_offset | mocs) : 0);
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-   if (brw->gen >= 8) {
+   if (brw->gen >= 9 && active) {
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      /* XXX: When using buffers other than 0, you need to specify the
+       * graphics virtual address regardless of INSPM/debug bits
+       */
+      OUT_RELOC64(brw->batch.bo, I915_GEM_DOMAIN_RENDER, 0,
+                  stage_state->push_const_offset);
       OUT_BATCH(0);
       OUT_BATCH(0);
+   } else if (brw->gen>= 8) {
+      OUT_BATCH(active ? (stage_state->push_const_offset | mocs) : 0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+   } else {
+      OUT_BATCH(active ? (stage_state->push_const_offset | mocs) : 0);
+      OUT_BATCH(0);
       OUT_BATCH(0);
       OUT_BATCH(0);
    }
index b9182758852ec666c11605daedc42676858dbecb..ea11ae845e3adf3f9fd2bec5b19aa0a59d64a2a8 100644 (file)
@@ -30,6 +30,7 @@
 #include "program/program.h"
 #include "program/prog_parameter.h"
 #include "program/prog_statevars.h"
+#include "main/framebuffer.h"
 #include "intel_batchbuffer.h"
 
 static void
@@ -45,7 +46,7 @@ upload_wm_state(struct brw_context *brw)
    uint32_t dw1, dw2;
 
    /* _NEW_BUFFERS */
-   bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
+   const bool multisampled_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
 
    dw1 = dw2 = 0;
    dw1 |= GEN7_WM_STATISTICS_ENABLE;
@@ -76,6 +77,10 @@ upload_wm_state(struct brw_context *brw)
       dw1 |= GEN7_WM_KILL_ENABLE;
    }
 
+   if (_mesa_active_fragment_shader_has_atomic_ops(&brw->ctx)) {
+      dw1 |= GEN7_WM_DISPATCH_ENABLE;
+   }
+
    /* _NEW_BUFFERS | _NEW_COLOR */
    if (brw_color_buffer_write_enabled(brw) || writes_depth ||
        dw1 & GEN7_WM_KILL_ENABLE) {
index b502650f9914ddab5215cd934ad66a1beb8bc5aa..12ac97a5d1418abf89772b318dad63bb51d788df 100644 (file)
@@ -417,6 +417,16 @@ gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
    uint32_t surface_width  = ALIGN(mt->logical_width0,  level == 0 ? 8 : 1);
    uint32_t surface_height = ALIGN(mt->logical_height0, level == 0 ? 4 : 1);
 
+   /* From the documentation for 3DSTATE_WM_HZ_OP: "3DSTATE_MULTISAMPLE packet
+    * must be used prior to this packet to change the Number of Multisamples.
+    * This packet must not be used to change Number of Multisamples in a
+    * rendering sequence."
+    */
+   if (brw->num_samples != mt->num_samples) {
+      gen8_emit_3dstate_multisample(brw, mt->num_samples);
+      brw->NewGLState |= _NEW_MULTISAMPLE;
+   }
+
    /* The basic algorithm is:
     * - If needed, emit 3DSTATE_{DEPTH,HIER_DEPTH,STENCIL}_BUFFER and
     *   3DSTATE_CLEAR_PARAMS packets to set up the relevant buffers.
index 46b97131e209533845fe4488d5b76a8e47649d7d..26a02d3b045601a1b8ecd2e27894b568cb5c2562 100644 (file)
@@ -48,8 +48,7 @@ gen8_upload_gs_state(struct brw_context *brw)
       OUT_BATCH(_3DSTATE_GS << 16 | (10 - 2));
       OUT_BATCH(stage_state->prog_offset);
       OUT_BATCH(0);
-      OUT_BATCH(GEN6_GS_VECTOR_MASK_ENABLE |
-                brw->geometry_program->VerticesIn |
+      OUT_BATCH(brw->geometry_program->VerticesIn |
                 ((ALIGN(stage_state->sampler_count, 4)/4) <<
                  GEN6_GS_SAMPLER_COUNT_SHIFT) |
                 ((prog_data->base.binding_table.size_bytes / 4) <<
@@ -59,10 +58,6 @@ gen8_upload_gs_state(struct brw_context *brw)
          OUT_RELOC64(stage_state->scratch_bo,
                      I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                      ffs(brw->gs.prog_data->base.base.total_scratch) - 11);
-         WARN_ONCE(true,
-                   "May need to implement a temporary workaround: GS Number of "
-                   "URB Entries must be less than or equal to the GS Maximum "
-                   "Number of Threads.\n");
       } else {
          OUT_BATCH(0);
          OUT_BATCH(0);
@@ -81,7 +76,8 @@ gen8_upload_gs_state(struct brw_context *brw)
 
       uint32_t dw7 = (brw->gs.prog_data->control_data_header_size_hwords <<
                       GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) |
-                      brw->gs.prog_data->dispatch_mode |
+                     SET_FIELD(prog_data->dispatch_mode,
+                               GEN7_GS_DISPATCH_MODE) |
                      ((brw->gs.prog_data->invocations - 1) <<
                       GEN7_GS_INSTANCE_CONTROL_SHIFT) |
                       GEN6_GS_STATISTICS_ENABLE |
index 85ad3b6c551cf4c100b1dce9aca91575fe8e4af8..a88f109c691a6c1bf4c39b6644eaf086cc515f0d 100644 (file)
@@ -58,6 +58,9 @@ gen8_upload_ps_extra(struct brw_context *brw,
    if (prog_data->uses_omask)
       dw1 |= GEN8_PSX_OMASK_TO_RENDER_TARGET;
 
+   if (_mesa_active_fragment_shader_has_atomic_ops(&brw->ctx))
+      dw1 |= GEN8_PSX_SHADER_HAS_UAV;
+
    BEGIN_BATCH(2);
    OUT_BATCH(_3DSTATE_PS_EXTRA << 16 | (2 - 2));
    OUT_BATCH(dw1);
@@ -72,7 +75,7 @@ upload_ps_extra(struct brw_context *brw)
       brw_fragment_program_const(brw->fragment_program);
    /* BRW_NEW_FS_PROG_DATA */
    const struct brw_wm_prog_data *prog_data = brw->wm.prog_data;
-   /* BRW_NEW_NUM_SAMPLES | _NEW_MULTISAMPLE */
+   /* BRW_NEW_NUM_SAMPLES */
    const bool multisampled_fbo = brw->num_samples > 1;
 
    gen8_upload_ps_extra(brw, &fp->program, prog_data, multisampled_fbo);
@@ -80,7 +83,7 @@ upload_ps_extra(struct brw_context *brw)
 
 const struct brw_tracked_state gen8_ps_extra = {
    .dirty = {
-      .mesa  = _NEW_MULTISAMPLE,
+      .mesa  = 0,
       .brw   = BRW_NEW_CONTEXT |
                BRW_NEW_FRAGMENT_PROGRAM |
                BRW_NEW_FS_PROG_DATA |
index 52a21b6a8e8d7069d297b447a2fc59c8147bf8dc..c2b585d00018b48bbbd1f2a885954ae46eb89680 100644 (file)
@@ -154,14 +154,7 @@ upload_sf(struct brw_context *brw)
        dw1 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
 
    /* _NEW_LINE */
-   /* OpenGL dictates that line width should be rounded to the nearest
-    * integer
-    */
-   float line_width =
-      roundf(CLAMP(ctx->Line.Width, 0.0, ctx->Const.MaxLineWidth));
-   uint32_t line_width_u3_7 = U_FIXED(line_width, 7);
-   if (line_width_u3_7 == 0)
-      line_width_u3_7 = 1;
+   uint32_t line_width_u3_7 = brw_get_line_width(brw);
    if (brw->gen >= 9 || brw->is_cherryview) {
       dw1 |= line_width_u3_7 << GEN9_SF_LINE_WIDTH_SHIFT;
    } else {
index d0c2d80b17bd00158c09e965f445ccf036defbf1..b2d1a579815c6b620d93f0844963d3c8ab158f5b 100644 (file)
@@ -56,6 +56,19 @@ swizzle_to_scs(unsigned swizzle)
    return (swizzle + 4) & 7;
 }
 
+static uint32_t
+surface_tiling_resource_mode(uint32_t tr_mode)
+{
+   switch (tr_mode) {
+   case INTEL_MIPTREE_TRMODE_YF:
+      return GEN9_SURFACE_TRMODE_TILEYF;
+   case INTEL_MIPTREE_TRMODE_YS:
+      return GEN9_SURFACE_TRMODE_TILEYS;
+   default:
+      return GEN9_SURFACE_TRMODE_NONE;
+   }
+}
+
 static uint32_t
 surface_tiling_mode(uint32_t tiling)
 {
@@ -70,8 +83,18 @@ surface_tiling_mode(uint32_t tiling)
 }
 
 static unsigned
-vertical_alignment(const struct intel_mipmap_tree *mt)
+vertical_alignment(const struct brw_context *brw,
+                   const struct intel_mipmap_tree *mt,
+                   uint32_t surf_type)
 {
+   /* On Gen9+ vertical alignment is ignored for 1D surfaces and when
+    * tr_mode is not TRMODE_NONE.
+    */
+   if (brw->gen > 8 &&
+       (mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE ||
+        surf_type == BRW_SURFACE_1D))
+      return 0;
+
    switch (mt->align_h) {
    case 4:
       return GEN8_SURFACE_VALIGN_4;
@@ -85,8 +108,18 @@ vertical_alignment(const struct intel_mipmap_tree *mt)
 }
 
 static unsigned
-horizontal_alignment(const struct intel_mipmap_tree *mt)
+horizontal_alignment(const struct brw_context *brw,
+                     const struct intel_mipmap_tree *mt,
+                     uint32_t surf_type)
 {
+   /* On Gen9+ horizontal alignment is ignored when tr_mode is not
+    * TRMODE_NONE.
+    */
+   if (brw->gen > 8 &&
+       (mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE ||
+        gen9_use_linear_1d_layout(brw, mt)))
+      return 0;
+
    switch (mt->align_w) {
    case 4:
       return GEN8_SURFACE_HALIGN_4;
@@ -100,11 +133,11 @@ horizontal_alignment(const struct intel_mipmap_tree *mt)
 }
 
 static uint32_t *
-allocate_surface_state(struct brw_context *brw, uint32_t *out_offset)
+allocate_surface_state(struct brw_context *brw, uint32_t *out_offset, int index)
 {
    int dwords = brw->gen >= 9 ? 16 : 13;
-   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
-                                    dwords * 4, 64, out_offset);
+   uint32_t *surf = __brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
+                                      dwords * 4, 64, index, out_offset);
    memset(surf, 0, dwords * 4);
    return surf;
 }
@@ -120,7 +153,7 @@ gen8_emit_buffer_surface_state(struct brw_context *brw,
                                bool rw)
 {
    const unsigned mocs = brw->gen >= 9 ? SKL_MOCS_WB : BDW_MOCS_WB;
-   uint32_t *surf = allocate_surface_state(brw, out_offset);
+   uint32_t *surf = allocate_surface_state(brw, out_offset, -1);
 
    surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
              surface_format << BRW_SURFACE_FORMAT_SHIFT |
@@ -164,7 +197,9 @@ gen8_emit_texture_surface_state(struct brw_context *brw,
    struct intel_mipmap_tree *aux_mt = NULL;
    uint32_t aux_mode = 0;
    uint32_t mocs_wb = brw->gen >= 9 ? SKL_MOCS_WB : BDW_MOCS_WB;
+   int surf_index = surf_offset - &brw->wm.base.surf_offset[0];
    unsigned tiling_mode, pitch;
+   const unsigned tr_mode = surface_tiling_resource_mode(mt->tr_mode);
 
    if (mt->format == MESA_FORMAT_S_UINT8) {
       tiling_mode = GEN8_SURFACE_TILING_W;
@@ -177,18 +212,29 @@ gen8_emit_texture_surface_state(struct brw_context *brw,
    if (mt->mcs_mt) {
       aux_mt = mt->mcs_mt;
       aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
+
+      /*
+       * From the BDW PRM, Volume 2d, page 260 (RENDER_SURFACE_STATE):
+       * "When MCS is enabled for non-MSRT, HALIGN_16 must be used"
+       *
+       * From the hardware spec for GEN9:
+       * "When Auxiliary Surface Mode is set to AUX_CCS_D or AUX_CCS_E, HALIGN
+       *  16 must be used."
+       */
+      assert(brw->gen < 9 || mt->align_w == 16);
+      assert(brw->gen < 8 || mt->num_samples > 1 || mt->align_w == 16);
    }
 
-   uint32_t *surf = allocate_surface_state(brw, surf_offset);
+   const uint32_t surf_type = translate_tex_target(target);
+   uint32_t *surf = allocate_surface_state(brw, surf_offset, surf_index);
 
-   surf[0] = translate_tex_target(target) << BRW_SURFACE_TYPE_SHIFT |
+   surf[0] = SET_FIELD(surf_type, BRW_SURFACE_TYPE) |
              format << BRW_SURFACE_FORMAT_SHIFT |
-             vertical_alignment(mt) |
-             horizontal_alignment(mt) |
+             vertical_alignment(brw, mt, surf_type) |
+             horizontal_alignment(brw, mt, surf_type) |
              tiling_mode;
 
-   if (target == GL_TEXTURE_CUBE_MAP ||
-       target == GL_TEXTURE_CUBE_MAP_ARRAY) {
+   if (surf_type == BRW_SURFACE_CUBE) {
       surf[0] |= BRW_SURFACE_CUBEFACE_ENABLES;
    }
 
@@ -209,6 +255,12 @@ gen8_emit_texture_surface_state(struct brw_context *brw,
    surf[5] = SET_FIELD(min_level - mt->first_level, GEN7_SURFACE_MIN_LOD) |
              (max_level - min_level - 1); /* mip count */
 
+   if (brw->gen >= 9) {
+      surf[5] |= SET_FIELD(tr_mode, GEN9_SURFACE_TRMODE);
+      /* Disable Mip Tail by setting a large value. */
+      surf[5] |= SET_FIELD(15, GEN9_SURFACE_MIP_TAIL_START_LOD);
+   }
+
    if (aux_mt) {
       surf[6] = SET_FIELD(mt->qpitch / 4, GEN8_SURFACE_AUX_QPITCH) |
                 SET_FIELD((aux_mt->pitch / 128) - 1, GEN8_SURFACE_AUX_PITCH) |
@@ -310,7 +362,7 @@ gen8_emit_null_surface_state(struct brw_context *brw,
                              unsigned samples,
                              uint32_t *out_offset)
 {
-   uint32_t *surf = allocate_surface_state(brw, out_offset);
+   uint32_t *surf = allocate_surface_state(brw, out_offset, -1);
 
    surf[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
              BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
@@ -339,6 +391,7 @@ gen8_update_renderbuffer_surface(struct brw_context *brw,
    unsigned height = mt->logical_height0;
    unsigned pitch = mt->pitch;
    uint32_t tiling = mt->tiling;
+   unsigned tr_mode = surface_tiling_resource_mode(mt->tr_mode);
    uint32_t format = 0;
    uint32_t surf_type;
    uint32_t offset;
@@ -390,15 +443,26 @@ gen8_update_renderbuffer_surface(struct brw_context *brw,
    if (mt->mcs_mt) {
       aux_mt = mt->mcs_mt;
       aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
+
+      /*
+       * From the BDW PRM, Volume 2d, page 260 (RENDER_SURFACE_STATE):
+       * "When MCS is enabled for non-MSRT, HALIGN_16 must be used"
+       *
+       * From the hardware spec for GEN9:
+       * "When Auxiliary Surface Mode is set to AUX_CCS_D or AUX_CCS_E, HALIGN
+       *  16 must be used."
+       */
+      assert(brw->gen < 9 || mt->align_w == 16);
+      assert(brw->gen < 8 || mt->num_samples > 1 || mt->align_w == 16);
    }
 
-   uint32_t *surf = allocate_surface_state(brw, &offset);
+   uint32_t *surf = allocate_surface_state(brw, &offset, surf_index);
 
    surf[0] = (surf_type << BRW_SURFACE_TYPE_SHIFT) |
              (is_array ? GEN7_SURFACE_IS_ARRAY : 0) |
              (format << BRW_SURFACE_FORMAT_SHIFT) |
-             vertical_alignment(mt) |
-             horizontal_alignment(mt) |
+             vertical_alignment(brw, mt, surf_type) |
+             horizontal_alignment(brw, mt, surf_type) |
              surface_tiling_mode(tiling);
 
    surf[1] = SET_FIELD(mocs, GEN8_SURFACE_MOCS) | mt->qpitch >> 2;
@@ -417,6 +481,12 @@ gen8_update_renderbuffer_surface(struct brw_context *brw,
 
    surf[5] = irb->mt_level - irb->mt->first_level;
 
+   if (brw->gen >= 9) {
+      surf[5] |= SET_FIELD(tr_mode, GEN9_SURFACE_TRMODE);
+      /* Disable Mip Tail by setting a large value. */
+      surf[5] |= SET_FIELD(15, GEN9_SURFACE_MIP_TAIL_START_LOD);
+   }
+
    if (aux_mt) {
       surf[6] = SET_FIELD(mt->qpitch / 4, GEN8_SURFACE_AUX_QPITCH) |
                 SET_FIELD((aux_mt->pitch / 128) - 1, GEN8_SURFACE_AUX_PITCH) |
index 322e4663b992647a58eac93a3e8f249a21cfe6f4..2d8eeb1f10fa76820a6ce0a1814339d976b94c3a 100644 (file)
@@ -26,6 +26,7 @@
 #include "brw_defines.h"
 #include "intel_batchbuffer.h"
 #include "main/fbobject.h"
+#include "main/framebuffer.h"
 #include "main/viewport.h"
 
 static void
@@ -33,6 +34,7 @@ gen8_upload_sf_clip_viewport(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
    float y_scale, y_bias;
+   const float fb_height = (float)_mesa_geometric_height(ctx->DrawBuffer);
    const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
 
    float *vp = brw_state_batch(brw, AUB_TRACE_SF_VP_STATE,
@@ -47,7 +49,7 @@ gen8_upload_sf_clip_viewport(struct brw_context *brw)
       y_bias = 0;
    } else {
       y_scale = -1.0;
-      y_bias = ctx->DrawBuffer->Height;
+      y_bias = fb_height;
    }
 
    for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
@@ -116,8 +118,8 @@ gen8_upload_sf_clip_viewport(struct brw_context *brw)
       } else {
          vp[12] = ctx->ViewportArray[i].X;
          vp[13] = viewport_Xmax - 1;
-         vp[14] = ctx->DrawBuffer->Height - viewport_Ymax;
-         vp[15] = ctx->DrawBuffer->Height - ctx->ViewportArray[i].Y - 1;
+         vp[14] = fb_height - viewport_Ymax;
+         vp[15] = fb_height - ctx->ViewportArray[i].Y - 1;
       }
 
       vp += 16;
index f92af55e37f38515430789151709d5a28312fa4f..28f5adddf14397627097c38cb74d8886ab72b229 100644 (file)
@@ -39,6 +39,9 @@ upload_vs_state(struct brw_context *brw)
    /* BRW_NEW_VS_PROG_DATA */
    const struct brw_vue_prog_data *prog_data = &brw->vs.prog_data->base;
 
+   assert(prog_data->dispatch_mode == DISPATCH_MODE_SIMD8 ||
+          prog_data->dispatch_mode == DISPATCH_MODE_4X2_DUAL_OBJECT);
+
    if (prog_data->base.use_alt_mode)
       floating_point_mode = GEN6_VS_FLOATING_POINT_MODE_ALT;
 
@@ -66,7 +69,8 @@ upload_vs_state(struct brw_context *brw)
              (prog_data->urb_read_length << GEN6_VS_URB_READ_LENGTH_SHIFT) |
              (0 << GEN6_VS_URB_ENTRY_READ_OFFSET_SHIFT));
 
-   uint32_t simd8_enable = prog_data->simd8 ? GEN8_VS_SIMD8_ENABLE : 0;
+   uint32_t simd8_enable = prog_data->dispatch_mode == DISPATCH_MODE_SIMD8 ?
+      GEN8_VS_SIMD8_ENABLE : 0;
    OUT_BATCH(((brw->max_vs_threads - 1) << HSW_VS_MAX_THREADS_SHIFT) |
              GEN6_VS_STATISTICS_ENABLE |
              simd8_enable |
index e522e4e9c1de942086f48d753c72d57c50f4616b..ed659ed625eb7546ea992df368e1a09edc113d14 100644 (file)
@@ -743,27 +743,54 @@ intel_batchbuffer_emit_mi_flush(struct brw_context *brw)
    brw_render_cache_set_clear(brw);
 }
 
-void
-brw_load_register_mem(struct brw_context *brw,
-                      uint32_t reg,
-                      drm_intel_bo *bo,
-                      uint32_t read_domains, uint32_t write_domain,
-                      uint32_t offset)
+static void
+load_sized_register_mem(struct brw_context *brw,
+                        uint32_t reg,
+                        drm_intel_bo *bo,
+                        uint32_t read_domains, uint32_t write_domain,
+                        uint32_t offset,
+                        int size)
 {
+   int i;
+
    /* MI_LOAD_REGISTER_MEM only exists on Gen7+. */
    assert(brw->gen >= 7);
 
    if (brw->gen >= 8) {
-      BEGIN_BATCH(4);
-      OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (4 - 2));
-      OUT_BATCH(reg);
-      OUT_RELOC64(bo, read_domains, write_domain, offset);
+      BEGIN_BATCH(4 * size);
+      for (i = 0; i < size; i++) {
+         OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (4 - 2));
+         OUT_BATCH(reg + i * 4);
+         OUT_RELOC64(bo, read_domains, write_domain, offset + i * 4);
+      }
       ADVANCE_BATCH();
    } else {
-      BEGIN_BATCH(3);
-      OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
-      OUT_BATCH(reg);
-      OUT_RELOC(bo, read_domains, write_domain, offset);
+      BEGIN_BATCH(3 * size);
+      for (i = 0; i < size; i++) {
+         OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+         OUT_BATCH(reg + i * 4);
+         OUT_RELOC(bo, read_domains, write_domain, offset + i * 4);
+      }
       ADVANCE_BATCH();
    }
 }
+
+void
+brw_load_register_mem(struct brw_context *brw,
+                      uint32_t reg,
+                      drm_intel_bo *bo,
+                      uint32_t read_domains, uint32_t write_domain,
+                      uint32_t offset)
+{
+   load_sized_register_mem(brw, reg, bo, read_domains, write_domain, offset, 1);
+}
+
+void
+brw_load_register_mem64(struct brw_context *brw,
+                        uint32_t reg,
+                        drm_intel_bo *bo,
+                        uint32_t read_domains, uint32_t write_domain,
+                        uint32_t offset)
+{
+   load_sized_register_mem(brw, reg, bo, read_domains, write_domain, offset, 2);
+}
index 7680a4029751c3c1a218889ac7894ac04bd8f506..d3ab769356ce07f26bc5435a422837cce00daf79 100644 (file)
@@ -77,13 +77,10 @@ br13_for_cpp(int cpp)
    switch (cpp) {
    case 4:
       return BR13_8888;
-      break;
    case 2:
       return BR13_565;
-      break;
    case 1:
       return BR13_8;
-      break;
    default:
       unreachable("not reached");
    }
@@ -130,6 +127,40 @@ set_blitter_tiling(struct brw_context *brw,
       ADVANCE_BATCH();                                                  \
    } while (0)
 
+static int
+blt_pitch(struct intel_mipmap_tree *mt)
+{
+   int pitch = mt->pitch;
+   if (mt->tiling)
+      pitch /= 4;
+   return pitch;
+}
+
+bool
+intel_miptree_blit_compatible_formats(mesa_format src, mesa_format dst)
+{
+   /* The BLT doesn't handle sRGB conversion */
+   assert(src == _mesa_get_srgb_format_linear(src));
+   assert(dst == _mesa_get_srgb_format_linear(dst));
+
+   /* No swizzle or format conversions possible, except... */
+   if (src == dst)
+      return true;
+
+   /* ...we can either discard the alpha channel when going from A->X,
+    * or we can fill the alpha channel with 0xff when going from X->A
+    */
+   if (src == MESA_FORMAT_B8G8R8A8_UNORM || src == MESA_FORMAT_B8G8R8X8_UNORM)
+      return (dst == MESA_FORMAT_B8G8R8A8_UNORM ||
+              dst == MESA_FORMAT_B8G8R8X8_UNORM);
+
+   if (src == MESA_FORMAT_R8G8B8A8_UNORM || src == MESA_FORMAT_R8G8B8X8_UNORM)
+      return (dst == MESA_FORMAT_R8G8B8A8_UNORM ||
+              dst == MESA_FORMAT_R8G8B8X8_UNORM);
+
+   return false;
+}
+
 /**
  * Implements a rectangular block transfer (blit) of pixels between two
  * miptrees.
@@ -172,11 +203,7 @@ intel_miptree_blit(struct brw_context *brw,
     * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
     * channel to 1.0 at the end.
     */
-   if (src_format != dst_format &&
-      ((src_format != MESA_FORMAT_B8G8R8A8_UNORM &&
-        src_format != MESA_FORMAT_B8G8R8X8_UNORM) ||
-       (dst_format != MESA_FORMAT_B8G8R8A8_UNORM &&
-        dst_format != MESA_FORMAT_B8G8R8X8_UNORM))) {
+   if (!intel_miptree_blit_compatible_formats(src_format, dst_format)) {
       perf_debug("%s: Can't use hardware blitter from %s to %s, "
                  "falling back.\n", __func__,
                  _mesa_get_format_name(src_format),
@@ -197,14 +224,14 @@ intel_miptree_blit(struct brw_context *brw,
     *
     * Furthermore, intelEmitCopyBlit (which is called below) uses a signed
     * 16-bit integer to represent buffer pitch, so it can only handle buffer
-    * pitches < 32k.
+    * pitches < 32k. However, the pitch is measured in bytes for linear buffers
+    * and dwords for tiled buffers.
     *
     * As a result of these two limitations, we can only use the blitter to do
-    * this copy when the miptree's pitch is less than 32k.
+    * this copy when the miptree's pitch is less than 32k linear or 128k tiled.
     */
-   if (src_mt->pitch >= 32768 ||
-       dst_mt->pitch >= 32768) {
-      perf_debug("Falling back due to >=32k pitch\n");
+   if (blt_pitch(src_mt) >= 32768 || blt_pitch(dst_mt) >= 32768) {
+      perf_debug("Falling back due to >= 32k/128k pitch\n");
       return false;
    }
 
@@ -261,8 +288,9 @@ intel_miptree_blit(struct brw_context *brw,
       return false;
    }
 
-   if (src_mt->format == MESA_FORMAT_B8G8R8X8_UNORM &&
-       dst_mt->format == MESA_FORMAT_B8G8R8A8_UNORM) {
+   /* XXX This could be done in a single pass using XY_FULL_MONO_PATTERN_BLT */
+   if (_mesa_get_format_bits(src_format, GL_ALPHA_BITS) == 0 &&
+       _mesa_get_format_bits(dst_format, GL_ALPHA_BITS) > 0) {
       intel_miptree_set_alpha_to_one(brw, dst_mt,
                                      dst_x, dst_y,
                                      width, height);
index f563939fdd93c24c685eb0806e8ed6120c806340..2287c379c4ea83da77b51773d713e02d4b100853 100644 (file)
@@ -46,6 +46,8 @@ intelEmitCopyBlit(struct brw_context *brw,
                               GLshort w, GLshort h,
                              GLenum logicop );
 
+bool intel_miptree_blit_compatible_formats(mesa_format src, mesa_format dst);
+
 bool intel_miptree_blit(struct brw_context *brw,
                         struct intel_mipmap_tree *src_mt,
                         int src_level, int src_slice,
index 33a0348486d05e1188d444e757021044a8e6c887..75cf7854effb78f139d209cea6711b6ffa1bfbd3 100644 (file)
@@ -88,25 +88,22 @@ intel_debug_flag_for_shader_stage(gl_shader_stage stage)
 }
 
 void
-brw_process_intel_debug_variable(struct brw_context *brw)
+brw_process_intel_debug_variable(struct intel_screen *screen)
 {
    uint64_t intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
    (void) p_atomic_cmpxchg(&INTEL_DEBUG, 0, intel_debug);
 
    if (INTEL_DEBUG & DEBUG_BUFMGR)
-      dri_bufmgr_set_debug(brw->bufmgr, true);
+      dri_bufmgr_set_debug(screen->bufmgr, true);
 
-   if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && brw->gen < 7) {
+   if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && screen->devinfo->gen < 7) {
       fprintf(stderr,
               "shader_time debugging requires gen7 (Ivybridge) or better.\n");
       INTEL_DEBUG &= ~DEBUG_SHADER_TIME;
    }
 
-   if (INTEL_DEBUG & DEBUG_PERF)
-      brw->perf_debug = true;
-
    if (INTEL_DEBUG & DEBUG_AUB)
-      drm_intel_bufmgr_gem_set_aub_dump(brw->bufmgr, true);
+      drm_intel_bufmgr_gem_set_aub_dump(screen->bufmgr, true);
 }
 
 /**
index f754be20b1d7ec714520da50f10ada4b4cc4f3ed..4689492e1fdce11f1746559907747cc7ae415323 100644 (file)
@@ -114,8 +114,8 @@ extern uint64_t INTEL_DEBUG;
 
 extern uint64_t intel_debug_flag_for_shader_stage(gl_shader_stage stage);
 
-struct brw_context;
+struct intel_screen;
 
-extern void brw_process_intel_debug_variable(struct brw_context *brw);
+extern void brw_process_intel_debug_variable(struct intel_screen *);
 
 extern bool brw_env_var_as_boolean(const char *var_name, bool default_value);
index d6da34c7065acf675717e1f47f97db2194664969..c99677c7197806027002925ec453a5dcf907c0ec 100644 (file)
@@ -323,9 +323,12 @@ intelInitExtensions(struct gl_context *ctx)
       }
    }
 
+   brw->predicate.supported = false;
+
    if (brw->gen >= 7) {
       ctx->Extensions.ARB_conservative_depth = true;
       ctx->Extensions.ARB_derivative_control = true;
+      ctx->Extensions.ARB_framebuffer_no_attachments = true;
       ctx->Extensions.ARB_gpu_shader5 = true;
       ctx->Extensions.ARB_shader_atomic_counters = true;
       ctx->Extensions.ARB_texture_compression_bptc = true;
@@ -337,6 +340,9 @@ intelInitExtensions(struct gl_context *ctx)
          ctx->Extensions.ARB_transform_feedback2 = true;
          ctx->Extensions.ARB_transform_feedback3 = true;
          ctx->Extensions.ARB_transform_feedback_instanced = true;
+
+         if (brw->intelScreen->cmd_parser_version >= 2)
+            brw->predicate.supported = true;
       }
 
       /* Only enable this in core profile because other parts of Mesa behave
index aebed723f755e1916bf3b721f5837abfd2bc091c..1b3a72f3ec21d3d59f84d37a6dcb250845df4601 100644 (file)
@@ -390,7 +390,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
                                          image->height,
                                          1,
                                          image->pitch,
-                                         true /*disable_aux_buffers*/);
+                                         MIPTREE_LAYOUT_DISABLE_AUX);
    if (!irb->mt)
       return;
 
@@ -1027,10 +1027,9 @@ intel_renderbuffer_move_to_temp(struct brw_context *brw,
                                  intel_image->base.Base.Level,
                                  intel_image->base.Base.Level,
                                  width, height, depth,
-                                 true,
                                  irb->mt->num_samples,
                                  INTEL_MIPTREE_TILING_ANY,
-                                 false);
+                                 MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
 
    if (intel_miptree_wants_hiz_buffer(brw, new_mt)) {
       intel_miptree_alloc_hiz(brw, new_mt);
index 24a5c3dc6663d4e72ba4497292bec480a307795e..6aa969a49307921e2aa498d2d80f38847f39c124 100644 (file)
@@ -158,15 +158,32 @@ intel_get_non_msrt_mcs_alignment(struct brw_context *brw,
    }
 }
 
+bool
+intel_tiling_supports_non_msrt_mcs(struct brw_context *brw, unsigned tiling)
+{
+   /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
+    * Target(s)", beneath the "Fast Color Clear" bullet (p326):
+    *
+    *     - Support is limited to tiled render targets.
+    *
+    * Gen9 changes the restriction to Y-tile only.
+    */
+   if (brw->gen >= 9)
+      return tiling == I915_TILING_Y;
+   else if (brw->gen >= 7)
+      return tiling != I915_TILING_NONE;
+   else
+      return false;
+}
 
 /**
  * For a single-sampled render target ("non-MSRT"), determine if an MCS buffer
- * can be used.
+ * can be used. This doesn't (and should not) inspect any of the properties of
+ * the miptree's BO.
  *
  * From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render Target(s)",
  * beneath the "Fast Color Clear" bullet (p326):
  *
- *     - Support is limited to tiled render targets.
  *     - Support is for non-mip-mapped and non-array surface types only.
  *
  * And then later, on p327:
@@ -175,8 +192,8 @@ intel_get_non_msrt_mcs_alignment(struct brw_context *brw,
  *       64bpp, and 128bpp.
  */
 bool
-intel_is_non_msrt_mcs_buffer_supported(struct brw_context *brw,
-                                       struct intel_mipmap_tree *mt)
+intel_miptree_is_fast_clear_capable(struct brw_context *brw,
+                                    struct intel_mipmap_tree *mt)
 {
    /* MCS support does not exist prior to Gen7 */
    if (brw->gen < 7)
@@ -193,15 +210,25 @@ intel_is_non_msrt_mcs_buffer_supported(struct brw_context *brw,
       return false;
    }
 
-   if (mt->tiling != I915_TILING_X &&
-       mt->tiling != I915_TILING_Y)
-      return false;
    if (mt->cpp != 4 && mt->cpp != 8 && mt->cpp != 16)
       return false;
-   if (mt->first_level != 0 || mt->last_level != 0)
+   if (mt->first_level != 0 || mt->last_level != 0) {
+      if (brw->gen >= 8) {
+         perf_debug("Multi-LOD fast clear - giving up (%dx%dx%d).\n",
+                    mt->logical_width0, mt->logical_height0, mt->last_level);
+      }
+
       return false;
-   if (mt->physical_depth0 != 1)
+   }
+   if (mt->physical_depth0 != 1) {
+      if (brw->gen >= 8) {
+         perf_debug("Layered fast clear - giving up. (%dx%d%d)\n",
+                    mt->logical_width0, mt->logical_height0,
+                    mt->physical_depth0);
+      }
+
       return false;
+   }
 
    /* There's no point in using an MCS buffer if the surface isn't in a
     * renderable format.
@@ -244,10 +271,9 @@ intel_miptree_create_layout(struct brw_context *brw,
                             GLuint width0,
                             GLuint height0,
                             GLuint depth0,
-                            bool for_bo,
                             GLuint num_samples,
-                            bool force_all_slices_at_each_lod,
-                            bool disable_aux_buffers)
+                            enum intel_miptree_tiling_mode requested,
+                            uint32_t layout_flags)
 {
    struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
    if (!mt)
@@ -286,7 +312,7 @@ intel_miptree_create_layout(struct brw_context *brw,
    mt->logical_height0 = height0;
    mt->logical_depth0 = depth0;
    mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_NO_MCS;
-   mt->disable_aux_buffers = disable_aux_buffers;
+   mt->disable_aux_buffers = (layout_flags & MIPTREE_LAYOUT_DISABLE_AUX) != 0;
    exec_list_make_empty(&mt->hiz_map);
 
    /* The cpp is bytes per (1, blockheight)-sized block for compressed
@@ -422,12 +448,15 @@ intel_miptree_create_layout(struct brw_context *brw,
    mt->physical_height0 = height0;
    mt->physical_depth0 = depth0;
 
-   if (!for_bo &&
+   if (!(layout_flags & MIPTREE_LAYOUT_FOR_BO) &&
        _mesa_get_format_base_format(format) == GL_DEPTH_STENCIL &&
        (brw->must_use_separate_stencil ||
        (brw->has_separate_stencil &&
          intel_miptree_wants_hiz_buffer(brw, mt)))) {
-      const bool force_all_slices_at_each_lod = brw->gen == 6;
+      uint32_t stencil_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD;
+      if (brw->gen == 6)
+         stencil_flags |= MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD;
+
       mt->stencil_mt = intel_miptree_create(brw,
                                             mt->target,
                                             MESA_FORMAT_S_UINT8,
@@ -436,10 +465,10 @@ intel_miptree_create_layout(struct brw_context *brw,
                                             mt->logical_width0,
                                             mt->logical_height0,
                                             mt->logical_depth0,
-                                            true,
                                             num_samples,
                                             INTEL_MIPTREE_TILING_ANY,
-                                            force_all_slices_at_each_lod);
+                                            stencil_flags);
+
       if (!mt->stencil_mt) {
         intel_miptree_release(&mt);
         return NULL;
@@ -457,119 +486,36 @@ intel_miptree_create_layout(struct brw_context *brw,
       }
    }
 
-   if (force_all_slices_at_each_lod)
+   if (layout_flags & MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD)
       mt->array_layout = ALL_SLICES_AT_EACH_LOD;
 
-   brw_miptree_layout(brw, mt);
-
-   if (mt->disable_aux_buffers)
-      assert(mt->msaa_layout != INTEL_MSAA_LAYOUT_CMS);
-
-   return mt;
-}
-
-/**
- * \brief Helper function for intel_miptree_create().
- */
-static uint32_t
-intel_miptree_choose_tiling(struct brw_context *brw,
-                            mesa_format format,
-                            uint32_t width0,
-                            uint32_t num_samples,
-                            enum intel_miptree_tiling_mode requested,
-                            struct intel_mipmap_tree *mt)
-{
-   if (format == MESA_FORMAT_S_UINT8) {
-      /* The stencil buffer is W tiled. However, we request from the kernel a
-       * non-tiled buffer because the GTT is incapable of W fencing.
-       */
-      return I915_TILING_NONE;
-   }
-
-   /* Some usages may want only one type of tiling, like depth miptrees (Y
-    * tiled), or temporary BOs for uploading data once (linear).
-    */
-   switch (requested) {
-   case INTEL_MIPTREE_TILING_ANY:
-      break;
-   case INTEL_MIPTREE_TILING_Y:
-      return I915_TILING_Y;
-   case INTEL_MIPTREE_TILING_NONE:
-      return I915_TILING_NONE;
-   }
-
-   if (num_samples > 1) {
-      /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
-       * Surface"):
-       *
-       *   [DevSNB+]: For multi-sample render targets, this field must be
-       *   1. MSRTs can only be tiled.
-       *
-       * Our usual reason for preferring X tiling (fast blits using the
-       * blitting engine) doesn't apply to MSAA, since we'll generally be
-       * downsampling or upsampling when blitting between the MSAA buffer
-       * and another buffer, and the blitting engine doesn't support that.
-       * So use Y tiling, since it makes better use of the cache.
-       */
-      return I915_TILING_Y;
-   }
-
-   GLenum base_format = _mesa_get_format_base_format(format);
-   if (base_format == GL_DEPTH_COMPONENT ||
-       base_format == GL_DEPTH_STENCIL_EXT)
-      return I915_TILING_Y;
-
-   /* 1D textures (and 1D array textures) don't get any benefit from tiling,
-    * in fact it leads to a less efficient use of memory space and bandwidth
-    * due to tile alignment.
+   /*
+    * Obey HALIGN_16 constraints for Gen8 and Gen9 buffers which are
+    * multisampled or have an AUX buffer attached to it.
+    *
+    * GEN  |    MSRT        | AUX_CCS_* or AUX_MCS
+    *  -------------------------------------------
+    *  9   |  HALIGN_16     |    HALIGN_16
+    *  8   |  HALIGN_ANY    |    HALIGN_16
+    *  7   |      ?         |        ?
+    *  6   |      ?         |        ?
     */
-   if (mt->logical_height0 == 1)
-      return I915_TILING_NONE;
-
-   int minimum_pitch = mt->total_width * mt->cpp;
-
-   /* If the width is much smaller than a tile, don't bother tiling. */
-   if (minimum_pitch < 64)
-      return I915_TILING_NONE;
-
-   if (ALIGN(minimum_pitch, 512) >= 32768 ||
-       mt->total_width >= 32768 || mt->total_height >= 32768) {
-      perf_debug("%dx%d miptree too large to blit, falling back to untiled",
-                 mt->total_width, mt->total_height);
-      return I915_TILING_NONE;
+   if (intel_miptree_is_fast_clear_capable(brw, mt)) {
+      if (brw->gen >= 9 || (brw->gen == 8 && num_samples <= 1))
+         layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16;
+   } else if (brw->gen >= 9 && num_samples > 1) {
+      layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16;
+   } else {
+      /* For now, nothing else has this requirement */
+      assert((layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16) == 0);
    }
 
-   /* Pre-gen6 doesn't have BLORP to handle Y-tiling, so use X-tiling. */
-   if (brw->gen < 6)
-      return I915_TILING_X;
+   brw_miptree_layout(brw, mt, requested, layout_flags);
 
-   /* From the Sandybridge PRM, Volume 1, Part 2, page 32:
-    * "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either TileX
-    *  or Linear."
-    * 128 bits per pixel translates to 16 bytes per pixel. This is necessary
-    * all the way back to 965, but is permitted on Gen7+.
-    */
-   if (brw->gen < 7 && mt->cpp >= 16)
-      return I915_TILING_X;
-
-   /* From the Ivy Bridge PRM, Vol4 Part1 2.12.2.1 (SURFACE_STATE for most
-    * messages), on p64, under the heading "Surface Vertical Alignment":
-    *
-    *     This field must be set to VALIGN_4 for all tiled Y Render Target
-    *     surfaces.
-    *
-    * So if the surface is renderable and uses a vertical alignment of 2,
-    * force it to be X tiled.  This is somewhat conservative (it's possible
-    * that the client won't ever render to this surface), but it's difficult
-    * to know that ahead of time.  And besides, since we use a vertical
-    * alignment of 4 as often as we can, this shouldn't happen very often.
-    */
-   if (brw->gen == 7 && mt->align_h == 2 &&
-       brw->format_supported_as_render_target[format]) {
-      return I915_TILING_X;
-   }
+   if (mt->disable_aux_buffers)
+      assert(mt->msaa_layout != INTEL_MSAA_LAYOUT_CMS);
 
-   return I915_TILING_Y | I915_TILING_X;
+   return mt;
 }
 
 
@@ -615,33 +561,33 @@ intel_lower_compressed_format(struct brw_context *brw, mesa_format format)
 
 struct intel_mipmap_tree *
 intel_miptree_create(struct brw_context *brw,
-                    GLenum target,
-                    mesa_format format,
-                    GLuint first_level,
-                    GLuint last_level,
-                    GLuint width0,
-                    GLuint height0,
-                    GLuint depth0,
-                    bool expect_accelerated_upload,
+                     GLenum target,
+                     mesa_format format,
+                     GLuint first_level,
+                     GLuint last_level,
+                     GLuint width0,
+                     GLuint height0,
+                     GLuint depth0,
                      GLuint num_samples,
                      enum intel_miptree_tiling_mode requested_tiling,
-                     bool force_all_slices_at_each_lod)
+                     uint32_t layout_flags)
 {
    struct intel_mipmap_tree *mt;
    mesa_format tex_format = format;
    mesa_format etc_format = MESA_FORMAT_NONE;
    GLuint total_width, total_height;
+   uint32_t alloc_flags = 0;
 
    format = intel_lower_compressed_format(brw, format);
 
    etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE;
 
+   assert((layout_flags & MIPTREE_LAYOUT_DISABLE_AUX) == 0);
+   assert((layout_flags & MIPTREE_LAYOUT_FOR_BO) == 0);
    mt = intel_miptree_create_layout(brw, target, format,
-                                     first_level, last_level, width0,
-                                     height0, depth0,
-                                    false, num_samples,
-                                    force_all_slices_at_each_lod,
-                                    false /*disable_aux_buffers*/);
+                                    first_level, last_level, width0,
+                                    height0, depth0, num_samples,
+                                    requested_tiling, layout_flags);
    /*
     * pitch == 0 || height == 0  indicates the null texture
     */
@@ -659,25 +605,21 @@ intel_miptree_create(struct brw_context *brw,
       total_height = ALIGN(total_height, 64);
    }
 
-   uint32_t tiling = intel_miptree_choose_tiling(brw, format, width0,
-                                                 num_samples, requested_tiling,
-                                                 mt);
    bool y_or_x = false;
 
-   if (tiling == (I915_TILING_Y | I915_TILING_X)) {
+   if (mt->tiling == (I915_TILING_Y | I915_TILING_X)) {
       y_or_x = true;
       mt->tiling = I915_TILING_Y;
-   } else {
-      mt->tiling = tiling;
    }
 
+   if (layout_flags & MIPTREE_LAYOUT_ACCELERATED_UPLOAD)
+      alloc_flags |= BO_ALLOC_FOR_RENDER;
+
    unsigned long pitch;
+   mt->bo = drm_intel_bo_alloc_tiled(brw->bufmgr, "miptree", total_width,
+                                     total_height, mt->cpp, &mt->tiling,
+                                     &pitch, alloc_flags);
    mt->etc_format = etc_format;
-   mt->bo = drm_intel_bo_alloc_tiled(brw->bufmgr, "miptree",
-                                     total_width, total_height, mt->cpp,
-                                     &mt->tiling, &pitch,
-                                     (expect_accelerated_upload ?
-                                      BO_ALLOC_FOR_RENDER : 0));
    mt->pitch = pitch;
 
    /* If the BO is too large to fit in the aperture, we need to use the
@@ -691,10 +633,8 @@ intel_miptree_create(struct brw_context *brw,
       mt->tiling = I915_TILING_X;
       drm_intel_bo_unreference(mt->bo);
       mt->bo = drm_intel_bo_alloc_tiled(brw->bufmgr, "miptree",
-                                        total_width, total_height, mt->cpp,
-                                        &mt->tiling, &pitch,
-                                        (expect_accelerated_upload ?
-                                         BO_ALLOC_FOR_RENDER : 0));
+                                  total_width, total_height, mt->cpp,
+                                  &mt->tiling, &pitch, alloc_flags);
       mt->pitch = pitch;
    }
 
@@ -707,6 +647,7 @@ intel_miptree_create(struct brw_context *brw,
 
 
    if (mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
+      assert(mt->num_samples > 1);
       if (!intel_miptree_alloc_mcs(brw, mt, num_samples)) {
          intel_miptree_release(&mt);
          return NULL;
@@ -718,8 +659,11 @@ intel_miptree_create(struct brw_context *brw,
     * Allocation of the MCS miptree will be deferred until the first fast
     * clear actually occurs.
     */
-   if (intel_is_non_msrt_mcs_buffer_supported(brw, mt))
+   if (intel_tiling_supports_non_msrt_mcs(brw, mt->tiling) &&
+       intel_miptree_is_fast_clear_capable(brw, mt)) {
       mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
+      assert(brw->gen < 8 || mt->align_w == 16 || num_samples <= 1);
+   }
 
    return mt;
 }
@@ -733,7 +677,7 @@ intel_miptree_create_for_bo(struct brw_context *brw,
                             uint32_t height,
                             uint32_t depth,
                             int pitch,
-                            bool disable_aux_buffers)
+                            uint32_t layout_flags)
 {
    struct intel_mipmap_tree *mt;
    uint32_t tiling, swizzle;
@@ -754,11 +698,18 @@ intel_miptree_create_for_bo(struct brw_context *brw,
 
    target = depth > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
 
+   /* 'requested' parameter of intel_miptree_create_layout() is relevant
+    * only for non bo miptree. Tiling for bo is already computed above.
+    * So, the tiling requested (INTEL_MIPTREE_TILING_ANY) below is
+    * just a place holder and will not make any change to the miptree
+    * tiling format.
+    */
+   layout_flags |= MIPTREE_LAYOUT_FOR_BO;
    mt = intel_miptree_create_layout(brw, target, format,
                                     0, 0,
-                                    width, height, depth,
-                                    true, 0, false,
-                                    disable_aux_buffers);
+                                    width, height, depth, 0,
+                                    INTEL_MIPTREE_TILING_ANY,
+                                    layout_flags);
    if (!mt)
       return NULL;
 
@@ -808,7 +759,7 @@ intel_update_winsys_renderbuffer_miptree(struct brw_context *intel,
                                                  height,
                                                  1,
                                                  pitch,
-                                                 false);
+                                                 0);
    if (!singlesample_mt)
       goto fail;
 
@@ -817,7 +768,8 @@ intel_update_winsys_renderbuffer_miptree(struct brw_context *intel,
     * Allocation of the MCS miptree will be deferred until the first fast
     * clear actually occurs.
     */
-   if (intel_is_non_msrt_mcs_buffer_supported(intel, singlesample_mt))
+   if (intel_tiling_supports_non_msrt_mcs(intel, singlesample_mt->tiling) &&
+       intel_miptree_is_fast_clear_capable(intel, singlesample_mt))
       singlesample_mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
 
    if (num_samples == 0) {
@@ -866,8 +818,9 @@ intel_miptree_create_for_renderbuffer(struct brw_context *brw,
    GLenum target = num_samples > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
 
    mt = intel_miptree_create(brw, target, format, 0, 0,
-                            width, height, depth, true, num_samples,
-                             INTEL_MIPTREE_TILING_ANY, false);
+                             width, height, depth, num_samples,
+                             INTEL_MIPTREE_TILING_ANY,
+                             MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
    if (!mt)
       goto fail;
 
@@ -1258,8 +1211,10 @@ intel_miptree_copy_slice(struct brw_context *brw,
    assert(src_mt->format == dst_mt->format);
 
    if (dst_mt->compressed) {
-      height = ALIGN(height, dst_mt->align_h) / dst_mt->align_h;
-      width = ALIGN(width, dst_mt->align_w);
+      unsigned int i, j;
+      _mesa_get_format_block_size(dst_mt->format, &i, &j);
+      height = ALIGN(height, j) / j;
+      width = ALIGN(width, i);
    }
 
    /* If it's a packed depth/stencil buffer with separate stencil, the blit
@@ -1378,10 +1333,9 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
                                      mt->logical_width0,
                                      mt->logical_height0,
                                      mt->logical_depth0,
-                                     true,
                                      0 /* num_samples */,
                                      INTEL_MIPTREE_TILING_Y,
-                                     false);
+                                     MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
 
    /* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
     *
@@ -1429,6 +1383,9 @@ intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw,
    unsigned mcs_height =
       ALIGN(mt->logical_height0, height_divisor) / height_divisor;
    assert(mt->logical_depth0 == 1);
+   uint32_t layout_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD;
+   if (brw->gen >= 8)
+      layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16;
    mt->mcs_mt = intel_miptree_create(brw,
                                      mt->target,
                                      format,
@@ -1437,10 +1394,9 @@ intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw,
                                      mcs_width,
                                      mcs_height,
                                      mt->logical_depth0,
-                                     true,
                                      0 /* num_samples */,
                                      INTEL_MIPTREE_TILING_Y,
-                                     false);
+                                     layout_flags);
 
    return mt->mcs_mt;
 }
@@ -1682,7 +1638,10 @@ intel_hiz_miptree_buf_create(struct brw_context *brw,
                              struct intel_mipmap_tree *mt)
 {
    struct intel_miptree_aux_buffer *buf = calloc(sizeof(*buf), 1);
-   const bool force_all_slices_at_each_lod = brw->gen == 6;
+   uint32_t layout_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD;
+
+   if (brw->gen == 6)
+      layout_flags |= MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD;
 
    if (!buf)
       return NULL;
@@ -1695,10 +1654,9 @@ intel_hiz_miptree_buf_create(struct brw_context *brw,
                                   mt->logical_width0,
                                   mt->logical_height0,
                                   mt->logical_depth0,
-                                  true,
                                   mt->num_samples,
                                   INTEL_MIPTREE_TILING_ANY,
-                                  force_all_slices_at_each_lod);
+                                  layout_flags);
    if (!buf->mt) {
       free(buf);
       return NULL;
@@ -2128,9 +2086,8 @@ intel_miptree_map_blit(struct brw_context *brw,
    map->mt = intel_miptree_create(brw, GL_TEXTURE_2D, mt->format,
                                   0, 0,
                                   map->w, map->h, 1,
-                                  false, 0,
-                                  INTEL_MIPTREE_TILING_NONE,
-                                  false);
+                                  0, INTEL_MIPTREE_TILING_NONE, 0);
+
    if (!map->mt) {
       fprintf(stderr, "Failed to allocate blit temporary\n");
       goto fail;
@@ -2675,7 +2632,9 @@ intel_miptree_map(struct brw_context *brw,
    } else if (use_intel_mipree_map_blit(brw, mt, mode, level, slice)) {
       intel_miptree_map_blit(brw, mt, map, level, slice);
 #if defined(USE_SSE41)
-   } else if (!(mode & GL_MAP_WRITE_BIT) && !mt->compressed && cpu_has_sse4_1) {
+   } else if (!(mode & GL_MAP_WRITE_BIT) &&
+              !mt->compressed && cpu_has_sse4_1 &&
+              (mt->pitch % 16 == 0)) {
       intel_miptree_map_movntdqa(brw, mt, map, level, slice);
 #endif
    } else {
index 8b42e4adb79af7aa336ef4102ed53cb00aabde6a..bde6daa4e2d78070c431fd88187cf15f9376acad 100644 (file)
@@ -330,6 +330,13 @@ struct intel_miptree_aux_buffer
    struct intel_mipmap_tree *mt; /**< hiz miptree used with Gen6 */
 };
 
+/* Tile resource modes */
+enum intel_miptree_tr_mode {
+   INTEL_MIPTREE_TRMODE_NONE,
+   INTEL_MIPTREE_TRMODE_YF,
+   INTEL_MIPTREE_TRMODE_YS
+};
+
 struct intel_mipmap_tree
 {
    /** Buffer object containing the pixel data. */
@@ -338,6 +345,7 @@ struct intel_mipmap_tree
    uint32_t pitch; /**< pitch in bytes. */
 
    uint32_t tiling; /**< One of the I915_TILING_* flags */
+   enum intel_miptree_tr_mode tr_mode;
 
    /* Effectively the key:
     */
@@ -514,19 +522,27 @@ enum intel_miptree_tiling_mode {
    INTEL_MIPTREE_TILING_NONE,
 };
 
-bool
-intel_is_non_msrt_mcs_buffer_supported(struct brw_context *brw,
-                                       struct intel_mipmap_tree *mt);
-
 void
 intel_get_non_msrt_mcs_alignment(struct brw_context *brw,
                                  struct intel_mipmap_tree *mt,
                                  unsigned *width_px, unsigned *height);
-
+bool
+intel_tiling_supports_non_msrt_mcs(struct brw_context *brw, unsigned tiling);
+bool
+intel_miptree_is_fast_clear_capable(struct brw_context *brw,
+                                    struct intel_mipmap_tree *mt);
 bool
 intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw,
                                  struct intel_mipmap_tree *mt);
 
+enum {
+   MIPTREE_LAYOUT_ACCELERATED_UPLOAD       = 1 << 0,
+   MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD   = 1 << 1,
+   MIPTREE_LAYOUT_FOR_BO                   = 1 << 2,
+   MIPTREE_LAYOUT_DISABLE_AUX              = 1 << 3,
+   MIPTREE_LAYOUT_FORCE_HALIGN16           = 1 << 4,
+};
+
 struct intel_mipmap_tree *intel_miptree_create(struct brw_context *brw,
                                                GLenum target,
                                               mesa_format format,
@@ -535,10 +551,9 @@ struct intel_mipmap_tree *intel_miptree_create(struct brw_context *brw,
                                                GLuint width0,
                                                GLuint height0,
                                                GLuint depth0,
-                                              bool expect_accelerated_upload,
                                                GLuint num_samples,
                                                enum intel_miptree_tiling_mode,
-                                               bool force_all_slices_at_each_lod);
+                                               uint32_t flags);
 
 struct intel_mipmap_tree *
 intel_miptree_create_for_bo(struct brw_context *brw,
@@ -549,7 +564,7 @@ intel_miptree_create_for_bo(struct brw_context *brw,
                             uint32_t height,
                             uint32_t depth,
                             int pitch,
-                            bool disable_aux_buffers);
+                            uint32_t layout_flags);
 
 void
 intel_update_winsys_renderbuffer_miptree(struct brw_context *intel,
@@ -753,7 +768,11 @@ brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
                                      const struct intel_mipmap_tree *mt,
                                      unsigned level);
 
-void brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt);
+void
+brw_miptree_layout(struct brw_context *brw,
+                   struct intel_mipmap_tree *mt,
+                   enum intel_miptree_tiling_mode requested,
+                   uint32_t layout_flags);
 
 void *intel_miptree_map_raw(struct brw_context *brw,
                             struct intel_mipmap_tree *mt);
index 4ecefc8cf542b2f0da373126bf13b37c9614904e..6c6bd8629ac27d98c2240f8a32110e9b6d89fc2f 100644 (file)
@@ -28,6 +28,7 @@
 #include "main/glheader.h"
 #include "main/enums.h"
 #include "main/image.h"
+#include "main/glformats.h"
 #include "main/mtypes.h"
 #include "main/condrender.h"
 #include "main/fbobject.h"
@@ -76,8 +77,16 @@ do_blit_drawpixels(struct gl_context * ctx,
    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
-   if (!_mesa_format_matches_format_and_type(irb->mt->format, format, type,
-                                             false)) {
+   mesa_format src_format = _mesa_format_from_format_and_type(format, type);
+   if (_mesa_format_is_mesa_array_format(src_format))
+      src_format = _mesa_format_from_array_format(src_format);
+   mesa_format dst_format = irb->mt->format;
+
+   /* We can safely discard sRGB encode/decode for the DrawPixels interface */
+   src_format = _mesa_get_srgb_format_linear(src_format);
+   dst_format = _mesa_get_srgb_format_linear(dst_format);
+
+   if (!intel_miptree_blit_compatible_formats(src_format, dst_format)) {
       DBG("%s: bad format for blit\n", __func__);
       return false;
    }
@@ -112,7 +121,7 @@ do_blit_drawpixels(struct gl_context * ctx,
                                   src_offset,
                                   width, height, 1,
                                   src_stride,
-                                  false /*disable_aux_buffers*/);
+                                  0);
    if (!pbo_mt)
       return false;
 
index d3ca38b6ecded2498bd9fd0a464fa393cab0415a..30380570d620f602040d0d7caac55525c63a96a0 100644 (file)
@@ -226,8 +226,30 @@ intelReadPixels(struct gl_context * ctx,
 
    if (_mesa_is_bufferobj(pack->BufferObj)) {
       if (_mesa_meta_pbo_GetTexSubImage(ctx, 2, NULL, x, y, 0, width, height, 1,
-                                        format, type, pixels, pack))
+                                        format, type, pixels, pack)) {
+         /* _mesa_meta_pbo_GetTexSubImage() implements PBO transfers by
+          * binding the user-provided BO as a fake framebuffer and rendering
+          * to it.  This breaks the invariant of the GL that nothing is able
+          * to render to a BO, causing nondeterministic corruption issues
+          * because the render cache is not coherent with a number of other
+          * caches that the BO could potentially be bound to afterwards.
+          *
+          * This could be solved in the same way that we guarantee texture
+          * coherency after a texture is attached to a framebuffer and
+          * rendered to, but that would involve checking *all* BOs bound to
+          * the pipeline for the case we need to emit a cache flush due to
+          * previous rendering to any of them -- Including vertex, index,
+          * uniform, atomic counter, shader image, transform feedback,
+          * indirect draw buffers, etc.
+          *
+          * That would increase the per-draw call overhead even though it's
+          * very unlikely that any of the BOs bound to the pipeline has been
+          * rendered to via a PBO at any point, so it seems better to just
+          * flush here unconditionally.
+          */
+         intel_batchbuffer_emit_mi_flush(brw);
          return;
+      }
 
       perf_debug("%s: fallback to CPU mapping in PBO case\n", __func__);
    }
index 488fb5b98f8a0013afaaab6cc3346a50d0097761..bd14e189da3818c037ea55076275549f0363f290 100644 (file)
 #define GEN7_MI_LOAD_REGISTER_MEM      (CMD_MI | (0x29 << 23))
 # define MI_LOAD_REGISTER_MEM_USE_GGTT         (1 << 22)
 
+/* Manipulate the predicate bit based on some register values. Only on Gen7+ */
+#define GEN7_MI_PREDICATE              (CMD_MI | (0xC << 23))
+# define MI_PREDICATE_LOADOP_KEEP              (0 << 6)
+# define MI_PREDICATE_LOADOP_LOAD              (2 << 6)
+# define MI_PREDICATE_LOADOP_LOADINV           (3 << 6)
+# define MI_PREDICATE_COMBINEOP_SET            (0 << 3)
+# define MI_PREDICATE_COMBINEOP_AND            (1 << 3)
+# define MI_PREDICATE_COMBINEOP_OR             (2 << 3)
+# define MI_PREDICATE_COMBINEOP_XOR            (3 << 3)
+# define MI_PREDICATE_COMPAREOP_TRUE           (0 << 0)
+# define MI_PREDICATE_COMPAREOP_FALSE          (1 << 0)
+# define MI_PREDICATE_COMPAREOP_SRCS_EQUAL     (2 << 0)
+# define MI_PREDICATE_COMPAREOP_DELTAS_EQUAL   (3 << 0)
+
 /** @{
  *
  * PIPE_CONTROL operation, a combination MI_FLUSH and register write with
@@ -69,6 +83,7 @@
 #define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE  (1 << 10) /* GM45+ only */
 #define PIPE_CONTROL_ISP_DIS           (1 << 9)
 #define PIPE_CONTROL_INTERRUPT_ENABLE  (1 << 8)
+#define PIPE_CONTROL_FLUSH_ENABLE      (1 << 7) /* Gen7+ only */
 /* GT */
 #define PIPE_CONTROL_DATA_CACHE_INVALIDATE     (1 << 5)
 #define PIPE_CONTROL_VF_CACHE_INVALIDATE       (1 << 4)
 # define GEN9_PARTIAL_RESOLVE_DISABLE_IN_VC (1 << 1)
 # define GEN8_HIZ_PMA_MASK_BITS \
    ((GEN8_HIZ_NP_PMA_FIX_ENABLE | GEN8_HIZ_NP_EARLY_Z_FAILS_DISABLE) << 16)
+
+/* Predicate registers */
+#define MI_PREDICATE_SRC0               0x2400
+#define MI_PREDICATE_SRC1               0x2408
+#define MI_PREDICATE_DATA               0x2410
+#define MI_PREDICATE_RESULT             0x2418
+#define MI_PREDICATE_RESULT_1           0x241C
+#define MI_PREDICATE_RESULT_2           0x2214
index 4860a160ee9e01fef37fb0536b3d238ca2baa5c2..de14696bd76f2fbc8577a9682f020777794a691d 100644 (file)
@@ -39,6 +39,7 @@
 #include "swrast/s_renderbuffer.h"
 #include "util/ralloc.h"
 #include "brw_shader.h"
+#include "glsl/nir/nir.h"
 
 #include "utils.h"
 #include "xmlpool.h"
@@ -1372,6 +1373,8 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
    if (!intelScreen->devinfo)
       return false;
 
+   brw_process_intel_debug_variable(intelScreen);
+
    intelScreen->hw_must_use_separate_stencil = intelScreen->devinfo->gen >= 7;
 
    intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
@@ -1407,6 +1410,13 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
          (ret != -1 || errno != EINVAL);
    }
 
+   struct drm_i915_getparam getparam;
+   getparam.param = I915_PARAM_CMD_PARSER_VERSION;
+   getparam.value = &intelScreen->cmd_parser_version;
+   const int ret = drmIoctl(psp->fd, DRM_IOCTL_I915_GETPARAM, &getparam);
+   if (ret == -1)
+      intelScreen->cmd_parser_version = 0;
+
    psp->extensions = !intelScreen->has_context_reset_notification
       ? intelScreenExtensions : intelRobustScreenExtensions;
 
index e7a14903d6e1333d1ada401bec3457e65fe755ac..742b3d30eee2a229d8d0c731ae81eb5b9de5fd8e 100644 (file)
@@ -72,7 +72,13 @@ struct intel_screen
    * Configuration cache with default values for all contexts
    */
    driOptionCache optionCache;
-};
+
+   /**
+    * Version of the command parser reported by the
+    * I915_PARAM_CMD_PARSER_VERSION parameter
+    */
+   int cmd_parser_version;
+ };
 
 extern void intelDestroyContext(__DRIcontext * driContextPriv);
 
index 777a682ad213c860b3a2d81e3c9bc2a241aef275..b0181ad1d75d688d912e543d1f46691b85cdcd54 100644 (file)
@@ -93,7 +93,7 @@ intel_alloc_texture_image_buffer(struct gl_context *ctx,
    } else {
       intel_image->mt = intel_miptree_create_for_teximage(brw, intel_texobj,
                                                           intel_image,
-                                                          false);
+                                                          0);
 
       /* Even if the object currently has a mipmap tree associated
        * with it, this one is a more likely candidate to represent the
@@ -144,10 +144,8 @@ intel_alloc_texture_storage(struct gl_context *ctx,
                                               first_image->TexFormat,
                                               0, levels - 1,
                                               width, height, depth,
-                                              false, /* expect_accelerated */
                                               num_samples,
-                                              INTEL_MIPTREE_TILING_ANY,
-                                              false);
+                                              INTEL_MIPTREE_TILING_ANY, 0);
 
       if (intel_texobj->mt == NULL) {
          return false;
@@ -341,7 +339,7 @@ intel_set_texture_storage_for_buffer_object(struct gl_context *ctx,
                                   buffer_offset,
                                   image->Width, image->Height, image->Depth,
                                   row_stride,
-                                  false /*disable_aux_buffers*/);
+                                  0);
    if (!intel_texobj->mt)
       return false;
 
index f048e846d55a2ca4d52cdea71e7daac76b43e68b..402a3891ecdd40e562ebb2b79f4fc2ff4489d2d5 100644 (file)
@@ -53,7 +53,7 @@ struct intel_mipmap_tree *
 intel_miptree_create_for_teximage(struct brw_context *brw,
                                  struct intel_texture_object *intelObj,
                                  struct intel_texture_image *intelImage,
-                                 bool expect_accelerated_upload);
+                                  uint32_t layout_flags);
 
 GLuint intel_finalize_mipmap_tree(struct brw_context *brw, GLuint unit);
 
index 7952ee5ad8899824f7967554627ac05ea14241bf..ebe84b664d43e66d1b05a898986df9627a85093d 100644 (file)
@@ -36,7 +36,7 @@ struct intel_mipmap_tree *
 intel_miptree_create_for_teximage(struct brw_context *brw,
                                  struct intel_texture_object *intelObj,
                                  struct intel_texture_image *intelImage,
-                                 bool expect_accelerated_upload)
+                                  uint32_t layout_flags)
 {
    GLuint lastLevel;
    int width, height, depth;
@@ -79,10 +79,9 @@ intel_miptree_create_for_teximage(struct brw_context *brw,
                               width,
                               height,
                               depth,
-                              expect_accelerated_upload,
                                intelImage->base.Base.NumSamples,
                                INTEL_MIPTREE_TILING_ANY,
-                               false);
+                               layout_flags);
 }
 
 static void
@@ -155,7 +154,7 @@ intel_set_texture_image_bo(struct gl_context *ctx,
                            GLuint width, GLuint height,
                            GLuint pitch,
                            GLuint tile_x, GLuint tile_y,
-                           bool disable_aux_buffers)
+                           uint32_t layout_flags)
 {
    struct brw_context *brw = brw_context(ctx);
    struct intel_texture_image *intel_image = intel_texture_image(image);
@@ -171,7 +170,7 @@ intel_set_texture_image_bo(struct gl_context *ctx,
 
    intel_image->mt = intel_miptree_create_for_bo(brw, bo, image->TexFormat,
                                                  0, width, height, 1, pitch,
-                                                 disable_aux_buffers);
+                                                 layout_flags);
    if (intel_image->mt == NULL)
        return;
    intel_image->mt->target = target;
@@ -255,8 +254,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
                               rb->Base.Base.Width,
                               rb->Base.Base.Height,
                               rb->mt->pitch,
-                              0, 0,
-                              false /*disable_aux_buffers*/);
+                              0, 0, 0);
    _mesa_unlock_texture(&brw->ctx, texObj);
 }
 
@@ -349,7 +347,7 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
                               image->width,  image->height,
                               image->pitch,
                               image->tile_x, image->tile_y,
-                              true /*disable_aux_buffers*/);
+                              MIPTREE_LAYOUT_DISABLE_AUX);
 }
 
 /**
@@ -486,8 +484,15 @@ intel_get_tex_image(struct gl_context *ctx,
       if (_mesa_meta_pbo_GetTexSubImage(ctx, 3, texImage, 0, 0, 0,
                                         texImage->Width, texImage->Height,
                                         texImage->Depth, format, type,
-                                        pixels, &ctx->Pack))
+                                        pixels, &ctx->Pack)) {
+         /* Flush to guarantee coherency between the render cache and other
+          * caches the PBO could potentially be bound to after this point.
+          * See the related comment in intelReadPixels() for a more detailed
+          * explanation.
+          */
+         intel_batchbuffer_emit_mi_flush(brw);
          return;
+      }
 
       perf_debug("%s: fallback to CPU mapping in PBO case\n", __func__);
    }
index 1d827683b99478fb20b22b7a883bdb40fc32c765..4991c2997efb3f7603852b818bcfd8607bb22454 100644 (file)
@@ -47,8 +47,10 @@ intel_update_max_level(struct intel_texture_object *intelObj,
 {
    struct gl_texture_object *tObj = &intelObj->base;
 
-   if (sampler->MinFilter == GL_NEAREST ||
-       sampler->MinFilter == GL_LINEAR) {
+   if (!tObj->_MipmapComplete ||
+       (tObj->_RenderToTexture &&
+        (sampler->MinFilter == GL_NEAREST ||
+         sampler->MinFilter == GL_LINEAR))) {
       intelObj->_MaxLevel = tObj->BaseLevel;
    } else {
       intelObj->_MaxLevel = tObj->_MaxLevel;
@@ -142,10 +144,9 @@ intel_finalize_mipmap_tree(struct brw_context *brw, GLuint unit)
                                           width,
                                           height,
                                           depth,
-                                         true,
                                           0 /* num_samples */,
                                           INTEL_MIPTREE_TILING_ANY,
-                                          false);
+                                          MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
       if (!intelObj->mt)
          return false;
    }
index 206a76e92428feb50b66ea3b7f6973e945ac8cf9..8010fb4f610861bcd193a5f94ab2d6fc9cf796c4 100644 (file)
 #include "brw_cfg.h"
 #include "program/program.h"
 
+using namespace brw;
+
 class cmod_propagation_test : public ::testing::Test {
    virtual void SetUp();
 
 public:
-   struct brw_context *brw;
+   struct brw_compiler *compiler;
    struct brw_device_info *devinfo;
    struct gl_context *ctx;
    struct brw_wm_prog_data *prog_data;
@@ -42,30 +44,31 @@ public:
 class cmod_propagation_fs_visitor : public fs_visitor
 {
 public:
-   cmod_propagation_fs_visitor(struct brw_context *brw,
+   cmod_propagation_fs_visitor(struct brw_compiler *compiler,
                                struct brw_wm_prog_data *prog_data,
                                struct gl_shader_program *shader_prog)
-      : fs_visitor(brw, NULL, NULL, prog_data, shader_prog, NULL, 8) {}
+      : fs_visitor(compiler, NULL, NULL, MESA_SHADER_FRAGMENT, NULL,
+                   &prog_data->base, shader_prog,
+                   (struct gl_program *) NULL, 8, -1) {}
 };
 
 
 void cmod_propagation_test::SetUp()
 {
-   brw = (struct brw_context *)calloc(1, sizeof(*brw));
-   devinfo = (struct brw_device_info *)calloc(1, sizeof(*brw));
-   brw->intelScreen = (struct intel_screen *)calloc(1, sizeof(*brw->intelScreen));
-   brw->intelScreen->devinfo = devinfo;
-   ctx = &brw->ctx;
+   ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
+   compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
+   devinfo = (struct brw_device_info *)calloc(1, sizeof(*devinfo));
+   compiler->devinfo = devinfo;
 
    fp = ralloc(NULL, struct brw_fragment_program);
    prog_data = ralloc(NULL, struct brw_wm_prog_data);
    shader_prog = ralloc(NULL, struct gl_shader_program);
 
-   v = new cmod_propagation_fs_visitor(brw, prog_data, shader_prog);
+   v = new cmod_propagation_fs_visitor(compiler, prog_data, shader_prog);
 
    _mesa_init_fragment_program(ctx, &fp->program, GL_FRAGMENT_SHADER, 0);
 
-   brw->gen = devinfo->gen = 4;
+   devinfo->gen = 4;
 }
 
 static fs_inst *
@@ -100,13 +103,13 @@ cmod_propagation(fs_visitor *v)
 
 TEST_F(cmod_propagation_test, basic)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, dest, src0, src1);
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.ADD(dest, src0, src1);
+   bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -132,13 +135,13 @@ TEST_F(cmod_propagation_test, basic)
 
 TEST_F(cmod_propagation_test, cmp_nonzero)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg nonzero(1.0f);
-   v->emit(BRW_OPCODE_ADD, dest, src0, src1);
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, nonzero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.ADD(dest, src0, src1);
+   bld.CMP(bld.null_reg_f(), dest, nonzero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -165,12 +168,12 @@ TEST_F(cmod_propagation_test, cmp_nonzero)
 
 TEST_F(cmod_propagation_test, non_cmod_instruction)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::uint_type);
    fs_reg src0 = v->vgrf(glsl_type::uint_type);
    fs_reg zero(0u);
-   v->emit(BRW_OPCODE_FBL, dest, src0);
-   v->emit(BRW_OPCODE_CMP, v->reg_null_ud, dest, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.FBL(dest, src0);
+   bld.CMP(bld.null_reg_ud(), dest, zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -197,16 +200,15 @@ TEST_F(cmod_propagation_test, non_cmod_instruction)
 
 TEST_F(cmod_propagation_test, intervening_flag_write)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg src2 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, dest, src0, src1);
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, src2, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.ADD(dest, src0, src1);
+   bld.CMP(bld.null_reg_f(), src2, zero, BRW_CONDITIONAL_GE);
+   bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -236,17 +238,16 @@ TEST_F(cmod_propagation_test, intervening_flag_write)
 
 TEST_F(cmod_propagation_test, intervening_flag_read)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest0 = v->vgrf(glsl_type::float_type);
    fs_reg dest1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg src2 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, dest0, src0, src1);
-   v->emit(BRW_OPCODE_SEL, dest1, src2, zero)
-      ->predicate = BRW_PREDICATE_NORMAL;
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest0, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.ADD(dest0, src0, src1);
+   set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
+   bld.CMP(bld.null_reg_f(), dest0, zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -276,16 +277,16 @@ TEST_F(cmod_propagation_test, intervening_flag_read)
 
 TEST_F(cmod_propagation_test, intervening_dest_write)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::vec4_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg src2 = v->vgrf(glsl_type::vec2_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, offset(dest, 2), src0, src1);
-   v->emit(SHADER_OPCODE_TEX, dest, src2)
+   bld.ADD(offset(dest, 2), src0, src1);
+   bld.emit(SHADER_OPCODE_TEX, dest, src2)
       ->regs_written = 4;
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, offset(dest, 2), zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.CMP(bld.null_reg_f(), offset(dest, 2), zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -316,18 +317,16 @@ TEST_F(cmod_propagation_test, intervening_dest_write)
 
 TEST_F(cmod_propagation_test, intervening_flag_read_same_value)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest0 = v->vgrf(glsl_type::float_type);
    fs_reg dest1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg src2 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, dest0, src0, src1)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
-   v->emit(BRW_OPCODE_SEL, dest1, src2, zero)
-      ->predicate = BRW_PREDICATE_NORMAL;
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest0, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   set_condmod(BRW_CONDITIONAL_GE, bld.ADD(dest0, src0, src1));
+   set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
+   bld.CMP(bld.null_reg_f(), dest0, zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -357,14 +356,14 @@ TEST_F(cmod_propagation_test, intervening_flag_read_same_value)
 
 TEST_F(cmod_propagation_test, negate)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, dest, src0, src1);
+   bld.ADD(dest, src0, src1);
    dest.negate = true;
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -390,13 +389,13 @@ TEST_F(cmod_propagation_test, negate)
 
 TEST_F(cmod_propagation_test, movnz)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_CMP, dest, src0, src1)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
-   v->emit(BRW_OPCODE_MOV, v->reg_null_f, dest)
-      ->conditional_mod = BRW_CONDITIONAL_NZ;
+   bld.CMP(dest, src0, src1, BRW_CONDITIONAL_GE);
+   set_condmod(BRW_CONDITIONAL_NZ,
+               bld.MOV(bld.null_reg_f(), dest));
 
    /* = Before =
     *
@@ -422,14 +421,14 @@ TEST_F(cmod_propagation_test, movnz)
 
 TEST_F(cmod_propagation_test, different_types_cmod_with_zero)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::int_type);
    fs_reg src0 = v->vgrf(glsl_type::int_type);
    fs_reg src1 = v->vgrf(glsl_type::int_type);
    fs_reg zero(0.0f);
-   v->emit(BRW_OPCODE_ADD, dest, src0, src1);
-   v->emit(BRW_OPCODE_CMP, v->reg_null_f, retype(dest, BRW_REGISTER_TYPE_F),
-                                          zero)
-      ->conditional_mod = BRW_CONDITIONAL_GE;
+   bld.ADD(dest, src0, src1);
+   bld.CMP(bld.null_reg_f(), retype(dest, BRW_REGISTER_TYPE_F), zero,
+           BRW_CONDITIONAL_GE);
 
    /* = Before =
     *
@@ -456,15 +455,15 @@ TEST_F(cmod_propagation_test, different_types_cmod_with_zero)
 
 TEST_F(cmod_propagation_test, andnz_one)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::int_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
    fs_reg one(1);
 
-   v->emit(BRW_OPCODE_CMP, retype(dest, BRW_REGISTER_TYPE_F), src0, zero)
-      ->conditional_mod = BRW_CONDITIONAL_L;
-   v->emit(BRW_OPCODE_AND, v->reg_null_d, dest, one)
-      ->conditional_mod = BRW_CONDITIONAL_NZ;
+   bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
+   set_condmod(BRW_CONDITIONAL_NZ,
+               bld.AND(bld.null_reg_d(), dest, one));
 
    /* = Before =
     * 0: cmp.l.f0(8)     dest:F  src0:F  0F
@@ -491,15 +490,15 @@ TEST_F(cmod_propagation_test, andnz_one)
 
 TEST_F(cmod_propagation_test, andnz_non_one)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::int_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
    fs_reg nonone(38);
 
-   v->emit(BRW_OPCODE_CMP, retype(dest, BRW_REGISTER_TYPE_F), src0, zero)
-      ->conditional_mod = BRW_CONDITIONAL_L;
-   v->emit(BRW_OPCODE_AND, v->reg_null_d, dest, nonone)
-      ->conditional_mod = BRW_CONDITIONAL_NZ;
+   bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
+   set_condmod(BRW_CONDITIONAL_NZ,
+               bld.AND(bld.null_reg_d(), dest, nonone));
 
    /* = Before =
     * 0: cmp.l.f0(8)     dest:F  src0:F  0F
@@ -526,15 +525,15 @@ TEST_F(cmod_propagation_test, andnz_non_one)
 
 TEST_F(cmod_propagation_test, andz_one)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dest = v->vgrf(glsl_type::int_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg zero(0.0f);
    fs_reg one(1);
 
-   v->emit(BRW_OPCODE_CMP, retype(dest, BRW_REGISTER_TYPE_F), src0, zero)
-      ->conditional_mod = BRW_CONDITIONAL_L;
-   v->emit(BRW_OPCODE_AND, v->reg_null_d, dest, one)
-      ->conditional_mod = BRW_CONDITIONAL_Z;
+   bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
+   set_condmod(BRW_CONDITIONAL_Z,
+               bld.AND(bld.null_reg_d(), dest, one));
 
    /* = Before =
     * 0: cmp.l.f0(8)     dest:F  src0:F  0F
index 4c91af3ea8d7dce93e5bda8db8a793d6d0b90a5a..3ef0cb319eb8786b63181ff5b88816c1199da7ff 100644 (file)
 #include "brw_cfg.h"
 #include "program/program.h"
 
+using namespace brw;
+
 class saturate_propagation_test : public ::testing::Test {
    virtual void SetUp();
 
 public:
-   struct brw_context *brw;
+   struct brw_compiler *compiler;
    struct brw_device_info *devinfo;
    struct gl_context *ctx;
    struct brw_wm_prog_data *prog_data;
@@ -42,30 +44,31 @@ public:
 class saturate_propagation_fs_visitor : public fs_visitor
 {
 public:
-   saturate_propagation_fs_visitor(struct brw_context *brw,
+   saturate_propagation_fs_visitor(struct brw_compiler *compiler,
                                    struct brw_wm_prog_data *prog_data,
                                    struct gl_shader_program *shader_prog)
-      : fs_visitor(brw, NULL, NULL, prog_data, shader_prog, NULL, 8) {}
+      : fs_visitor(compiler, NULL, NULL, MESA_SHADER_FRAGMENT, NULL,
+                   &prog_data->base, shader_prog,
+                   (struct gl_program *) NULL, 8, -1) {}
 };
 
 
 void saturate_propagation_test::SetUp()
 {
-   brw = (struct brw_context *)calloc(1, sizeof(*brw));
-   devinfo = (struct brw_device_info *)calloc(1, sizeof(*brw));
-   brw->intelScreen = (struct intel_screen *)calloc(1, sizeof(*brw->intelScreen));
-   brw->intelScreen->devinfo = devinfo;
-   ctx = &brw->ctx;
+   ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
+   compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
+   devinfo = (struct brw_device_info *)calloc(1, sizeof(*devinfo));
+   compiler->devinfo = devinfo;
 
    fp = ralloc(NULL, struct brw_fragment_program);
    prog_data = ralloc(NULL, struct brw_wm_prog_data);
    shader_prog = ralloc(NULL, struct gl_shader_program);
 
-   v = new saturate_propagation_fs_visitor(brw, prog_data, shader_prog);
+   v = new saturate_propagation_fs_visitor(compiler, prog_data, shader_prog);
 
    _mesa_init_fragment_program(ctx, &fp->program, GL_FRAGMENT_SHADER, 0);
 
-   brw->gen = devinfo->gen = 4;
+   devinfo->gen = 4;
 }
 
 static fs_inst *
@@ -100,13 +103,13 @@ saturate_propagation(fs_visitor *v)
 
 TEST_F(saturate_propagation_test, basic)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1);
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
+   bld.ADD(dst0, src0, src1);
+   set_saturate(true, bld.MOV(dst1, dst0));
 
    /* = Before =
     *
@@ -135,15 +138,15 @@ TEST_F(saturate_propagation_test, basic)
 
 TEST_F(saturate_propagation_test, other_non_saturated_use)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg dst2 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1);
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
-   v->emit(BRW_OPCODE_ADD, dst2, dst0, src0);
+   bld.ADD(dst0, src0, src1);
+   set_saturate(true, bld.MOV(dst1, dst0));
+   bld.ADD(dst2, dst0, src0);
 
    /* = Before =
     *
@@ -173,14 +176,14 @@ TEST_F(saturate_propagation_test, other_non_saturated_use)
 
 TEST_F(saturate_propagation_test, predicated_instruction)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1)
+   bld.ADD(dst0, src0, src1)
       ->predicate = BRW_PREDICATE_NORMAL;
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
+   set_saturate(true, bld.MOV(dst1, dst0));
 
    /* = Before =
     *
@@ -208,14 +211,14 @@ TEST_F(saturate_propagation_test, predicated_instruction)
 
 TEST_F(saturate_propagation_test, neg_mov_sat)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1);
+   bld.ADD(dst0, src0, src1);
    dst0.negate = true;
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
+   set_saturate(true, bld.MOV(dst1, dst0));
 
    /* = Before =
     *
@@ -243,14 +246,14 @@ TEST_F(saturate_propagation_test, neg_mov_sat)
 
 TEST_F(saturate_propagation_test, abs_mov_sat)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1);
+   bld.ADD(dst0, src0, src1);
    dst0.abs = true;
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
+   set_saturate(true, bld.MOV(dst1, dst0));
 
    /* = Before =
     *
@@ -278,16 +281,15 @@ TEST_F(saturate_propagation_test, abs_mov_sat)
 
 TEST_F(saturate_propagation_test, producer_saturates)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg dst2 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1)
-      ->saturate = true;
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
-   v->emit(BRW_OPCODE_MOV, dst2, dst0);
+   set_saturate(true, bld.ADD(dst0, src0, src1));
+   set_saturate(true, bld.MOV(dst1, dst0));
+   bld.MOV(dst2, dst0);
 
    /* = Before =
     *
@@ -318,16 +320,15 @@ TEST_F(saturate_propagation_test, producer_saturates)
 
 TEST_F(saturate_propagation_test, intervening_saturating_copy)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg dst2 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_ADD, dst0, src0, src1);
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
-   v->emit(BRW_OPCODE_MOV, dst2, dst0)
-      ->saturate = true;
+   bld.ADD(dst0, src0, src1);
+   set_saturate(true, bld.MOV(dst1, dst0));
+   set_saturate(true, bld.MOV(dst2, dst0));
 
    /* = Before =
     *
@@ -360,16 +361,16 @@ TEST_F(saturate_propagation_test, intervening_saturating_copy)
 
 TEST_F(saturate_propagation_test, intervening_dest_write)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::vec4_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
    fs_reg src2 = v->vgrf(glsl_type::vec2_type);
-   v->emit(BRW_OPCODE_ADD, offset(dst0, 2), src0, src1);
-   v->emit(SHADER_OPCODE_TEX, dst0, src2)
+   bld.ADD(offset(dst0, 2), src0, src1);
+   bld.emit(SHADER_OPCODE_TEX, dst0, src2)
       ->regs_written = 4;
-   v->emit(BRW_OPCODE_MOV, dst1, offset(dst0, 2))
-      ->saturate = true;
+   set_saturate(true, bld.MOV(dst1, offset(dst0, 2)));
 
    /* = Before =
     *
@@ -400,18 +401,17 @@ TEST_F(saturate_propagation_test, intervening_dest_write)
 
 TEST_F(saturate_propagation_test, mul_neg_mov_sat_mov_sat)
 {
+   const fs_builder &bld = v->bld;
    fs_reg dst0 = v->vgrf(glsl_type::float_type);
    fs_reg dst1 = v->vgrf(glsl_type::float_type);
    fs_reg dst2 = v->vgrf(glsl_type::float_type);
    fs_reg src0 = v->vgrf(glsl_type::float_type);
    fs_reg src1 = v->vgrf(glsl_type::float_type);
-   v->emit(BRW_OPCODE_MUL, dst0, src0, src1);
+   bld.MUL(dst0, src0, src1);
    dst0.negate = true;
-   v->emit(BRW_OPCODE_MOV, dst1, dst0)
-      ->saturate = true;
+   set_saturate(true, bld.MOV(dst1, dst0));
    dst0.negate = false;
-   v->emit(BRW_OPCODE_MOV, dst2, dst0)
-      ->saturate = true;
+   set_saturate(true, bld.MOV(dst2, dst0));
 
    /* = Before =
     *
index 2ef52e9fd6bdffa19c56874a9805b3346b1df1b5..84e43fa75cd1b6c9bdf0423802857cd591ee833a 100644 (file)
@@ -33,7 +33,7 @@ class copy_propagation_test : public ::testing::Test {
    virtual void SetUp();
 
 public:
-   struct brw_context *brw;
+   struct brw_compiler *compiler;
    struct brw_device_info *devinfo;
    struct gl_context *ctx;
    struct gl_shader_program *shader_prog;
@@ -44,12 +44,11 @@ public:
 class copy_propagation_vec4_visitor : public vec4_visitor
 {
 public:
-   copy_propagation_vec4_visitor(struct brw_context *brw,
+   copy_propagation_vec4_visitor(struct brw_compiler *compiler,
                                   struct gl_shader_program *shader_prog)
-      : vec4_visitor(brw, NULL, NULL, NULL, NULL, shader_prog,
+      : vec4_visitor(compiler, NULL, NULL, NULL, NULL, shader_prog,
                      MESA_SHADER_VERTEX, NULL,
-                     false /* no_spills */,
-                     ST_NONE, ST_NONE, ST_NONE)
+                     false /* no_spills */, -1)
    {
    }
 
@@ -93,21 +92,20 @@ protected:
 
 void copy_propagation_test::SetUp()
 {
-   brw = (struct brw_context *)calloc(1, sizeof(*brw));
-   devinfo = (struct brw_device_info *)calloc(1, sizeof(*brw));
-   brw->intelScreen = (struct intel_screen *)calloc(1, sizeof(*brw->intelScreen));
-   brw->intelScreen->devinfo = devinfo;
-   ctx = &brw->ctx;
+   ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
+   compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
+   devinfo = (struct brw_device_info *)calloc(1, sizeof(*devinfo));
+   compiler->devinfo = devinfo;
 
    vp = ralloc(NULL, struct brw_vertex_program);
 
    shader_prog = ralloc(NULL, struct gl_shader_program);
 
-   v = new copy_propagation_vec4_visitor(brw, shader_prog);
+   v = new copy_propagation_vec4_visitor(compiler, shader_prog);
 
    _mesa_init_vertex_program(ctx, &vp->program, GL_VERTEX_SHADER, 0);
 
-   brw->gen = devinfo->gen = 4;
+   devinfo->gen = 4;
 }
 
 static void
index c8c67574e95394340612a30e77ea1d78e67dceb8..de2afd39cfe1629be8f48b1ad04a1e193be499f7 100644 (file)
@@ -35,7 +35,7 @@ class register_coalesce_test : public ::testing::Test {
    virtual void SetUp();
 
 public:
-   struct brw_context *brw;
+   struct brw_compiler *compiler;
    struct brw_device_info *devinfo;
    struct gl_context *ctx;
    struct gl_shader_program *shader_prog;
@@ -47,12 +47,11 @@ public:
 class register_coalesce_vec4_visitor : public vec4_visitor
 {
 public:
-   register_coalesce_vec4_visitor(struct brw_context *brw,
+   register_coalesce_vec4_visitor(struct brw_compiler *compiler,
                                   struct gl_shader_program *shader_prog)
-      : vec4_visitor(brw, NULL, NULL, NULL, NULL, shader_prog,
+      : vec4_visitor(compiler, NULL, NULL, NULL, NULL, shader_prog,
                      MESA_SHADER_VERTEX, NULL,
-                     false /* no_spills */,
-                     ST_NONE, ST_NONE, ST_NONE)
+                     false /* no_spills */, -1)
    {
    }
 
@@ -96,21 +95,20 @@ protected:
 
 void register_coalesce_test::SetUp()
 {
-   brw = (struct brw_context *)calloc(1, sizeof(*brw));
-   devinfo = (struct brw_device_info *)calloc(1, sizeof(*brw));
-   brw->intelScreen = (struct intel_screen *)calloc(1, sizeof(*brw->intelScreen));
-   brw->intelScreen->devinfo = devinfo;
-   ctx = &brw->ctx;
+   ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
+   compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
+   devinfo = (struct brw_device_info *)calloc(1, sizeof(*devinfo));
+   compiler->devinfo = devinfo;
 
    vp = ralloc(NULL, struct brw_vertex_program);
 
    shader_prog = ralloc(NULL, struct gl_shader_program);
 
-   v = new register_coalesce_vec4_visitor(brw, shader_prog);
+   v = new register_coalesce_vec4_visitor(compiler, shader_prog);
 
    _mesa_init_vertex_program(ctx, &vp->program, GL_VERTEX_SHADER, 0);
 
-   brw->gen = devinfo->gen = 4;
+   devinfo->gen = 4;
 }
 
 static void
index 6c479f5f0c637c1ea0700479eaa8380b130624d1..c78d4baa12446a47e967c658370e82dad833076b 100644 (file)
@@ -242,7 +242,7 @@ static void
 nouveau_framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
                                 GLenum attachment, struct gl_renderbuffer *rb)
 {
-       _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+       _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb);
 
        context_dirty(ctx, FRAMEBUFFER);
 }
index c0c7b26bbf70eabbf35c6b38fa5b26c8dc777964..1398385b262611e9453a4dfaf886cbc24f47ca42 100644 (file)
@@ -31,6 +31,8 @@
 #include "nv10_3d.xml.h"
 #include "nv10_driver.h"
 
+#include "util/simple_list.h"
+
 void
 nv10_emit_clip_plane(struct gl_context *ctx, int emit)
 {
index f0acbed8560f5a7aa9aa6a5a990f704583a3fdc1..41395516ea415d4f02df849d0fccff2b09781b14 100644 (file)
@@ -32,6 +32,8 @@
 #include "nv10_driver.h"
 #include "nv20_driver.h"
 
+#include "util/simple_list.h"
+
 #define LIGHT_MODEL_AMBIENT_R(side)                    \
        ((side) ? NV20_3D_LIGHT_MODEL_BACK_AMBIENT_R :  \
         NV20_3D_LIGHT_MODEL_FRONT_AMBIENT_R)
index b0a6bd573b6221b1bf188a6a9e6d449e35a0245a..6fe70b5c9d0a3bc341fc055ae9583f118ae0bdbd 100644 (file)
@@ -2215,9 +2215,9 @@ GLboolean r200ValidateState( struct gl_context *ctx )
    GLuint new_state = rmesa->radeon.NewGLState;
 
    if (new_state & _NEW_BUFFERS) {
-      _mesa_update_framebuffer(ctx);
+      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
       /* this updates the DrawBuffer's Width/Height if it's a FBO */
-      _mesa_update_draw_buffer_bounds(ctx);
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
 
       R200_STATECHANGE(rmesa, ctx);
    }
index 0ca526d2a025820a88dc49a7526e4243412fdf21..2a8bd6c9edc88b7ea1b9d6ee718e352b3f038a52 100644 (file)
@@ -220,9 +220,9 @@ void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
         */
        if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
                /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
-               _mesa_update_framebuffer(ctx);
+               _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
                /* this updates the DrawBuffer's Width/Height if it's a FBO */
-               _mesa_update_draw_buffer_bounds(ctx);
+               _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
        }
 
        if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
index 97022f9595389177f609f6a939c7d4b4bd9abc8d..ef62d097bae6eaa08624897ae11331047f8195ca 100644 (file)
@@ -723,7 +723,7 @@ radeon_framebuffer_renderbuffer(struct gl_context * ctx,
                "%s(%p, fb %p, rb %p) \n",
                __func__, ctx, fb, rb);
 
-   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+   _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb);
    radeon_draw_buffer(ctx, fb);
 }
 
index c45bb513dca4ef48fc0bc6b5ed69cb55bc9d1789..cba3d9c9689f680008881960cd4efab44ebdfc12 100644 (file)
@@ -1994,9 +1994,9 @@ GLboolean radeonValidateState( struct gl_context *ctx )
    GLuint new_state = rmesa->radeon.NewGLState;
 
    if (new_state & _NEW_BUFFERS) {
-     _mesa_update_framebuffer(ctx);
+     _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
      /* this updates the DrawBuffer's Width/Height if it's a FBO */
-     _mesa_update_draw_buffer_bounds(ctx);
+     _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
      RADEON_STATECHANGE(rmesa, ctx);
    }
 
index 2ddb474dde736db3a23445e4902cd740f645a18c..2d4bb702fc26718d5e4d0372c69de20afc2d2a8c 100644 (file)
@@ -62,7 +62,9 @@
 #include "swrast/s_context.h"
 
 #include <sys/types.h>
-#include <sys/sysctl.h>
+#ifdef HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+#endif
 
 const __DRIextension **__driDriverGetExtensions_swrast(void);
 
@@ -958,6 +960,7 @@ static const __DRIextension *swrast_driver_extensions[] = {
     &driCoreExtension.base,
     &driSWRastExtension.base,
     &driCopySubBufferExtension.base,
+    &dri2ConfigQueryExtension.base,
     &swrast_vtable.base,
     NULL
 };
diff --git a/src/mesa/drivers/haiku/swrast/SConscript b/src/mesa/drivers/haiku/swrast/SConscript
deleted file mode 100644 (file)
index 907325e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-Import('*')
-
-env = env.Clone()
-
-env.Append(CPPPATH = [
-    '#/src',
-    '#/src/mapi',
-    '#/src/mesa',
-    '#/src/mesa/main',
-    '#/include/HaikuGL',
-    '/boot/system/develop/headers/private',
-    Dir('../../../mapi'), # src/mapi build path for python-generated GL API files/headers
-])
-
-env.Prepend(LIBS = [
-    mesautil,
-    glsl,
-    mesa,
-])
-
-env.Prepend(LIBS = [libgl])
-
-sources = [
-       'SoftwareRast.cpp'
-]
-
-# Disallow undefined symbols
-#env.Append(SHLINKFLAGS = ['-Wl,-z,defs'])
-
-libswrast = env.SharedLibrary(
-    target = 'swrast',
-    source = sources
-)
diff --git a/src/mesa/drivers/haiku/swrast/SoftwareRast.cpp b/src/mesa/drivers/haiku/swrast/SoftwareRast.cpp
deleted file mode 100644 (file)
index 813ad1f..0000000
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright 2006-2012, Haiku, Inc. All rights reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- *             Jérôme Duval, korli@users.berlios.de
- *             Philippe Houdoin, philippe.houdoin@free.fr
- *             Artur Wyszynski, harakash@gmail.com
- *             Alexander von Gluck, kallisti5@unixzen.com
- */
-
-
-#include <kernel/image.h>
-#include "SoftwareRast.h"
-
-#include <Autolock.h>
-#include <interface/DirectWindowPrivate.h>
-#include <GraphicsDefs.h>
-#include <Screen.h>
-#include <stdio.h>
-#include <string.h>
-
-extern "C" {
-#include "extensions.h"
-#include "drivers/common/driverfuncs.h"
-#include "drivers/common/meta.h"
-#include "main/api_exec.h"
-#include "main/colormac.h"
-#include "main/cpuinfo.h"
-#include "main/buffers.h"
-#include "main/formats.h"
-#include "main/framebuffer.h"
-#include "main/renderbuffer.h"
-#include "main/version.h"
-#include "main/vtxfmt.h"
-#include "swrast/swrast.h"
-#include "swrast/s_renderbuffer.h"
-#include "swrast_setup/swrast_setup.h"
-#include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "tnl/t_pipeline.h"
-#include "vbo/vbo.h"
-
-
-#ifdef DEBUG
-#      define TRACE(x...) printf("MesaSoftwareRast: " x)
-#      define CALLED() printf("MesaSoftwareRast: %s\n", __PRETTY_FUNCTION__)
-#else
-#      define TRACE(x...)
-#      define CALLED()
-#endif
-
-#define ERROR(x...) printf("MesaSoftwareRast: " x)
-}
-
-
-extern const char* color_space_name(color_space space);
-
-
-extern "C" _EXPORT BGLRenderer*
-instantiate_gl_renderer(BGLView* view, ulong options,
-       BGLDispatcher* dispatcher)
-{
-       return new MesaSoftwareRast(view, options, dispatcher);
-}
-
-
-MesaSoftwareRast::MesaSoftwareRast(BGLView* view, ulong options,
-       BGLDispatcher* dispatcher)
-       : BGLRenderer(view, options, dispatcher),
-       fBitmap(NULL),
-       fDirectModeEnabled(false),
-       fInfo(NULL),
-       fInfoLocker("info locker"),
-       fVisual(NULL),
-       fFrameBuffer(NULL),
-       fFrontRenderBuffer(NULL),
-       fBackRenderBuffer(NULL),
-       fColorSpace(B_NO_COLOR_SPACE)
-{
-       CALLED();
-
-       fColorSpace = BScreen(GLView()->Window()).ColorSpace();
-
-       // We force single buffering for the time being
-       options &= ~BGL_DOUBLE;
-
-       const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
-       const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
-       const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
-       const GLboolean stereoFlag = false;
-       const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
-       const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
-       const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
-       const GLint red = rgbFlag ? 8 : 0;
-       const GLint green = rgbFlag ? 8 : 0;
-       const GLint blue = rgbFlag ? 8 : 0;
-       const GLint alpha = alphaFlag ? 8 : 0;
-
-       fOptions = options; // | BGL_INDIRECT;
-       struct dd_function_table functions;
-
-       fVisual = _mesa_create_visual(dblFlag, stereoFlag, red, green,
-               blue, alpha, depth, stencil, accum, accum, accum,
-               alpha ? accum : 0, 1);
-
-       // Initialize device driver function table
-       _mesa_init_driver_functions(&functions);
-
-       functions.GetString = _GetString;
-       functions.UpdateState = _UpdateState;
-       functions.MapRenderbuffer = _RenderBufferMap;
-       functions.Flush = _Flush;
-
-       // create core context
-       // We inherit gl_context to this class
-       _mesa_initialize_context(this, API_OPENGL_COMPAT, fVisual, NULL,
-               &functions);
-
-       /* Initialize the software rasterizer and helper modules. */
-       _swrast_CreateContext(this);
-       _vbo_CreateContext(this);
-       _tnl_CreateContext(this);
-       _swsetup_CreateContext(this);
-       _swsetup_Wakeup(this);
-
-       // Use default TCL pipeline
-       TNL_CONTEXT(this)->Driver.RunPipeline = _tnl_run_pipeline;
-
-       _mesa_meta_init(this);
-       _mesa_enable_sw_extensions(this);
-
-       _mesa_compute_version(this);
-
-       _mesa_initialize_dispatch_tables(this);
-       _mesa_initialize_vbo_vtxfmt(this);
-
-       // create core framebuffer
-       fFrameBuffer = _mesa_create_framebuffer(fVisual);
-       if (fFrameBuffer == NULL) {
-               ERROR("%s: Unable to calloc GL FrameBuffer!\n", __func__);
-               _mesa_destroy_visual(fVisual);
-               return;
-       }
-
-       // Setup front render buffer
-       fFrontRenderBuffer = _NewRenderBuffer(true);
-       if (fFrontRenderBuffer == NULL) {
-               ERROR("%s: FrontRenderBuffer is requested but unallocated!\n",
-                       __func__);
-               _mesa_destroy_visual(fVisual);
-               free(fFrameBuffer);
-               return;
-       }
-       _mesa_add_renderbuffer(fFrameBuffer, BUFFER_FRONT_LEFT,
-               &fFrontRenderBuffer->Base);
-
-       // Setup back render buffer (if requested)
-       if (fVisual->doubleBufferMode) {
-               fBackRenderBuffer = _NewRenderBuffer(false);
-               if (fBackRenderBuffer == NULL) {
-                       ERROR("%s: BackRenderBuffer is requested but unallocated!\n",
-                               __func__);
-                       _mesa_destroy_visual(fVisual);
-                       free(fFrameBuffer);
-                       return;
-               }
-               _mesa_add_renderbuffer(fFrameBuffer, BUFFER_BACK_LEFT,
-                       &fBackRenderBuffer->Base);
-       }
-
-       _swrast_add_soft_renderbuffers(fFrameBuffer, GL_FALSE,
-               fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
-               fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);
-
-       BRect bounds = view->Bounds();
-       fWidth = (GLint)bounds.Width();
-       fHeight = (GLint)bounds.Height();
-
-       // some stupid applications (Quake2) don't even think about calling LockGL()
-       // before using glGetString and its glGet*() friends...
-       // so make sure there is at least a valid context.
-
-       if (!_mesa_get_current_context()) {
-               LockGL();
-               // not needed, we don't have a looper yet: UnlockLooper();
-       }
-}
-
-
-MesaSoftwareRast::~MesaSoftwareRast()
-{
-       CALLED();
-       _swsetup_DestroyContext(this);
-       _swrast_DestroyContext(this);
-       _tnl_DestroyContext(this);
-       _vbo_DestroyContext(this);
-       _mesa_destroy_visual(fVisual);
-       _mesa_destroy_framebuffer(fFrameBuffer);
-       _mesa_destroy_context(this);
-
-       free(fInfo);
-       free(fFrameBuffer);
-
-       delete fBitmap;
-}
-
-
-void
-MesaSoftwareRast::LockGL()
-{
-       CALLED();
-       BGLRenderer::LockGL();
-
-       _mesa_make_current(this, fFrameBuffer, fFrameBuffer);
-
-       color_space colorSpace = BScreen(GLView()->Window()).ColorSpace();
-
-       GLuint width = fWidth;
-       GLuint height = fHeight;
-
-       BAutolock lock(fInfoLocker);
-       if (fDirectModeEnabled && fInfo != NULL) {
-               width = fInfo->window_bounds.right
-                       - fInfo->window_bounds.left + 1;
-               height = fInfo->window_bounds.bottom
-                       - fInfo->window_bounds.top + 1;
-       }
-
-       if (fColorSpace != colorSpace) {
-               fColorSpace = colorSpace;
-               _SetupRenderBuffer(&fFrontRenderBuffer->Base, fColorSpace);
-               if (fVisual->doubleBufferMode)
-                       _SetupRenderBuffer(&fBackRenderBuffer->Base, fColorSpace);
-       }
-
-       _CheckResize(width, height);
-}
-
-
-void
-MesaSoftwareRast::UnlockGL()
-{
-       CALLED();
-       _mesa_make_current(this, NULL, NULL);
-       BGLRenderer::UnlockGL();
-}
-
-
-void
-MesaSoftwareRast::SwapBuffers(bool VSync)
-{
-       CALLED();
-
-       if (!fBitmap)
-               return;
-
-       if (fVisual->doubleBufferMode)
-               _mesa_notifySwapBuffers(this);
-
-       if (!fDirectModeEnabled || fInfo == NULL) {
-               if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
-                       GLView()->DrawBitmap(fBitmap, B_ORIGIN);
-                       GLView()->UnlockLooper();
-               }
-       } else {
-               // TODO: Here the BGLView needs to be drawlocked.
-               _CopyToDirect();
-       }
-
-       if (VSync) {
-               BScreen screen(GLView()->Window());
-               screen.WaitForRetrace();
-       }
-}
-
-
-void
-MesaSoftwareRast::Draw(BRect updateRect)
-{
-       CALLED();
-       if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL)))
-               GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
-}
-
-
-status_t
-MesaSoftwareRast::CopyPixelsOut(BPoint location, BBitmap* bitmap)
-{
-       CALLED();
-       color_space scs = fBitmap->ColorSpace();
-       color_space dcs = bitmap->ColorSpace();
-
-       if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) {
-               fprintf(stderr, "CopyPixelsOut(): incompatible color space: %s != %s\n",
-                       color_space_name(scs),
-                       color_space_name(dcs));
-               return B_BAD_TYPE;
-       }
-
-       BRect sr = fBitmap->Bounds();
-       BRect dr = bitmap->Bounds();
-
-       sr = sr & dr.OffsetBySelf(location);
-       dr = sr.OffsetByCopy(-location.x, -location.y);
-
-       uint8* ps = (uint8*)fBitmap->Bits();
-       uint8* pd = (uint8*)bitmap->Bits();
-       uint32* s;
-       uint32* d;
-       uint32 y;
-       for (y = (uint32)sr.top; y <= (uint32)sr.bottom; y++) {
-               s = (uint32*)(ps + y * fBitmap->BytesPerRow());
-               s += (uint32)sr.left;
-
-               d = (uint32*)(pd + (y + (uint32)(dr.top - sr.top))
-                       * bitmap->BytesPerRow());
-               d += (uint32)dr.left;
-
-               memcpy(d, s, dr.IntegerWidth() * 4);
-       }
-       return B_OK;
-}
-
-
-status_t
-MesaSoftwareRast::CopyPixelsIn(BBitmap* bitmap, BPoint location)
-{
-       CALLED();
-       color_space scs = bitmap->ColorSpace();
-       color_space dcs = fBitmap->ColorSpace();
-
-       if (scs != dcs && (dcs != B_RGBA32 || scs != B_RGB32)) {
-               fprintf(stderr, "CopyPixelsIn(): incompatible color space: %s != %s\n",
-                       color_space_name(scs),
-                       color_space_name(dcs));
-               return B_BAD_TYPE;
-       }
-
-       BRect sr = bitmap->Bounds();
-       BRect dr = fBitmap->Bounds();
-
-       sr = sr & dr.OffsetBySelf(location);
-       dr = sr.OffsetByCopy(-location.x, -location.y);
-
-       uint8* ps = (uint8*)bitmap->Bits();
-       uint8* pd = (uint8*)fBitmap->Bits();
-       uint32* s;
-       uint32* d;
-       uint32 y;
-       for (y = (uint32)sr.top; y <= (uint32)sr.bottom; y++) {
-               s = (uint32*)(ps + y * bitmap->BytesPerRow());
-               s += (uint32)sr.left;
-
-               d = (uint32*)(pd + (y + (uint32)(dr.top - sr.top))
-                       * fBitmap->BytesPerRow());
-               d += (uint32)dr.left;
-
-               memcpy(d, s, dr.IntegerWidth() * 4);
-       }
-       return B_OK;
-}
-
-
-void
-MesaSoftwareRast::EnableDirectMode(bool enabled)
-{
-       fDirectModeEnabled = enabled;
-}
-
-
-void
-MesaSoftwareRast::DirectConnected(direct_buffer_info* info)
-{
-       // TODO: I'm not sure we need to do this: BGLView already
-       // keeps a local copy of the direct_buffer_info passed by
-       // BDirectWindow::DirectConnected().
-       BAutolock lock(fInfoLocker);
-       if (info) {
-               if (!fInfo) {
-                       fInfo = (direct_buffer_info*)malloc(DIRECT_BUFFER_INFO_AREA_SIZE);
-                       if (!fInfo)
-                               return;
-               }
-               memcpy(fInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
-       } else if (fInfo) {
-               free(fInfo);
-               fInfo = NULL;
-       }
-}
-
-
-void
-MesaSoftwareRast::FrameResized(float width, float height)
-{
-       BAutolock lock(fInfoLocker);
-       _CheckResize((GLuint)width, (GLuint)height);
-}
-
-
-void
-MesaSoftwareRast::_CheckResize(GLuint newWidth, GLuint newHeight)
-{
-       CALLED();
-
-       if (fBitmap && newWidth == fWidth
-               && newHeight == fHeight) {
-               return;
-       }
-
-       _mesa_resize_framebuffer(this, fFrameBuffer, newWidth, newHeight);
-       fHeight = newHeight;
-       fWidth = newWidth;
-
-       _AllocateBitmap();
-}
-
-
-void
-MesaSoftwareRast::_AllocateBitmap()
-{
-       CALLED();
-
-       // allocate new size of back buffer bitmap
-       delete fBitmap;
-       fBitmap = NULL;
-
-       if (fWidth < 1 || fHeight < 1) {
-               TRACE("%s: Cannot allocate bitmap < 1x1!\n", __func__);
-               return;
-       }
-
-       BRect rect(0.0, 0.0, fWidth - 1, fHeight - 1);
-       fBitmap = new BBitmap(rect, fColorSpace);
-
-       #if 0
-       // Used for platform optimized drawing
-       for (uint i = 0; i < fHeight; i++) {
-               fRowAddr[fHeight - i - 1] = (GLvoid *)((GLubyte *)fBitmap->Bits()
-                       + i * fBitmap->BytesPerRow());
-       }
-       #endif
-
-       fFrameBuffer->Width = fWidth;
-       fFrameBuffer->Height = fHeight;
-       TRACE("%s: Bitmap Size: %" B_PRIu32 "\n", __func__, fBitmap->BitsLength());
-
-       fFrontRenderBuffer->Buffer = (GLubyte*)fBitmap->Bits();
-}
-
-
-// #pragma mark - static
-
-
-const GLubyte*
-MesaSoftwareRast::_GetString(gl_context* ctx, GLenum name)
-{
-       switch (name) {
-               case GL_VENDOR:
-                       return (const GLubyte*) "Mesa Project";
-               case GL_RENDERER:
-                       return (const GLubyte*) "Software Rasterizer";
-               default:
-                       // Let core library handle all other cases
-                       return NULL;
-       }
-}
-
-
-void
-MesaSoftwareRast::_UpdateState(gl_context* ctx, GLuint new_state)
-{
-       if (!ctx)
-               return;
-
-       CALLED();
-       _swrast_InvalidateState(ctx, new_state);
-       _swsetup_InvalidateState(ctx, new_state);
-       _vbo_InvalidateState(ctx, new_state);
-       _tnl_InvalidateState(ctx, new_state);
-}
-
-
-GLboolean
-MesaSoftwareRast::_RenderBufferStorage(gl_context* ctx,
-       struct gl_renderbuffer* render, GLenum internalFormat,
-       GLuint width, GLuint height)
-{
-       CALLED();
-
-       render->Width = width;
-       render->Height = height;
-
-       struct swrast_renderbuffer *swRenderBuffer = swrast_renderbuffer(render);
-
-       swRenderBuffer->RowStride = width * _mesa_get_format_bytes(render->Format);
-
-       return GL_TRUE;
-}
-
-
-GLboolean
-MesaSoftwareRast::_RenderBufferStorageMalloc(gl_context* ctx,
-       struct gl_renderbuffer* render, GLenum internalFormat,
-       GLuint width, GLuint height)
-{
-       CALLED();
-
-       render->Width = width;
-       render->Height = height;
-
-       struct swrast_renderbuffer *swRenderBuffer = swrast_renderbuffer(render);
-
-       if (swRenderBuffer != NULL) {
-               free(swRenderBuffer->Buffer);
-               swRenderBuffer->RowStride
-                       = width * _mesa_get_format_bytes(render->Format);
-
-               uint32 size = swRenderBuffer->RowStride * height;
-               TRACE("%s: Allocate %" B_PRIu32 " bytes for RenderBuffer\n",
-                       __func__, size);
-               swRenderBuffer->Buffer = (GLubyte*)malloc(size);
-               if (!swRenderBuffer->Buffer) {
-                       ERROR("%s: Memory allocation failure!\n", __func__);
-                       return GL_FALSE;
-               }
-       } else {
-               ERROR("%s: Couldn't obtain software renderbuffer!\n",
-                       __func__);
-               return GL_FALSE;
-       }
-
-       return GL_TRUE;
-}
-
-
-void
-MesaSoftwareRast::_Flush(gl_context* ctx)
-{
-       CALLED();
-       MesaSoftwareRast* driverContext = static_cast<MesaSoftwareRast*>(ctx);
-
-       //MesaSoftwareRast* driverContext = (MesaSoftwareRast*)ctx->DriverCtx;
-       if ((driverContext->fOptions & BGL_DOUBLE) == 0) {
-               // TODO: SwapBuffers() can call _CopyToDirect(), which should
-               // be always called with with the BGLView drawlocked.
-               // This is not always the case if called from here.
-               driverContext->SwapBuffers();
-       }
-}
-
-
-struct swrast_renderbuffer*
-MesaSoftwareRast::_NewRenderBuffer(bool front)
-{
-       CALLED();
-       struct swrast_renderbuffer *swRenderBuffer
-               = (struct swrast_renderbuffer*)calloc(1, sizeof *swRenderBuffer);
-
-       if (!swRenderBuffer) {
-               ERROR("%s: Failed calloc RenderBuffer\n", __func__);
-               return NULL;
-       }
-
-       _mesa_init_renderbuffer(&swRenderBuffer->Base, 0);
-
-       swRenderBuffer->Base.ClassID = HAIKU_SWRAST_RENDERBUFFER_CLASS;
-       swRenderBuffer->Base.RefCount = 1;
-       swRenderBuffer->Base.Delete = _RenderBufferDelete;
-
-       if (!front)
-               swRenderBuffer->Base.AllocStorage = _RenderBufferStorageMalloc;
-       else
-               swRenderBuffer->Base.AllocStorage = _RenderBufferStorage;
-
-       if (_SetupRenderBuffer(&swRenderBuffer->Base, fColorSpace) != B_OK) {
-               free(swRenderBuffer);
-               return NULL;
-       }
-
-       return swRenderBuffer;
-}
-
-
-status_t
-MesaSoftwareRast::_SetupRenderBuffer(struct gl_renderbuffer* rb,
-       color_space colorSpace)
-{
-       CALLED();
-
-       rb->InternalFormat = GL_RGBA;
-
-       switch (colorSpace) {
-               case B_RGBA32:
-                       rb->_BaseFormat = GL_RGBA;
-                       rb->Format = MESA_FORMAT_B8G8R8A8_UNORM;
-                       break;
-               case B_RGB32:
-                       rb->_BaseFormat = GL_RGB;
-                       rb->Format = MESA_FORMAT_B8G8R8X8_UNORM;
-                       break;
-               case B_RGB24:
-                       rb->_BaseFormat = GL_RGB;
-                       rb->Format = MESA_FORMAT_BGR_UNORM8;
-                       break;
-               case B_RGB16:
-                       rb->_BaseFormat = GL_RGB;
-                       rb->Format = MESA_FORMAT_B5G6R5_UNORM;
-                       break;
-               case B_RGB15:
-                       rb->_BaseFormat = GL_RGB;
-                       rb->Format = MESA_FORMAT_B5G5R5A1_UNORM;
-                       break;
-               default:
-                       fprintf(stderr, "Unsupported screen color space %s\n",
-                               color_space_name(fColorSpace));
-                       debugger("Unsupported OpenGL color space");
-                       return B_ERROR;
-       }
-       return B_OK;
-}
-
-
-/*!    Y inverted Map RenderBuffer function
-       We use a BBitmap for storage which has Y inverted.
-       If the Mesa provided Map function ever allows external
-       control of this we can omit this function.
-*/
-void
-MesaSoftwareRast::_RenderBufferMap(gl_context *ctx,
-       struct gl_renderbuffer *rb, GLuint x, GLuint y, GLuint w, GLuint h,
-       GLbitfield mode, GLubyte **mapOut, GLint *rowStrideOut)
-{
-       if (rb->ClassID == HAIKU_SWRAST_RENDERBUFFER_CLASS) {
-               struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
-               const GLuint bpp = _mesa_get_format_bytes(rb->Format);
-               GLint rowStride = rb->Width * bpp; // in Bytes
-
-               y = rb->Height - y - 1;
-
-               *rowStrideOut = -rowStride;
-               *mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
-       } else {
-               _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
-                       mapOut, rowStrideOut);
-       }
-}
-
-
-void
-MesaSoftwareRast::_RenderBufferDelete(struct gl_context *ctx,
-       struct gl_renderbuffer* rb)
-{
-       CALLED();
-       if (rb != NULL) {
-               struct swrast_renderbuffer *swRenderBuffer
-                       = swrast_renderbuffer(rb);
-               if (swRenderBuffer != NULL)
-                       free(swRenderBuffer->Buffer);
-       }
-       free(rb);
-}
-
-
-void
-MesaSoftwareRast::_CopyToDirect()
-{
-       BAutolock lock(fInfoLocker);
-
-       // check the bitmap size still matches the size
-       if (fInfo->window_bounds.bottom - fInfo->window_bounds.top
-               != fBitmap->Bounds().IntegerHeight()
-               || fInfo->window_bounds.right - fInfo->window_bounds.left
-                       != fBitmap->Bounds().IntegerWidth())
-               return;
-
-       uint8 bytesPerPixel = fInfo->bits_per_pixel / 8;
-       uint32 bytesPerRow = fBitmap->BytesPerRow();
-       for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
-               clipping_rect *clip = &fInfo->clip_list[i];
-               int32 height = clip->bottom - clip->top + 1;
-               int32 bytesWidth
-                       = (clip->right - clip->left + 1) * bytesPerPixel;
-               uint8* p = (uint8*)fInfo->bits + clip->top
-                       * fInfo->bytes_per_row + clip->left * bytesPerPixel;
-               uint8* b = (uint8*)fBitmap->Bits()
-                       + (clip->top - fInfo->window_bounds.top) * bytesPerRow
-                       + (clip->left - fInfo->window_bounds.left)
-                               * bytesPerPixel;
-
-               for (int y = 0; y < height; y++) {
-                       memcpy(p, b, bytesWidth);
-                       p += fInfo->bytes_per_row;
-                       b += bytesPerRow;
-               }
-       }
-}
diff --git a/src/mesa/drivers/haiku/swrast/SoftwareRast.h b/src/mesa/drivers/haiku/swrast/SoftwareRast.h
deleted file mode 100644 (file)
index 8f0f018..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2006-2012, Haiku, Inc. All rights reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- *             Jérôme Duval, korli@users.berlios.de
- *             Philippe Houdoin, philippe.houdoin@free.fr
- *             Artur Wyszynski, harakash@gmail.com
- */
-#ifndef MESASOFTWARERENDERER_H
-#define MESASOFTWARERENDERER_H
-
-
-#define HAIKU_SWRAST_RENDERBUFFER_CLASS 0x737752 // swR
-
-
-#include "GLRenderer.h"
-
-extern "C" {
-#include "context.h"
-#include "main/version.h"
-#include "swrast/s_chan.h"
-#include "swrast/s_context.h"
-}
-
-
-class MesaSoftwareRast : public BGLRenderer, public gl_context {
-public:
-                                                       MesaSoftwareRast(BGLView* view,
-                                                               ulong bgl_options,
-                                                               BGLDispatcher* dispatcher);
-       virtual                                 ~MesaSoftwareRast();
-
-       virtual void                    LockGL();
-       virtual void                    UnlockGL();
-
-       virtual void                    SwapBuffers(bool VSync = false);
-       virtual void                    Draw(BRect updateRect);
-       virtual status_t                CopyPixelsOut(BPoint source, BBitmap* dest);
-       virtual status_t                CopyPixelsIn(BBitmap* source, BPoint dest);
-       virtual void                    FrameResized(float width, float height);
-
-       virtual void                    EnableDirectMode(bool enabled);
-       virtual void                    DirectConnected(direct_buffer_info* info);
-
-private:
-       static  const GLubyte*  _GetString(gl_context* ctx, GLenum name);
-                       void                    _CheckResize(GLuint newWidth, GLuint newHeight);
-       static  void                    _UpdateState(gl_context* ctx, GLuint newState);
-       static  void                    _Flush(gl_context *ctx);
-
-       struct  swrast_renderbuffer* _NewRenderBuffer(bool front);
-                       status_t                _SetupRenderBuffer(struct gl_renderbuffer* rb,
-                                                               color_space colorSpace);
-
-/* Mesa callbacks */
-       static  void                    _RenderBufferDelete(struct gl_context *ctx,
-                                                               struct gl_renderbuffer* rb);
-       static  GLboolean               _RenderBufferStorage(gl_context* ctx,
-                                                               struct gl_renderbuffer* render,
-                                                               GLenum internalFormat,
-                                                               GLuint width, GLuint height);
-       static  GLboolean               _RenderBufferStorageMalloc(gl_context* ctx,
-                                                               struct gl_renderbuffer* render,
-                                                               GLenum internalFormat,
-                                                               GLuint width, GLuint height);
-       static  void                    _RenderBufferMap(gl_context *ctx,
-                                                               struct gl_renderbuffer *rb,
-                                                               GLuint x, GLuint y, GLuint w, GLuint h,
-                                                               GLbitfield mode, GLubyte **mapOut,
-                                                               GLint *rowStrideOut);
-
-                       void                    _AllocateBitmap();
-                       void                    _CopyToDirect();
-
-                       BBitmap*                fBitmap;
-                       bool                    fDirectModeEnabled;
-                       direct_buffer_info* fInfo;
-                       BLocker                 fInfoLocker;
-                       ulong                   fOptions;
-
-                       gl_config*              fVisual;
-
-                       struct gl_framebuffer* fFrameBuffer;
-                       struct swrast_renderbuffer* fFrontRenderBuffer;
-                       struct swrast_renderbuffer* fBackRenderBuffer;
-
-                       GLuint                  fWidth;
-                       GLuint                  fHeight;
-                       color_space             fColorSpace;
-
-                       void*                   fRowAddr[SWRAST_MAX_HEIGHT];
-};
-
-#endif // MESASOFTWARERENDERER_H
diff --git a/src/mesa/drivers/haiku/swrast/SoftwareRast.rdef b/src/mesa/drivers/haiku/swrast/SoftwareRast.rdef
deleted file mode 100644 (file)
index cb60332..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2012, Haiku, Inc. All rights reserved.
- * Distributed under the terms of the MIT License.
- */
-
-resource app_signature "application/x-vnd.Haiku-swrast";
-
-resource app_version {
-    major  = 9,
-    middle = 0,
-    minor  = 0,
-    variety = 0,
-    internal = 0,
-    short_info = "Software Rasterizer",
-    long_info = "Haiku Mesa Software GL Rasterizer"
-};
-
-resource vector_icon {
-       $"6E6369660A0200140294A9FF18020014028DFFFF97058C0500020006023B10B7"
-       $"37F036BA1A993D466848C719BEBE2000919292FFD5D5D5020016023900000000"
-       $"000000003EE0004AE00048E0005EF884C702000203392E8D383001BAD97F3C12"
-       $"8B4786BD48B8AD0D97BBFFFF7B4168DBE9FF4168DB97020002023A0C1238D099"
-       $"BE44203F4BD14B38844678240DF56A7D9FE1EA064CC704016B0500090A044024"
-       $"2438404C5C380A044028243C40505C3C0A042438243B5C3C5C380608BFBE4D59"
-       $"4D59515957575659585560406044603C5E3A5C3CCB4FBFBA5E3ECA9DC11F564B"
-       $"584A544C504C0606AF0F2F3D2F3D393D4034BF593542324130432F42364432C0"
-       $"3FBC5A2F48354A2F480608AE9A22303EB5BD3AB42542B755422E412F3C29322D"
-       $"32223C0204263726372538263F253E263F304430443143303C313D303C02043D"
-       $"423D423C433D4A3C493D4A495049504A4F49474A484947060DAEAAAE014E445A"
-       $"3456365E325E3D5D3F5A3A5542544E4D573A4E364439463342324A2242310A0A"
-       $"0002020102403CA00C88888C8CC1401673C40D6544F2950A01010002403CA000"
-       $"0000000000401673C40D65446CF80A08020304023EC16A0000000000003EC16A"
-       $"45DD1844C6550A030105123EC16A0000000000003EC16A45DD1844C655011784"
-       $"22040A040105023EC16A0000000000003EC16A45DD1844C6550A030108123EC1"
-       $"6A0000000000003EC16A45DD1844C65501178422040A0503080706023EC16A00"
-       $"00000000003EC16A45DD1844C6550A030206071A3EC16A0000000000003EC16A"
-       $"45DD1844C65510FF0215810004178222040A060106023EC16A0000000000003E"
-       $"C16A45DD1844C6550A070107023EC16A0000000000003EC16A45DD1844C655"
-};
index 9a388d64cd5c2bead8d64d147c47e608d312d399..46332e16bd1b22f1e15939e0dc92f053a80bc2c3 100644 (file)
@@ -39,7 +39,6 @@ nodist_EXTRA_lib@OSMESA_LIB@_la_SOURCES = dummy.cpp
 lib@OSMESA_LIB@_la_SOURCES = osmesa.c
 
 lib@OSMESA_LIB@_la_LDFLAGS = \
-       -module \
        -no-undefined \
        -version-number @OSMESA_VERSION@ \
        $(GC_SECTIONS) \
index c0596f8119edff91527c89977fe8d601cbbca737..ba79f6981b97213900dc5792861ea8f76da6e0f7 100644 (file)
 
 EXTRA_DIST = SConscript
 
+if HAVE_SHARED_GLAPI
+SHARED_GLAPI_CFLAGS = -DGLX_SHARED_GLAPI
+SHARED_GLAPI_LIB = $(top_builddir)/src/mapi/shared-glapi/libglapi.la
+endif
+
 AM_CPPFLAGS = \
        -I$(top_srcdir)/include \
        -I$(top_srcdir)/src/mapi \
@@ -34,11 +39,10 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/gallium/auxiliary \
        -I$(top_srcdir)/src/mesa/main \
        $(X11_INCLUDES) \
+       $(SHARED_GLAPI_CFLAGS) \
        $(DEFINES)
 
-if HAVE_X11_DRIVER
 lib_LTLIBRARIES = lib@GL_LIB@.la
-endif
 
 lib@GL_LIB@_la_SOURCES = \
        glxapi.h \
@@ -66,6 +70,7 @@ GL_PATCH = 0
 lib@GL_LIB@_la_LIBADD = \
        $(top_builddir)/src/mesa/libmesa.la \
        $(top_builddir)/src/mapi/glapi/libglapi.la \
+       $(SHARED_GLAPI_LIB) \
        $(GL_LIB_DEPS)
 
 lib@GL_LIB@_la_LDFLAGS = \
index 12249fec2283642c9eddf26f9c84d769b3845619..655cb32d0a458ef7718ebc7c42afb9f1f27d650a 100644 (file)
@@ -38,6 +38,9 @@ _mesa_initialize_exec_table(struct gl_context *ctx);
 extern void
 _mesa_initialize_dispatch_tables(struct gl_context *ctx);
 
+extern struct _glapi_table *
+_mesa_new_nop_table(unsigned numEntries);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 9932a837336b16e8eb79cd973c4f70726b09a318..a7fd82c531fcaaba51d8737d3fddc8a177038473 100644 (file)
@@ -1772,7 +1772,9 @@ _mesa_loopback_init_api_table(const struct gl_context *ctx,
       SET_VertexAttribI4sv(dest, _mesa_VertexAttribI4sv);
       SET_VertexAttribI4ubv(dest, _mesa_VertexAttribI4ubv);
       SET_VertexAttribI4usv(dest, _mesa_VertexAttribI4usv);
+   }
 
+   if (ctx->API == API_OPENGL_CORE) {
       /* GL 4.1 / GL_ARB_vertex_attrib_64bit */
       SET_VertexAttribL1d(dest, _mesa_VertexAttribL1d);
       SET_VertexAttribL2d(dest, _mesa_VertexAttribL2d);
index b163c0aa699c6e592f2172796af6a735e65b3f27..53626e38be91aa32b60698c043459de157b767a5 100644 (file)
@@ -177,6 +177,10 @@ struct texture_state
 };
 
 
+/** An unused GL_*_BIT value */
+#define DUMMY_BIT 0x10000000
+
+
 /**
  * Allocate new attribute node of given type/kind.  Attach payload data.
  * Insert it into the linked list named by 'head'.
@@ -253,6 +257,15 @@ _mesa_PushAttrib(GLbitfield mask)
    /* groups specified by the mask. */
    head = NULL;
 
+   if (mask == 0) {
+      /* if mask is zero we still need to push something so that we
+       * don't get a GL_STACK_UNDERFLOW error in glPopAttrib().
+       */
+      GLuint dummy = 0;
+      if (!push_attrib(ctx, &head, DUMMY_BIT, sizeof(dummy), &dummy))
+         goto end;
+   }
+
    if (mask & GL_ACCUM_BUFFER_BIT) {
       if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT,
                        sizeof(struct gl_accum_attrib),
@@ -928,6 +941,10 @@ _mesa_PopAttrib(void)
       }
 
       switch (attr->kind) {
+         case DUMMY_BIT:
+            /* do nothing */
+            break;
+
          case GL_ACCUM_BUFFER_BIT:
             {
                const struct gl_accum_attrib *accum;
@@ -1074,6 +1091,11 @@ _mesa_PopAttrib(void)
                _mesa_ClearDepth(depth->Clear);
                _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
                _mesa_DepthMask(depth->Mask);
+               if (ctx->Extensions.EXT_depth_bounds_test) {
+                  _mesa_set_enable(ctx, GL_DEPTH_BOUNDS_TEST_EXT,
+                                   depth->BoundsTest);
+                  _mesa_DepthBoundsEXT(depth->BoundsMin, depth->BoundsMax);
+               }
             }
             break;
          case GL_ENABLE_BIT:
index 774fc888ec41ff5d7b31bdeaae984fc3b5f7e4c5..d869fa2aa09f82a0526810843499b075149f5c6a 100644 (file)
@@ -769,7 +769,7 @@ _mesa_ClampColor(GLenum target, GLenum clamp)
       }
       FLUSH_VERTICES(ctx, _NEW_LIGHT);
       ctx->Light.ClampVertexColor = clamp;
-      _mesa_update_clamp_vertex_color(ctx);
+      _mesa_update_clamp_vertex_color(ctx, ctx->DrawBuffer);
       break;
    case GL_CLAMP_FRAGMENT_COLOR_ARB:
       if (ctx->API == API_OPENGL_CORE &&
@@ -778,7 +778,7 @@ _mesa_ClampColor(GLenum target, GLenum clamp)
       }
       FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
       ctx->Color.ClampFragmentColor = clamp;
-      _mesa_update_clamp_fragment_color(ctx);
+      _mesa_update_clamp_fragment_color(ctx, ctx->DrawBuffer);
       break;
    case GL_CLAMP_READ_COLOR_ARB:
       ctx->Color.ClampReadColor = clamp;
@@ -807,50 +807,55 @@ get_clamp_color(const struct gl_framebuffer *fb, GLenum clamp)
 }
 
 GLboolean
-_mesa_get_clamp_fragment_color(const struct gl_context *ctx)
+_mesa_get_clamp_fragment_color(const struct gl_context *ctx,
+                               const struct gl_framebuffer *drawFb)
 {
-   return get_clamp_color(ctx->DrawBuffer,
-                                ctx->Color.ClampFragmentColor);
+   return get_clamp_color(drawFb, ctx->Color.ClampFragmentColor);
 }
 
 GLboolean
-_mesa_get_clamp_vertex_color(const struct gl_context *ctx)
+_mesa_get_clamp_vertex_color(const struct gl_context *ctx,
+                             const struct gl_framebuffer *drawFb)
 {
-   return get_clamp_color(ctx->DrawBuffer, ctx->Light.ClampVertexColor);
+   return get_clamp_color(drawFb, ctx->Light.ClampVertexColor);
 }
 
 GLboolean
-_mesa_get_clamp_read_color(const struct gl_context *ctx)
+_mesa_get_clamp_read_color(const struct gl_context *ctx,
+                           const struct gl_framebuffer *readFb)
 {
-   return get_clamp_color(ctx->ReadBuffer, ctx->Color.ClampReadColor);
+   return get_clamp_color(readFb, ctx->Color.ClampReadColor);
 }
 
 /**
  * Update the ctx->Color._ClampFragmentColor field
  */
 void
-_mesa_update_clamp_fragment_color(struct gl_context *ctx)
+_mesa_update_clamp_fragment_color(struct gl_context *ctx,
+                                  const struct gl_framebuffer *drawFb)
 {
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-
    /* Don't clamp if:
     * - there is no colorbuffer
     * - all colorbuffers are unsigned normalized, so clamping has no effect
     * - there is an integer colorbuffer
     */
-   if (!fb || !fb->_HasSNormOrFloatColorBuffer || fb->_IntegerColor)
+   if (!drawFb || !drawFb->_HasSNormOrFloatColorBuffer ||
+       drawFb->_IntegerColor)
       ctx->Color._ClampFragmentColor = GL_FALSE;
    else
-      ctx->Color._ClampFragmentColor = _mesa_get_clamp_fragment_color(ctx);
+      ctx->Color._ClampFragmentColor =
+         _mesa_get_clamp_fragment_color(ctx, drawFb);
 }
 
 /**
  * Update the ctx->Color._ClampVertexColor field
  */
 void
-_mesa_update_clamp_vertex_color(struct gl_context *ctx)
+_mesa_update_clamp_vertex_color(struct gl_context *ctx,
+                                const struct gl_framebuffer *drawFb)
 {
-   ctx->Light._ClampVertexColor = _mesa_get_clamp_vertex_color(ctx);
+   ctx->Light._ClampVertexColor =
+         _mesa_get_clamp_vertex_color(ctx, drawFb);
 }
 
 /**
index fe31a7440f09e305db3c0852fe2191301537ee9f..8ab9e02fc13d18d7e06f92aa9bf142a8a37ed2e2 100644 (file)
@@ -37,6 +37,7 @@
 #include "formats.h"
 
 struct gl_context;
+struct gl_framebuffer;
 
 
 extern void GLAPIENTRY
@@ -101,19 +102,24 @@ extern void GLAPIENTRY
 _mesa_ClampColor(GLenum target, GLenum clamp);
 
 extern GLboolean
-_mesa_get_clamp_fragment_color(const struct gl_context *ctx);
+_mesa_get_clamp_fragment_color(const struct gl_context *ctx,
+                               const struct gl_framebuffer *drawFb);
 
 extern GLboolean
-_mesa_get_clamp_vertex_color(const struct gl_context *ctx);
+_mesa_get_clamp_vertex_color(const struct gl_context *ctx,
+                             const struct gl_framebuffer *drawFb);
 
 extern GLboolean
-_mesa_get_clamp_read_color(const struct gl_context *ctx);
+_mesa_get_clamp_read_color(const struct gl_context *ctx,
+                           const struct gl_framebuffer *readFb);
 
 extern void
-_mesa_update_clamp_fragment_color(struct gl_context *ctx);
+_mesa_update_clamp_fragment_color(struct gl_context *ctx,
+                                  const struct gl_framebuffer *drawFb);
 
 extern void
-_mesa_update_clamp_vertex_color(struct gl_context *ctx);
+_mesa_update_clamp_vertex_color(struct gl_context *ctx,
+                                const struct gl_framebuffer *drawFb);
 
 extern mesa_format
 _mesa_get_render_format(const struct gl_context *ctx, mesa_format format);
index 0694466eb75bfa8dfa97c4018e4d9b0e37a04c43..db8fee5a414f6a382a85ee4fb20acae106340135 100644 (file)
@@ -34,6 +34,7 @@
 #include "enums.h"
 #include "blit.h"
 #include "fbobject.h"
+#include "framebuffer.h"
 #include "glformats.h"
 #include "mtypes.h"
 #include "state.h"
@@ -148,38 +149,25 @@ is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
 }
 
 
-/**
- * Blit rectangular region, optionally from one framebuffer to another.
- *
- * Note, if the src buffer is multisampled and the dest is not, this is
- * when the samples must be resolved to a single color.
- */
-void GLAPIENTRY
-_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                         GLbitfield mask, GLenum filter)
+void
+_mesa_blit_framebuffer(struct gl_context *ctx,
+                       struct gl_framebuffer *readFb,
+                       struct gl_framebuffer *drawFb,
+                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                       GLbitfield mask, GLenum filter, const char *func)
 {
    const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
                                      GL_DEPTH_BUFFER_BIT |
                                      GL_STENCIL_BUFFER_BIT);
-   const struct gl_framebuffer *readFb, *drawFb;
-   GET_CURRENT_CONTEXT(ctx);
 
    FLUSH_VERTICES(ctx, 0);
 
-   if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx,
-                  "glBlitFramebuffer(%d, %d, %d, %d,  %d, %d, %d, %d, 0x%x, %s)\n",
-                  srcX0, srcY0, srcX1, srcY1,
-                  dstX0, dstY0, dstX1, dstY1,
-                  mask, _mesa_lookup_enum_by_nr(filter));
-
-   if (ctx->NewState) {
-      _mesa_update_state(ctx);
-   }
+   /* Update completeness status of readFb and drawFb. */
+   _mesa_update_framebuffer(ctx, readFb, drawFb);
 
-   readFb = ctx->ReadBuffer;
-   drawFb = ctx->DrawBuffer;
+   /* Make sure drawFb has an initialized bounding box. */
+   _mesa_update_draw_buffer_bounds(ctx, drawFb);
 
    if (!readFb || !drawFb) {
       /* This will normally never happen but someday we may want to
@@ -192,12 +180,12 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
        readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
-                  "glBlitFramebufferEXT(incomplete draw/read buffers)");
+                  "%s(incomplete draw/read buffers)", func);
       return;
    }
 
    if (!is_valid_blit_filter(ctx, filter)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(%s)",
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
                   _mesa_lookup_enum_by_nr(filter));
       return;
    }
@@ -205,13 +193,13 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
         filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
         (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(%s)",
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
                   _mesa_lookup_enum_by_nr(filter));
       return;
    }
 
    if (mask & ~legalMaskBits) {
-      _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
       return;
    }
 
@@ -219,13 +207,13 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
         && filter != GL_NEAREST) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-             "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)");
+             "%s(depth/stencil requires GL_NEAREST filter)", func);
       return;
    }
 
    /* get color read/draw renderbuffers */
    if (mask & GL_COLOR_BUFFER_BIT) {
-      const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers;
+      const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
       const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
       const struct gl_renderbuffer *colorDrawRb = NULL;
       GLuint i;
@@ -241,7 +229,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
       }
       else {
          for (i = 0; i < numColorDrawBuffers; i++) {
-            colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+            colorDrawRb = drawFb->_ColorDrawBuffers[i];
             if (!colorDrawRb)
                continue;
 
@@ -257,15 +245,15 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
              */
             if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
                _mesa_error(ctx, GL_INVALID_OPERATION,
-                           "glBlitFramebuffer(source and destination color "
-                           "buffer cannot be the same)");
+                           "%s(source and destination color "
+                           "buffer cannot be the same)", func);
                return;
             }
 
             if (!compatible_color_datatypes(colorReadRb->Format,
                                             colorDrawRb->Format)) {
                _mesa_error(ctx, GL_INVALID_OPERATION,
-                           "glBlitFramebufferEXT(color buffer datatypes mismatch)");
+                           "%s(color buffer datatypes mismatch)", func);
                return;
             }
             /* extra checks for multisample copies... */
@@ -273,7 +261,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                /* color formats must match */
                if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) {
                   _mesa_error(ctx, GL_INVALID_OPERATION,
-                         "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
+                         "%s(bad src/dst multisample pixel formats)", func);
                   return;
                }
             }
@@ -286,7 +274,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
             GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
             if (type == GL_INT || type == GL_UNSIGNED_INT) {
                _mesa_error(ctx, GL_INVALID_OPERATION,
-                           "glBlitFramebufferEXT(integer color type)");
+                           "%s(integer color type)", func);
                return;
             }
          }
@@ -306,15 +294,15 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
        *     ignored."
        */
       if ((readRb == NULL) || (drawRb == NULL)) {
-        mask &= ~GL_STENCIL_BUFFER_BIT;
+         mask &= ~GL_STENCIL_BUFFER_BIT;
       }
       else {
          int read_z_bits, draw_z_bits;
 
          if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glBlitFramebuffer(source and destination stencil "
-                        "buffer cannot be the same)");
+                        "%s(source and destination stencil "
+                        "buffer cannot be the same)", func);
             return;
          }
 
@@ -324,7 +312,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
              * there is only one: GL_UNSIGNED_INT.
              */
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glBlitFramebuffer(stencil attachment format mismatch)");
+                        "%s(stencil attachment format mismatch)", func);
             return;
          }
 
@@ -340,8 +328,8 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
               _mesa_get_format_datatype(readRb->Format) !=
               _mesa_get_format_datatype(drawRb->Format))) {
 
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
-                        "(stencil attachment depth format mismatch)");
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "%s(stencil attachment depth format mismatch)", func);
             return;
          }
       }
@@ -360,15 +348,15 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
        *     ignored."
        */
       if ((readRb == NULL) || (drawRb == NULL)) {
-        mask &= ~GL_DEPTH_BUFFER_BIT;
+         mask &= ~GL_DEPTH_BUFFER_BIT;
       }
       else {
          int read_s_bit, draw_s_bit;
 
          if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glBlitFramebuffer(source and destination depth "
-                        "buffer cannot be the same)");
+                        "%s(source and destination depth "
+                        "buffer cannot be the same)", func);
             return;
          }
 
@@ -377,7 +365,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
              (_mesa_get_format_datatype(readRb->Format) !=
               _mesa_get_format_datatype(drawRb->Format))) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glBlitFramebuffer(depth attachment format mismatch)");
+                        "%s(depth attachment format mismatch)", func);
             return;
          }
 
@@ -389,8 +377,8 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
           * we should ignore the stencil format check.
           */
          if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
-                        "(depth attachment stencil bits mismatch)");
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "%s(depth attachment stencil bits mismatch)", func);
             return;
          }
       }
@@ -406,7 +394,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
        */
       if (drawFb->Visual.samples > 0) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBlitFramebuffer(destination samples must be 0)");
+                     "%s(destination samples must be 0)", func);
          return;
       }
 
@@ -426,7 +414,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
           && (srcX0 != dstX0 || srcY0 != dstY0
               || srcX1 != dstX1 || srcY1 != dstY1)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBlitFramebuffer(bad src/dst multisample region)");
+                     "%s(bad src/dst multisample region)", func);
          return;
       }
    } else {
@@ -434,7 +422,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
           drawFb->Visual.samples > 0 &&
           readFb->Visual.samples != drawFb->Visual.samples) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBlitFramebufferEXT(mismatched samples)");
+                     "%s(mismatched samples)", func);
          return;
       }
 
@@ -445,7 +433,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
          if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
              abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glBlitFramebufferEXT(bad src/dst multisample region sizes)");
+                        "%s(bad src/dst multisample region sizes)", func);
             return;
          }
       }
@@ -457,43 +445,44 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
       const struct gl_renderbuffer *colorDrawRb = NULL;
       GLuint i = 0;
 
-      printf("glBlitFramebuffer(%d, %d, %d, %d,  %d, %d, %d, %d,"
-            " 0x%x, 0x%x)\n",
-            srcX0, srcY0, srcX1, srcY1,
-            dstX0, dstY0, dstX1, dstY1,
-            mask, filter);
+      printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
+             " 0x%x, 0x%x)\n", func,
+             srcX0, srcY0, srcX1, srcY1,
+             dstX0, dstY0, dstX1, dstY1,
+             mask, filter);
+
       if (colorReadRb) {
          const struct gl_renderbuffer_attachment *att;
 
          att = find_attachment(readFb, colorReadRb);
          printf("  Src FBO %u  RB %u (%dx%d)  ",
-               readFb->Name, colorReadRb->Name,
-               colorReadRb->Width, colorReadRb->Height);
+                readFb->Name, colorReadRb->Name,
+                colorReadRb->Width, colorReadRb->Height);
          if (att && att->Texture) {
             printf("Tex %u  tgt 0x%x  level %u  face %u",
-                  att->Texture->Name,
-                  att->Texture->Target,
-                  att->TextureLevel,
-                  att->CubeMapFace);
+                   att->Texture->Name,
+                   att->Texture->Target,
+                   att->TextureLevel,
+                   att->CubeMapFace);
          }
          printf("\n");
 
          /* Print all active color render buffers */
-         for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-            colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+         for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
+            colorDrawRb = drawFb->_ColorDrawBuffers[i];
             if (!colorDrawRb)
                continue;
 
             att = find_attachment(drawFb, colorDrawRb);
             printf("  Dst FBO %u  RB %u (%dx%d)  ",
-                  drawFb->Name, colorDrawRb->Name,
-                  colorDrawRb->Width, colorDrawRb->Height);
+                   drawFb->Name, colorDrawRb->Name,
+                   colorDrawRb->Width, colorDrawRb->Height);
             if (att && att->Texture) {
                printf("Tex %u  tgt 0x%x  level %u  face %u",
-                     att->Texture->Name,
-                     att->Texture->Target,
-                     att->TextureLevel,
-                     att->CubeMapFace);
+                      att->Texture->Name,
+                      att->Texture->Target,
+                      att->TextureLevel,
+                      att->CubeMapFace);
             }
             printf("\n");
          }
@@ -507,8 +496,87 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    }
 
    assert(ctx->Driver.BlitFramebuffer);
-   ctx->Driver.BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
+   ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
                                srcX0, srcY0, srcX1, srcY1,
                                dstX0, dstY0, dstX1, dstY1,
                                mask, filter);
 }
+
+
+/**
+ * Blit rectangular region, optionally from one framebuffer to another.
+ *
+ * Note, if the src buffer is multisampled and the dest is not, this is
+ * when the samples must be resolved to a single color.
+ */
+void GLAPIENTRY
+_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                      GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                      GLbitfield mask, GLenum filter)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx,
+                  "glBlitFramebuffer(%d, %d, %d, %d, "
+                  " %d, %d, %d, %d, 0x%x, %s)\n",
+                  srcX0, srcY0, srcX1, srcY1,
+                  dstX0, dstY0, dstX1, dstY1,
+                  mask, _mesa_lookup_enum_by_nr(filter));
+
+   _mesa_blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
+                          srcX0, srcY0, srcX1, srcY1,
+                          dstX0, dstY0, dstX1, dstY1,
+                          mask, filter, "glBlitFramebuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
+                           GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                           GLbitfield mask, GLenum filter)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *readFb, *drawFb;
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx,
+                  "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
+                  " %d, %d, %d, %d, 0x%x, %s)\n",
+                  readFramebuffer, drawFramebuffer,
+                  srcX0, srcY0, srcX1, srcY1,
+                  dstX0, dstY0, dstX1, dstY1,
+                  mask, _mesa_lookup_enum_by_nr(filter));
+
+   /*
+    * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
+    * Section 18.3 Copying Pixels):
+    *   "... if readFramebuffer or drawFramebuffer is zero (for
+    *   BlitNamedFramebuffer), then the default read or draw framebuffer is
+    *   used as the corresponding source or destination framebuffer,
+    *   respectively."
+    */
+   if (readFramebuffer) {
+      readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
+                                            "glBlitNamedFramebuffer");
+      if (!readFb)
+         return;
+   }
+   else
+      readFb = ctx->WinSysReadBuffer;
+
+   if (drawFramebuffer) {
+      drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
+                                            "glBlitNamedFramebuffer");
+      if (!drawFb)
+         return;
+   }
+   else
+      drawFb = ctx->WinSysDrawBuffer;
+
+   _mesa_blit_framebuffer(ctx, readFb, drawFb,
+                          srcX0, srcY0, srcX1, srcY1,
+                          dstX0, dstY0, dstX1, dstY1,
+                          mask, filter, "glBlitNamedFramebuffer");
+}
index 01a958af5a275e3c5fa8cbc3235abec81c783954..54b946e3192941a418b02aedd506eeeb189e89f9 100644 (file)
 
 #include "glheader.h"
 
+extern void
+_mesa_blit_framebuffer(struct gl_context *ctx,
+                       struct gl_framebuffer *readFb,
+                       struct gl_framebuffer *drawFb,
+                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                       GLbitfield mask, GLenum filter, const char *func);
 
 extern void GLAPIENTRY
 _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                          GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                          GLbitfield mask, GLenum filter);
 
+extern void GLAPIENTRY
+_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
+                           GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                           GLbitfield mask, GLenum filter);
+
 
 #endif /* BLIT_H */
index 37a9790923b1f6f169ac22e21795eac595713692..0536266d7564ce9222a4dc5bef7e33a97b49dbcf 100644 (file)
@@ -242,16 +242,16 @@ read_buffer_enum_to_index(GLenum buffer)
  *
  * See the GL_EXT_framebuffer_object spec for more info.
  */
-void GLAPIENTRY
-_mesa_DrawBuffer(GLenum buffer)
+void
+_mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+                  GLenum buffer, const char *caller)
 {
    GLbitfield destMask;
-   GET_CURRENT_CONTEXT(ctx);
 
    FLUSH_VERTICES(ctx, 0);
 
    if (MESA_VERBOSE & VERBOSE_API) {
-      _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+      _mesa_debug(ctx, "%s %s\n", caller, _mesa_lookup_enum_by_nr(buffer));
    }
 
    if (buffer == GL_NONE) {
@@ -259,33 +259,60 @@ _mesa_DrawBuffer(GLenum buffer)
    }
    else {
       const GLbitfield supportedMask
-         = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
+         = supported_buffer_bitmask(ctx, fb);
       destMask = draw_buffer_enum_to_bitmask(ctx, buffer);
       if (destMask == BAD_MASK) {
          /* totally bogus buffer */
-         _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glDrawBuffer(buffer=0x%x)", buffer);
+         _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", caller,
+                     _mesa_lookup_enum_by_nr(buffer));
          return;
       }
       destMask &= supportedMask;
       if (destMask == 0x0) {
          /* none of the named color buffers exist! */
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glDrawBuffer(buffer=0x%x)", buffer);
+         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffer %s)",
+                     caller, _mesa_lookup_enum_by_nr(buffer));
          return;
       }
    }
 
    /* if we get here, there's no error so set new state */
-   _mesa_drawbuffers(ctx, 1, &buffer, &destMask);
+   _mesa_drawbuffers(ctx, fb, 1, &buffer, &destMask);
+
+   /* Call device driver function only if fb is the bound draw buffer */
+   if (fb == ctx->DrawBuffer) {
+      if (ctx->Driver.DrawBuffers)
+         ctx->Driver.DrawBuffers(ctx, 1, &buffer);
+      else if (ctx->Driver.DrawBuffer)
+         ctx->Driver.DrawBuffer(ctx, buffer);
+   }
+}
 
-   /*
-    * Call device driver function.
-    */
-   if (ctx->Driver.DrawBuffers)
-      ctx->Driver.DrawBuffers(ctx, 1, &buffer);
-   else if (ctx->Driver.DrawBuffer)
-      ctx->Driver.DrawBuffer(ctx, buffer);
+
+void GLAPIENTRY
+_mesa_DrawBuffer(GLenum buffer)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_draw_buffer(ctx, ctx->DrawBuffer, buffer, "glDrawBuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glNamedFramebufferDrawBuffer");
+      if (!fb)
+         return;
+   }
+   else
+      fb = ctx->WinSysDrawBuffer;
+
+   _mesa_draw_buffer(ctx, fb, buf, "glNamedFramebufferDrawBuffer");
 }
 
 
@@ -298,13 +325,13 @@ _mesa_DrawBuffer(GLenum buffer)
  *                 names cannot specify more than one buffer.  For example,
  *                 GL_FRONT_AND_BACK is illegal.
  */
-void GLAPIENTRY
-_mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
+void
+_mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+                   GLsizei n, const GLenum *buffers, const char *caller)
 {
    GLuint output;
    GLbitfield usedBufferMask, supportedMask;
    GLbitfield destMask[MAX_DRAW_BUFFERS];
-   GET_CURRENT_CONTEXT(ctx);
 
    FLUSH_VERTICES(ctx, 0);
 
@@ -315,12 +342,18 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
     * "An INVALID_VALUE error is generated if n is greater than
     *  MAX_DRAW_BUFFERS."
     */
-   if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller);
+      return;
+   }
+
+   if (n > (GLsizei) ctx->Const.MaxDrawBuffers) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(n > maximum number of draw buffers)", caller);
       return;
    }
 
-   supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
+   supportedMask = supported_buffer_bitmask(ctx, fb);
    usedBufferMask = 0x0;
 
    /* From the ES 3.0 specification, page 180:
@@ -328,9 +361,9 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
     *  and the constant must be BACK or NONE."
     * (same restriction applies with GL_EXT_draw_buffers specification)
     */
-   if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(ctx->DrawBuffer) &&
+   if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(fb) &&
        (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffers)", caller);
       return;
    }
 
@@ -362,9 +395,11 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
           *     or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
           *     INVALID_OPERATION results."
           */
-         if (_mesa_is_user_fbo(ctx->DrawBuffer) && buffers[output] >=
+         if (_mesa_is_user_fbo(fb) && buffers[output] >=
              GL_COLOR_ATTACHMENT0 + ctx->Const.MaxDrawBuffers) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(buffer)");
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "%s(buffers[%d] >= maximum number of draw buffers)",
+                        caller, output);
             return;
          }
 
@@ -375,9 +410,10 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
           *  4.5 or 4.6.  Otherwise, an INVALID_ENUM error is generated.
           */
          if (destMask[output] == BAD_MASK) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
+                        caller, _mesa_lookup_enum_by_nr(buffers[output]));
             return;
-         }         
+         }
 
          /* From the OpenGL 4.0 specification, page 256:
           * "For both the default framebuffer and framebuffer objects, the
@@ -390,7 +426,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
           *  but the Khronos conformance tests expect INVALID_ENUM.
           */
          if (_mesa_bitcount(destMask[output]) > 1) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
+                        caller, _mesa_lookup_enum_by_nr(buffers[output]));
             return;
          }
 
@@ -407,7 +444,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
          destMask[output] &= supportedMask;
          if (destMask[output] == 0) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glDrawBuffersARB(unsupported buffer)");
+                        "%s(unsupported buffer %s)",
+                        caller, _mesa_lookup_enum_by_nr(buffers[output]));
             return;
          }
 
@@ -416,10 +454,12 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
           *  in bufs must be COLOR_ATTACHMENTi or NONE. [...] INVALID_OPERATION."
           * (same restriction applies with GL_EXT_draw_buffers specification)
           */
-         if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(ctx->DrawBuffer) &&
+         if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(fb) &&
              buffers[output] != GL_NONE &&
              buffers[output] != GL_COLOR_ATTACHMENT0 + output) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "%s(unsupported buffer %s)",
+                        caller, _mesa_lookup_enum_by_nr(buffers[output]));
             return;
          }
 
@@ -430,7 +470,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
           */
          if (destMask[output] & usedBufferMask) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glDrawBuffersARB(duplicated buffer)");
+                        "%s(duplicated buffer %s)",
+                        caller, _mesa_lookup_enum_by_nr(buffers[output]));
             return;
          }
 
@@ -440,17 +481,48 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
    }
 
    /* OK, if we get here, there were no errors so set the new state */
-   _mesa_drawbuffers(ctx, n, buffers, destMask);
+   _mesa_drawbuffers(ctx, fb, n, buffers, destMask);
 
    /*
-    * Call device driver function.  Note that n can be equal to 0,
+    * Call device driver function if fb is the bound draw buffer.
+    * Note that n can be equal to 0,
     * in which case we don't want to reference buffers[0], which
     * may not be valid.
     */
-   if (ctx->Driver.DrawBuffers)
-      ctx->Driver.DrawBuffers(ctx, n, buffers);
-   else if (ctx->Driver.DrawBuffer)
-      ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE);
+   if (fb == ctx->DrawBuffer) {
+      if (ctx->Driver.DrawBuffers)
+         ctx->Driver.DrawBuffers(ctx, n, buffers);
+      else if (ctx->Driver.DrawBuffer)
+         ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_draw_buffers(ctx, ctx->DrawBuffer, n, buffers, "glDrawBuffers");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n,
+                                  const GLenum *bufs)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glNamedFramebufferDrawBuffers");
+      if (!fb)
+         return;
+   }
+   else
+      fb = ctx->WinSysDrawBuffer;
+
+   _mesa_draw_buffers(ctx, fb, n, bufs, "glNamedFramebufferDrawBuffers");
 }
 
 
@@ -459,13 +531,11 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
  * actual change.
  */
 static void
-updated_drawbuffers(struct gl_context *ctx)
+updated_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
 
    if (ctx->API == API_OPENGL_COMPAT && !ctx->Extensions.ARB_ES2_compatibility) {
-      struct gl_framebuffer *fb = ctx->DrawBuffer;
-
       /* Flag the FBO as requiring validation. */
       if (_mesa_is_user_fbo(fb)) {
         fb->_Status = 0;
@@ -482,6 +552,7 @@ updated_drawbuffers(struct gl_context *ctx)
  * so nothing should go wrong at this point.
  *
  * \param ctx  current context
+ * \param fb   the desired draw buffer
  * \param n    number of color outputs to set
  * \param buffers  array[n] of colorbuffer names, like GL_LEFT.
  * \param destMask  array[n] of BUFFER_BIT_* bitmasks which correspond to the
@@ -489,10 +560,9 @@ updated_drawbuffers(struct gl_context *ctx)
  *                  BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT).
  */
 void
-_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
-                  const GLbitfield *destMask)
+_mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+                  GLuint n, const GLenum *buffers, const GLbitfield *destMask)
 {
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLbitfield mask[MAX_DRAW_BUFFERS];
    GLuint buf;
 
@@ -518,7 +588,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
       while (destMask0) {
          GLint bufIndex = ffs(destMask0) - 1;
          if (fb->_ColorDrawBufferIndexes[count] != bufIndex) {
-            updated_drawbuffers(ctx);
+            updated_drawbuffers(ctx, fb);
             fb->_ColorDrawBufferIndexes[count] = bufIndex;
          }
          count++;
@@ -535,14 +605,14 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
             /* only one bit should be set in the destMask[buf] field */
             assert(_mesa_bitcount(destMask[buf]) == 1);
             if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) {
-              updated_drawbuffers(ctx);
+              updated_drawbuffers(ctx, fb);
                fb->_ColorDrawBufferIndexes[buf] = bufIndex;
             }
             count = buf + 1;
          }
          else {
             if (fb->_ColorDrawBufferIndexes[buf] != -1) {
-              updated_drawbuffers(ctx);
+              updated_drawbuffers(ctx, fb);
                fb->_ColorDrawBufferIndexes[buf] = -1;
             }
          }
@@ -554,7 +624,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
    /* set remaining outputs to -1 (GL_NONE) */
    for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) {
       if (fb->_ColorDrawBufferIndexes[buf] != -1) {
-         updated_drawbuffers(ctx);
+         updated_drawbuffers(ctx, fb);
          fb->_ColorDrawBufferIndexes[buf] = -1;
       }
    }
@@ -566,7 +636,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
       /* also set context drawbuffer state */
       for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
          if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) {
-           updated_drawbuffers(ctx);
+           updated_drawbuffers(ctx, fb);
             ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf];
          }
       }
@@ -585,7 +655,7 @@ _mesa_update_draw_buffers(struct gl_context *ctx)
    /* should be a window system FBO */
    assert(_mesa_is_winsys_fbo(ctx->DrawBuffer));
 
-   _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+   _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers,
                      ctx->Color.DrawBuffer, NULL);
 }
 
@@ -598,11 +668,10 @@ _mesa_update_draw_buffers(struct gl_context *ctx)
  * \param bufferIndex  the numerical index corresponding to 'buffer'
  */
 void
-_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex)
+_mesa_readbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+                 GLenum buffer, GLint bufferIndex)
 {
-   struct gl_framebuffer *fb = ctx->ReadBuffer;
-
-   if (_mesa_is_winsys_fbo(fb)) {
+   if ((fb == ctx->ReadBuffer) && _mesa_is_winsys_fbo(fb)) {
       /* Only update the per-context READ_BUFFER state if we're bound to
        * a window-system framebuffer.
        */
@@ -621,23 +690,17 @@ _mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex)
  * Called by glReadBuffer to set the source renderbuffer for reading pixels.
  * \param mode color buffer such as GL_FRONT, GL_BACK, etc.
  */
-void GLAPIENTRY
-_mesa_ReadBuffer(GLenum buffer)
+void
+_mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+                  GLenum buffer, const char *caller)
 {
-   struct gl_framebuffer *fb;
    GLbitfield supportedMask;
    GLint srcBuffer;
-   GET_CURRENT_CONTEXT(ctx);
 
    FLUSH_VERTICES(ctx, 0);
 
    if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
-
-   fb = ctx->ReadBuffer;
-
-   if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+      _mesa_debug(ctx, "%s %s\n", caller, _mesa_lookup_enum_by_nr(buffer));
 
    if (buffer == GL_NONE) {
       /* This is legal--it means that no buffer should be bound for reading. */
@@ -648,24 +711,53 @@ _mesa_ReadBuffer(GLenum buffer)
       srcBuffer = read_buffer_enum_to_index(buffer);
       if (srcBuffer == -1) {
          _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glReadBuffer(buffer=0x%x)", buffer);
+                     "%s(invalid buffer %s)", caller,
+                     _mesa_lookup_enum_by_nr(buffer));
          return;
       }
       supportedMask = supported_buffer_bitmask(ctx, fb);
       if (((1 << srcBuffer) & supportedMask) == 0) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glReadBuffer(buffer=0x%x)", buffer);
+                     "%s(invalid buffer %s)", caller,
+                     _mesa_lookup_enum_by_nr(buffer));
          return;
       }
    }
 
    /* OK, all error checking has been completed now */
 
-   _mesa_readbuffer(ctx, buffer, srcBuffer);
+   _mesa_readbuffer(ctx, fb, buffer, srcBuffer);
 
-   /*
-    * Call device driver function.
-    */
-   if (ctx->Driver.ReadBuffer)
-      (*ctx->Driver.ReadBuffer)(ctx, buffer);
+   /* Call the device driver function only if fb is the bound read buffer */
+   if (fb == ctx->ReadBuffer) {
+      if (ctx->Driver.ReadBuffer)
+         (*ctx->Driver.ReadBuffer)(ctx, buffer);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_ReadBuffer(GLenum buffer)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_read_buffer(ctx, ctx->ReadBuffer, buffer, "glReadBuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glNamedFramebufferReadBuffer");
+      if (!fb)
+         return;
+   }
+   else
+      fb = ctx->WinSysReadBuffer;
+
+   _mesa_read_buffer(ctx, fb, src, "glNamedFramebufferReadBuffer");
 }
index ebcfa1c1e74e0e554ce0bf7be89d002b49d46033..5aa79fda54bda4106e1835ba4177b31e0ef659fc 100644 (file)
 #include "glheader.h"
 
 struct gl_context;
+struct gl_framebuffer;
+
+extern void
+_mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+                  GLenum buffer, const char *caller);
 
 extern void GLAPIENTRY
 _mesa_DrawBuffer( GLenum mode );
 
+extern void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf);
+
+extern void
+_mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+                   GLsizei n, const GLenum *buffers, const char *caller);
+
 extern void GLAPIENTRY
 _mesa_DrawBuffers(GLsizei n, const GLenum *buffers);
 
+extern void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n,
+                                  const GLenum *bufs);
+
 extern void
-_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
+_mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+                  GLuint n, const GLenum *buffers,
                   const GLbitfield *destMask);
 
 extern void
-_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex);
+_mesa_readbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+                 GLenum buffer, GLint bufferIndex);
 
 extern void
 _mesa_update_draw_buffers(struct gl_context *ctx);
 
 
+extern void
+_mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+                  GLenum buffer, const char *caller);
+
 extern void GLAPIENTRY
 _mesa_ReadBuffer( GLenum mode );
 
+extern void GLAPIENTRY
+_mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src);
+
 
 #endif
index 8d707bc34a1869e78f1f8a32f4ae0a018c8b1b71..426caea470903dddce970400216862c12fd52d28 100644 (file)
@@ -34,6 +34,8 @@
 #include "clear.h"
 #include "context.h"
 #include "enums.h"
+#include "fbobject.h"
+#include "get.h"
 #include "macros.h"
 #include "mtypes.h"
 #include "state.h"
@@ -399,6 +401,24 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
 }
 
 
+/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
+                              GLint drawbuffer, const GLint *value)
+{
+   GLint oldfb;
+
+   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+   _mesa_ClearBufferiv(buffer, drawbuffer, value);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
+
+
 /**
  * New in GL 3.0
  * Clear unsigned integer color buffer (not depth, not stencil).
@@ -471,6 +491,24 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
 }
 
 
+/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
+                               GLint drawbuffer, const GLuint *value)
+{
+   GLint oldfb;
+
+   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+   _mesa_ClearBufferuiv(buffer, drawbuffer, value);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
+
+
 /**
  * New in GL 3.0
  * Clear fixed-pt or float color buffer or depth buffer (not stencil).
@@ -564,6 +602,24 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
 }
 
 
+/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
+                              GLint drawbuffer, const GLfloat *value)
+{
+   GLint oldfb;
+
+   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+   _mesa_ClearBufferfv(buffer, drawbuffer, value);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
+
+
 /**
  * New in GL 3.0
  * Clear depth/stencil buffer only.
@@ -626,3 +682,21 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
       ctx->Stencil.Clear = clearStencilSave;
    }
 }
+
+
+/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
+                              GLfloat depth, GLint stencil)
+{
+   GLint oldfb;
+
+   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+   _mesa_ClearBufferfi(buffer, 0, depth, stencil);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
index 96ce47b929eb89016c51b8bb33cb952c83de139c..c29850676ca0b3b2427350cd45a5ff63669dc6af 100644 (file)
@@ -51,14 +51,30 @@ _mesa_Clear( GLbitfield mask );
 extern void GLAPIENTRY
 _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
 
+extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
+                              GLint drawbuffer, const GLint *value);
+
 extern void GLAPIENTRY
 _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value);
 
+extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
+                               GLint drawbuffer, const GLuint *value);
+
 extern void GLAPIENTRY
 _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value);
 
+extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
+                              GLint drawbuffer, const GLfloat *value);
+
 extern void GLAPIENTRY
 _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
                     GLfloat depth, GLint stencil);
 
+extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
+                              GLfloat depth, GLint stencil);
+
 #endif
index 5a66a4eec90fc1d12191dafe05cd58455800a98c..9c3baf4c6aa10bced483b6682a573a822f57c2b8 100644 (file)
 /** For GL_ARB_fragment_program */
 /*@{*/
 #define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0
+#define MAX_FRAGMENT_PROGRAM_PARAMS       64
+#define MAX_FRAGMENT_PROGRAM_INPUTS       12
 /*@}*/
 
-/** For GL_NV_fragment_program */
-/*@{*/
-#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */
-#define MAX_NV_FRAGMENT_PROGRAM_TEMPS         96
-#define MAX_NV_FRAGMENT_PROGRAM_PARAMS        64
-#define MAX_NV_FRAGMENT_PROGRAM_INPUTS        12
-#define MAX_NV_FRAGMENT_PROGRAM_OUTPUTS        3
-#define MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS    2
-/*@}*/
-
-
 /** For GL_ARB_vertex_shader */
 /*@{*/
 #define MAX_VERTEX_GENERIC_ATTRIBS 16
index 0a192de8c0a47087076e9638c2235e100a2bb361..79fa01849e09b9df3eb175393b1e1b25cb6dceb1 100644 (file)
@@ -489,8 +489,8 @@ init_program_limits(struct gl_constants *consts, gl_shader_stage stage,
       prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
       break;
    case MESA_SHADER_FRAGMENT:
-      prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
-      prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
+      prog->MaxParameters = MAX_FRAGMENT_PROGRAM_PARAMS;
+      prog->MaxAttribs = MAX_FRAGMENT_PROGRAM_INPUTS;
       prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
       prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
       prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
@@ -883,6 +883,19 @@ update_default_objects(struct gl_context *ctx)
 }
 
 
+/* XXX this is temporary and should be removed at some point in the
+ * future when there's a reasonable expectation that the libGL library
+ * contains the _glapi_new_nop_table() and _glapi_set_nop_handler()
+ * functions which were added in Mesa 10.6.
+ */
+#if !defined(_WIN32)
+/* Avoid libGL / driver ABI break */
+#define USE_GLAPI_NOP_FEATURES 0
+#else
+#define USE_GLAPI_NOP_FEATURES 1
+#endif
+
+
 /**
  * This function is called by the glapi no-op functions.  For each OpenGL
  * function/entrypoint there's a simple no-op function.  These "no-op"
@@ -898,6 +911,7 @@ update_default_objects(struct gl_context *ctx)
  *
  * \param name  the name of the OpenGL function
  */
+#if USE_GLAPI_NOP_FEATURES
 static void
 nop_handler(const char *name)
 {
@@ -914,6 +928,7 @@ nop_handler(const char *name)
    }
 #endif
 }
+#endif
 
 
 /**
@@ -923,11 +938,51 @@ nop_handler(const char *name)
 static void GLAPIENTRY
 nop_glFlush(void)
 {
-   /* don't record an error like we do in _mesa_generic_nop() */
+   /* don't record an error like we do in nop_handler() */
+}
+#endif
+
+
+#if !USE_GLAPI_NOP_FEATURES
+static int
+generic_nop(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "unsupported function called "
+               "(unsupported extension or deprecated function?)");
+   return 0;
 }
 #endif
 
 
+/**
+ * Create a new API dispatch table in which all entries point to the
+ * generic_nop() function.  This will not work on Windows because of
+ * the __stdcall convention which requires the callee to clean up the
+ * call stack.  That's impossible with one generic no-op function.
+ */
+struct _glapi_table *
+_mesa_new_nop_table(unsigned numEntries)
+{
+   struct _glapi_table *table;
+
+#if !USE_GLAPI_NOP_FEATURES
+   table = malloc(numEntries * sizeof(_glapi_proc));
+   if (table) {
+      _glapi_proc *entry = (_glapi_proc *) table;
+      unsigned i;
+      for (i = 0; i < numEntries; i++) {
+         entry[i] = (_glapi_proc) generic_nop;
+      }
+   }
+#else
+   table = _glapi_new_nop_table(numEntries);
+#endif
+   return table;
+}
+
+
 /**
  * Allocate and initialize a new dispatch table.  The table will be
  * populated with pointers to "no-op" functions.  In turn, the no-op
@@ -941,8 +996,9 @@ alloc_dispatch_table(void)
     * Mesa we do this to accommodate different versions of libGL and various
     * DRI drivers.
     */
-   GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
-   struct _glapi_table *table = _glapi_new_nop_table(numEntries);
+   int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
+
+   struct _glapi_table *table = _mesa_new_nop_table(numEntries);
 
 #if defined(_WIN32)
    if (table) {
@@ -966,7 +1022,9 @@ alloc_dispatch_table(void)
    }
 #endif
 
+#if USE_GLAPI_NOP_FEATURES
    _glapi_set_nop_handler(nop_handler);
+#endif
 
    return table;
 }
@@ -1111,9 +1169,7 @@ _mesa_initialize_context(struct gl_context *ctx,
       ctx->HasConfig = GL_FALSE;
    }
 
-   if (_mesa_is_desktop_gl(ctx)) {
-      _mesa_override_gl_version(ctx);
-   }
+   _mesa_override_gl_version(ctx);
 
    /* misc one-time initializations */
    one_time_init(ctx);
@@ -1275,7 +1331,6 @@ _mesa_free_context_data( struct gl_context *ctx )
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
 
-   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
    _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
 
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
@@ -1565,7 +1620,8 @@ handle_first_current(struct gl_context *ctx)
          else
             buffer = GL_FRONT;
 
-         _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */);
+         _mesa_drawbuffers(ctx, ctx->DrawBuffer, 1, &buffer,
+                           NULL /* destMask */);
       }
 
       if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
@@ -1578,7 +1634,7 @@ handle_first_current(struct gl_context *ctx)
             bufferIndex = BUFFER_FRONT_LEFT;
          }
 
-         _mesa_readbuffer(ctx, buffer, bufferIndex);
+         _mesa_readbuffer(ctx, ctx->ReadBuffer, buffer, bufferIndex);
       }
    }
 
index fd22f28892c82b158aebf9e71ea3fb6d787353cc..e8732c6175b63b35457e34080c869fa1084a11e7 100644 (file)
@@ -40,14 +40,25 @@ enum mesa_block_class {
    BLOCK_CLASS_64_BITS
 };
 
+/**
+ * Prepare the source or destination resource, including:
+ * - Error checking
+ * - Creating texture wrappers for renderbuffers
+ * \param name  the texture or renderbuffer name
+ * \param target  GL_TEXTURE target or GL_RENDERBUFFER.  For the later, will
+ *                be changed to a compatible GL_TEXTURE target.
+ * \param level  mipmap level
+ * \param tex_obj  returns a pointer to a texture object
+ * \param tex_image  returns a pointer to a texture image
+ * \param tmp_tex  returns temporary texture object name
+ * \return true if success, false if error
+ */
 static bool
 prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
                struct gl_texture_object **tex_obj,
                struct gl_texture_image **tex_image, GLuint *tmp_tex,
                const char *dbg_prefix)
 {
-   struct gl_renderbuffer *rb;
-
    if (name == 0) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glCopyImageSubData(%sName = %d)", dbg_prefix, name);
@@ -87,7 +98,7 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
    }
 
    if (*target == GL_RENDERBUFFER) {
-      rb = _mesa_lookup_renderbuffer(ctx, name);
+      struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
       if (!rb) {
          _mesa_error(ctx, GL_INVALID_VALUE,
                      "glCopyImageSubData(%sName = %u)", dbg_prefix, name);
@@ -169,8 +180,15 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
    return true;
 }
 
+
+/**
+ * Check that the x,y,z,width,height,region is within the texture image
+ * dimensions.
+ * \return true if bounds OK, false if regions is out of bounds
+ */
 static bool
-check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
+check_region_bounds(struct gl_context *ctx,
+                    const struct gl_texture_image *tex_image,
                     int x, int y, int z, int width, int height, int depth,
                     const char *dbg_prefix)
 {
@@ -188,6 +206,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
       return false;
    }
 
+   /* Check X direction */
    if (x + width > tex_image->Width) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glCopyImageSubData(%sX or %sWidth exceeds image bounds)",
@@ -195,6 +214,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
       return false;
    }
 
+   /* Check Y direction */
    switch (tex_image->TexObject->Target) {
    case GL_TEXTURE_1D:
    case GL_TEXTURE_1D_ARRAY:
@@ -215,6 +235,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
       break;
    }
 
+   /* Check Z direction */
    switch (tex_image->TexObject->Target) {
    case GL_TEXTURE_1D:
    case GL_TEXTURE_2D:
@@ -260,7 +281,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
 }
 
 static bool
-compressed_format_compatible(struct gl_context *ctx,
+compressed_format_compatible(const struct gl_context *ctx,
                              GLenum compressedFormat, GLenum otherFormat)
 {
    enum mesa_block_class compressedClass, otherClass;
@@ -348,8 +369,8 @@ compressed_format_compatible(struct gl_context *ctx,
 }
 
 static bool
-copy_format_compatible(struct gl_context *ctx,
-                                GLenum srcFormat, GLenum dstFormat)
+copy_format_compatible(const struct gl_context *ctx,
+                       GLenum srcFormat, GLenum dstFormat)
 {
    /*
     * From ARB_copy_image spec:
@@ -389,7 +410,7 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
    struct gl_texture_object *srcTexObj, *dstTexObj;
    struct gl_texture_image *srcTexImage, *dstTexImage;
    GLuint src_bw, src_bh, dst_bw, dst_bh;
-   int i, srcNewZ, dstNewZ;
+   int i;
 
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
@@ -447,6 +468,8 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
    }
 
    for (i = 0; i < srcDepth; ++i) {
+      int srcNewZ, dstNewZ;
+
       if (srcTexObj->Target == GL_TEXTURE_CUBE_MAP) {
          srcTexImage = srcTexObj->Image[i + srcZ][srcLevel];
          srcNewZ = 0;
index 29851ecb8a40ec1bc739a3b190e9b1339ea91332..bb4591cf152e88aa79669b01e3525cf9fa3a281e 100644 (file)
@@ -65,6 +65,9 @@ _mesa_DepthFunc( GLenum func )
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glDepthFunc %s\n", _mesa_lookup_enum_by_nr(func));
 
+   if (ctx->Depth.Func == func)
+      return;
+
    switch (func) {
    case GL_LESS:    /* (default) pass if incoming z < stored z */
    case GL_GEQUAL:
@@ -80,9 +83,6 @@ _mesa_DepthFunc( GLenum func )
       return;
    }
 
-   if (ctx->Depth.Func == func)
-      return;
-
    FLUSH_VERTICES(ctx, _NEW_DEPTH);
    ctx->Depth.Func = func;
 
index 431c4b48b7979b3c8cf00293a8b0bde3ce2152e7..aafe486fb60c58e68db635750b41d82161bf4f1a 100644 (file)
@@ -7592,28 +7592,6 @@ save_FramebufferTexture(GLenum target, GLenum attachment,
    }
 }
 
-static void GLAPIENTRY
-save_FramebufferTextureFace(GLenum target, GLenum attachment,
-                            GLuint texture, GLint level, GLenum face)
-{
-   Node *n;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE_FACE, 5);
-   if (n) {
-      n[1].e = target;
-      n[2].e = attachment;
-      n[3].ui = texture;
-      n[4].i = level;
-      n[5].e = face;
-   }
-   if (ctx->ExecuteFlag) {
-      CALL_FramebufferTextureFaceARB(ctx->Exec, (target, attachment, texture,
-                                                 level, face));
-   }
-}
-
-
 
 static void GLAPIENTRY
 save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
@@ -8873,11 +8851,6 @@ execute_list(struct gl_context *ctx, GLuint list)
             CALL_FramebufferTexture(ctx->Exec, (n[1].e, n[2].e,
                                                    n[3].ui, n[4].i));
             break;
-         case OPCODE_FRAMEBUFFER_TEXTURE_FACE:
-            CALL_FramebufferTextureFaceARB(ctx->Exec, (n[1].e, n[2].e,
-                                                       n[3].ui, n[4].i, n[5].e));
-            break;
-
          /* GL_ARB_sync */
          case OPCODE_WAIT_SYNC:
             {
@@ -9644,10 +9617,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_BlendEquationiARB(table, save_BlendEquationi);
    SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei);
 
-   /* GL_ARB_geometry_shader4 */
+   /* OpenGL 3.2 */
    SET_ProgramParameteri(table, save_ProgramParameteri);
    SET_FramebufferTexture(table, save_FramebufferTexture);
-   SET_FramebufferTextureFaceARB(table, save_FramebufferTextureFace);
 
    /* GL_NV_conditional_render */
    SET_BeginConditionalRender(table, save_BeginConditionalRender);
index 2aa1deb635f4f3dd0359c24bc32df2b58610feab..b3406665d94f9cfde19aa923d2996383d9e059ca 100644 (file)
@@ -39,6 +39,7 @@
 #include "mtypes.h"
 #include "version.h"
 #include "util/hash_table.h"
+#include "util/simple_list.h"
 
 static mtx_t DynamicIDMutex = _MTX_INITIALIZER_NP;
 static GLuint NextDynamicID = 1;
@@ -1411,6 +1412,26 @@ should_output(struct gl_context *ctx, GLenum error, const char *fmtString)
 }
 
 
+void
+_mesa_gl_vdebug(struct gl_context *ctx,
+                GLuint *id,
+                enum mesa_debug_source source,
+                enum mesa_debug_type type,
+                enum mesa_debug_severity severity,
+                const char *fmtString,
+                va_list args)
+{
+   char s[MAX_DEBUG_MESSAGE_LENGTH];
+   int len;
+
+   debug_get_id(id);
+
+   len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+
+   log_msg(ctx, source, type, *id, severity, len, s);
+}
+
+
 void
 _mesa_gl_debug(struct gl_context *ctx,
                GLuint *id,
@@ -1419,17 +1440,10 @@ _mesa_gl_debug(struct gl_context *ctx,
                enum mesa_debug_severity severity,
                const char *fmtString, ...)
 {
-   char s[MAX_DEBUG_MESSAGE_LENGTH];
-   int len;
    va_list args;
-
-   debug_get_id(id);
-
    va_start(args, fmtString);
-   len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+   _mesa_gl_vdebug(ctx, id, source, type, severity, fmtString, args);
    va_end(args);
-
-   log_msg(ctx, source, type, *id, severity, len, s);
 }
 
 
index e6dc9b5f1b9d4bf04715e96d05bee1b1c3dd1d19..24f234f7f103cf44c6891bee7f517ed4199475c7 100644 (file)
@@ -75,6 +75,15 @@ _mesa_log(const char *fmtString, ...) PRINTFLIKE(1, 2);
 extern FILE *
 _mesa_get_log_file(void);
 
+extern void
+_mesa_gl_vdebug(struct gl_context *ctx,
+                GLuint *id,
+                enum mesa_debug_source source,
+                enum mesa_debug_type type,
+                enum mesa_debug_severity severity,
+                const char *fmtString,
+                va_list args);
+
 extern void
 _mesa_gl_debug(struct gl_context *ctx,
                GLuint *id,
index f7ce0642aef44c9f0f65d3ba2460520770c25fae..4176a69ed7c9a85a69b35ac0e2e18d70d2d540f3 100644 (file)
@@ -104,7 +104,7 @@ static const struct extension extension_table[] = {
    { "GL_ARB_depth_clamp",                         o(ARB_depth_clamp),                         GL,             2003 },
    { "GL_ARB_depth_texture",                       o(ARB_depth_texture),                       GLL,            2001 },
    { "GL_ARB_derivative_control",                  o(ARB_derivative_control),                  GL,             2014 },
-   { "GL_ARB_direct_state_access",                 o(dummy_false),                             GL,             2014 },
+   { "GL_ARB_direct_state_access",                 o(dummy_true),                              GLC,            2014 },
    { "GL_ARB_draw_buffers",                        o(dummy_true),                              GL,             2002 },
    { "GL_ARB_draw_buffers_blend",                  o(ARB_draw_buffers_blend),                  GL,             2009 },
    { "GL_ARB_draw_elements_base_vertex",           o(ARB_draw_elements_base_vertex),           GL,             2009 },
@@ -117,6 +117,7 @@ static const struct extension extension_table[] = {
    { "GL_ARB_fragment_program",                    o(ARB_fragment_program),                    GLL,            2002 },
    { "GL_ARB_fragment_program_shadow",             o(ARB_fragment_program_shadow),             GLL,            2003 },
    { "GL_ARB_fragment_shader",                     o(ARB_fragment_shader),                     GL,             2002 },
+   { "GL_ARB_framebuffer_no_attachments",          o(ARB_framebuffer_no_attachments),          GL,             2012 },
    { "GL_ARB_framebuffer_object",                  o(ARB_framebuffer_object),                  GL,             2005 },
    { "GL_ARB_framebuffer_sRGB",                    o(EXT_framebuffer_sRGB),                    GL,             1998 },
    { "GL_ARB_get_program_binary",                  o(dummy_true),                              GL,             2010 },
index 27cf97f177853cfffaba8d3adc329f753d8f7032..f8dcf122d99aa6cf108b63f35580c7fe4304e9df 100644 (file)
@@ -120,6 +120,27 @@ _mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
 }
 
 
+/**
+ * A convenience function for direct state access that throws
+ * GL_INVALID_OPERATION if the renderbuffer doesn't exist.
+ */
+struct gl_renderbuffer *
+_mesa_lookup_renderbuffer_err(struct gl_context *ctx, GLuint id,
+                              const char *func)
+{
+   struct gl_renderbuffer *rb;
+
+   rb = _mesa_lookup_renderbuffer(ctx, id);
+   if (!rb || rb == &DummyRenderbuffer) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(non-existent renderbuffer %u)", func, id);
+      return NULL;
+   }
+
+   return rb;
+}
+
+
 /**
  * Helper routine for getting a gl_framebuffer.
  */
@@ -137,6 +158,27 @@ _mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
 }
 
 
+/**
+ * A convenience function for direct state access that throws
+ * GL_INVALID_OPERATION if the framebuffer doesn't exist.
+ */
+struct gl_framebuffer *
+_mesa_lookup_framebuffer_err(struct gl_context *ctx, GLuint id,
+                             const char *func)
+{
+   struct gl_framebuffer *fb;
+
+   fb = _mesa_lookup_framebuffer(ctx, id);
+   if (!fb || fb == &DummyFramebuffer) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(non-existent framebuffer %u)", func, id);
+      return NULL;
+   }
+
+   return fb;
+}
+
+
 /**
  * Mark the given framebuffer as invalid.  This will force the
  * test for framebuffer completeness to be done before the framebuffer
@@ -423,7 +465,7 @@ set_texture_attachment(struct gl_context *ctx,
                        struct gl_framebuffer *fb,
                        struct gl_renderbuffer_attachment *att,
                        struct gl_texture_object *texObj,
-                       GLenum texTarget, GLuint level, GLuint zoffset,
+                       GLenum texTarget, GLuint level, GLuint layer,
                        GLboolean layered)
 {
    struct gl_renderbuffer *rb = att->Renderbuffer;
@@ -447,7 +489,7 @@ set_texture_attachment(struct gl_context *ctx,
    /* always update these fields */
    att->TextureLevel = level;
    att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
-   att->Zoffset = zoffset;
+   att->Zoffset = layer;
    att->Layered = layered;
    att->Complete = GL_FALSE;
 
@@ -479,9 +521,10 @@ set_renderbuffer_attachment(struct gl_context *ctx,
  * Attach a renderbuffer object to a framebuffer object.
  */
 void
-_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
-                               struct gl_framebuffer *fb,
-                               GLenum attachment, struct gl_renderbuffer *rb)
+_mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx,
+                                 struct gl_framebuffer *fb,
+                                 GLenum attachment,
+                                 struct gl_renderbuffer *rb)
 {
    struct gl_renderbuffer_attachment *att;
 
@@ -914,6 +957,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
    fb->Height = 0;
    fb->_AllColorBuffersFixedPoint = GL_TRUE;
    fb->_HasSNormOrFloatColorBuffer = GL_FALSE;
+   fb->_HasAttachments = true;
 
    /* Start at -2 to more easily loop over all attachment points.
     *  -2: depth buffer
@@ -1112,14 +1156,48 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
       } else if (att_layer_count > max_layer_count) {
          max_layer_count = att_layer_count;
       }
+
+      /*
+       * The extension GL_ARB_framebuffer_no_attachments places additional
+       * requirement on each attachment. Those additional requirements are
+       * tighter that those of previous versions of GL. In interest of better
+       * compatibility, we will not enforce these restrictions. For the record
+       * those additional restrictions are quoted below:
+       *
+       * "The width and height of image are greater than zero and less than or
+       *  equal to the values of the implementation-dependent limits
+       *  MAX_FRAMEBUFFER_WIDTH and MAX_FRAMEBUFFER_HEIGHT, respectively."
+       *
+       * "If <image> is a three-dimensional texture or a one- or two-dimensional
+       *  array texture and the attachment is layered, the depth or layer count
+       *  of the texture is less than or equal to the implementation-dependent
+       *  limit MAX_FRAMEBUFFER_LAYERS."
+       *
+       * "If image has multiple samples, its sample count is less than or equal
+       *  to the value of the implementation-dependent limit
+       *  MAX_FRAMEBUFFER_SAMPLES."
+       *
+       * The same requirements are also in place for GL 4.5,
+       * Section 9.4.1 "Framebuffer Attachment Completeness", pg 310-311
+       */
    }
 
    fb->MaxNumLayers = max_layer_count;
 
    if (numImages == 0) {
-      fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
-      fbo_incomplete(ctx, "no attachments", -1);
-      return;
+      fb->_HasAttachments = false;
+
+      if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+         fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+         fbo_incomplete(ctx, "no attachments", -1);
+         return;
+      }
+
+      if (fb->DefaultGeometry.Width == 0 || fb->DefaultGeometry.Height == 0) {
+         fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+         fbo_incomplete(ctx, "no attachments and default width or height is 0", -1);
+         return;
+      }
    }
 
    if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
@@ -1184,8 +1262,10 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
        * renderbuffers/textures are different sizes, the framebuffer
        * width/height will be set to the smallest width/height.
        */
-      fb->Width = minWidth;
-      fb->Height = minHeight;
+      if (numImages != 0) {
+         fb->Width = minWidth;
+         fb->Height = minHeight;
+      }
 
       /* finally, update the visual info for the framebuffer */
       _mesa_update_framebuffer_visual(ctx, fb);
@@ -1291,6 +1371,131 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
    bind_renderbuffer(target, renderbuffer, true);
 }
 
+static void
+framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
+                       GLenum pname, GLint param, const char *func)
+{
+   switch (pname) {
+   case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+      if (param < 0 || param > ctx->Const.MaxFramebufferWidth)
+        _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+      else
+         fb->DefaultGeometry.Width = param;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+      if (param < 0 || param > ctx->Const.MaxFramebufferHeight)
+        _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+      else
+         fb->DefaultGeometry.Height = param;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_LAYERS:
+      if (param < 0 || param > ctx->Const.MaxFramebufferLayers)
+        _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+      else
+         fb->DefaultGeometry.Layers = param;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+      if (param < 0 || param > ctx->Const.MaxFramebufferSamples)
+        _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+      else
+        fb->DefaultGeometry.NumSamples = param;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+      fb->DefaultGeometry.FixedSampleLocations = param;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "%s(pname=0x%x)", func, pname);
+   }
+}
+
+void GLAPIENTRY
+_mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+
+   if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glFramebufferParameteriv not supported "
+                  "(ARB_framebuffer_no_attachments not implemented)");
+      return;
+   }
+
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glFramebufferParameteri(target=0x%x)", target);
+      return;
+   }
+
+   /* check framebuffer binding */
+   if (_mesa_is_winsys_fbo(fb)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glFramebufferParameteri");
+      return;
+   }
+
+   framebuffer_parameteri(ctx, fb, pname, param, "glFramebufferParameteri");
+}
+
+static void
+get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb,
+                            GLenum pname, GLint *params, const char *func)
+{
+   switch (pname) {
+   case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+      *params = fb->DefaultGeometry.Width;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+      *params = fb->DefaultGeometry.Height;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_LAYERS:
+      *params = fb->DefaultGeometry.Layers;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+      *params = fb->DefaultGeometry.NumSamples;
+      break;
+   case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+      *params = fb->DefaultGeometry.FixedSampleLocations;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "%s(pname=0x%x)", func, pname);
+   }
+}
+
+void GLAPIENTRY
+_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+
+   if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetFramebufferParameteriv not supported "
+                  "(ARB_framebuffer_no_attachments not implemented)");
+      return;
+   }
+
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetFramebufferParameteriv(target=0x%x)", target);
+      return;
+   }
+
+   /* check framebuffer binding */
+   if (_mesa_is_winsys_fbo(fb)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetFramebufferParameteriv");
+      return;
+   }
+
+   get_framebuffer_parameteriv(ctx, fb, pname, params,
+                               "glGetFramebufferParameteriv");
+}
+
 
 /**
  * Remove the specified renderbuffer or texture from any attachment point in
@@ -2396,15 +2601,23 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
 }
 
 
-void GLAPIENTRY
-_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
+/**
+ * This is the implementation for glGenFramebuffers and glCreateFramebuffers.
+ * It is not exposed to the rest of Mesa to encourage the use of
+ * nameless buffers in driver internals.
+ */
+static void
+create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa)
 {
    GET_CURRENT_CONTEXT(ctx);
    GLuint first;
    GLint i;
+   struct gl_framebuffer *fb;
+
+   const char *func = dsa ? "glCreateFramebuffers" : "glGenFramebuffers";
 
    if (n < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
       return;
    }
 
@@ -2416,31 +2629,43 @@ _mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
    for (i = 0; i < n; i++) {
       GLuint name = first + i;
       framebuffers[i] = name;
-      /* insert dummy placeholder into hash table */
+
+      if (dsa) {
+         fb = ctx->Driver.NewFramebuffer(ctx, framebuffers[i]);
+         if (!fb) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+            return;
+         }
+      }
+      else
+         fb = &DummyFramebuffer;
+
       mtx_lock(&ctx->Shared->Mutex);
-      _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
+      _mesa_HashInsert(ctx->Shared->FrameBuffers, name, fb);
       mtx_unlock(&ctx->Shared->Mutex);
    }
 }
 
 
-GLenum GLAPIENTRY
-_mesa_CheckFramebufferStatus(GLenum target)
+void GLAPIENTRY
+_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
 {
-   struct gl_framebuffer *buffer;
-   GET_CURRENT_CONTEXT(ctx);
+   create_framebuffers(n, framebuffers, false);
+}
 
-   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
 
-   if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
-                  _mesa_lookup_enum_by_nr(target));
+void GLAPIENTRY
+_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+   create_framebuffers(n, framebuffers, true);
+}
 
-   buffer = get_framebuffer_target(ctx, target);
-   if (!buffer) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
-      return 0;
-   }
+
+GLenum
+_mesa_check_framebuffer_status(struct gl_context *ctx,
+                               struct gl_framebuffer *buffer)
+{
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
 
    if (_mesa_is_winsys_fbo(buffer)) {
       /* EGL_KHR_surfaceless_context allows the winsys FBO to be incomplete. */
@@ -2461,6 +2686,67 @@ _mesa_CheckFramebufferStatus(GLenum target)
 }
 
 
+GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatus(GLenum target)
+{
+   struct gl_framebuffer *fb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
+                  _mesa_lookup_enum_by_nr(target));
+
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glCheckFramebufferStatus(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
+      return 0;
+   }
+
+   return _mesa_check_framebuffer_status(ctx, fb);
+}
+
+
+GLenum GLAPIENTRY
+_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
+{
+   struct gl_framebuffer *fb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   /* Validate the target (for conformance's sake) and grab a reference to the
+    * default framebuffer in case framebuffer = 0.
+    * Section 9.4 Framebuffer Completeness of the OpenGL 4.5 core spec
+    * (30.10.2014, PDF page 336) says:
+    *    "If framebuffer is zero, then the status of the default read or
+    *    draw framebuffer (as determined by target) is returned."
+    */
+   switch (target) {
+      case GL_DRAW_FRAMEBUFFER:
+      case GL_FRAMEBUFFER:
+         fb = ctx->WinSysDrawBuffer;
+         break;
+      case GL_READ_FRAMEBUFFER:
+         fb = ctx->WinSysReadBuffer;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "glCheckNamedFramebufferStatus(invalid target %s)",
+                     _mesa_lookup_enum_by_nr(target));
+         return 0;
+   }
+
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glCheckNamedFramebufferStatus");
+      if (!fb)
+         return 0;
+   }
+
+   return _mesa_check_framebuffer_status(ctx, fb);
+}
+
+
 /**
  * Replicate the src attachment point. Used by framebuffer_texture() when
  * the same texture is attached at GL_DEPTH_ATTACHMENT and
@@ -2487,157 +2773,321 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
 
 
 /**
- * Common code called by glFramebufferTexture1D/2D/3D() and
- * glFramebufferTextureLayer().
+ * Common code called by gl*FramebufferTexture*() to retrieve the correct
+ * texture object pointer.
  *
- * \param textarget is the textarget that was passed to the
- * glFramebufferTexture...() function, or 0 if the corresponding function
- * doesn't have a textarget parameter.
+ * \param texObj where the pointer to the texture object is returned.  Note
+ * that a successful call may return texObj = NULL.
  *
- * \param layered is true if this function was called from
- * glFramebufferTexture(), false otherwise.
+ * \return true if no errors, false if errors
  */
-static void
-framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
-                    GLenum attachment, GLenum textarget, GLuint texture,
-                    GLint level, GLuint zoffset, GLboolean layered)
+static bool
+get_texture_for_framebuffer(struct gl_context *ctx, GLuint texture,
+                            bool layered, const char *caller,
+                            struct gl_texture_object **texObj)
 {
-   struct gl_renderbuffer_attachment *att;
-   struct gl_texture_object *texObj = NULL;
-   struct gl_framebuffer *fb;
-   GLenum maxLevelsTarget;
+   *texObj = NULL; /* This will get returned if texture = 0. */
 
-   fb = get_framebuffer_target(ctx, target);
-   if (!fb) {
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glFramebufferTexture%s(target=0x%x)", caller, target);
-      return;
-   }
+   if (!texture)
+      return true;
 
-   /* check framebuffer binding */
-   if (_mesa_is_winsys_fbo(fb)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glFramebufferTexture%s", caller);
-      return;
+   *texObj = _mesa_lookup_texture(ctx, texture);
+   if (*texObj == NULL || (*texObj)->Target == 0) {
+      /* Can't render to a non-existent texture object.
+       *
+       * The OpenGL 4.5 core spec (02.02.2015) in Section 9.2 Binding and
+       * Managing Framebuffer Objects specifies a different error
+       * depending upon the calling function (PDF pages 325-328).
+       * *FramebufferTexture (where layered = GL_TRUE) throws invalid
+       * value, while the other commands throw invalid operation (where
+       * layered = GL_FALSE).
+       */
+      const GLenum error = layered ? GL_INVALID_VALUE :
+                           GL_INVALID_OPERATION;
+      _mesa_error(ctx, error,
+                  "%s(non-existent texture %u)", caller, texture);
+      return false;
    }
 
-   /* The textarget, level, and zoffset parameters are only validated if
-    * texture is non-zero.
-    */
-   if (texture) {
-      GLboolean err = GL_TRUE;
-
-      texObj = _mesa_lookup_texture(ctx, texture);
-      if (texObj != NULL) {
-         if (textarget == 0) {
-            if (layered) {
-               /* We're being called by glFramebufferTexture() and textarget
-                * is not used.
-                */
-               switch (texObj->Target) {
-               case GL_TEXTURE_3D:
-               case GL_TEXTURE_1D_ARRAY_EXT:
-               case GL_TEXTURE_2D_ARRAY_EXT:
-               case GL_TEXTURE_CUBE_MAP:
-               case GL_TEXTURE_CUBE_MAP_ARRAY:
-               case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
-                  err = false;
-                  break;
-               case GL_TEXTURE_1D:
-               case GL_TEXTURE_2D:
-               case GL_TEXTURE_RECTANGLE:
-               case GL_TEXTURE_2D_MULTISAMPLE:
-                  /* These texture types are valid to pass to
-                   * glFramebufferTexture(), but since they aren't layered, it
-                   * is equivalent to calling glFramebufferTexture{1D,2D}().
-                   */
-                  err = false;
-                  layered = false;
-                  textarget = texObj->Target;
-                  break;
-               default:
-                  err = true;
-                  break;
-               }
-            } else {
-               /* We're being called by glFramebufferTextureLayer() and
-                * textarget is not used.  The only legal texture types for
-                * that function are 3D and 1D/2D arrays textures.
-                */
-               err = (texObj->Target != GL_TEXTURE_3D) &&
-                  (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
-                  (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
-                  (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
-                  (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
-            }
-         }
-         else {
-            /* Make sure textarget is consistent with the texture's type */
-            err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
-                ? !_mesa_is_cube_face(textarget)
-                : (texObj->Target != textarget);
-         }
-      }
-      else {
-         /* can't render to a non-existant texture */
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferTexture%s(non existant texture)",
-                     caller);
-         return;
-      }
+   return true;
+}
 
-      if (err) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferTexture%s(texture target mismatch)",
-                     caller);
-         return;
-      }
 
-      if (texObj->Target == GL_TEXTURE_3D) {
-         const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
-         if (zoffset >= maxSize) {
-            _mesa_error(ctx, GL_INVALID_VALUE,
-                        "glFramebufferTexture%s(zoffset)", caller);
-            return;
-         }
-      }
-      else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
-               (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) ||
-               (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
-               (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
-         if (zoffset >= ctx->Const.MaxArrayTextureLayers) {
-            _mesa_error(ctx, GL_INVALID_VALUE,
-                        "glFramebufferTexture%s(layer)", caller);
-            return;
-         }
-      }
+/**
+ * Common code called by gl*FramebufferTexture() to verify the texture target
+ * and decide whether or not the attachment should truly be considered
+ * layered.
+ *
+ * \param layered true if attachment should be considered layered, false if
+ * not
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_layered_texture_target(struct gl_context *ctx, GLenum target,
+                             const char *caller, GLboolean *layered)
+{
+   *layered = GL_TRUE;
 
-      maxLevelsTarget = textarget ? textarget : texObj->Target;
-      if ((level < 0) ||
-          (level >= _mesa_max_texture_levels(ctx, maxLevelsTarget))) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glFramebufferTexture%s(level)", caller);
-         return;
-      }
+   switch (target) {
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_1D_ARRAY_EXT:
+   case GL_TEXTURE_2D_ARRAY_EXT:
+   case GL_TEXTURE_CUBE_MAP:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      return true;
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_RECTANGLE:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+      /* These texture types are valid to pass to
+       * glFramebufferTexture(), but since they aren't layered, it
+       * is equivalent to calling glFramebufferTexture{1D,2D}().
+       */
+      *layered = GL_FALSE;
+      return true;
    }
 
-   att = get_attachment(ctx, fb, attachment);
-   if (att == NULL) {
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glFramebufferTexture%s(attachment)", caller);
-      return;
-   }
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "%s(invalid texture target %s)", caller,
+               _mesa_lookup_enum_by_nr(target));
+   return false;
+}
 
-   FLUSH_VERTICES(ctx, _NEW_BUFFERS);
 
-   mtx_lock(&fb->Mutex);
-   if (texObj) {
+/**
+ * Common code called by gl*FramebufferTextureLayer() to verify the texture
+ * target.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_texture_target(struct gl_context *ctx, GLenum target,
+                     const char *caller)
+{
+   /* We're being called by glFramebufferTextureLayer().
+    * The only legal texture types for that function are 3D,
+    * cube-map, and 1D/2D/cube-map array textures.
+    *
+    * We don't need to check for GL_ARB_texture_cube_map_array because the
+    * application wouldn't have been able to create a texture with a
+    * GL_TEXTURE_CUBE_MAP_ARRAY target if the extension were not enabled.
+    */
+   switch (target) {
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_1D_ARRAY:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      return true;
+   case GL_TEXTURE_CUBE_MAP:
+      /* We don't need to check the extension (GL_ARB_direct_state_access) or
+       * GL version (4.5) for GL_TEXTURE_CUBE_MAP because DSA is always
+       * enabled in core profile.  This can be called from
+       * _mesa_FramebufferTextureLayer in compatibility profile (OpenGL 3.0),
+       * so we do have to check the profile.
+       */
+      return ctx->API == API_OPENGL_CORE;
+   }
+
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "%s(invalid texture target %s)", caller,
+               _mesa_lookup_enum_by_nr(target));
+   return false;
+}
+
+
+/**
+ * Common code called by glFramebufferTexture*D() to verify the texture
+ * target.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_textarget(struct gl_context *ctx, int dims, GLenum target,
+                GLenum textarget, const char *caller)
+{
+   bool err = false;
+
+   switch (dims) {
+   case 1:
+      switch (textarget) {
+      case GL_TEXTURE_1D:
+         break;
+      case GL_TEXTURE_1D_ARRAY:
+         err = !ctx->Extensions.EXT_texture_array;
+         break;
+      default:
+         err = true;
+      }
+      break;
+   case 2:
+      switch (textarget) {
+      case GL_TEXTURE_2D:
+         break;
+      case GL_TEXTURE_RECTANGLE:
+         err = _mesa_is_gles(ctx)
+            || !ctx->Extensions.NV_texture_rectangle;
+         break;
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+         err = !ctx->Extensions.ARB_texture_cube_map;
+         break;
+      case GL_TEXTURE_2D_ARRAY:
+         err = (_mesa_is_gles(ctx) && ctx->Version < 30)
+               || !ctx->Extensions.EXT_texture_array;
+         break;
+      case GL_TEXTURE_2D_MULTISAMPLE:
+      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+         err = _mesa_is_gles(ctx)
+               || !ctx->Extensions.ARB_texture_multisample;
+         break;
+      default:
+         err = true;
+      }
+      break;
+   case 3:
+      if (textarget != GL_TEXTURE_3D)
+         err = true;
+      break;
+   default:
+      err = true;
+   }
+
+   if (err) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(invalid textarget %s)",
+                  caller, _mesa_lookup_enum_by_nr(textarget));
+      return false;
+   }
+
+   /* Make sure textarget is consistent with the texture's type */
+   err = (target == GL_TEXTURE_CUBE_MAP) ?
+          !_mesa_is_cube_face(textarget): (target != textarget);
+
+   if (err) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(mismatched texture target)", caller);
+      return false;
+   }
+
+   return true;
+}
+
+
+/**
+ * Common code called by gl*FramebufferTextureLayer() and
+ * glFramebufferTexture3D() to validate the layer.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_layer(struct gl_context *ctx, GLenum target, GLint layer,
+            const char *caller)
+{
+   /* Page 306 (page 328 of the PDF) of the OpenGL 4.5 (Core Profile)
+    * spec says:
+    *
+    *    "An INVALID_VALUE error is generated if texture is non-zero
+    *     and layer is negative."
+    */
+   if (layer < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(layer %u < 0)", caller, layer);
+      return false;
+   }
+
+   if (target == GL_TEXTURE_3D) {
+      const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
+      if (layer >= maxSize) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "%s(invalid layer %u)", caller, layer);
+         return false;
+      }
+   }
+   else if ((target == GL_TEXTURE_1D_ARRAY) ||
+            (target == GL_TEXTURE_2D_ARRAY) ||
+            (target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
+            (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
+      if (layer >= ctx->Const.MaxArrayTextureLayers) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "%s(layer %u >= GL_MAX_ARRAY_TEXTURE_LAYERS)",
+                     caller, layer);
+         return false;
+      }
+   }
+   else if (target == GL_TEXTURE_CUBE_MAP) {
+      if (layer >= 6) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "%s(layer %u >= 6)", caller, layer);
+         return false;
+      }
+   }
+
+   return true;
+}
+
+
+/**
+ * Common code called by all gl*FramebufferTexture*() entry points to verify
+ * the level.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_level(struct gl_context *ctx, GLenum target, GLint level,
+            const char *caller)
+{
+   if ((level < 0) ||
+       (level >= _mesa_max_texture_levels(ctx, target))) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(invalid level %d)", caller, level);
+      return false;
+   }
+
+   return true;
+}
+
+
+void
+_mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
+                          GLenum attachment,
+                          struct gl_texture_object *texObj, GLenum textarget,
+                          GLint level, GLuint layer, GLboolean layered,
+                          const char *caller)
+{
+   struct gl_renderbuffer_attachment *att;
+
+   /* The window-system framebuffer object is immutable */
+   if (_mesa_is_winsys_fbo(fb)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(window-system framebuffer)",
+                  caller);
+      return;
+   }
+
+   /* Not a hash lookup, so we can afford to get the attachment here. */
+   att = get_attachment(ctx, fb, attachment);
+   if (att == NULL) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
+                  _mesa_lookup_enum_by_nr(attachment));
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+   mtx_lock(&fb->Mutex);
+   if (texObj) {
       if (attachment == GL_DEPTH_ATTACHMENT &&
           texObj == fb->Attachment[BUFFER_STENCIL].Texture &&
           level == fb->Attachment[BUFFER_STENCIL].TextureLevel &&
           _mesa_tex_target_to_face(textarget) ==
           fb->Attachment[BUFFER_STENCIL].CubeMapFace &&
-          zoffset == fb->Attachment[BUFFER_STENCIL].Zoffset) {
+          layer == fb->Attachment[BUFFER_STENCIL].Zoffset) {
          /* The texture object is already attached to the stencil attachment
           * point. Don't create a new renderbuffer; just reuse the stencil
           * attachment's. This is required to prevent a GL error in
@@ -2650,13 +3100,14 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
                  level == fb->Attachment[BUFFER_DEPTH].TextureLevel &&
                  _mesa_tex_target_to_face(textarget) ==
                  fb->Attachment[BUFFER_DEPTH].CubeMapFace &&
-                 zoffset == fb->Attachment[BUFFER_DEPTH].Zoffset) {
+                 layer == fb->Attachment[BUFFER_DEPTH].Zoffset) {
          /* As above, but with depth and stencil transposed. */
          reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
                                               BUFFER_DEPTH);
       } else {
          set_texture_attachment(ctx, fb, att, texObj, textarget,
-                                      level, zoffset, layered);
+                                level, layer, layered);
+
          if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
             /* Above we created a new renderbuffer and attached it to the
              * depth attachment point. Now attach it to the stencil attachment
@@ -2692,116 +3143,157 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
 }
 
 
-void GLAPIENTRY
-_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
-                           GLenum textarget, GLuint texture, GLint level)
+static void
+framebuffer_texture_with_dims(int dims, GLenum target,
+                              GLenum attachment, GLenum textarget,
+                              GLuint texture, GLint level, GLint layer,
+                              const char *caller)
 {
    GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+   struct gl_texture_object *texObj;
 
-   if (texture != 0) {
-      GLboolean error;
+   /* Get the framebuffer object */
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
+                  _mesa_lookup_enum_by_nr(target));
+      return;
+   }
 
-      switch (textarget) {
-      case GL_TEXTURE_1D:
-         error = GL_FALSE;
-         break;
-      case GL_TEXTURE_1D_ARRAY:
-         error = !ctx->Extensions.EXT_texture_array;
-         break;
-      default:
-         error = GL_TRUE;
-      }
+   /* Get the texture object */
+   if (!get_texture_for_framebuffer(ctx, texture, false, caller, &texObj))
+      return;
 
-      if (error) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferTexture1D(textarget=%s)",
-                     _mesa_lookup_enum_by_nr(textarget));
+   if (texObj) {
+      if (!check_textarget(ctx, dims, texObj->Target, textarget, caller))
+         return;
+
+      if ((dims == 3) && !check_layer(ctx, texObj->Target, layer, caller))
          return;
-      }
    }
 
-   framebuffer_texture(ctx, "1D", target, attachment, textarget, texture,
-                       level, 0, GL_FALSE);
+   if (!check_level(ctx, textarget, level, caller))
+      return;
+
+   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
+                             layer, GL_FALSE, caller);
 }
 
 
 void GLAPIENTRY
-_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
+_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
                            GLenum textarget, GLuint texture, GLint level)
 {
-   GET_CURRENT_CONTEXT(ctx);
-
-   if (texture != 0) {
-      GLboolean error;
-
-      switch (textarget) {
-      case GL_TEXTURE_2D:
-         error = GL_FALSE;
-         break;
-      case GL_TEXTURE_RECTANGLE:
-         error = _mesa_is_gles(ctx)
-            || !ctx->Extensions.NV_texture_rectangle;
-         break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-         error = !ctx->Extensions.ARB_texture_cube_map;
-         break;
-      case GL_TEXTURE_2D_ARRAY:
-         error = (_mesa_is_gles(ctx) && ctx->Version < 30)
-            || !ctx->Extensions.EXT_texture_array;
-         break;
-      case GL_TEXTURE_2D_MULTISAMPLE:
-      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
-         error = _mesa_is_gles(ctx)
-            || !ctx->Extensions.ARB_texture_multisample;
-         break;
-      default:
-         error = GL_TRUE;
-      }
+   framebuffer_texture_with_dims(1, target, attachment, textarget, texture,
+                                 level, 0, "glFramebufferTexture1D");
+}
 
-      if (error) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferTexture2D(textarget=%s)",
-                     _mesa_lookup_enum_by_nr(textarget));
-         return;
-      }
-   }
 
-   framebuffer_texture(ctx, "2D", target, attachment, textarget, texture,
-                       level, 0, GL_FALSE);
+void GLAPIENTRY
+_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
+                           GLenum textarget, GLuint texture, GLint level)
+{
+   framebuffer_texture_with_dims(2, target, attachment, textarget, texture,
+                                 level, 0, "glFramebufferTexture2D");
 }
 
 
 void GLAPIENTRY
 _mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
                            GLenum textarget, GLuint texture,
-                           GLint level, GLint zoffset)
+                           GLint level, GLint layer)
+{
+   framebuffer_texture_with_dims(3, target, attachment, textarget, texture,
+                                 level, layer, "glFramebufferTexture3D");
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
+                              GLuint texture, GLint level, GLint layer)
 {
    GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+   struct gl_texture_object *texObj;
+   GLenum textarget = 0;
 
-   if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glFramebufferTexture3D(textarget)");
+   const char *func = "glFramebufferTextureLayer";
+
+   /* Get the framebuffer object */
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glFramebufferTextureLayer(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
       return;
    }
 
-   framebuffer_texture(ctx, "3D", target, attachment, textarget, texture,
-                       level, zoffset, GL_FALSE);
+   /* Get the texture object */
+   if (!get_texture_for_framebuffer(ctx, texture, false, func, &texObj))
+      return;
+
+   if (texObj) {
+      if (!check_texture_target(ctx, texObj->Target, func))
+         return;
+
+      if (!check_layer(ctx, texObj->Target, layer, func))
+         return;
+
+      if (!check_level(ctx, texObj->Target, level, func))
+         return;
+
+      if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+         assert(layer >= 0 && layer < 6);
+         textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
+         layer = 0;
+      }
+   }
+
+   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
+                             layer, GL_FALSE, func);
 }
 
 
 void GLAPIENTRY
-_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
-                              GLuint texture, GLint level, GLint layer)
+_mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
+                                   GLuint texture, GLint level, GLint layer)
 {
    GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+   struct gl_texture_object *texObj;
+   GLenum textarget = 0;
+
+   const char *func = "glNamedFramebufferTextureLayer";
+
+   /* Get the framebuffer object */
+   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
+   if (!fb)
+      return;
 
-   framebuffer_texture(ctx, "Layer", target, attachment, 0, texture,
-                       level, layer, GL_FALSE);
+   /* Get the texture object */
+   if (!get_texture_for_framebuffer(ctx, texture, false, func, &texObj))
+      return;
+
+   if (texObj) {
+      if (!check_texture_target(ctx, texObj->Target, func))
+         return;
+
+      if (!check_layer(ctx, texObj->Target, layer, func))
+         return;
+
+      if (!check_level(ctx, texObj->Target, level, func))
+         return;
+
+      if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+         assert(layer >= 0 && layer < 6);
+         textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
+         layer = 0;
+      }
+   }
+
+   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
+                             layer, GL_FALSE, func);
 }
 
 
@@ -2810,82 +3302,115 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
                          GLuint texture, GLint level)
 {
    GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+   struct gl_texture_object *texObj;
+   GLboolean layered;
 
-   if (_mesa_has_geometry_shaders(ctx)) {
-      framebuffer_texture(ctx, "", target, attachment, 0, texture,
-                          level, 0, GL_TRUE);
-   } else {
+   const char *func = "FramebufferTexture";
+
+   if (!_mesa_has_geometry_shaders(ctx)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "unsupported function (glFramebufferTexture) called");
+      return;
+   }
+
+   /* Get the framebuffer object */
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glFramebufferTexture(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
+      return;
    }
+
+   /* Get the texture object */
+   if (!get_texture_for_framebuffer(ctx, texture, true, func, &texObj))
+      return;
+
+   if (texObj) {
+      if (!check_layered_texture_target(ctx, texObj->Target, func, &layered))
+         return;
+
+      if (!check_level(ctx, texObj->Target, level, func))
+         return;
+   }
+
+   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
+                             0, layered, func);
 }
 
 
 void GLAPIENTRY
-_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
-                              GLenum renderbufferTarget,
-                              GLuint renderbuffer)
+_mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
+                              GLuint texture, GLint level)
 {
-   struct gl_renderbuffer_attachment *att;
-   struct gl_framebuffer *fb;
-   struct gl_renderbuffer *rb;
    GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+   struct gl_texture_object *texObj;
+   GLboolean layered;
 
-   fb = get_framebuffer_target(ctx, target);
-   if (!fb) {
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glFramebufferRenderbuffer(target)");
+   const char *func = "glNamedFramebufferTexture";
+
+   if (!_mesa_has_geometry_shaders(ctx)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "unsupported function (glNamedFramebufferTexture) called");
       return;
    }
 
-   if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glFramebufferRenderbuffer(renderbufferTarget)");
+   /* Get the framebuffer object */
+   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
+   if (!fb)
+      return;
+
+   /* Get the texture object */
+   if (!get_texture_for_framebuffer(ctx, texture, true, func, &texObj))
       return;
+
+   if (texObj) {
+      if (!check_layered_texture_target(ctx, texObj->Target, func,
+                                        &layered))
+         return;
+
+      if (!check_level(ctx, texObj->Target, level, func))
+         return;
    }
 
+   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
+                             0, layered, func);
+}
+
+
+void
+_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
+                               struct gl_framebuffer *fb,
+                               GLenum attachment,
+                               struct gl_renderbuffer *rb,
+                               const char *func)
+{
+   struct gl_renderbuffer_attachment *att;
+
    if (_mesa_is_winsys_fbo(fb)) {
       /* Can't attach new renderbuffers to a window system framebuffer */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbuffer");
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(window-system framebuffer)", func);
       return;
    }
 
    att = get_attachment(ctx, fb, attachment);
    if (att == NULL) {
       _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glFramebufferRenderbuffer(invalid attachment %s)",
+                  "%s(invalid attachment %s)", func,
                   _mesa_lookup_enum_by_nr(attachment));
       return;
    }
 
-   if (renderbuffer) {
-      rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
-      if (!rb) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferRenderbuffer(non-existant"
-                     " renderbuffer %u)", renderbuffer);
-         return;
-      }
-      else if (rb == &DummyRenderbuffer) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferRenderbuffer(renderbuffer %u)",
-                     renderbuffer);
-         return;
-      }
-   }
-   else {
-      /* remove renderbuffer attachment */
-      rb = NULL;
-   }
-
    if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
        rb && rb->Format != MESA_FORMAT_NONE) {
       /* make sure the renderbuffer is a depth/stencil format */
       const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
       if (baseFormat != GL_DEPTH_STENCIL) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glFramebufferRenderbuffer(renderbuffer"
-                     " is not DEPTH_STENCIL format)");
+                     "%s(renderbuffer is not DEPTH_STENCIL format)", func);
          return;
       }
    }
@@ -2903,24 +3428,94 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
 
 
 void GLAPIENTRY
-_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
-                                          GLenum pname, GLint *params)
+_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
+                              GLenum renderbuffertarget,
+                              GLuint renderbuffer)
 {
-   const struct gl_renderbuffer_attachment *att;
-   struct gl_framebuffer *buffer;
-   GLenum err;
+   struct gl_framebuffer *fb;
+   struct gl_renderbuffer *rb;
    GET_CURRENT_CONTEXT(ctx);
 
-   /* The error differs in GL and GLES. */
-   err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glFramebufferRenderbuffer(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
+      return;
+   }
 
-   buffer = get_framebuffer_target(ctx, target);
-   if (!buffer) {
+   if (renderbuffertarget != GL_RENDERBUFFER) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glFramebufferRenderbuffer(renderbuffertarget is not "
+                  "GL_RENDERBUFFER)");
+      return;
+   }
+
+   if (renderbuffer) {
+      rb = _mesa_lookup_renderbuffer_err(ctx, renderbuffer,
+                                         "glFramebufferRenderbuffer");
+      if (!rb)
+         return;
+   }
+   else {
+      /* remove renderbuffer attachment */
+      rb = NULL;
+   }
+
+   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb,
+                                  "glFramebufferRenderbuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment,
+                                   GLenum renderbuffertarget,
+                                   GLuint renderbuffer)
+{
+   struct gl_framebuffer *fb;
+   struct gl_renderbuffer *rb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                     "glNamedFramebufferRenderbuffer");
+   if (!fb)
+      return;
+
+   if (renderbuffertarget != GL_RENDERBUFFER) {
       _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glGetFramebufferAttachmentParameteriv(target)");
+                  "glNamedFramebufferRenderbuffer(renderbuffertarget is not "
+                  "GL_RENDERBUFFER)");
       return;
    }
 
+   if (renderbuffer) {
+      rb = _mesa_lookup_renderbuffer_err(ctx, renderbuffer,
+                                         "glNamedFramebufferRenderbuffer");
+      if (!rb)
+         return;
+   }
+   else {
+      /* remove renderbuffer attachment */
+      rb = NULL;
+   }
+
+   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb,
+                                  "glNamedFramebufferRenderbuffer");
+}
+
+
+void
+_mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
+                                           struct gl_framebuffer *buffer,
+                                           GLenum attachment, GLenum pname,
+                                           GLint *params, const char *caller)
+{
+   const struct gl_renderbuffer_attachment *att;
+   GLenum err;
+
+   /* The error differs in GL and GLES. */
+   err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+
    if (_mesa_is_winsys_fbo(buffer)) {
       /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
        * says:
@@ -2936,14 +3531,15 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
            !ctx->Extensions.ARB_framebuffer_object)
           && !_mesa_is_gles3(ctx)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
+                     "%s(window-system framebuffer)", caller);
          return;
       }
 
       if (_mesa_is_gles3(ctx) && attachment != GL_BACK &&
           attachment != GL_DEPTH && attachment != GL_STENCIL) {
          _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glGetFramebufferAttachmentParameteriv(attachment)");
+                     "%s(invalid attachment %s)", caller,
+                     _mesa_lookup_enum_by_nr(attachment));
          return;
       }
       /* the default / window-system FBO */
@@ -2955,8 +3551,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
    }
 
    if (att == NULL) {
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glGetFramebufferAttachmentParameteriv(attachment)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
+                  _mesa_lookup_enum_by_nr(attachment));
       return;
    }
 
@@ -2970,9 +3566,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
           *    attachment, since it does not have a single format."
           */
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glGetFramebufferAttachmentParameteriv("
-                     "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
-                     " is invalid for depth+stencil attachment)");
+                     "%s(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
+                     " is invalid for depth+stencil attachment)", caller);
          return;
       }
       /* the depth and stencil attachments must point to the same buffer */
@@ -2980,8 +3575,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
       stencilAtt = get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT);
       if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glGetFramebufferAttachmentParameteriv(DEPTH/STENCIL"
-                     " attachments differ)");
+                     "%s(DEPTH/STENCIL attachments differ)", caller);
          return;
       }
    }
@@ -3014,8 +3608,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
          *params = att->TextureLevel;
       }
       else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       }
       else {
          goto invalid_pname_enum;
@@ -3031,8 +3625,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
          }
       }
       else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       }
       else {
          goto invalid_pname_enum;
@@ -3042,8 +3636,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
       if (ctx->API == API_OPENGLES) {
          goto invalid_pname_enum;
       } else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       } else if (att->Type == GL_TEXTURE) {
          if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D ||
              att->Texture->Target == GL_TEXTURE_2D_ARRAY)) {
@@ -3064,8 +3658,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
          goto invalid_pname_enum;
       }
       else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       }
       else {
          if (ctx->Extensions.EXT_framebuffer_sRGB) {
@@ -3087,8 +3681,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
          goto invalid_pname_enum;
       }
       else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       }
       else {
          mesa_format format = att->Renderbuffer->Format;
@@ -3103,9 +3697,9 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
          if (_mesa_is_gles3(ctx) &&
              attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glGetFramebufferAttachmentParameteriv(cannot query "
+                        "%s(cannot query "
                         "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE of "
-                        "GL_DEPTH_STENCIL_ATTACHMENT");
+                        "GL_DEPTH_STENCIL_ATTACHMENT)", caller);
             return;
          }
 
@@ -3139,8 +3733,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
          goto invalid_pname_enum;
       }
       else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       }
       else if (att->Texture) {
          const struct gl_texture_image *texImage =
@@ -3159,8 +3753,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
                                       att->Renderbuffer->Format);
       }
       else {
-         _mesa_problem(ctx, "glGetFramebufferAttachmentParameterivEXT:"
-                       " invalid FBO attachment structure");
+         _mesa_problem(ctx, "%s: invalid FBO attachment structure", caller);
       }
       return;
    case GL_FRAMEBUFFER_ATTACHMENT_LAYERED:
@@ -3169,8 +3762,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
       } else if (att->Type == GL_TEXTURE) {
          *params = att->Layered;
       } else if (att->Type == GL_NONE) {
-         _mesa_error(ctx, err,
-                     "glGetFramebufferAttachmentParameteriv(pname)");
+         _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+                     _mesa_lookup_enum_by_nr(pname));
       } else {
          goto invalid_pname_enum;
       }
@@ -3182,30 +3775,144 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
    return;
 
 invalid_pname_enum:
-   _mesa_error(ctx, GL_INVALID_ENUM,
-               "glGetFramebufferAttachmentParameteriv(pname)");
+   _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname %s)", caller,
+               _mesa_lookup_enum_by_nr(pname));
    return;
 }
 
 
+void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
+                                          GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *buffer;
+
+   buffer = get_framebuffer_target(ctx, target);
+   if (!buffer) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetFramebufferAttachmentParameteriv(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
+      return;
+   }
+
+   _mesa_get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
+                                              params,
+                                    "glGetFramebufferAttachmentParameteriv");
+}
+
+
+void GLAPIENTRY
+_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
+                                               GLenum attachment,
+                                               GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *buffer;
+
+   if (framebuffer) {
+      buffer = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                              "glGetNamedFramebufferAttachmentParameteriv");
+      if (!buffer)
+         return;
+   }
+   else {
+      /*
+       * Section 9.2 Binding and Managing Framebuffer Objects of the OpenGL
+       * 4.5 core spec (30.10.2014, PDF page 314):
+       *    "If framebuffer is zero, then the default draw framebuffer is
+       *    queried."
+       */
+      buffer = ctx->WinSysDrawBuffer;
+   }
+
+   _mesa_get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
+                                              params,
+                              "glGetNamedFramebufferAttachmentParameteriv");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname,
+                                 GLint param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb = NULL;
+
+   if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glNamedFramebufferParameteri("
+                  "ARB_framebuffer_no_attachments not implemented)");
+      return;
+   }
+
+   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                     "glNamedFramebufferParameteri");
+
+   if (fb) {
+      framebuffer_parameteri(ctx, fb, pname, param,
+                             "glNamedFramebufferParameteriv");
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname,
+                                     GLint *param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_framebuffer *fb;
+
+   if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glNamedFramebufferParameteriv("
+                  "ARB_framebuffer_no_attachments not implemented)");
+      return;
+   }
+
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glGetNamedFramebufferParameteriv");
+   } else {
+      fb = ctx->WinSysDrawBuffer;
+   }
+
+   if (fb) {
+      get_framebuffer_parameteriv(ctx, fb, pname, param,
+                                  "glGetNamedFramebufferParameteriv");
+   }
+}
+
+
 static void
-invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments,
+invalidate_framebuffer_storage(struct gl_context *ctx,
+                               struct gl_framebuffer *fb,
+                               GLsizei numAttachments,
                                const GLenum *attachments, GLint x, GLint y,
                                GLsizei width, GLsizei height, const char *name)
 {
    int i;
-   struct gl_framebuffer *fb;
-   GET_CURRENT_CONTEXT(ctx);
 
-   fb = get_framebuffer_target(ctx, target);
-   if (!fb) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", name);
+   /* Section 17.4 Whole Framebuffer Operations of the OpenGL 4.5 Core
+    * Spec (2.2.2015, PDF page 522) says:
+    *    "An INVALID_VALUE error is generated if numAttachments, width, or
+    *    height is negative."
+    */
+   if (numAttachments < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(numAttachments < 0)", name);
       return;
    }
 
-   if (numAttachments < 0) {
+   if (width < 0) {
       _mesa_error(ctx, GL_INVALID_VALUE,
-                  "%s(numAttachments < 0)", name);
+                  "%s(width < 0)", name);
+      return;
+   }
+
+   if (height < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(height < 0)", name);
       return;
    }
 
@@ -3301,7 +4008,8 @@ invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments,
    return;
 
 invalid_enum:
-   _mesa_error(ctx, GL_INVALID_ENUM, "%s(attachment)", name);
+   _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", name,
+               _mesa_lookup_enum_by_nr(attachments[i]));
    return;
 }
 
@@ -3311,16 +4019,67 @@ _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
                                const GLenum *attachments, GLint x, GLint y,
                                GLsizei width, GLsizei height)
 {
-   invalidate_framebuffer_storage(target, numAttachments, attachments,
+   struct gl_framebuffer *fb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glInvalidateSubFramebuffer(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
+      return;
+   }
+
+   invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
                                   x, y, width, height,
                                   "glInvalidateSubFramebuffer");
 }
 
 
+void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer,
+                                        GLsizei numAttachments,
+                                        const GLenum *attachments,
+                                        GLint x, GLint y,
+                                        GLsizei width, GLsizei height)
+{
+   struct gl_framebuffer *fb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole
+    * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the
+    * default draw framebuffer is affected."
+    */
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glInvalidateNamedFramebufferSubData");
+      if (!fb)
+         return;
+   }
+   else
+      fb = ctx->WinSysDrawBuffer;
+
+   invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
+                                  x, y, width, height,
+                                  "glInvalidateNamedFramebufferSubData");
+}
+
+
 void GLAPIENTRY
 _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
                             const GLenum *attachments)
 {
+   struct gl_framebuffer *fb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   fb = get_framebuffer_target(ctx, target);
+   if (!fb) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glInvalidateFramebuffer(invalid target %s)",
+                  _mesa_lookup_enum_by_nr(target));
+      return;
+   }
+
    /* The GL_ARB_invalidate_subdata spec says:
     *
     *     "The command
@@ -3333,13 +4092,53 @@ _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
     *     <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
     *     <MAX_VIEWPORT_DIMS[1]> respectively."
     */
-   invalidate_framebuffer_storage(target, numAttachments, attachments,
+   invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
                                   0, 0,
                                   MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
                                   "glInvalidateFramebuffer");
 }
 
 
+void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferData(GLuint framebuffer,
+                                     GLsizei numAttachments,
+                                     const GLenum *attachments)
+{
+   struct gl_framebuffer *fb;
+   GET_CURRENT_CONTEXT(ctx);
+
+   /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole
+    * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the
+    * default draw framebuffer is affected."
+    */
+   if (framebuffer) {
+      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+                                        "glInvalidateNamedFramebufferData");
+      if (!fb)
+         return;
+   }
+   else
+      fb = ctx->WinSysDrawBuffer;
+
+   /* The GL_ARB_invalidate_subdata spec says:
+    *
+    *     "The command
+    *
+    *        void InvalidateFramebuffer(enum target,
+    *                                   sizei numAttachments,
+    *                                   const enum *attachments);
+    *
+    *     is equivalent to the command InvalidateSubFramebuffer with <x>, <y>,
+    *     <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
+    *     <MAX_VIEWPORT_DIMS[1]> respectively."
+    */
+   invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
+                                  0, 0,
+                                  MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
+                                  "glInvalidateNamedFramebufferData");
+}
+
+
 void GLAPIENTRY
 _mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
                             const GLenum *attachments)
index 61aa1f50308859440cd9ec8561844cde5b1087d7..8dad0ff34e7f962e148ea32afdc4c175b5c527d5 100644 (file)
@@ -64,19 +64,35 @@ _mesa_get_incomplete_framebuffer(void);
 extern struct gl_renderbuffer *
 _mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id);
 
+extern struct gl_renderbuffer *
+_mesa_lookup_renderbuffer_err(struct gl_context *ctx, GLuint id,
+                              const char *func);
+
 extern struct gl_framebuffer *
 _mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id);
 
+extern struct gl_framebuffer *
+_mesa_lookup_framebuffer_err(struct gl_context *ctx, GLuint id,
+                             const char *func);
+
 
 void
 _mesa_update_texture_renderbuffer(struct gl_context *ctx,
                                   struct gl_framebuffer *fb,
                                   struct gl_renderbuffer_attachment *att);
 
+extern void
+_mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx,
+                                 struct gl_framebuffer *fb,
+                                 GLenum attachment,
+                                 struct gl_renderbuffer *rb);
+
 extern void
 _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
                                struct gl_framebuffer *fb,
-                               GLenum attachment, struct gl_renderbuffer *rb);
+                               GLenum attachment,
+                               struct gl_renderbuffer *rb,
+                               const char *func);
 
 extern void
 _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb);
@@ -99,6 +115,24 @@ _mesa_detach_renderbuffer(struct gl_context *ctx,
                           struct gl_framebuffer *fb,
                           const void *att);
 
+extern void
+_mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
+                          GLenum attachment,
+                          struct gl_texture_object *texObj, GLenum textarget,
+                          GLint level, GLuint layer, GLboolean layered,
+                          const char *caller);
+
+extern GLenum
+_mesa_check_framebuffer_status(struct gl_context *ctx,
+                               struct gl_framebuffer *fb);
+
+extern void
+_mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
+                                           struct gl_framebuffer *buffer,
+                                           GLenum attachment, GLenum pname,
+                                           GLint *params, const char *caller);
+
+
 extern GLboolean GLAPIENTRY
 _mesa_IsRenderbuffer(GLuint renderbuffer);
 
@@ -165,9 +199,15 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
 extern void GLAPIENTRY
 _mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers);
 
+extern void GLAPIENTRY
+_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers);
+
 extern GLenum GLAPIENTRY
 _mesa_CheckFramebufferStatus(GLenum target);
 
+extern GLenum GLAPIENTRY
+_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target);
+
 extern void GLAPIENTRY
 _mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
                               GLenum textarget, GLuint texture, GLint level);
@@ -179,36 +219,79 @@ _mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
 extern void GLAPIENTRY
 _mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
                               GLenum textarget, GLuint texture,
-                              GLint level, GLint zoffset);
+                              GLint level, GLint layer);
 
 extern void GLAPIENTRY
 _mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
                                  GLuint texture, GLint level, GLint layer);
 
+extern void GLAPIENTRY
+_mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
+                                   GLuint texture, GLint level, GLint layer);
+
 extern void GLAPIENTRY
 _mesa_FramebufferTexture(GLenum target, GLenum attachment,
                          GLuint texture, GLint level);
 
+extern void GLAPIENTRY
+_mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
+                              GLuint texture, GLint level);
+
 extern void GLAPIENTRY
 _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
                                  GLenum renderbuffertarget,
                                  GLuint renderbuffer);
 
+extern void GLAPIENTRY
+_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment,
+                                   GLenum renderbuffertarget,
+                                   GLuint renderbuffer);
+
 extern void GLAPIENTRY
 _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
                                              GLenum pname, GLint *params);
+extern void GLAPIENTRY
+_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
+                                               GLenum attachment,
+                                               GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname,
+                                 GLint param);
+
+extern void GLAPIENTRY
+_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname,
+                                     GLint *param);
 
 extern void GLAPIENTRY
 _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
                                const GLenum *attachments, GLint x, GLint y,
                                GLsizei width, GLsizei height);
 
+extern void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer,
+                                        GLsizei numAttachments,
+                                        const GLenum *attachments,
+                                        GLint x, GLint y,
+                                        GLsizei width, GLsizei height);
+
 extern void GLAPIENTRY
 _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
                             const GLenum *attachments);
 
+extern void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferData(GLuint framebuffer,
+                                     GLsizei numAttachments,
+                                     const GLenum *attachments);
+
 extern void GLAPIENTRY
 _mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
                             const GLenum *attachments);
 
+extern void GLAPIENTRY
+_mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param);
+
+extern void GLAPIENTRY
+_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+
 #endif /* FBOBJECT_H */
index 8af44e90520097bf25cb7d57653e2c45f8851a29..baeb1bfe5deda82a6a16de6d51e582eb1ca54376 100644 (file)
@@ -397,6 +397,11 @@ format_array_format_table_init(void)
    format_array_format_table = _mesa_hash_table_create(NULL, NULL,
                                                        array_formats_equal);
 
+   if (!format_array_format_table) {
+      _mesa_error_no_memory(__func__);
+      return;
+   }
+
    for (f = 1; f < MESA_FORMAT_COUNT; ++f) {
       info = _mesa_get_format_info(f);
       if (!info->ArrayFormat)
@@ -432,6 +437,12 @@ _mesa_format_from_array_format(uint32_t array_format)
 
    call_once(&format_array_format_table_exists, format_array_format_table_init);
 
+   if (!format_array_format_table) {
+      static const once_flag once_flag_init = ONCE_FLAG_INIT;
+      format_array_format_table_exists = once_flag_init;
+      return MESA_FORMAT_NONE;
+   }
+
    entry = _mesa_hash_table_search_pre_hashed(format_array_format_table,
                                               array_format,
                                               (void *)(intptr_t)array_format);
index 4f7736a64d04c526a8456bcf9fd7443bd7df3020..77c04b8dab8677fa0c8b35e52afdc7d8ba15a13c 100644 (file)
@@ -157,6 +157,7 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
    fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
    fb->_AllColorBuffersFixedPoint = !visual->floatMode;
    fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
+   fb->_HasAttachments = true;
 
    compute_depth_max(fb);
 }
@@ -312,7 +313,7 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
 
    if (ctx) {
       /* update scissor / window bounds */
-      _mesa_update_draw_buffer_bounds(ctx);
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
       /* Signal new buffer state so that swrast will update its clipping
        * info (the CLIP_BIT flag).
        */
@@ -356,30 +357,20 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
 }
 
 
+
 /**
- * Calculate the inclusive bounding box for the scissor of a specific viewport
+ * Given a bounding box, intersect the bounding box with the scissor of
+ * a specified vieport.
  *
  * \param ctx     GL context.
- * \param buffer  Framebuffer to be checked against
  * \param idx     Index of the desired viewport
  * \param bbox    Bounding box for the scissored viewport.  Stored as xmin,
  *                xmax, ymin, ymax.
- *
- * \warning This function assumes that the framebuffer dimensions are up to
- * date (e.g., update_framebuffer_size has been recently called on \c buffer).
- *
- * \sa _mesa_clip_to_region
  */
 void
-_mesa_scissor_bounding_box(const struct gl_context *ctx,
-                           const struct gl_framebuffer *buffer,
-                           unsigned idx, int *bbox)
+_mesa_intersect_scissor_bounding_box(const struct gl_context *ctx,
+                                     unsigned idx, int *bbox)
 {
-   bbox[0] = 0;
-   bbox[2] = 0;
-   bbox[1] = buffer->Width;
-   bbox[3] = buffer->Height;
-
    if (ctx->Scissor.EnableFlags & (1u << idx)) {
       if (ctx->Scissor.ScissorArray[idx].X > bbox[0]) {
          bbox[0] = ctx->Scissor.ScissorArray[idx].X;
@@ -401,6 +392,33 @@ _mesa_scissor_bounding_box(const struct gl_context *ctx,
          bbox[2] = bbox[3];
       }
    }
+}
+
+/**
+ * Calculate the inclusive bounding box for the scissor of a specific viewport
+ *
+ * \param ctx     GL context.
+ * \param buffer  Framebuffer to be checked against
+ * \param idx     Index of the desired viewport
+ * \param bbox    Bounding box for the scissored viewport.  Stored as xmin,
+ *                xmax, ymin, ymax.
+ *
+ * \warning This function assumes that the framebuffer dimensions are up to
+ * date (e.g., update_framebuffer_size has been recently called on \c buffer).
+ *
+ * \sa _mesa_clip_to_region
+ */
+void
+_mesa_scissor_bounding_box(const struct gl_context *ctx,
+                           const struct gl_framebuffer *buffer,
+                           unsigned idx, int *bbox)
+{
+   bbox[0] = 0;
+   bbox[2] = 0;
+   bbox[1] = buffer->Width;
+   bbox[3] = buffer->Height;
+
+   _mesa_intersect_scissor_bounding_box(ctx, idx, bbox);
 
    assert(bbox[0] <= bbox[1]);
    assert(bbox[2] <= bbox[3]);
@@ -413,9 +431,9 @@ _mesa_scissor_bounding_box(const struct gl_context *ctx,
  * \param ctx  the GL context.
  */
 void
-_mesa_update_draw_buffer_bounds(struct gl_context *ctx)
+_mesa_update_draw_buffer_bounds(struct gl_context *ctx,
+                                struct gl_framebuffer *buffer)
 {
-   struct gl_framebuffer *buffer = ctx->DrawBuffer;
    int bbox[4];
 
    if (!buffer)
@@ -652,7 +670,7 @@ update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
        * context state (GL_READ_BUFFER too).
        */
       if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
-         _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+         _mesa_drawbuffers(ctx, fb, ctx->Const.MaxDrawBuffers,
                            ctx->Color.DrawBuffer, NULL);
       }
    }
@@ -678,24 +696,21 @@ update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
 
 
 /**
- * Update state related to the current draw/read framebuffers.
+ * Update state related to the draw/read framebuffers.
  */
 void
-_mesa_update_framebuffer(struct gl_context *ctx)
+_mesa_update_framebuffer(struct gl_context *ctx,
+                         struct gl_framebuffer *readFb,
+                         struct gl_framebuffer *drawFb)
 {
-   struct gl_framebuffer *drawFb;
-   struct gl_framebuffer *readFb;
-
    assert(ctx);
-   drawFb = ctx->DrawBuffer;
-   readFb = ctx->ReadBuffer;
 
    update_framebuffer(ctx, drawFb);
    if (readFb != drawFb)
       update_framebuffer(ctx, readFb);
 
-   _mesa_update_clamp_vertex_color(ctx);
-   _mesa_update_clamp_fragment_color(ctx);
+   _mesa_update_clamp_vertex_color(ctx, drawFb);
+   _mesa_update_clamp_fragment_color(ctx, drawFb);
 }
 
 
index a4274216ec2205138d9d0be29a7f11d393b77f86..08e43222045eb15772324154c3a8dbc26548e42a 100644 (file)
@@ -75,16 +75,50 @@ extern void
 _mesa_scissor_bounding_box(const struct gl_context *ctx,
                            const struct gl_framebuffer *buffer,
                            unsigned idx, int *bbox);
+extern void
+_mesa_intersect_scissor_bounding_box(const struct gl_context *ctx,
+                                     unsigned idx, int *bbox);
+
+static inline GLuint
+_mesa_geometric_width(const struct gl_framebuffer *buffer)
+{
+   return buffer->_HasAttachments ?
+      buffer->Width : buffer->DefaultGeometry.Width;
+}
+
+static inline GLuint
+_mesa_geometric_height(const struct gl_framebuffer *buffer)
+{
+   return buffer->_HasAttachments ?
+      buffer->Height : buffer->DefaultGeometry.Height;
+}
+
+static inline GLuint
+_mesa_geometric_samples(const struct gl_framebuffer *buffer)
+{
+   return buffer->_HasAttachments ?
+      buffer->Visual.samples : buffer->DefaultGeometry.NumSamples;
+}
+
+static inline GLuint
+_mesa_geometric_layers(const struct gl_framebuffer *buffer)
+{
+   return buffer->_HasAttachments ?
+      buffer->MaxNumLayers : buffer->DefaultGeometry.Layers;
+}
 
 extern void 
-_mesa_update_draw_buffer_bounds(struct gl_context *ctx);
+_mesa_update_draw_buffer_bounds(struct gl_context *ctx,
+                                struct gl_framebuffer *drawFb);
 
 extern void
 _mesa_update_framebuffer_visual(struct gl_context *ctx,
                                struct gl_framebuffer *fb);
 
 extern void
-_mesa_update_framebuffer(struct gl_context *ctx);
+_mesa_update_framebuffer(struct gl_context *ctx,
+                         struct gl_framebuffer *readFb,
+                         struct gl_framebuffer *drawFb);
 
 extern GLboolean
 _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format);
index a881bc589baa6b12229da968559c25a033ffcad6..3d6d63916b383b436cd60f8d34f4e3677f2e056c 100644 (file)
@@ -138,6 +138,7 @@ enum value_extra {
    EXTRA_API_GL_CORE,
    EXTRA_API_ES2,
    EXTRA_API_ES3,
+   EXTRA_API_ES31,
    EXTRA_NEW_BUFFERS, 
    EXTRA_NEW_FRAG_CLAMP,
    EXTRA_VALID_DRAW_BUFFER,
@@ -348,6 +349,12 @@ static const int extra_ARB_shader_image_load_store_and_geometry_shader[] = {
    EXTRA_END
 };
 
+static const int extra_ARB_draw_indirect_es31[] = {
+   EXT(ARB_draw_indirect),
+   EXTRA_API_ES31,
+   EXTRA_END
+};
+
 EXTRA_EXT(ARB_texture_cube_map);
 EXTRA_EXT(EXT_texture_array);
 EXTRA_EXT(NV_fog_distance);
@@ -393,6 +400,7 @@ EXTRA_EXT(INTEL_performance_query);
 EXTRA_EXT(ARB_explicit_uniform_location);
 EXTRA_EXT(ARB_clip_control);
 EXTRA_EXT(EXT_polygon_offset_clamp);
+EXTRA_EXT(ARB_framebuffer_no_attachments);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -909,13 +917,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       break;
 
    case GL_FOG_COLOR:
-      if (_mesa_get_clamp_fragment_color(ctx))
+      if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
          COPY_4FV(v->value_float_4, ctx->Fog.Color);
       else
          COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
       break;
    case GL_COLOR_CLEAR_VALUE:
-      if (_mesa_get_clamp_fragment_color(ctx)) {
+      if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
          v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F);
          v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F);
          v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F);
@@ -924,13 +932,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
          COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f);
       break;
    case GL_BLEND_COLOR_EXT:
-      if (_mesa_get_clamp_fragment_color(ctx))
+      if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
          COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
       else
          COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped);
       break;
    case GL_ALPHA_TEST_REF:
-      if (_mesa_get_clamp_fragment_color(ctx))
+      if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
          v->value_float = ctx->Color.AlphaRef;
       else
          v->value_float = ctx->Color.AlphaRefUnclamped;
@@ -1078,6 +1086,11 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
          if (_mesa_is_gles3(ctx))
             api_found = GL_TRUE;
         break;
+      case EXTRA_API_ES31:
+         api_check = GL_TRUE;
+         if (_mesa_is_gles31(ctx))
+            api_found = GL_TRUE;
+        break;
       case EXTRA_API_GL:
          api_check = GL_TRUE;
          if (_mesa_is_desktop_gl(ctx))
@@ -1911,6 +1924,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
       if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs)
           goto invalid_value;
       v->value_int = ctx->Array.VAO->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
+      return TYPE_INT;
 
    /* ARB_shader_image_load_store */
    case GL_IMAGE_BINDING_NAME: {
index 41cb2c17b602a8e08e0c65ae5cdbb53e5605b230..74ff3ba661998e85899763996d6be7d281b5ef8c 100644 (file)
@@ -409,6 +409,12 @@ descriptor=[
   [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
 ]},
 
+# Enums in OpenGL Core profile and ES 3.1
+{ "apis": ["GL_CORE", "GLES3"], "params": [
+# GL_ARB_draw_indirect / GLES 3.1
+  [ "DRAW_INDIRECT_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_draw_indirect_es31" ],
+]},
+
 # Remaining enums are only in OpenGL
 { "apis": ["GL", "GL_CORE"], "params": [
   [ "ACCUM_RED_BITS", "BUFFER_INT(Visual.accumRedBits), NO_EXTRA" ],
@@ -793,19 +799,20 @@ descriptor=[
   [ "MAX_COMPUTE_UNIFORM_COMPONENTS", "CONST(MAX_COMPUTE_UNIFORM_COMPONENTS), extra_ARB_compute_shader" ],
   [ "MAX_COMPUTE_IMAGE_UNIFORMS", "CONST(MAX_COMPUTE_IMAGE_UNIFORMS), extra_ARB_compute_shader" ],
 
-# GL_ARB_gpu_shader5
-  [ "MAX_GEOMETRY_SHADER_INVOCATIONS", "CONST(MAX_GEOMETRY_SHADER_INVOCATIONS), extra_ARB_gpu_shader5" ],
-  [ "MIN_FRAGMENT_INTERPOLATION_OFFSET", "CONTEXT_FLOAT(Const.MinFragmentInterpolationOffset), extra_ARB_gpu_shader5" ],
-  [ "MAX_FRAGMENT_INTERPOLATION_OFFSET", "CONTEXT_FLOAT(Const.MaxFragmentInterpolationOffset), extra_ARB_gpu_shader5" ],
-  [ "FRAGMENT_INTERPOLATION_OFFSET_BITS", "CONST(FRAGMENT_INTERPOLATION_OFFSET_BITS), extra_ARB_gpu_shader5" ],
+# GL_ARB_framebuffer_no_attachments
+  ["MAX_FRAMEBUFFER_WIDTH", "CONTEXT_INT(Const.MaxFramebufferWidth), extra_ARB_framebuffer_no_attachments"],
+  ["MAX_FRAMEBUFFER_HEIGHT", "CONTEXT_INT(Const.MaxFramebufferHeight), extra_ARB_framebuffer_no_attachments"],
+  ["MAX_FRAMEBUFFER_LAYERS", "CONTEXT_INT(Const.MaxFramebufferLayers), extra_ARB_framebuffer_no_attachments"],
+  ["MAX_FRAMEBUFFER_SAMPLES", "CONTEXT_INT(Const.MaxFramebufferSamples), extra_ARB_framebuffer_no_attachments"],
+
+# GL_EXT_polygon_offset_clamp
+  [ "POLYGON_OFFSET_CLAMP_EXT", "CONTEXT_FLOAT(Polygon.OffsetClamp), extra_EXT_polygon_offset_clamp" ],
 ]},
 
 # Enums restricted to OpenGL Core profile
 { "apis": ["GL_CORE"], "params": [
 # GL_ARB_texture_buffer_range
   [ "TEXTURE_BUFFER_OFFSET_ALIGNMENT", "CONTEXT_INT(Const.TextureBufferOffsetAlignment), extra_ARB_texture_buffer_range" ],
-# GL_ARB_draw_indirect
-  [ "DRAW_INDIRECT_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_draw_indirect" ],
 
 # GL_ARB_viewport_array
   [ "MAX_VIEWPORTS", "CONTEXT_INT(Const.MaxViewports), extra_ARB_viewport_array" ],
@@ -814,8 +821,11 @@ descriptor=[
   [ "LAYER_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ],
   [ "VIEWPORT_INDEX_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ],
 
-# GL_EXT_polygon_offset_clamp
-  [ "POLYGON_OFFSET_CLAMP_EXT", "CONTEXT_FLOAT(Polygon.OffsetClamp), extra_EXT_polygon_offset_clamp" ],
+# GL_ARB_gpu_shader5
+  [ "MAX_GEOMETRY_SHADER_INVOCATIONS", "CONST(MAX_GEOMETRY_SHADER_INVOCATIONS), extra_ARB_gpu_shader5" ],
+  [ "MIN_FRAGMENT_INTERPOLATION_OFFSET", "CONTEXT_FLOAT(Const.MinFragmentInterpolationOffset), extra_ARB_gpu_shader5" ],
+  [ "MAX_FRAGMENT_INTERPOLATION_OFFSET", "CONTEXT_FLOAT(Const.MaxFragmentInterpolationOffset), extra_ARB_gpu_shader5" ],
+  [ "FRAGMENT_INTERPOLATION_OFFSET_BITS", "CONST(FRAGMENT_INTERPOLATION_OFFSET_BITS), extra_ARB_gpu_shader5" ],
 ]}
 
 ]
index 1b2c7f054f6489cb97d0ac2d43fdce3a3176910b..72d99ca4e22bac9d4e7dfbe999764b90e594b63e 100644 (file)
@@ -72,10 +72,18 @@ shading_language_version(struct gl_context *ctx)
       break;
 
    case API_OPENGLES2:
-      return (ctx->Version < 30)
-         ? (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"
-         : (const GLubyte *) "OpenGL ES GLSL ES 3.00";
-
+      switch (ctx->Version) {
+      case 20:
+         return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16";
+      case 30:
+         return (const GLubyte *) "OpenGL ES GLSL ES 3.00";
+      case 31:
+         return (const GLubyte *) "OpenGL ES GLSL ES 3.10";
+      default:
+         _mesa_problem(ctx,
+                       "Invalid OpenGL ES version in shading_language_version()");
+         return (const GLubyte *) 0;
+      }
    case API_OPENGLES:
       /* fall-through */
 
index 8ced5794938835a0d6778a52d3dbda88a6fb1b9e..ac69fabccaa766bd64cd730fe2bceed708f55fd1 100644 (file)
@@ -1200,7 +1200,7 @@ _mesa_is_depth_or_stencil_format(GLenum format)
  * \return GL_TRUE if compressed, GL_FALSE if uncompressed
  */
 GLboolean
-_mesa_is_compressed_format(struct gl_context *ctx, GLenum format)
+_mesa_is_compressed_format(const struct gl_context *ctx, GLenum format)
 {
    switch (format) {
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
@@ -1678,6 +1678,10 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
       case GL_LUMINANCE:
       case GL_ALPHA:
          return GL_NO_ERROR;
+      case GL_RG:
+      case GL_RED:
+        if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_texture_rg)
+            return GL_NO_ERROR;
       default:
          return GL_INVALID_OPERATION;
       }
@@ -2292,8 +2296,18 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
          break;
 
       case GL_HALF_FLOAT:
-         if (internalFormat != GL_RG16F)
-            return GL_INVALID_OPERATION;
+      case GL_HALF_FLOAT_OES:
+         switch (internalFormat) {
+            case GL_RG16F:
+               break;
+            case GL_RG:
+               if (ctx->Extensions.ARB_texture_rg &&
+                   ctx->Extensions.OES_texture_half_float)
+                  break;
+            /* fallthrough */
+            default:
+               return GL_INVALID_OPERATION;
+         }
          break;
 
       case GL_FLOAT:
@@ -2301,6 +2315,11 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
          case GL_RG16F:
          case GL_RG32F:
             break;
+         case GL_RG:
+            if (ctx->Extensions.ARB_texture_rg &&
+                ctx->Extensions.OES_texture_float)
+               break;
+            /* fallthrough */
          default:
             return GL_INVALID_OPERATION;
          }
@@ -2361,8 +2380,19 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
          break;
 
       case GL_HALF_FLOAT:
-         if (internalFormat != GL_R16F)
+      case GL_HALF_FLOAT_OES:
+         switch (internalFormat) {
+         case GL_R16F:
+            break;
+         case GL_RG:
+         case GL_RED:
+            if (ctx->Extensions.ARB_texture_rg &&
+                ctx->Extensions.OES_texture_half_float)
+               break;
+            /* fallthrough */
+         default:
             return GL_INVALID_OPERATION;
+         }
          break;
 
       case GL_FLOAT:
@@ -2370,6 +2400,11 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
          case GL_R16F:
          case GL_R32F:
             break;
+         case GL_RED:
+            if (ctx->Extensions.ARB_texture_rg &&
+                ctx->Extensions.OES_texture_float)
+               break;
+            /* fallthrough */
          default:
             return GL_INVALID_OPERATION;
          }
index e1ecd64d5f9b439381f24e95ddd3e31ab549e3e7..8881cb7d86bdd6ffb2f9b42a4d2e5fd60dd20a37 100644 (file)
@@ -96,7 +96,7 @@ extern GLboolean
 _mesa_is_depth_or_stencil_format(GLenum format);
 
 extern GLboolean
-_mesa_is_compressed_format(struct gl_context *ctx, GLenum format);
+_mesa_is_compressed_format(const struct gl_context *ctx, GLenum format);
 
 extern GLenum
 _mesa_base_format_to_integer_format(GLenum format);
index 7f7f9a39b3b30b76a028fdeaeba57288f7ab96cd..a2d98d4ddff6e56f80f0f114d3f6bcb8af21eee4 100644 (file)
@@ -135,12 +135,6 @@ typedef void *GLeglImageOES;
 #define GL_SHADER_PROGRAM_MESA 0x9999
 
 
-/**
- * Internal token for geometry programs.
- * Use the value for GL_GEOMETRY_PROGRAM_NV for now.
- */
-#define MESA_GEOMETRY_PROGRAM 0x8c26
-
 /* Several fields of struct gl_config can take these as values.  Since
  * GLX header files may not be available everywhere they need to be used,
  * redefine them here.
index d04cccd94d2786df3a90488a450ad931920e5dba..315b5d64004b80656640ce096e3ccfc88241848a 100644 (file)
@@ -388,34 +388,6 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table,
 }
 
 
-/**
- * Clone all entries in a hash table, into a new table.
- *
- * \param table  the hash table to clone
- */
-struct _mesa_HashTable *
-_mesa_HashClone(const struct _mesa_HashTable *table)
-{
-   /* cast-away const */
-   struct _mesa_HashTable *table2 = (struct _mesa_HashTable *) table;
-   struct hash_entry *entry;
-   struct _mesa_HashTable *clonetable;
-
-   assert(table);
-   mtx_lock(&table2->Mutex);
-
-   clonetable = _mesa_NewHashTable();
-   assert(clonetable);
-   hash_table_foreach(table->ht, entry) {
-      _mesa_HashInsert(clonetable, (GLint)(uintptr_t)entry->key, entry->data);
-   }
-
-   mtx_unlock(&table2->Mutex);
-
-   return clonetable;
-}
-
-
 /**
  * Walk over all entries in a hash table, calling callback function for each.
  * Note: we use a separate mutex in this function to avoid a recursive
index e3e8f492e8bf4cd124a3eeb5d16ee3e1d0c58420..da3b9973d24e5ca07e3a8ea8bb1c01d920a8773f 100644 (file)
@@ -59,9 +59,6 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table,
                     void (*callback)(GLuint key, void *data, void *userData),
                     void *userData);
 
-extern struct _mesa_HashTable *
-_mesa_HashClone(const struct _mesa_HashTable *table);
-
 extern void
 _mesa_HashWalk(const struct _mesa_HashTable *table,
                void (*callback)(GLuint key, void *data, void *userData),
index c4d917ebba49d26828f5f4e0951e227084f894c7..9ffe3decd0fcbf6fb3df75faf5a1ae738a5260b8 100644 (file)
@@ -230,38 +230,6 @@ static inline int IFLOOR(float f)
 }
 
 
-/** Return (as an integer) ceiling of float */
-static inline int ICEIL(float f)
-{
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
-   /*
-    * IEEE ceil for computers that round to nearest or even.
-    * 'f' must be between -4194304 and 4194303.
-    * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
-    * but uses some IEEE specific tricks for better speed.
-    * Contributed by Josh Vanderhoof
-    */
-   int ai, bi;
-   double af, bf;
-   af = (3 << 22) + 0.5 + (double)f;
-   bf = (3 << 22) + 0.5 - (double)f;
-   /* GCC generates an extra fstp/fld without this. */
-   __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
-   __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
-   return (ai - bi + 1) >> 1;
-#else
-   int ai, bi;
-   double af, bf;
-   fi_type u;
-   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) >> 1;
-#endif
-}
-
-
 /**
  * Is x a power of two?
  */
index bd84113ea919e5ee16a215c5f2aecd862288ad0a..481fd5e7fdf87545e0428f6e108354fa0c89944a 100644 (file)
@@ -43,7 +43,6 @@
 #include "glapi/glapi.h"
 #include "math/m_matrix.h"     /* GLmatrix */
 #include "glsl/shader_enums.h"
-#include "util/simple_list.h"  /* struct simple_node */
 #include "main/formats.h"       /* MESA_FORMAT_COUNT */
 
 
@@ -398,7 +397,6 @@ struct gl_config
 {
    GLboolean rgbMode;
    GLboolean floatMode;
-   GLboolean colorIndexMode;  /* XXX is this used anywhere? */
    GLuint doubleBufferMode;
    GLuint stereoMode;
 
@@ -2099,8 +2097,6 @@ struct gl_program
    GLbitfield64 DoubleInputsRead;     /**< Bitmask of which input regs are read  and are doubles */
    GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
    GLbitfield SystemValuesRead;   /**< Bitmask of SYSTEM_VALUE_x inputs used */
-   GLbitfield InputFlags[MAX_PROGRAM_INPUTS];   /**< PROG_PARAM_BIT_x flags */
-   GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
    GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];  /**< TEXTURE_x_BIT bitmask */
    GLbitfield SamplersUsed;   /**< Bitfield of which samplers are used */
    GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
@@ -2275,16 +2271,10 @@ struct gl_vertex_program_state
  */
 struct gl_geometry_program_state
 {
-   GLboolean Enabled;               /**< GL_ARB_GEOMETRY_SHADER4 */
-   GLboolean _Enabled;              /**< Enabled and valid program? */
-   struct gl_geometry_program *Current;  /**< user-bound geometry program */
-
    /** Currently enabled and valid program (including internal programs
     * and compiled shader programs).
     */
    struct gl_geometry_program *_Current;
-
-   GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
 };
 
 /**
@@ -2320,8 +2310,6 @@ struct gl_fragment_program_state
  */
 struct gl_compute_program_state
 {
-   struct gl_compute_program *Current;  /**< user-bound compute program */
-
    /** Currently enabled and valid program (including internal programs
     * and compiled shader programs).
     */
@@ -2733,7 +2721,7 @@ struct gl_shader_program
    } Comp;
 
    /* post-link info: */
-   unsigned NumUserUniformStorage;
+   unsigned NumUniformStorage;
    unsigned NumHiddenUniforms;
    struct gl_uniform_storage *UniformStorage;
 
@@ -2832,6 +2820,8 @@ struct gl_pipeline_object
 
    mtx_t Mutex;
 
+   GLchar *Label;   /**< GL_KHR_debug */
+
    /**
     * Programs used for rendering
     *
@@ -3009,7 +2999,6 @@ struct gl_shared_state
    struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
    struct gl_vertex_program *DefaultVertexProgram;
    struct gl_fragment_program *DefaultFragmentProgram;
-   struct gl_geometry_program *DefaultGeometryProgram;
    /*@}*/
 
    /* GL_ATI_fragment_shader */
@@ -3151,12 +3140,29 @@ struct gl_framebuffer
     */
    struct gl_config Visual;
 
-   GLuint Width, Height;       /**< size of frame buffer in pixels */
+   /**
+    * Size of frame buffer in pixels. If there are no attachments, then both
+    * of these are 0.
+    */
+   GLuint Width, Height;
 
-   /** \name  Drawing bounds (Intersection of buffer size and scissor box) */
+   /**
+    * In the case that the framebuffer has no attachment (i.e.
+    * GL_ARB_framebuffer_no_attachments) then the geometry of
+    * the framebuffer is specified by the default values.
+    */
+   struct {
+     GLuint Width, Height, Layers, NumSamples;
+     GLboolean FixedSampleLocations;
+   } DefaultGeometry;
+
+   /** \name  Drawing bounds (Intersection of buffer size and scissor box)
+    * The drawing region is given by [_Xmin, _Xmax) x [_Ymin, _Ymax),
+    * (inclusive for _Xmin and _Ymin while exclusive for _Xmax and _Ymax)
+    */
    /*@{*/
-   GLint _Xmin, _Xmax;  /**< inclusive */
-   GLint _Ymin, _Ymax;  /**< exclusive */
+   GLint _Xmin, _Xmax;
+   GLint _Ymin, _Ymax;
    /*@}*/
 
    /** \name  Derived Z buffer stuff */
@@ -3169,6 +3175,22 @@ struct gl_framebuffer
    /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
    GLenum _Status;
 
+   /** Whether one of Attachment has Type != GL_NONE
+    * NOTE: the values for Width and Height are set to 0 in case of having
+    * no attachments, a backend driver supporting the extension
+    * GL_ARB_framebuffer_no_attachments must check for the flag _HasAttachments
+    * and if GL_FALSE, must then use the values in DefaultGeometry to initialize
+    * its viewport, scissor and so on (in particular _Xmin, _Xmax, _Ymin and
+    * _Ymax do NOT take into account _HasAttachments being false). To get the
+    * geometry of the framebuffer, the  helper functions
+    *   _mesa_geometric_width(),
+    *   _mesa_geometric_height(),
+    *   _mesa_geometric_samples() and
+    *   _mesa_geometric_layers()
+    * are available that check _HasAttachments.
+    */
+   bool _HasAttachments;
+
    /** Integer color values */
    GLboolean _IntegerColor;
 
@@ -3179,7 +3201,9 @@ struct gl_framebuffer
    /**
     * The maximum number of layers in the framebuffer, or 0 if the framebuffer
     * is not layered.  For cube maps and cube map arrays, each cube face
-    * counts as a layer.
+    * counts as a layer. As the case for Width, Height a backend driver
+    * supporting GL_ARB_framebuffer_no_attachments must use DefaultGeometry
+    * in the case that _HasAttachments is false
     */
    GLuint MaxNumLayers;
 
@@ -3358,6 +3382,14 @@ struct gl_constants
    GLuint MaxRenderbufferSize;   /**< GL_EXT_framebuffer_object */
    GLuint MaxSamples;            /**< GL_ARB_framebuffer_object */
 
+   /**
+    * GL_ARB_framebuffer_no_attachments
+    */
+   GLuint MaxFramebufferWidth;
+   GLuint MaxFramebufferHeight;
+   GLuint MaxFramebufferLayers;
+   GLuint MaxFramebufferSamples;
+
    /** Number of varying vectors between any two shader stages. */
    GLuint MaxVarying;
 
@@ -3635,6 +3667,7 @@ struct gl_extensions
    GLboolean ARB_fragment_program;
    GLboolean ARB_fragment_program_shadow;
    GLboolean ARB_fragment_shader;
+   GLboolean ARB_framebuffer_no_attachments;
    GLboolean ARB_framebuffer_object;
    GLboolean ARB_explicit_attrib_location;
    GLboolean ARB_explicit_uniform_location;
@@ -4422,7 +4455,12 @@ enum _debug
    DEBUG_INCOMPLETE_FBO         = (1 << 3)
 };
 
-
+static inline bool
+_mesa_active_fragment_shader_has_atomic_ops(const struct gl_context *ctx)
+{
+   return ctx->Shader._CurrentFragmentProgram != NULL &&
+      ctx->Shader._CurrentFragmentProgram->NumAtomicBuffers > 0;
+}
 
 #ifdef __cplusplus
 }
index aecb5b1fa51f52712563ea65c99b5e4d0d2d0c98..5626054687b5841834ebb2c4f0109eeb3d546a49 100644 (file)
@@ -30,6 +30,7 @@
 #include "enums.h"
 #include "fbobject.h"
 #include "objectlabel.h"
+#include "pipelineobj.h"
 #include "queryobj.h"
 #include "samplerobj.h"
 #include "shaderobj.h"
@@ -214,8 +215,13 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name,
       }
       break;
    case GL_PROGRAM_PIPELINE:
-      /* requires GL 4.2 */
-      goto invalid_enum;
+      {
+         struct gl_pipeline_object *pipe =
+            _mesa_lookup_pipeline_object(ctx, name);
+         if (pipe)
+            labelPtr = &pipe->Label;
+      }
+      break;
    default:
       goto invalid_enum;
    }
index 0fefa7d568b5da5e954e830c0fdfb23ec4022154..279ae2078fedc6b166d3be64504dd0eb9d438c34 100644 (file)
@@ -65,6 +65,7 @@ _mesa_delete_pipeline_object(struct gl_context *ctx,
 
    _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
    mtx_destroy(&obj->Mutex);
+   free(obj->Label);
    ralloc_free(obj);
 }
 
@@ -136,8 +137,8 @@ _mesa_free_pipeline_data(struct gl_context *ctx)
  * a non-existent ID.  The spec defines ID 0 as being technically
  * non-existent.
  */
-static inline struct gl_pipeline_object *
-lookup_pipeline_object(struct gl_context *ctx, GLuint id)
+struct gl_pipeline_object *
+_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id)
 {
    if (id == 0)
       return NULL;
@@ -225,7 +226,7 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
 {
    GET_CURRENT_CONTEXT(ctx);
 
-   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+   struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
    struct gl_shader_program *shProg = NULL;
    GLbitfield any_valid_stages;
 
@@ -337,7 +338,7 @@ _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg = NULL;
-   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+   struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
 
    if (program != 0) {
       shProg = _mesa_lookup_shader_program_err(ctx, program,
@@ -399,7 +400,7 @@ _mesa_BindProgramPipeline(GLuint pipeline)
     */
    if (pipeline) {
       /* non-default pipeline object */
-      newObj = lookup_pipeline_object(ctx, pipeline);
+      newObj = _mesa_lookup_pipeline_object(ctx, pipeline);
       if (!newObj) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glBindProgramPipeline(non-gen name)");
@@ -468,7 +469,7 @@ _mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
 
    for (i = 0; i < n; i++) {
       struct gl_pipeline_object *obj =
-         lookup_pipeline_object(ctx, pipelines[i]);
+         _mesa_lookup_pipeline_object(ctx, pipelines[i]);
 
       if (obj) {
          assert(obj->Name == pipelines[i]);
@@ -568,7 +569,7 @@ _mesa_IsProgramPipeline(GLuint pipeline)
 {
    GET_CURRENT_CONTEXT(ctx);
 
-   struct gl_pipeline_object *obj = lookup_pipeline_object(ctx, pipeline);
+   struct gl_pipeline_object *obj = _mesa_lookup_pipeline_object(ctx, pipeline);
    if (obj == NULL)
       return GL_FALSE;
 
@@ -582,7 +583,7 @@ void GLAPIENTRY
 _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
 {
    GET_CURRENT_CONTEXT(ctx);
-   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+   struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
 
    /* Are geometry shaders available in this context?
     */
@@ -673,6 +674,38 @@ program_stages_all_active(struct gl_pipeline_object *pipe,
    return status;
 }
 
+static bool
+program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe)
+{
+   struct gl_shader_program *prev = NULL;
+   unsigned i, j;
+
+   /* Look for programs bound to stages: A -> B -> A, with any intervening
+    * sequence of unrelated programs or empty stages.
+    */
+   for (i = 0; i < MESA_SHADER_STAGES; i++) {
+      struct gl_shader_program *cur = pipe->CurrentProgram[i];
+
+      /* Empty stages anywhere in the pipe are OK */
+      if (!cur || cur == prev)
+         continue;
+
+      if (prev) {
+         /* We've seen an A -> B transition; look at the rest of the pipe
+          * to see if we ever see A again.
+          */
+         for (j = i + 1; j < MESA_SHADER_STAGES; j++) {
+            if (pipe->CurrentProgram[j] == prev)
+               return true;
+         }
+      }
+
+      prev = cur;
+   }
+
+   return false;
+}
+
 extern GLboolean
 _mesa_validate_program_pipeline(struct gl_context* ctx,
                                 struct gl_pipeline_object *pipe,
@@ -721,24 +754,13 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
     *         - One program object is active for at least two shader stages
     *           and a second program is active for a shader stage between two
     *           stages for which the first program was active."
-    *
-    * Without Tesselation, the only case where this can occur is the geometry
-    * shader between the fragment shader and vertex shader.
     */
-   if (pipe->CurrentProgram[MESA_SHADER_GEOMETRY]
-       && pipe->CurrentProgram[MESA_SHADER_FRAGMENT]
-       && pipe->CurrentProgram[MESA_SHADER_VERTEX]) {
-      if (pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name == pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Name &&
-          pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name != pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name) {
-         pipe->InfoLog =
-            ralloc_asprintf(pipe,
-                            "Program %d is active for geometry stage between "
-                            "two stages for which another program %d is "
-                            "active",
-                            pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name,
-                            pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name);
-         goto err;
-      }
+   if (program_stages_interleaved_illegally(pipe)) {
+      pipe->InfoLog =
+         ralloc_strdup(pipe,
+                       "Program is active for multiple shader stages with an "
+                       "intervening stage provided by another program");
+      goto err;
    }
 
    /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
@@ -820,7 +842,7 @@ _mesa_ValidateProgramPipeline(GLuint pipeline)
 {
    GET_CURRENT_CONTEXT(ctx);
 
-   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+   struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
 
    if (!pipe) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -838,7 +860,7 @@ _mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize,
 {
    GET_CURRENT_CONTEXT(ctx);
 
-   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+   struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
 
    if (!pipe) {
       _mesa_error(ctx, GL_INVALID_VALUE,
index b57bcb99e5c93627f02b15256f9be06a54e3821c..6dee775ab5e5942f36904df209692d202c026454 100644 (file)
@@ -45,6 +45,9 @@ _mesa_init_pipeline(struct gl_context *ctx);
 extern void
 _mesa_free_pipeline_data(struct gl_context *ctx);
 
+extern struct gl_pipeline_object *
+_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id);
+
 extern void
 _mesa_reference_pipeline_object_(struct gl_context *ctx,
                                  struct gl_pipeline_object **ptr,
index b15a13210c01f27d38ea34b4e77a2e5a71401be2..d857b84e60de89540c76a83678f7f9e5b6697840 100644 (file)
@@ -220,12 +220,12 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
    case GL_PROGRAM_INPUT:
    case GL_PROGRAM_OUTPUT:
    case GL_UNIFORM:
-   case GL_UNIFORM_BLOCK:
    case GL_TRANSFORM_FEEDBACK_VARYING:
-      /* Validate name syntax for arrays. */
+      /* Validate name syntax for array variables */
       if (!valid_program_resource_index_name(name))
          return GL_INVALID_INDEX;
-
+      /* fall-through */
+   case GL_UNIFORM_BLOCK:
       res = _mesa_program_resource_find_name(shProg, programInterface, name);
       if (!res)
          return GL_INVALID_INDEX;
index ed0104c9e46c32ef646dc8adb24c73fbd15acc04..a3357cd6419918e263695003983af4ef602d24a6 100644 (file)
 /**
  * Return true if the conversion L=R+G+B is needed.
  */
-static GLboolean
-need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format)
+GLboolean
+_mesa_need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format)
 {
    GLenum baseTexFormat = _mesa_get_format_base_format(texFormat);
 
    return (baseTexFormat == GL_RG ||
            baseTexFormat == GL_RGB ||
            baseTexFormat == GL_RGBA) &&
-          (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA);
+          (format == GL_LUMINANCE ||
+           format == GL_LUMINANCE_ALPHA ||
+           format == GL_LUMINANCE_INTEGER_EXT ||
+           format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
 }
 
 
@@ -83,7 +86,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
    if (uses_blit) {
       /* For blit-based ReadPixels packing, the clamping is done automatically
        * unless the type is float. */
-      if (_mesa_get_clamp_read_color(ctx) &&
+      if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
           (type == GL_FLOAT || type == GL_HALF_FLOAT)) {
          transferOps |= IMAGE_CLAMP_BIT;
       }
@@ -91,7 +94,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
    else {
       /* For CPU-based ReadPixels packing, the clamping must always be done
        * for non-float types, */
-      if (_mesa_get_clamp_read_color(ctx) ||
+      if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) ||
           (type != GL_FLOAT && type != GL_HALF_FLOAT)) {
          transferOps |= IMAGE_CLAMP_BIT;
       }
@@ -102,7 +105,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
     * have any effect anyway.
     */
    if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
-       !need_rgb_to_luminance_conversion(texFormat, format)) {
+       !_mesa_need_rgb_to_luminance_conversion(texFormat, format)) {
       transferOps &= ~IMAGE_CLAMP_BIT;
    }
 
@@ -146,7 +149,7 @@ _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
 
    default:
       /* Color formats. */
-      if (need_rgb_to_luminance_conversion(rb->Format, format)) {
+      if (_mesa_need_rgb_to_luminance_conversion(rb->Format, format)) {
          return GL_TRUE;
       }
 
@@ -418,7 +421,7 @@ read_rgba_pixels( struct gl_context *ctx,
                   const struct gl_pixelstore_attrib *packing )
 {
    GLbitfield transferOps;
-   bool dst_is_integer, dst_is_luminance, needs_rebase;
+   bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
    int dst_stride, src_stride, rb_stride;
    uint32_t dst_format, src_format;
    GLubyte *dst, *map;
@@ -439,10 +442,8 @@ read_rgba_pixels( struct gl_context *ctx,
    dst_is_integer = _mesa_is_enum_format_integer(format);
    dst_stride = _mesa_image_row_stride(packing, width, format, type);
    dst_format = _mesa_format_from_format_and_type(format, type);
-   dst_is_luminance = format == GL_LUMINANCE ||
-                      format == GL_LUMINANCE_ALPHA ||
-                      format == GL_LUMINANCE_INTEGER_EXT ||
-                      format == GL_LUMINANCE_ALPHA_INTEGER_EXT;
+   convert_rgb_to_lum =
+      _mesa_need_rgb_to_luminance_conversion(rb->Format, format);
    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
                                            format, type, 0, 0);
 
@@ -490,7 +491,7 @@ read_rgba_pixels( struct gl_context *ctx,
     */
    assert(!transferOps || (transferOps && !dst_is_integer));
 
-   needs_rgba = transferOps || dst_is_luminance;
+   needs_rgba = transferOps || convert_rgb_to_lum;
    rgba = NULL;
    if (needs_rgba) {
       uint32_t rgba_format;
@@ -563,7 +564,7 @@ read_rgba_pixels( struct gl_context *ctx,
     * If the dst format is Luminance, we need to do the conversion by computing
     * L=R+G+B values.
     */
-   if (!dst_is_luminance) {
+   if (!convert_rgb_to_lum) {
       _mesa_format_convert(dst, dst_format, dst_stride,
                            src, src_format, src_stride,
                            width, height,
index 4bb35e17e4d64715d19367dbd49d95ff1dd98201..1636dd9ce3e7ed917b6155d5eef499253a2dbe84 100644 (file)
@@ -37,6 +37,9 @@ extern GLboolean
 _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
                                  GLenum type, GLboolean uses_blit);
 
+extern GLboolean
+_mesa_need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format);
+
 extern void
 _mesa_readpixels(struct gl_context *ctx,
                  GLint x, GLint y, GLsizei width, GLsizei height,
index 6e46553724be47b2f1ba35ea2e2fdc502bd5484f..a6246a39aada161ea4af34d6c7bbeb2e51496aaa 100644 (file)
@@ -28,6 +28,7 @@
  * \author Ian Romanick <ian.d.romanick@intel.com>
  */
 
+#include "main/context.h"
 #include "main/core.h"
 #include "glsl_symbol_table.h"
 #include "ir.h"
@@ -478,12 +479,20 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
 const char*
 _mesa_program_resource_name(struct gl_program_resource *res)
 {
+   const ir_variable *var;
    switch (res->Type) {
    case GL_UNIFORM_BLOCK:
       return RESOURCE_UBO(res)->Name;
    case GL_TRANSFORM_FEEDBACK_VARYING:
       return RESOURCE_XFB(res)->Name;
    case GL_PROGRAM_INPUT:
+      var = RESOURCE_VAR(res);
+      /* Special case gl_VertexIDMESA -> gl_VertexID. */
+      if (var->data.mode == ir_var_system_value &&
+          var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
+         return "gl_VertexID";
+      }
+   /* fallthrough */
    case GL_PROGRAM_OUTPUT:
       return RESOURCE_VAR(res)->name;
    case GL_UNIFORM:
@@ -538,6 +547,17 @@ struct gl_program_resource *
 _mesa_program_resource_find_name(struct gl_shader_program *shProg,
                                  GLenum programInterface, const char *name)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   const char *full_name = name;
+
+   /* When context has 'VertexID_is_zero_based' set, gl_VertexID has been
+    * lowered to gl_VertexIDMESA.
+    */
+   if (name && ctx->Const.VertexID_is_zero_based) {
+      if (strcmp(name, "gl_VertexID") == 0)
+         full_name = "gl_VertexIDMESA";
+   }
+
    struct gl_program_resource *res = shProg->ProgramResourceList;
    for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
       if (res->Type != programInterface)
@@ -562,7 +582,7 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
          break;
       case GL_PROGRAM_INPUT:
       case GL_PROGRAM_OUTPUT:
-         if (array_index_of_resource(res, name) >= 0)
+         if (array_index_of_resource(res, full_name) >= 0)
             return res;
          break;
       default:
@@ -727,6 +747,10 @@ program_resource_location(struct gl_shader_program *shProg,
          return -1;
    }
 
+   /* Built-in locations should report GL_INVALID_INDEX. */
+   if (is_gl_identifier(name))
+      return GL_INVALID_INDEX;
+
    /* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these
     * offsets are used internally to differentiate between built-in attributes
     * and user-defined attributes.
@@ -986,8 +1010,9 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
    case GL_ACTIVE_VARIABLES:
       return get_buffer_property(shProg, res, prop, val, caller);
    case GL_REFERENCED_BY_COMPUTE_SHADER:
-      if (!ctx->Extensions.ARB_compute_shader)
+      if (!_mesa_has_compute_shaders(ctx))
          goto invalid_enum;
+      /* fallthrough */
    case GL_REFERENCED_BY_VERTEX_SHADER:
    case GL_REFERENCED_BY_GEOMETRY_SHADER:
    case GL_REFERENCED_BY_FRAGMENT_SHADER:
index a04b28711f780ef5db51098d422c0e16d5ac8088..a4296adf7991877e975b907b30ed12215361795e 100644 (file)
@@ -532,7 +532,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
    /* True if geometry shaders (of the form that was adopted into GLSL 1.50
     * and GL 3.2) are available in this context
     */
-   const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;
+   const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
 
    /* Are uniform buffer objects available in this context?
     */
@@ -569,13 +569,13 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
       *params = _mesa_longest_attribute_name_length(shProg);
       return;
    case GL_ACTIVE_UNIFORMS:
-      *params = shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
+      *params = shProg->NumUniformStorage - shProg->NumHiddenUniforms;
       return;
    case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
       unsigned i;
       GLint max_len = 0;
       const unsigned num_uniforms =
-         shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
+         shProg->NumUniformStorage - shProg->NumHiddenUniforms;
 
       for (i = 0; i < num_uniforms; i++) {
         /* Add one for the terminating NUL character for a non-array, and
index e428960362df2a489d74d1d95b9e855676d347e1..110a18e1e2c427e26cfac5e0924b90890273d678 100644 (file)
@@ -282,10 +282,10 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
    unsigned i;
 
    if (shProg->UniformStorage) {
-      for (i = 0; i < shProg->NumUserUniformStorage; ++i)
+      for (i = 0; i < shProg->NumUniformStorage; ++i)
          _mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]);
       ralloc_free(shProg->UniformStorage);
-      shProg->NumUserUniformStorage = 0;
+      shProg->NumUniformStorage = 0;
       shProg->UniformStorage = NULL;
    }
 
index 0b76cc01218a65c0f72d83e6020d00673a0ec436..d5ac9f1fb13380868ff6ec0ad23f0dd246ec4766 100644 (file)
@@ -313,7 +313,6 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
    _mesa_DeleteHashTable(shared->Programs);
 
    _mesa_reference_vertprog(ctx, &shared->DefaultVertexProgram, NULL);
-   _mesa_reference_geomprog(ctx, &shared->DefaultGeometryProgram, NULL);
    _mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL);
 
    _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
index 99db37bafd7eb6b76b1ff32ad19bea13d6299550..bede7fe1d0e5263c0b9aaa52728d09e6110850d5 100644 (file)
@@ -225,7 +225,7 @@ update_program(struct gl_context *ctx)
    if (ctx->GeometryProgram._Current != prevGP) {
       new_state |= _NEW_PROGRAM;
       if (ctx->Driver.BindProgram) {
-         ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
+         ctx->Driver.BindProgram(ctx, GL_GEOMETRY_PROGRAM_NV,
                             (struct gl_program *) ctx->GeometryProgram._Current);
       }
    }
@@ -266,15 +266,9 @@ update_program_constants(struct gl_context *ctx)
       }
    }
 
-   if (ctx->GeometryProgram._Current) {
-      const struct gl_program_parameter_list *params =
-         ctx->GeometryProgram._Current->Base.Parameters;
-      /*FIXME: StateFlags is always 0 because we have unnamed constant
-       *       not state changes */
-      if (params /*&& params->StateFlags & ctx->NewState*/) {
-         new_state |= _NEW_PROGRAM_CONSTANTS;
-      }
-   }
+   /* Don't handle geometry shaders here. They don't use any state
+    * constants.
+    */
 
    if (ctx->VertexProgram._Current) {
       const struct gl_program_parameter_list *params =
@@ -389,10 +383,10 @@ _mesa_update_state_locked( struct gl_context *ctx )
       update_frontbit( ctx );
 
    if (new_state & _NEW_BUFFERS)
-      _mesa_update_framebuffer(ctx);
+      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
 
    if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
-      _mesa_update_draw_buffer_bounds( ctx );
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
 
    if (new_state & _NEW_LIGHT)
       _mesa_update_lighting( ctx );
index ccd0124a2bbd06ed7f2f37870b4f09a032e2fbe9..800720b798ed70a4cb555c58adb2d314c1f4d647 100644 (file)
@@ -68,10 +68,13 @@ struct function {
    int offset;
 };
 
+extern const struct function common_desktop_functions_possible[];
+extern const struct function gl_compatibility_functions_possible[];
 extern const struct function gl_core_functions_possible[];
 extern const struct function gles11_functions_possible[];
 extern const struct function gles2_functions_possible[];
 extern const struct function gles3_functions_possible[];
+extern const struct function gles31_functions_possible[];
 
 class DispatchSanity_test : public ::testing::Test {
 public:
@@ -96,7 +99,7 @@ DispatchSanity_test::SetUp()
    _mesa_init_driver_functions(&driver_functions);
 
    const unsigned size = _glapi_get_dispatch_table_size();
-   nop_table = (_glapi_proc *) _glapi_new_nop_table(size);
+   nop_table = (_glapi_proc *) _mesa_new_nop_table(size);
 }
 
 void
@@ -175,10 +178,19 @@ validate_nops(struct gl_context *ctx, const _glapi_proc *nop_table)
 TEST_F(DispatchSanity_test, GL31_CORE)
 {
    SetUpCtx(API_OPENGL_CORE, 31);
+   validate_functions(&ctx, common_desktop_functions_possible, nop_table);
    validate_functions(&ctx, gl_core_functions_possible, nop_table);
    validate_nops(&ctx, nop_table);
 }
 
+TEST_F(DispatchSanity_test, GL30)
+{
+   SetUpCtx(API_OPENGL_COMPAT, 30);
+   validate_functions(&ctx, common_desktop_functions_possible, nop_table);
+   validate_functions(&ctx, gl_compatibility_functions_possible, nop_table);
+   validate_nops(&ctx, nop_table);
+}
+
 TEST_F(DispatchSanity_test, GLES11)
 {
    SetUpCtx(API_OPENGLES, 11);
@@ -201,7 +213,16 @@ TEST_F(DispatchSanity_test, GLES3)
    validate_nops(&ctx, nop_table);
 }
 
-const struct function gl_core_functions_possible[] = {
+TEST_F(DispatchSanity_test, GLES31)
+{
+   SetUpCtx(API_OPENGLES2, 31);
+   validate_functions(&ctx, gles2_functions_possible, nop_table);
+   validate_functions(&ctx, gles3_functions_possible, nop_table);
+   validate_functions(&ctx, gles31_functions_possible, nop_table);
+   validate_nops(&ctx, nop_table);
+}
+
+const struct function common_desktop_functions_possible[] = {
    { "glCullFace", 10, -1 },
    { "glFrontFace", 10, -1 },
    { "glHint", 10, -1 },
@@ -213,8 +234,8 @@ const struct function gl_core_functions_possible[] = {
    { "glTexParameterfv", 10, -1 },
    { "glTexParameteri", 10, -1 },
    { "glTexParameteriv", 10, -1 },
-   { "glTexImage1D", 10, -1 },
-   { "glTexImage2D", 10, -1 },
+   { "glTexImage1D", 10, _gloffset_TexImage1D },
+   { "glTexImage2D", 10, _gloffset_TexImage2D },
    { "glDrawBuffer", 10, -1 },
    { "glClear", 10, -1 },
    { "glClearColor", 10, -1 },
@@ -482,7 +503,6 @@ const struct function gl_core_functions_possible[] = {
    /* GL 3.1 */
    { "glDrawArraysInstanced", 31, -1 },
    { "glDrawElementsInstanced", 31, -1 },
-   { "glTexBuffer", 31, -1 },
    { "glPrimitiveRestartIndex", 31, -1 },
 
    /* GL_ARB_shader_objects */
@@ -535,12 +555,8 @@ const struct function gl_core_functions_possible[] = {
    { "glGetInteger64i_v", 32, -1 },
    { "glGetBufferParameteri64v", 32, -1 },
    { "glFramebufferTexture", 32, -1 },
-
-   /* GL_ARB_geometry_shader4 */
-   { "glProgramParameteriARB", 32, -1 },
-   { "glFramebufferTextureARB", 32, -1 },
-   { "glFramebufferTextureLayerARB", 32, -1 },
-   { "glFramebufferTextureFaceARB", 32, -1 },
+   { "glProgramParameteri", 32, -1 },
+   { "glFramebufferTextureLayer", 32, -1 },
 
    /* GL 3.3 */
    { "glVertexAttribDivisor", 33, -1 },
@@ -673,34 +689,6 @@ const struct function gl_core_functions_possible[] = {
    { "glVertexAttribP4uiv", 43, -1 },
    { "glDrawArraysIndirect", 43, -1 },
    { "glDrawElementsIndirect", 43, -1 },
-   { "glUniform1d", 40, -1 },
-   { "glUniform2d", 40, -1 },
-   { "glUniform3d", 40, -1 },
-   { "glUniform4d", 40, -1 },
-   { "glUniform1dv", 40, -1 },
-   { "glUniform2dv", 40, -1 },
-   { "glUniform3dv", 40, -1 },
-   { "glUniform4dv", 40, -1 },
-   { "glUniformMatrix2dv", 40, -1 },
-   { "glUniformMatrix3dv", 40, -1 },
-   { "glUniformMatrix4dv", 40, -1 },
-   { "glUniformMatrix2x3dv", 40, -1 },
-   { "glUniformMatrix2x4dv", 40, -1 },
-   { "glUniformMatrix3x2dv", 40, -1 },
-   { "glUniformMatrix3x4dv", 40, -1 },
-   { "glUniformMatrix4x2dv", 40, -1 },
-   { "glUniformMatrix4x3dv", 40, -1 },
-   { "glGetUniformdv", 43, -1 },
-// { "glGetSubroutineUniformLocation", 43, -1 },        // XXX: Add to xml
-// { "glGetSubroutineIndex", 43, -1 },                  // XXX: Add to xml
-// { "glGetActiveSubroutineUniformiv", 43, -1 },        // XXX: Add to xml
-// { "glGetActiveSubroutineUniformName", 43, -1 },      // XXX: Add to xml
-// { "glGetActiveSubroutineName", 43, -1 },             // XXX: Add to xml
-// { "glUniformSubroutinesuiv", 43, -1 },               // XXX: Add to xml
-// { "glGetUniformSubroutineuiv", 43, -1 },             // XXX: Add to xml
-// { "glGetProgramStageiv", 43, -1 },                   // XXX: Add to xml
-// { "glPatchParameteri", 43, -1 },                     // XXX: Add to xml
-// { "glPatchParameterfv", 43, -1 },                    // XXX: Add to xml
    { "glBindTransformFeedback", 43, -1 },
    { "glDeleteTransformFeedbacks", 43, -1 },
    { "glGenTransformFeedbacks", 43, -1 },
@@ -728,12 +716,12 @@ const struct function gl_core_functions_possible[] = {
    { "glGenProgramPipelines", 43, -1 },
    { "glIsProgramPipeline", 43, -1 },
    { "glGetProgramPipelineiv", 43, -1 },
+   { "glProgramUniform1d", 43, -1 },
+   { "glProgramUniform1dv", 43, -1 },
    { "glProgramUniform1i", 43, -1 },
    { "glProgramUniform1iv", 43, -1 },
    { "glProgramUniform1f", 43, -1 },
    { "glProgramUniform1fv", 43, -1 },
-   { "glProgramUniform1d", 40, -1 },
-   { "glProgramUniform1dv", 40, -1 },
    { "glProgramUniform1ui", 43, -1 },
    { "glProgramUniform1uiv", 43, -1 },
    { "glProgramUniform2i", 43, -1 },
@@ -754,50 +742,32 @@ const struct function gl_core_functions_possible[] = {
    { "glProgramUniform3uiv", 43, -1 },
    { "glProgramUniform4i", 43, -1 },
    { "glProgramUniform4iv", 43, -1 },
+   { "glProgramUniform4d", 43, -1 },
+   { "glProgramUniform4dv", 43, -1 },
    { "glProgramUniform4f", 43, -1 },
    { "glProgramUniform4fv", 43, -1 },
-   { "glProgramUniform4d", 40, -1 },
-   { "glProgramUniform4dv", 40, -1 },
    { "glProgramUniform4ui", 43, -1 },
    { "glProgramUniform4uiv", 43, -1 },
+   { "glProgramUniformMatrix2dv", 43, -1 },
    { "glProgramUniformMatrix2fv", 43, -1 },
+   { "glProgramUniformMatrix3dv", 43, -1 },
    { "glProgramUniformMatrix3fv", 43, -1 },
+   { "glProgramUniformMatrix4dv", 43, -1 },
    { "glProgramUniformMatrix4fv", 43, -1 },
-   { "glProgramUniformMatrix2dv", 40, -1 },
-   { "glProgramUniformMatrix3dv", 40, -1 },
-   { "glProgramUniformMatrix4dv", 40, -1 },
+   { "glProgramUniformMatrix2x3dv", 43, -1 },
    { "glProgramUniformMatrix2x3fv", 43, -1 },
+   { "glProgramUniformMatrix3x2dv", 43, -1 },
    { "glProgramUniformMatrix3x2fv", 43, -1 },
+   { "glProgramUniformMatrix2x4dv", 43, -1 },
    { "glProgramUniformMatrix2x4fv", 43, -1 },
+   { "glProgramUniformMatrix4x2dv", 43, -1 },
    { "glProgramUniformMatrix4x2fv", 43, -1 },
+   { "glProgramUniformMatrix3x4dv", 43, -1 },
    { "glProgramUniformMatrix3x4fv", 43, -1 },
+   { "glProgramUniformMatrix4x3dv", 43, -1 },
    { "glProgramUniformMatrix4x3fv", 43, -1 },
-   { "glProgramUniformMatrix2x3dv", 40, -1 },
-   { "glProgramUniformMatrix3x2dv", 40, -1 },
-   { "glProgramUniformMatrix2x4dv", 40, -1 },
-   { "glProgramUniformMatrix4x2dv", 40, -1 },
-   { "glProgramUniformMatrix3x4dv", 40, -1 },
-   { "glProgramUniformMatrix4x3dv", 40, -1 },
    { "glValidateProgramPipeline", 43, -1 },
    { "glGetProgramPipelineInfoLog", 43, -1 },
-   { "glVertexAttribL1d", 41, -1 },
-   { "glVertexAttribL2d", 41, -1 },
-   { "glVertexAttribL3d", 41, -1 },
-   { "glVertexAttribL4d", 41, -1 },
-   { "glVertexAttribL1dv", 41, -1 },
-   { "glVertexAttribL2dv", 41, -1 },
-   { "glVertexAttribL3dv", 41, -1 },
-   { "glVertexAttribL4dv", 41, -1 },
-   { "glVertexAttribLPointer", 41, -1 },
-   { "glGetVertexAttribLdv", 41, -1 },
-   { "glViewportArrayv", 43, -1 },
-   { "glViewportIndexedf", 43, -1 },
-   { "glViewportIndexedfv", 43, -1 },
-   { "glScissorArrayv", 43, -1 },
-   { "glScissorIndexed", 43, -1 },
-   { "glScissorIndexedv", 43, -1 },
-   { "glDepthRangeArrayv", 43, -1 },
-   { "glDepthRangeIndexed", 43, -1 },
    { "glGetFloati_v", 43, -1 },
    { "glGetDoublei_v", 43, -1 },
 // { "glCreateSyncFromCLeventARB", 43, -1 },            // XXX: Add to xml
@@ -840,8 +810,6 @@ const struct function gl_core_functions_possible[] = {
    { "glClearBufferSubData", 43, -1 },
 // { "glClearNamedBufferDataEXT", 43, -1 },             // XXX: Add to xml
 // { "glClearNamedBufferSubDataEXT", 43, -1 },          // XXX: Add to xml
-   { "glDispatchCompute", 43, -1 },
-   { "glDispatchComputeIndirect", 43, -1 },
    { "glCopyImageSubData", 43, -1 },
    { "glTextureView", 43, -1 },
    { "glBindVertexBuffer", 43, -1 },
@@ -853,11 +821,10 @@ const struct function gl_core_functions_possible[] = {
 // { "glVertexArrayBindVertexBufferEXT", 43, -1 },      // XXX: Add to xml
 // { "glVertexArrayVertexAttribFormatEXT", 43, -1 },    // XXX: Add to xml
 // { "glVertexArrayVertexAttribIFormatEXT", 43, -1 },   // XXX: Add to xml
-// { "glVertexArrayVertexAttribLFormatEXT", 43, -1 },   // XXX: Add to xml
 // { "glVertexArrayVertexAttribBindingEXT", 43, -1 },   // XXX: Add to xml
 // { "glVertexArrayVertexBindingDivisorEXT", 43, -1 },  // XXX: Add to xml
-// { "glFramebufferParameteri", 43, -1 },               // XXX: Add to xml
-// { "glGetFramebufferParameteriv", 43, -1 },           // XXX: Add to xml
+   { "glFramebufferParameteri", 43, -1 },
+   { "glGetFramebufferParameteriv", 43, -1 },
 // { "glNamedFramebufferParameteriEXT", 43, -1 },       // XXX: Add to xml
 // { "glGetNamedFramebufferParameterivEXT", 43, -1 },   // XXX: Add to xml
 // { "glGetInternalformati64v", 43, -1 },               // XXX: Add to xml
@@ -876,7 +843,6 @@ const struct function gl_core_functions_possible[] = {
    { "glGetProgramResourceLocation", 43, -1 },
    { "glGetProgramResourceLocationIndex", 43, -1 },
 // { "glShaderStorageBlockBinding", 43, -1 },           // XXX: Add to xml
-   { "glTexBufferRange", 43, -1 },
 // { "glTextureBufferRangeEXT", 43, -1 },               // XXX: Add to xml
    { "glTexStorage2DMultisample", 43, -1 },
    { "glTexStorage3DMultisample", 43, -1 },
@@ -958,6 +924,814 @@ const struct function gl_core_functions_possible[] = {
    /* GL_ARB_clip_control */
    { "glClipControl", 45, -1 },
 
+   /* GL_ARB_compute_shader */
+   { "glDispatchCompute", 43, -1 },
+   { "glDispatchComputeIndirect", 43, -1 },
+
+   /* GL_EXT_polygon_offset_clamp */
+   { "glPolygonOffsetClampEXT", 11, -1 },
+   { NULL, 0, -1 }
+};
+
+const struct function gl_compatibility_functions_possible[] = {
+   { "glBindVertexArrayAPPLE", 10, -1 },
+   { "glGenVertexArraysAPPLE", 10, -1 },
+   { "glBindRenderbufferEXT", 10, -1 },
+   { "glBindFramebufferEXT", 10, -1 },
+   { "glNewList", 10, _gloffset_NewList },
+   { "glEndList", 10, _gloffset_EndList },
+   { "glCallList", 10, _gloffset_CallList },
+   { "glCallLists", 10, _gloffset_CallLists },
+   { "glDeleteLists", 10, _gloffset_DeleteLists },
+   { "glGenLists", 10, _gloffset_GenLists },
+   { "glListBase", 10, _gloffset_ListBase },
+   { "glBegin", 10, _gloffset_Begin },
+   { "glBitmap", 10, _gloffset_Bitmap },
+   { "glColor3b", 10, _gloffset_Color3b },
+   { "glColor3bv", 10, _gloffset_Color3bv },
+   { "glColor3d", 10, _gloffset_Color3d },
+   { "glColor3dv", 10, _gloffset_Color3dv },
+   { "glColor3f", 10, _gloffset_Color3f },
+   { "glColor3fv", 10, _gloffset_Color3fv },
+   { "glColor3i", 10, _gloffset_Color3i },
+   { "glColor3iv", 10, _gloffset_Color3iv },
+   { "glColor3s", 10, _gloffset_Color3s },
+   { "glColor3sv", 10, _gloffset_Color3sv },
+   { "glColor3ub", 10, _gloffset_Color3ub },
+   { "glColor3ubv", 10, _gloffset_Color3ubv },
+   { "glColor3ui", 10, _gloffset_Color3ui },
+   { "glColor3uiv", 10, _gloffset_Color3uiv },
+   { "glColor3us", 10, _gloffset_Color3us },
+   { "glColor3usv", 10, _gloffset_Color3usv },
+   { "glColor4b", 10, _gloffset_Color4b },
+   { "glColor4bv", 10, _gloffset_Color4bv },
+   { "glColor4d", 10, _gloffset_Color4d },
+   { "glColor4dv", 10, _gloffset_Color4dv },
+   { "glColor4f", 10, _gloffset_Color4f },
+   { "glColor4fv", 10, _gloffset_Color4fv },
+   { "glColor4i", 10, _gloffset_Color4i },
+   { "glColor4iv", 10, _gloffset_Color4iv },
+   { "glColor4s", 10, _gloffset_Color4s },
+   { "glColor4sv", 10, _gloffset_Color4sv },
+   { "glColor4ub", 10, _gloffset_Color4ub },
+   { "glColor4ubv", 10, _gloffset_Color4ubv },
+   { "glColor4ui", 10, _gloffset_Color4ui },
+   { "glColor4uiv", 10, _gloffset_Color4uiv },
+   { "glColor4us", 10, _gloffset_Color4us },
+   { "glColor4usv", 10, _gloffset_Color4usv },
+   { "glEdgeFlag", 10, _gloffset_EdgeFlag },
+   { "glEdgeFlagv", 10, _gloffset_EdgeFlagv },
+   { "glEnd", 10, _gloffset_End },
+   { "glIndexd", 10, _gloffset_Indexd },
+   { "glIndexdv", 10, _gloffset_Indexdv },
+   { "glIndexf", 10, _gloffset_Indexf },
+   { "glIndexfv", 10, _gloffset_Indexfv },
+   { "glIndexi", 10, _gloffset_Indexi },
+   { "glIndexiv", 10, _gloffset_Indexiv },
+   { "glIndexs", 10, _gloffset_Indexs },
+   { "glIndexsv", 10, _gloffset_Indexsv },
+   { "glNormal3b", 10, _gloffset_Normal3b },
+   { "glNormal3bv", 10, _gloffset_Normal3bv },
+   { "glNormal3d", 10, _gloffset_Normal3d },
+   { "glNormal3dv", 10, _gloffset_Normal3dv },
+   { "glNormal3f", 10, _gloffset_Normal3f },
+   { "glNormal3fv", 10, _gloffset_Normal3fv },
+   { "glNormal3i", 10, _gloffset_Normal3i },
+   { "glNormal3iv", 10, _gloffset_Normal3iv },
+   { "glNormal3s", 10, _gloffset_Normal3s },
+   { "glNormal3sv", 10, _gloffset_Normal3sv },
+   { "glRasterPos2d", 10, _gloffset_RasterPos2d },
+   { "glRasterPos2dv", 10, _gloffset_RasterPos2dv },
+   { "glRasterPos2f", 10, _gloffset_RasterPos2f },
+   { "glRasterPos2fv", 10, _gloffset_RasterPos2fv },
+   { "glRasterPos2i", 10, _gloffset_RasterPos2i },
+   { "glRasterPos2iv", 10, _gloffset_RasterPos2iv },
+   { "glRasterPos2s", 10, _gloffset_RasterPos2s },
+   { "glRasterPos2sv", 10, _gloffset_RasterPos2sv },
+   { "glRasterPos3d", 10, _gloffset_RasterPos3d },
+   { "glRasterPos3dv", 10, _gloffset_RasterPos3dv },
+   { "glRasterPos3f", 10, _gloffset_RasterPos3f },
+   { "glRasterPos3fv", 10, _gloffset_RasterPos3fv },
+   { "glRasterPos3i", 10, _gloffset_RasterPos3i },
+   { "glRasterPos3iv", 10, _gloffset_RasterPos3iv },
+   { "glRasterPos3s", 10, _gloffset_RasterPos3s },
+   { "glRasterPos3sv", 10, _gloffset_RasterPos3sv },
+   { "glRasterPos4d", 10, _gloffset_RasterPos4d },
+   { "glRasterPos4dv", 10, _gloffset_RasterPos4dv },
+   { "glRasterPos4f", 10, _gloffset_RasterPos4f },
+   { "glRasterPos4fv", 10, _gloffset_RasterPos4fv },
+   { "glRasterPos4i", 10, _gloffset_RasterPos4i },
+   { "glRasterPos4iv", 10, _gloffset_RasterPos4iv },
+   { "glRasterPos4s", 10, _gloffset_RasterPos4s },
+   { "glRasterPos4sv", 10, _gloffset_RasterPos4sv },
+   { "glRectd", 10, _gloffset_Rectd },
+   { "glRectdv", 10, _gloffset_Rectdv },
+   { "glRectf", 10, _gloffset_Rectf },
+   { "glRectfv", 10, _gloffset_Rectfv },
+   { "glRecti", 10, _gloffset_Recti },
+   { "glRectiv", 10, _gloffset_Rectiv },
+   { "glRects", 10, _gloffset_Rects },
+   { "glRectsv", 10, _gloffset_Rectsv },
+   { "glTexCoord1d", 10, _gloffset_TexCoord1d },
+   { "glTexCoord1dv", 10, _gloffset_TexCoord1dv },
+   { "glTexCoord1f", 10, _gloffset_TexCoord1f },
+   { "glTexCoord1fv", 10, _gloffset_TexCoord1fv },
+   { "glTexCoord1i", 10, _gloffset_TexCoord1i },
+   { "glTexCoord1iv", 10, _gloffset_TexCoord1iv },
+   { "glTexCoord1s", 10, _gloffset_TexCoord1s },
+   { "glTexCoord1sv", 10, _gloffset_TexCoord1sv },
+   { "glTexCoord2d", 10, _gloffset_TexCoord2d },
+   { "glTexCoord2dv", 10, _gloffset_TexCoord2dv },
+   { "glTexCoord2f", 10, _gloffset_TexCoord2f },
+   { "glTexCoord2fv", 10, _gloffset_TexCoord2fv },
+   { "glTexCoord2i", 10, _gloffset_TexCoord2i },
+   { "glTexCoord2iv", 10, _gloffset_TexCoord2iv },
+   { "glTexCoord2s", 10, _gloffset_TexCoord2s },
+   { "glTexCoord2sv", 10, _gloffset_TexCoord2sv },
+   { "glTexCoord3d", 10, _gloffset_TexCoord3d },
+   { "glTexCoord3dv", 10, _gloffset_TexCoord3dv },
+   { "glTexCoord3f", 10, _gloffset_TexCoord3f },
+   { "glTexCoord3fv", 10, _gloffset_TexCoord3fv },
+   { "glTexCoord3i", 10, _gloffset_TexCoord3i },
+   { "glTexCoord3iv", 10, _gloffset_TexCoord3iv },
+   { "glTexCoord3s", 10, _gloffset_TexCoord3s },
+   { "glTexCoord3sv", 10, _gloffset_TexCoord3sv },
+   { "glTexCoord4d", 10, _gloffset_TexCoord4d },
+   { "glTexCoord4dv", 10, _gloffset_TexCoord4dv },
+   { "glTexCoord4f", 10, _gloffset_TexCoord4f },
+   { "glTexCoord4fv", 10, _gloffset_TexCoord4fv },
+   { "glTexCoord4i", 10, _gloffset_TexCoord4i },
+   { "glTexCoord4iv", 10, _gloffset_TexCoord4iv },
+   { "glTexCoord4s", 10, _gloffset_TexCoord4s },
+   { "glTexCoord4sv", 10, _gloffset_TexCoord4sv },
+   { "glVertex2d", 10, _gloffset_Vertex2d },
+   { "glVertex2dv", 10, _gloffset_Vertex2dv },
+   { "glVertex2f", 10, _gloffset_Vertex2f },
+   { "glVertex2fv", 10, _gloffset_Vertex2fv },
+   { "glVertex2i", 10, _gloffset_Vertex2i },
+   { "glVertex2iv", 10, _gloffset_Vertex2iv },
+   { "glVertex2s", 10, _gloffset_Vertex2s },
+   { "glVertex2sv", 10, _gloffset_Vertex2sv },
+   { "glVertex3d", 10, _gloffset_Vertex3d },
+   { "glVertex3dv", 10, _gloffset_Vertex3dv },
+   { "glVertex3f", 10, _gloffset_Vertex3f },
+   { "glVertex3fv", 10, _gloffset_Vertex3fv },
+   { "glVertex3i", 10, _gloffset_Vertex3i },
+   { "glVertex3iv", 10, _gloffset_Vertex3iv },
+   { "glVertex3s", 10, _gloffset_Vertex3s },
+   { "glVertex3sv", 10, _gloffset_Vertex3sv },
+   { "glVertex4d", 10, _gloffset_Vertex4d },
+   { "glVertex4dv", 10, _gloffset_Vertex4dv },
+   { "glVertex4f", 10, _gloffset_Vertex4f },
+   { "glVertex4fv", 10, _gloffset_Vertex4fv },
+   { "glVertex4i", 10, _gloffset_Vertex4i },
+   { "glVertex4iv", 10, _gloffset_Vertex4iv },
+   { "glVertex4s", 10, _gloffset_Vertex4s },
+   { "glVertex4sv", 10, _gloffset_Vertex4sv },
+   { "glClipPlane", 10, _gloffset_ClipPlane },
+   { "glColorMaterial", 10, _gloffset_ColorMaterial },
+   { "glFogf", 10, _gloffset_Fogf },
+   { "glFogfv", 10, _gloffset_Fogfv },
+   { "glFogi", 10, _gloffset_Fogi },
+   { "glFogiv", 10, _gloffset_Fogiv },
+   { "glLightf", 10, _gloffset_Lightf },
+   { "glLightfv", 10, _gloffset_Lightfv },
+   { "glLighti", 10, _gloffset_Lighti },
+   { "glLightiv", 10, _gloffset_Lightiv },
+   { "glLightModelf", 10, _gloffset_LightModelf },
+   { "glLightModelfv", 10, _gloffset_LightModelfv },
+   { "glLightModeli", 10, _gloffset_LightModeli },
+   { "glLightModeliv", 10, _gloffset_LightModeliv },
+   { "glLineStipple", 10, _gloffset_LineStipple },
+   { "glMaterialf", 10, _gloffset_Materialf },
+   { "glMaterialfv", 10, _gloffset_Materialfv },
+   { "glMateriali", 10, _gloffset_Materiali },
+   { "glMaterialiv", 10, _gloffset_Materialiv },
+   { "glPolygonStipple", 10, _gloffset_PolygonStipple },
+   { "glShadeModel", 10, _gloffset_ShadeModel },
+   { "glTexEnvf", 10, _gloffset_TexEnvf },
+   { "glTexEnvfv", 10, _gloffset_TexEnvfv },
+   { "glTexEnvi", 10, _gloffset_TexEnvi },
+   { "glTexEnviv", 10, _gloffset_TexEnviv },
+   { "glTexGend", 10, _gloffset_TexGend },
+   { "glTexGendv", 10, _gloffset_TexGendv },
+   { "glTexGenf", 10, _gloffset_TexGenf },
+   { "glTexGenfv", 10, _gloffset_TexGenfv },
+   { "glTexGeni", 10, _gloffset_TexGeni },
+   { "glTexGeniv", 10, _gloffset_TexGeniv },
+   { "glFeedbackBuffer", 10, _gloffset_FeedbackBuffer },
+   { "glSelectBuffer", 10, _gloffset_SelectBuffer },
+   { "glRenderMode", 10, _gloffset_RenderMode },
+   { "glInitNames", 10, _gloffset_InitNames },
+   { "glLoadName", 10, _gloffset_LoadName },
+   { "glPassThrough", 10, _gloffset_PassThrough },
+   { "glPopName", 10, _gloffset_PopName },
+   { "glPushName", 10, _gloffset_PushName },
+   { "glClearAccum", 10, _gloffset_ClearAccum },
+   { "glClearIndex", 10, _gloffset_ClearIndex },
+   { "glIndexMask", 10, _gloffset_IndexMask },
+   { "glAccum", 10, _gloffset_Accum },
+   { "glPopAttrib", 10, _gloffset_PopAttrib },
+   { "glPushAttrib", 10, _gloffset_PushAttrib },
+   { "glMap1d", 10, _gloffset_Map1d },
+   { "glMap1f", 10, _gloffset_Map1f },
+   { "glMap2d", 10, _gloffset_Map2d },
+   { "glMap2f", 10, _gloffset_Map2f },
+   { "glMapGrid1d", 10, _gloffset_MapGrid1d },
+   { "glMapGrid1f", 10, _gloffset_MapGrid1f },
+   { "glMapGrid2d", 10, _gloffset_MapGrid2d },
+   { "glMapGrid2f", 10, _gloffset_MapGrid2f },
+   { "glEvalCoord1d", 10, _gloffset_EvalCoord1d },
+   { "glEvalCoord1dv", 10, _gloffset_EvalCoord1dv },
+   { "glEvalCoord1f", 10, _gloffset_EvalCoord1f },
+   { "glEvalCoord1fv", 10, _gloffset_EvalCoord1fv },
+   { "glEvalCoord2d", 10, _gloffset_EvalCoord2d },
+   { "glEvalCoord2dv", 10, _gloffset_EvalCoord2dv },
+   { "glEvalCoord2f", 10, _gloffset_EvalCoord2f },
+   { "glEvalCoord2fv", 10, _gloffset_EvalCoord2fv },
+   { "glEvalMesh1", 10, _gloffset_EvalMesh1 },
+   { "glEvalPoint1", 10, _gloffset_EvalPoint1 },
+   { "glEvalMesh2", 10, _gloffset_EvalMesh2 },
+   { "glEvalPoint2", 10, _gloffset_EvalPoint2 },
+   { "glAlphaFunc", 10, _gloffset_AlphaFunc },
+   { "glPixelZoom", 10, _gloffset_PixelZoom },
+   { "glPixelTransferf", 10, _gloffset_PixelTransferf },
+   { "glPixelTransferi", 10, _gloffset_PixelTransferi },
+   { "glPixelMapfv", 10, _gloffset_PixelMapfv },
+   { "glPixelMapuiv", 10, _gloffset_PixelMapuiv },
+   { "glPixelMapusv", 10, _gloffset_PixelMapusv },
+   { "glCopyPixels", 10, _gloffset_CopyPixels },
+   { "glDrawPixels", 10, _gloffset_DrawPixels },
+   { "glGetClipPlane", 10, _gloffset_GetClipPlane },
+   { "glGetLightfv", 10, _gloffset_GetLightfv },
+   { "glGetLightiv", 10, _gloffset_GetLightiv },
+   { "glGetMapdv", 10, _gloffset_GetMapdv },
+   { "glGetMapfv", 10, _gloffset_GetMapfv },
+   { "glGetMapiv", 10, _gloffset_GetMapiv },
+   { "glGetMaterialfv", 10, _gloffset_GetMaterialfv },
+   { "glGetMaterialiv", 10, _gloffset_GetMaterialiv },
+   { "glGetPixelMapfv", 10, _gloffset_GetPixelMapfv },
+   { "glGetPixelMapuiv", 10, _gloffset_GetPixelMapuiv },
+   { "glGetPixelMapusv", 10, _gloffset_GetPixelMapusv },
+   { "glGetPolygonStipple", 10, _gloffset_GetPolygonStipple },
+   { "glGetTexEnvfv", 10, _gloffset_GetTexEnvfv },
+   { "glGetTexEnviv", 10, _gloffset_GetTexEnviv },
+   { "glGetTexGendv", 10, _gloffset_GetTexGendv },
+   { "glGetTexGenfv", 10, _gloffset_GetTexGenfv },
+   { "glGetTexGeniv", 10, _gloffset_GetTexGeniv },
+   { "glIsList", 10, _gloffset_IsList },
+   { "glFrustum", 10, _gloffset_Frustum },
+   { "glLoadIdentity", 10, _gloffset_LoadIdentity },
+   { "glLoadMatrixf", 10, _gloffset_LoadMatrixf },
+   { "glLoadMatrixd", 10, _gloffset_LoadMatrixd },
+   { "glMatrixMode", 10, _gloffset_MatrixMode },
+   { "glMultMatrixf", 10, _gloffset_MultMatrixf },
+   { "glMultMatrixd", 10, _gloffset_MultMatrixd },
+   { "glOrtho", 10, _gloffset_Ortho },
+   { "glPopMatrix", 10, _gloffset_PopMatrix },
+   { "glPushMatrix", 10, _gloffset_PushMatrix },
+   { "glRotated", 10, _gloffset_Rotated },
+   { "glRotatef", 10, _gloffset_Rotatef },
+   { "glScaled", 10, _gloffset_Scaled },
+   { "glScalef", 10, _gloffset_Scalef },
+   { "glTranslated", 10, _gloffset_Translated },
+   { "glTranslatef", 10, _gloffset_Translatef },
+   { "glArrayElement", 10, _gloffset_ArrayElement },
+   { "glColorPointer", 10, _gloffset_ColorPointer },
+   { "glDisableClientState", 10, _gloffset_DisableClientState },
+   { "glEdgeFlagPointer", 10, _gloffset_EdgeFlagPointer },
+   { "glEnableClientState", 10, _gloffset_EnableClientState },
+   { "glIndexPointer", 10, _gloffset_IndexPointer },
+   { "glInterleavedArrays", 10, _gloffset_InterleavedArrays },
+   { "glNormalPointer", 10, _gloffset_NormalPointer },
+   { "glTexCoordPointer", 10, _gloffset_TexCoordPointer },
+   { "glVertexPointer", 10, _gloffset_VertexPointer },
+   { "glAreTexturesResident", 10, _gloffset_AreTexturesResident },
+   { "glPrioritizeTextures", 10, _gloffset_PrioritizeTextures },
+   { "glIndexub", 10, _gloffset_Indexub },
+   { "glIndexubv", 10, _gloffset_Indexubv },
+   { "glPopClientAttrib", 10, _gloffset_PopClientAttrib },
+   { "glPushClientAttrib", 10, _gloffset_PushClientAttrib },
+   { "glColorTable", 10, _gloffset_ColorTable },
+   { "glColorTableParameterfv", 10, _gloffset_ColorTableParameterfv },
+   { "glColorTableParameteriv", 10, _gloffset_ColorTableParameteriv },
+   { "glCopyColorTable", 10, _gloffset_CopyColorTable },
+   { "glGetColorTable", 10, _gloffset_GetColorTable },
+   { "glGetColorTableParameterfv", 10, _gloffset_GetColorTableParameterfv },
+   { "glGetColorTableParameteriv", 10, _gloffset_GetColorTableParameteriv },
+   { "glColorSubTable", 10, _gloffset_ColorSubTable },
+   { "glCopyColorSubTable", 10, _gloffset_CopyColorSubTable },
+   { "glConvolutionFilter1D", 10, _gloffset_ConvolutionFilter1D },
+   { "glConvolutionFilter2D", 10, _gloffset_ConvolutionFilter2D },
+   { "glConvolutionParameterf", 10, _gloffset_ConvolutionParameterf },
+   { "glConvolutionParameterfv", 10, _gloffset_ConvolutionParameterfv },
+   { "glConvolutionParameteri", 10, _gloffset_ConvolutionParameteri },
+   { "glConvolutionParameteriv", 10, _gloffset_ConvolutionParameteriv },
+   { "glCopyConvolutionFilter1D", 10, _gloffset_CopyConvolutionFilter1D },
+   { "glCopyConvolutionFilter2D", 10, _gloffset_CopyConvolutionFilter2D },
+   { "glGetConvolutionFilter", 10, _gloffset_GetConvolutionFilter },
+   { "glGetConvolutionParameterfv", 10, _gloffset_GetConvolutionParameterfv },
+   { "glGetConvolutionParameteriv", 10, _gloffset_GetConvolutionParameteriv },
+   { "glGetSeparableFilter", 10, _gloffset_GetSeparableFilter },
+   { "glSeparableFilter2D", 10, _gloffset_SeparableFilter2D },
+   { "glGetHistogram", 10, _gloffset_GetHistogram },
+   { "glGetHistogramParameterfv", 10, _gloffset_GetHistogramParameterfv },
+   { "glGetHistogramParameteriv", 10, _gloffset_GetHistogramParameteriv },
+   { "glGetMinmax", 10, _gloffset_GetMinmax },
+   { "glGetMinmaxParameterfv", 10, _gloffset_GetMinmaxParameterfv },
+   { "glGetMinmaxParameteriv", 10, _gloffset_GetMinmaxParameteriv },
+   { "glHistogram", 10, _gloffset_Histogram },
+   { "glMinmax", 10, _gloffset_Minmax },
+   { "glResetHistogram", 10, _gloffset_ResetHistogram },
+   { "glResetMinmax", 10, _gloffset_ResetMinmax },
+   { "glClientActiveTexture", 10, _gloffset_ClientActiveTexture },
+   { "glMultiTexCoord1d", 10, _gloffset_MultiTexCoord1d },
+   { "glMultiTexCoord1dv", 10, _gloffset_MultiTexCoord1dv },
+   { "glMultiTexCoord1f", 10, _gloffset_MultiTexCoord1fARB },
+   { "glMultiTexCoord1fv", 10, _gloffset_MultiTexCoord1fvARB },
+   { "glMultiTexCoord1i", 10, _gloffset_MultiTexCoord1i },
+   { "glMultiTexCoord1iv", 10, _gloffset_MultiTexCoord1iv },
+   { "glMultiTexCoord1s", 10, _gloffset_MultiTexCoord1s },
+   { "glMultiTexCoord1sv", 10, _gloffset_MultiTexCoord1sv },
+   { "glMultiTexCoord2d", 10, _gloffset_MultiTexCoord2d },
+   { "glMultiTexCoord2dv", 10, _gloffset_MultiTexCoord2dv },
+   { "glMultiTexCoord2f", 10, _gloffset_MultiTexCoord2fARB },
+   { "glMultiTexCoord2fv", 10, _gloffset_MultiTexCoord2fvARB },
+   { "glMultiTexCoord2i", 10, _gloffset_MultiTexCoord2i },
+   { "glMultiTexCoord2iv", 10, _gloffset_MultiTexCoord2iv },
+   { "glMultiTexCoord2s", 10, _gloffset_MultiTexCoord2s },
+   { "glMultiTexCoord2sv", 10, _gloffset_MultiTexCoord2sv },
+   { "glMultiTexCoord3d", 10, _gloffset_MultiTexCoord3d },
+   { "glMultiTexCoord3dv", 10, _gloffset_MultiTexCoord3dv },
+   { "glMultiTexCoord3f", 10, _gloffset_MultiTexCoord3fARB },
+   { "glMultiTexCoord3fv", 10, _gloffset_MultiTexCoord3fvARB },
+   { "glMultiTexCoord3i", 10, _gloffset_MultiTexCoord3i },
+   { "glMultiTexCoord3iv", 10, _gloffset_MultiTexCoord3iv },
+   { "glMultiTexCoord3s", 10, _gloffset_MultiTexCoord3s },
+   { "glMultiTexCoord3sv", 10, _gloffset_MultiTexCoord3sv },
+   { "glMultiTexCoord4d", 10, _gloffset_MultiTexCoord4d },
+   { "glMultiTexCoord4dv", 10, _gloffset_MultiTexCoord4dv },
+   { "glMultiTexCoord4f", 10, _gloffset_MultiTexCoord4fARB },
+   { "glMultiTexCoord4fv", 10, _gloffset_MultiTexCoord4fvARB },
+   { "glMultiTexCoord4i", 10, _gloffset_MultiTexCoord4i },
+   { "glMultiTexCoord4iv", 10, _gloffset_MultiTexCoord4iv },
+   { "glMultiTexCoord4s", 10, _gloffset_MultiTexCoord4s },
+   { "glMultiTexCoord4sv", 10, _gloffset_MultiTexCoord4sv },
+   { "glLoadTransposeMatrixf", 10, -1 },
+   { "glLoadTransposeMatrixd", 10, -1 },
+   { "glMultTransposeMatrixf", 10, -1 },
+   { "glMultTransposeMatrixd", 10, -1 },
+   { "glFogCoordf", 10, -1 },
+   { "glFogCoordfv", 10, -1 },
+   { "glFogCoordd", 10, -1 },
+   { "glFogCoorddv", 10, -1 },
+   { "glFogCoordPointer", 10, -1 },
+   { "glSecondaryColor3b", 10, -1 },
+   { "glSecondaryColor3bv", 10, -1 },
+   { "glSecondaryColor3d", 10, -1 },
+   { "glSecondaryColor3dv", 10, -1 },
+   { "glSecondaryColor3f", 10, -1 },
+   { "glSecondaryColor3fv", 10, -1 },
+   { "glSecondaryColor3i", 10, -1 },
+   { "glSecondaryColor3iv", 10, -1 },
+   { "glSecondaryColor3s", 10, -1 },
+   { "glSecondaryColor3sv", 10, -1 },
+   { "glSecondaryColor3ub", 10, -1 },
+   { "glSecondaryColor3ubv", 10, -1 },
+   { "glSecondaryColor3ui", 10, -1 },
+   { "glSecondaryColor3uiv", 10, -1 },
+   { "glSecondaryColor3us", 10, -1 },
+   { "glSecondaryColor3usv", 10, -1 },
+   { "glSecondaryColorPointer", 10, -1 },
+   { "glWindowPos2d", 10, -1 },
+   { "glWindowPos2dv", 10, -1 },
+   { "glWindowPos2f", 10, -1 },
+   { "glWindowPos2fv", 10, -1 },
+   { "glWindowPos2i", 10, -1 },
+   { "glWindowPos2iv", 10, -1 },
+   { "glWindowPos2s", 10, -1 },
+   { "glWindowPos2sv", 10, -1 },
+   { "glWindowPos3d", 10, -1 },
+   { "glWindowPos3dv", 10, -1 },
+   { "glWindowPos3f", 10, -1 },
+   { "glWindowPos3fv", 10, -1 },
+   { "glWindowPos3i", 10, -1 },
+   { "glWindowPos3iv", 10, -1 },
+   { "glWindowPos3s", 10, -1 },
+   { "glWindowPos3sv", 10, -1 },
+   { "glProgramStringARB", 10, -1 },
+   { "glProgramEnvParameter4dARB", 10, -1 },
+   { "glProgramEnvParameter4dvARB", 10, -1 },
+   { "glProgramEnvParameter4fARB", 10, -1 },
+   { "glProgramEnvParameter4fvARB", 10, -1 },
+   { "glProgramLocalParameter4dARB", 10, -1 },
+   { "glProgramLocalParameter4dvARB", 10, -1 },
+   { "glProgramLocalParameter4fARB", 10, -1 },
+   { "glProgramLocalParameter4fvARB", 10, -1 },
+   { "glGetProgramEnvParameterdvARB", 10, -1 },
+   { "glGetProgramEnvParameterfvARB", 10, -1 },
+   { "glGetProgramLocalParameterdvARB", 10, -1 },
+   { "glGetProgramLocalParameterfvARB", 10, -1 },
+   { "glGetProgramivARB", 10, -1 },
+   { "glGetProgramStringARB", 10, -1 },
+   { "glPolygonOffsetEXT", 10, -1 },
+   { "glColorPointerEXT", 10, -1 },
+   { "glEdgeFlagPointerEXT", 10, -1 },
+   { "glIndexPointerEXT", 10, -1 },
+   { "glNormalPointerEXT", 10, -1 },
+   { "glTexCoordPointerEXT", 10, -1 },
+   { "glVertexPointerEXT", 10, -1 },
+   { "glLockArraysEXT", 10, -1 },
+   { "glUnlockArraysEXT", 10, -1 },
+   { "glWindowPos4dMESA", 10, -1 },
+   { "glWindowPos4dvMESA", 10, -1 },
+   { "glWindowPos4fMESA", 10, -1 },
+   { "glWindowPos4fvMESA", 10, -1 },
+   { "glWindowPos4iMESA", 10, -1 },
+   { "glWindowPos4ivMESA", 10, -1 },
+   { "glWindowPos4sMESA", 10, -1 },
+   { "glWindowPos4svMESA", 10, -1 },
+   { "glBindProgramNV", 10, -1 },
+   { "glDeleteProgramsNV", 10, -1 },
+   { "glGenProgramsNV", 10, -1 },
+   { "glIsProgramNV", 10, -1 },
+   { "glVertexAttrib1sNV", 10, -1 },
+   { "glVertexAttrib1svNV", 10, -1 },
+   { "glVertexAttrib2sNV", 10, -1 },
+   { "glVertexAttrib2svNV", 10, -1 },
+   { "glVertexAttrib3sNV", 10, -1 },
+   { "glVertexAttrib3svNV", 10, -1 },
+   { "glVertexAttrib4sNV", 10, -1 },
+   { "glVertexAttrib4svNV", 10, -1 },
+   { "glVertexAttrib1fNV", 10, -1 },
+   { "glVertexAttrib1fvNV", 10, -1 },
+   { "glVertexAttrib2fNV", 10, -1 },
+   { "glVertexAttrib2fvNV", 10, -1 },
+   { "glVertexAttrib3fNV", 10, -1 },
+   { "glVertexAttrib3fvNV", 10, -1 },
+   { "glVertexAttrib4fNV", 10, -1 },
+   { "glVertexAttrib4fvNV", 10, -1 },
+   { "glVertexAttrib1dNV", 10, -1 },
+   { "glVertexAttrib1dvNV", 10, -1 },
+   { "glVertexAttrib2dNV", 10, -1 },
+   { "glVertexAttrib2dvNV", 10, -1 },
+   { "glVertexAttrib3dNV", 10, -1 },
+   { "glVertexAttrib3dvNV", 10, -1 },
+   { "glVertexAttrib4dNV", 10, -1 },
+   { "glVertexAttrib4dvNV", 10, -1 },
+   { "glVertexAttrib4ubNV", 10, -1 },
+   { "glVertexAttrib4ubvNV", 10, -1 },
+   { "glVertexAttribs1svNV", 10, -1 },
+   { "glVertexAttribs2svNV", 10, -1 },
+   { "glVertexAttribs3svNV", 10, -1 },
+   { "glVertexAttribs4svNV", 10, -1 },
+   { "glVertexAttribs1fvNV", 10, -1 },
+   { "glVertexAttribs2fvNV", 10, -1 },
+   { "glVertexAttribs3fvNV", 10, -1 },
+   { "glVertexAttribs4fvNV", 10, -1 },
+   { "glVertexAttribs1dvNV", 10, -1 },
+   { "glVertexAttribs2dvNV", 10, -1 },
+   { "glVertexAttribs3dvNV", 10, -1 },
+   { "glVertexAttribs4dvNV", 10, -1 },
+   { "glVertexAttribs4ubvNV", 10, -1 },
+   { "glGenFragmentShadersATI", 10, -1 },
+   { "glBindFragmentShaderATI", 10, -1 },
+   { "glDeleteFragmentShaderATI", 10, -1 },
+   { "glBeginFragmentShaderATI", 10, -1 },
+   { "glEndFragmentShaderATI", 10, -1 },
+   { "glPassTexCoordATI", 10, -1 },
+   { "glSampleMapATI", 10, -1 },
+   { "glColorFragmentOp1ATI", 10, -1 },
+   { "glColorFragmentOp2ATI", 10, -1 },
+   { "glColorFragmentOp3ATI", 10, -1 },
+   { "glAlphaFragmentOp1ATI", 10, -1 },
+   { "glAlphaFragmentOp2ATI", 10, -1 },
+   { "glAlphaFragmentOp3ATI", 10, -1 },
+   { "glSetFragmentShaderConstantATI", 10, -1 },
+   { "glActiveStencilFaceEXT", 10, -1 },
+   { "glStencilFuncSeparateATI", 10, -1 },
+   { "glProgramEnvParameters4fvEXT", 10, -1 },
+   { "glProgramLocalParameters4fvEXT", 10, -1 },
+   { "glPrimitiveRestartNV", 10, -1 },
+
+   { NULL, 0, -1 }
+};
+
+const struct function gl_core_functions_possible[] = {
+   /* GL 3.1 */
+   { "glTexBuffer", 31, -1 },
+
+   /* GL 3.2 */
+   { "glFramebufferTexture", 32, -1 },
+
+   /* GL 4.3 */
+   { "glIsRenderbuffer", 43, -1 },
+   { "glBindRenderbuffer", 43, -1 },
+   { "glDeleteRenderbuffers", 43, -1 },
+   { "glGenRenderbuffers", 43, -1 },
+   { "glRenderbufferStorage", 43, -1 },
+   { "glGetRenderbufferParameteriv", 43, -1 },
+   { "glIsFramebuffer", 43, -1 },
+   { "glBindFramebuffer", 43, -1 },
+   { "glDeleteFramebuffers", 43, -1 },
+   { "glGenFramebuffers", 43, -1 },
+   { "glCheckFramebufferStatus", 43, -1 },
+   { "glFramebufferTexture1D", 43, -1 },
+   { "glFramebufferTexture2D", 43, -1 },
+   { "glFramebufferTexture3D", 43, -1 },
+   { "glFramebufferRenderbuffer", 43, -1 },
+   { "glGetFramebufferAttachmentParameteriv", 43, -1 },
+   { "glGenerateMipmap", 43, -1 },
+   { "glBlitFramebuffer", 43, -1 },
+   { "glRenderbufferStorageMultisample", 43, -1 },
+   { "glFramebufferTextureLayer", 43, -1 },
+   { "glMapBufferRange", 43, -1 },
+   { "glFlushMappedBufferRange", 43, -1 },
+   { "glBindVertexArray", 43, -1 },
+   { "glDeleteVertexArrays", 43, -1 },
+   { "glGenVertexArrays", 43, -1 },
+   { "glIsVertexArray", 43, -1 },
+   { "glGetUniformIndices", 43, -1 },
+   { "glGetActiveUniformsiv", 43, -1 },
+   { "glGetActiveUniformName", 43, -1 },
+   { "glGetUniformBlockIndex", 43, -1 },
+   { "glGetActiveUniformBlockiv", 43, -1 },
+   { "glGetActiveUniformBlockName", 43, -1 },
+   { "glUniformBlockBinding", 43, -1 },
+   { "glCopyBufferSubData", 43, -1 },
+   { "glDrawElementsBaseVertex", 43, -1 },
+   { "glDrawRangeElementsBaseVertex", 43, -1 },
+   { "glDrawElementsInstancedBaseVertex", 43, -1 },
+   { "glMultiDrawElementsBaseVertex", 43, -1 },
+   { "glProvokingVertex", 43, -1 },
+   { "glFenceSync", 43, -1 },
+   { "glIsSync", 43, -1 },
+   { "glDeleteSync", 43, -1 },
+   { "glClientWaitSync", 43, -1 },
+   { "glWaitSync", 43, -1 },
+   { "glGetInteger64v", 43, -1 },
+   { "glGetSynciv", 43, -1 },
+   { "glTexImage2DMultisample", 43, -1 },
+   { "glTexImage3DMultisample", 43, -1 },
+   { "glGetMultisamplefv", 43, -1 },
+   { "glSampleMaski", 43, -1 },
+   { "glBlendEquationiARB", 43, -1 },
+   { "glBlendEquationSeparateiARB", 43, -1 },
+   { "glBlendFunciARB", 43, -1 },
+   { "glBlendFuncSeparateiARB", 43, -1 },
+   { "glMinSampleShadingARB", 43, -1 },                 // XXX: Add to xml
+// { "glNamedStringARB", 43, -1 },                      // XXX: Add to xml
+// { "glDeleteNamedStringARB", 43, -1 },                // XXX: Add to xml
+// { "glCompileShaderIncludeARB", 43, -1 },             // XXX: Add to xml
+// { "glIsNamedStringARB", 43, -1 },                    // XXX: Add to xml
+// { "glGetNamedStringARB", 43, -1 },                   // XXX: Add to xml
+// { "glGetNamedStringivARB", 43, -1 },                 // XXX: Add to xml
+   { "glBindFragDataLocationIndexed", 43, -1 },
+   { "glGetFragDataIndex", 43, -1 },
+   { "glGenSamplers", 43, -1 },
+   { "glDeleteSamplers", 43, -1 },
+   { "glIsSampler", 43, -1 },
+   { "glBindSampler", 43, -1 },
+   { "glSamplerParameteri", 43, -1 },
+   { "glSamplerParameteriv", 43, -1 },
+   { "glSamplerParameterf", 43, -1 },
+   { "glSamplerParameterfv", 43, -1 },
+   { "glSamplerParameterIiv", 43, -1 },
+   { "glSamplerParameterIuiv", 43, -1 },
+   { "glGetSamplerParameteriv", 43, -1 },
+   { "glGetSamplerParameterIiv", 43, -1 },
+   { "glGetSamplerParameterfv", 43, -1 },
+   { "glGetSamplerParameterIuiv", 43, -1 },
+   { "glQueryCounter", 43, -1 },
+   { "glGetQueryObjecti64v", 43, -1 },
+   { "glGetQueryObjectui64v", 43, -1 },
+   { "glVertexP2ui", 43, -1 },
+   { "glVertexP2uiv", 43, -1 },
+   { "glVertexP3ui", 43, -1 },
+   { "glVertexP3uiv", 43, -1 },
+   { "glVertexP4ui", 43, -1 },
+   { "glVertexP4uiv", 43, -1 },
+   { "glTexCoordP1ui", 43, -1 },
+   { "glTexCoordP1uiv", 43, -1 },
+   { "glTexCoordP2ui", 43, -1 },
+   { "glTexCoordP2uiv", 43, -1 },
+   { "glTexCoordP3ui", 43, -1 },
+   { "glTexCoordP3uiv", 43, -1 },
+   { "glTexCoordP4ui", 43, -1 },
+   { "glTexCoordP4uiv", 43, -1 },
+   { "glMultiTexCoordP1ui", 43, -1 },
+   { "glMultiTexCoordP1uiv", 43, -1 },
+   { "glMultiTexCoordP2ui", 43, -1 },
+   { "glMultiTexCoordP2uiv", 43, -1 },
+   { "glMultiTexCoordP3ui", 43, -1 },
+   { "glMultiTexCoordP3uiv", 43, -1 },
+   { "glMultiTexCoordP4ui", 43, -1 },
+   { "glMultiTexCoordP4uiv", 43, -1 },
+   { "glNormalP3ui", 43, -1 },
+   { "glNormalP3uiv", 43, -1 },
+   { "glColorP3ui", 43, -1 },
+   { "glColorP3uiv", 43, -1 },
+   { "glColorP4ui", 43, -1 },
+   { "glColorP4uiv", 43, -1 },
+   { "glVertexAttribP1ui", 43, -1 },
+   { "glVertexAttribP1uiv", 43, -1 },
+   { "glVertexAttribP2ui", 43, -1 },
+   { "glVertexAttribP2uiv", 43, -1 },
+   { "glVertexAttribP3ui", 43, -1 },
+   { "glVertexAttribP3uiv", 43, -1 },
+   { "glVertexAttribP4ui", 43, -1 },
+   { "glVertexAttribP4uiv", 43, -1 },
+   { "glDrawArraysIndirect", 43, -1 },
+   { "glDrawElementsIndirect", 43, -1 },
+
+   { "glUniform1d", 40, -1 },
+   { "glUniform2d", 40, -1 },
+   { "glUniform3d", 40, -1 },
+   { "glUniform4d", 40, -1 },
+   { "glUniform1dv", 40, -1 },
+   { "glUniform2dv", 40, -1 },
+   { "glUniform3dv", 40, -1 },
+   { "glUniform4dv", 40, -1 },
+   { "glUniformMatrix2dv", 40, -1 },
+   { "glUniformMatrix3dv", 40, -1 },
+   { "glUniformMatrix4dv", 40, -1 },
+   { "glUniformMatrix2x3dv", 40, -1 },
+   { "glUniformMatrix2x4dv", 40, -1 },
+   { "glUniformMatrix3x2dv", 40, -1 },
+   { "glUniformMatrix3x4dv", 40, -1 },
+   { "glUniformMatrix4x2dv", 40, -1 },
+   { "glUniformMatrix4x3dv", 40, -1 },
+   { "glGetUniformdv", 43, -1 },
+// { "glGetSubroutineUniformLocation", 43, -1 },        // XXX: Add to xml
+// { "glGetSubroutineIndex", 43, -1 },                  // XXX: Add to xml
+// { "glGetActiveSubroutineUniformiv", 43, -1 },        // XXX: Add to xml
+// { "glGetActiveSubroutineUniformName", 43, -1 },      // XXX: Add to xml
+// { "glGetActiveSubroutineName", 43, -1 },             // XXX: Add to xml
+// { "glUniformSubroutinesuiv", 43, -1 },               // XXX: Add to xml
+// { "glGetUniformSubroutineuiv", 43, -1 },             // XXX: Add to xml
+// { "glGetProgramStageiv", 43, -1 },                   // XXX: Add to xml
+// { "glPatchParameteri", 43, -1 },                     // XXX: Add to xml
+// { "glPatchParameterfv", 43, -1 },                    // XXX: Add to xml
+
+   { "glBindTransformFeedback", 43, -1 },
+   { "glDeleteTransformFeedbacks", 43, -1 },
+   { "glGenTransformFeedbacks", 43, -1 },
+   { "glIsTransformFeedback", 43, -1 },
+   { "glPauseTransformFeedback", 43, -1 },
+   { "glResumeTransformFeedback", 43, -1 },
+   { "glDrawTransformFeedback", 43, -1 },
+   { "glDrawTransformFeedbackStream", 43, -1 },
+   { "glBeginQueryIndexed", 43, -1 },
+   { "glEndQueryIndexed", 43, -1 },
+   { "glGetQueryIndexediv", 43, -1 },
+   { "glReleaseShaderCompiler", 43, -1 },
+   { "glShaderBinary", 43, -1 },
+   { "glGetShaderPrecisionFormat", 43, -1 },
+   { "glDepthRangef", 43, -1 },
+   { "glClearDepthf", 43, -1 },
+   { "glGetProgramBinary", 43, -1 },
+   { "glProgramBinary", 43, -1 },
+   { "glProgramParameteri", 43, -1 },
+   { "glUseProgramStages", 43, -1 },
+   { "glActiveShaderProgram", 43, -1 },
+   { "glCreateShaderProgramv", 43, -1 },
+   { "glBindProgramPipeline", 43, -1 },
+   { "glDeleteProgramPipelines", 43, -1 },
+   { "glGenProgramPipelines", 43, -1 },
+   { "glIsProgramPipeline", 43, -1 },
+   { "glGetProgramPipelineiv", 43, -1 },
+   { "glProgramUniform1i", 43, -1 },
+   { "glProgramUniform1iv", 43, -1 },
+   { "glProgramUniform1f", 43, -1 },
+   { "glProgramUniform1fv", 43, -1 },
+   { "glProgramUniform1d", 40, -1 },
+   { "glProgramUniform1dv", 40, -1 },
+   { "glProgramUniform1ui", 43, -1 },
+   { "glProgramUniform1uiv", 43, -1 },
+   { "glProgramUniform2i", 43, -1 },
+   { "glProgramUniform2iv", 43, -1 },
+   { "glProgramUniform2f", 43, -1 },
+   { "glProgramUniform2fv", 43, -1 },
+   { "glProgramUniform2d", 40, -1 },
+   { "glProgramUniform2dv", 40, -1 },
+   { "glProgramUniform2ui", 43, -1 },
+   { "glProgramUniform2uiv", 43, -1 },
+   { "glProgramUniform3i", 43, -1 },
+   { "glProgramUniform3iv", 43, -1 },
+   { "glProgramUniform3f", 43, -1 },
+   { "glProgramUniform3fv", 43, -1 },
+   { "glProgramUniform3d", 40, -1 },
+   { "glProgramUniform3dv", 40, -1 },
+   { "glProgramUniform3ui", 43, -1 },
+   { "glProgramUniform3uiv", 43, -1 },
+   { "glProgramUniform4i", 43, -1 },
+   { "glProgramUniform4iv", 43, -1 },
+   { "glProgramUniform4f", 43, -1 },
+   { "glProgramUniform4fv", 43, -1 },
+   { "glProgramUniform4d", 40, -1 },
+   { "glProgramUniform4dv", 40, -1 },
+   { "glProgramUniform4ui", 43, -1 },
+   { "glProgramUniform4uiv", 43, -1 },
+   { "glProgramUniformMatrix2fv", 43, -1 },
+   { "glProgramUniformMatrix3fv", 43, -1 },
+   { "glProgramUniformMatrix4fv", 43, -1 },
+   { "glProgramUniformMatrix2dv", 40, -1 },
+   { "glProgramUniformMatrix3dv", 40, -1 },
+   { "glProgramUniformMatrix4dv", 40, -1 },
+   { "glProgramUniformMatrix2x3fv", 43, -1 },
+   { "glProgramUniformMatrix3x2fv", 43, -1 },
+   { "glProgramUniformMatrix2x4fv", 43, -1 },
+   { "glProgramUniformMatrix4x2fv", 43, -1 },
+   { "glProgramUniformMatrix3x4fv", 43, -1 },
+   { "glProgramUniformMatrix4x3fv", 43, -1 },
+   { "glProgramUniformMatrix2x3dv", 40, -1 },
+   { "glProgramUniformMatrix3x2dv", 40, -1 },
+   { "glProgramUniformMatrix2x4dv", 40, -1 },
+   { "glProgramUniformMatrix4x2dv", 40, -1 },
+   { "glProgramUniformMatrix3x4dv", 40, -1 },
+   { "glProgramUniformMatrix4x3dv", 40, -1 },
+   { "glValidateProgramPipeline", 43, -1 },
+   { "glGetProgramPipelineInfoLog", 43, -1 },
+
+   { "glVertexAttribL1d", 41, -1 },
+   { "glVertexAttribL2d", 41, -1 },
+   { "glVertexAttribL3d", 41, -1 },
+   { "glVertexAttribL4d", 41, -1 },
+   { "glVertexAttribL1dv", 41, -1 },
+   { "glVertexAttribL2dv", 41, -1 },
+   { "glVertexAttribL3dv", 41, -1 },
+   { "glVertexAttribL4dv", 41, -1 },
+   { "glVertexAttribLPointer", 41, -1 },
+   { "glGetVertexAttribLdv", 41, -1 },
+   { "glViewportArrayv", 43, -1 },
+   { "glViewportIndexedf", 43, -1 },
+   { "glViewportIndexedfv", 43, -1 },
+   { "glScissorArrayv", 43, -1 },
+   { "glScissorIndexed", 43, -1 },
+   { "glScissorIndexedv", 43, -1 },
+   { "glDepthRangeArrayv", 43, -1 },
+   { "glDepthRangeIndexed", 43, -1 },
+
+// { "glCreateSyncFromCLeventARB", 43, -1 },            // XXX: Add to xml
+
+   { "glDrawArraysInstancedBaseInstance", 43, -1 },
+   { "glDrawElementsInstancedBaseInstance", 43, -1 },
+   { "glDrawElementsInstancedBaseVertexBaseInstance", 43, -1 },
+   { "glDrawTransformFeedbackInstanced", 43, -1 },
+   { "glDrawTransformFeedbackStreamInstanced", 43, -1 },
+   { "glGetActiveAtomicCounterBufferiv", 43, -1 },
+   { "glBindImageTexture", 43, -1 },
+   { "glMemoryBarrier", 43, -1 },
+   { "glTexStorage1D", 43, -1 },
+   { "glTexStorage2D", 43, -1 },
+   { "glTexStorage3D", 43, -1 },
+   { "glTextureStorage1DEXT", 43, -1 },
+   { "glTextureStorage2DEXT", 43, -1 },
+   { "glTextureStorage3DEXT", 43, -1 },
+   { "glClearBufferData", 43, -1 },
+   { "glClearBufferSubData", 43, -1 },
+// { "glClearNamedBufferDataEXT", 43, -1 },             // XXX: Add to xml
+// { "glClearNamedBufferSubDataEXT", 43, -1 },          // XXX: Add to xml
+   { "glCopyImageSubData", 43, -1 },
+   { "glTextureView", 43, -1 },
+   { "glBindVertexBuffer", 43, -1 },
+   { "glVertexAttribFormat", 43, -1 },
+   { "glVertexAttribIFormat", 43, -1 },
+   { "glVertexAttribBinding", 43, -1 },
+   { "glVertexBindingDivisor", 43, -1 },
+// { "glVertexArrayBindVertexBufferEXT", 43, -1 },      // XXX: Add to xml
+// { "glVertexArrayVertexAttribFormatEXT", 43, -1 },    // XXX: Add to xml
+// { "glVertexArrayVertexAttribIFormatEXT", 43, -1 },   // XXX: Add to xml
+// { "glVertexArrayVertexAttribLFormatEXT", 43, -1 },   // XXX: Add to xml
+// { "glVertexArrayVertexAttribBindingEXT", 43, -1 },   // XXX: Add to xml
+// { "glVertexArrayVertexBindingDivisorEXT", 43, -1 },  // XXX: Add to xml
+// { "glFramebufferParameteri", 43, -1 },               // XXX: Add to xml
+// { "glGetFramebufferParameteriv", 43, -1 },           // XXX: Add to xml
+// { "glNamedFramebufferParameteriEXT", 43, -1 },       // XXX: Add to xml
+// { "glGetNamedFramebufferParameterivEXT", 43, -1 },   // XXX: Add to xml
+// { "glGetInternalformati64v", 43, -1 },               // XXX: Add to xml
+   { "glInvalidateTexSubImage", 43, -1 },
+   { "glInvalidateTexImage", 43, -1 },
+   { "glInvalidateBufferSubData", 43, -1 },
+   { "glInvalidateBufferData", 43, -1 },
+   { "glInvalidateFramebuffer", 43, -1 },
+   { "glInvalidateSubFramebuffer", 43, -1 },
+   { "glMultiDrawArraysIndirect", 43, -1 },
+   { "glMultiDrawElementsIndirect", 43, -1 },
+   { "glGetProgramInterfaceiv", 43, -1 },
+   { "glGetProgramResourceIndex", 43, -1 },
+   { "glGetProgramResourceName", 43, -1 },
+   { "glGetProgramResourceiv", 43, -1 },
+   { "glGetProgramResourceLocation", 43, -1 },
+   { "glGetProgramResourceLocationIndex", 43, -1 },
+// { "glShaderStorageBlockBinding", 43, -1 },           // XXX: Add to xml
+   { "glTexBufferRange", 43, -1 },
+// { "glTextureBufferRangeEXT", 43, -1 },               // XXX: Add to xml
+   { "glTexStorage2DMultisample", 43, -1 },
+   { "glTexStorage3DMultisample", 43, -1 },
+// { "glTextureStorage2DMultisampleEXT", 43, -1 },      // XXX: Add to xml
+// { "glTextureStorage3DMultisampleEXT", 43, -1 },      // XXX: Add to xml
+
    /* GL_ARB_direct_state_access */
    { "glCreateTransformFeedbacks", 45, -1 },
    { "glTransformFeedbackBufferBase", 45, -1 },
@@ -980,6 +1754,24 @@ const struct function gl_core_functions_possible[] = {
    { "glGetNamedBufferParameteri64v", 45, -1 },
    { "glGetNamedBufferPointerv", 45, -1 },
    { "glGetNamedBufferSubData", 45, -1 },
+   { "glCreateFramebuffers", 45, -1 },
+   { "glNamedFramebufferRenderbuffer", 45, -1 },
+   { "glNamedFramebufferParameteri", 45, -1 },
+   { "glNamedFramebufferTexture", 45, -1 },
+   { "glNamedFramebufferTextureLayer", 45, -1 },
+   { "glNamedFramebufferDrawBuffer", 45, -1 },
+   { "glNamedFramebufferDrawBuffers", 45, -1 },
+   { "glNamedFramebufferReadBuffer", 45, -1 },
+   { "glInvalidateNamedFramebufferSubData", 45, -1 },
+   { "glInvalidateNamedFramebufferData", 45, -1 },
+   { "glClearNamedFramebufferiv", 45, -1 },
+   { "glClearNamedFramebufferuiv", 45, -1 },
+   { "glClearNamedFramebufferfv", 45, -1 },
+   { "glClearNamedFramebufferfi", 45, -1 },
+   { "glBlitNamedFramebuffer", 45, -1 },
+   { "glCheckNamedFramebufferStatus", 45, -1 },
+   { "glGetNamedFramebufferParameteriv", 45, -1 },
+   { "glGetNamedFramebufferAttachmentParameteriv", 45, -1 },
    { "glCreateRenderbuffers", 45, -1 },
    { "glNamedRenderbufferStorage", 45, -1 },
    { "glNamedRenderbufferStorageMultisample", 45, -1 },
@@ -1039,9 +1831,6 @@ const struct function gl_core_functions_possible[] = {
    { "glGetQueryBufferObjecti64v", 45, -1 },
    { "glGetQueryBufferObjectui64v", 45, -1 },
 
-   /* GL_EXT_polygon_offset_clamp */
-   { "glPolygonOffsetClampEXT", 11, -1 },
-
    { NULL, 0, -1 }
 };
 
@@ -1596,3 +2385,88 @@ const struct function gles3_functions_possible[] = {
 
    { NULL, 0, -1 }
 };
+
+const struct function gles31_functions_possible[] = {
+   { "glDispatchCompute", 31, -1 },
+   { "glDispatchComputeIndirect", 31, -1 },
+   { "glDrawArraysIndirect", 31, -1 },
+   { "glDrawElementsIndirect", 31, -1 },
+
+   // FINISHME: These two functions have not been implemented yet.  They come
+   // FINISHME: from the ARB_framebuffer_no_attachments extension.
+   // { "glFramebufferParameteri", 31, -1 },
+   // { "glGetFramebufferParameteriv", 31, -1 },
+
+   { "glGetProgramInterfaceiv", 31, -1 },
+   { "glGetProgramResourceIndex", 31, -1 },
+   { "glGetProgramResourceName", 31, -1 },
+   { "glGetProgramResourceiv", 31, -1 },
+   { "glGetProgramResourceLocation", 31, -1 },
+
+   // We check for the aliased EXT versions in GLES 2
+   // { "glUseProgramStages", 31, -1 },
+   // { "glActiveShaderProgram", 31, -1 },
+   // { "glCreateShaderProgramv", 31, -1 },
+   // { "glBindProgramPipeline", 31, -1 },
+   // { "glDeleteProgramPipelines", 31, -1 },
+   // { "glGenProgramPipelines", 31, -1 },
+   // { "glIsProgramPipeline", 31, -1 },
+   // { "glGetProgramPipelineiv", 31, -1 },
+   // { "glProgramUniform1i", 31, -1 },
+   // { "glProgramUniform2i", 31, -1 },
+   // { "glProgramUniform3i", 31, -1 },
+   // { "glProgramUniform4i", 31, -1 },
+   // { "glProgramUniform1f", 31, -1 },
+   // { "glProgramUniform2f", 31, -1 },
+   // { "glProgramUniform3f", 31, -1 },
+   // { "glProgramUniform4f", 31, -1 },
+   // { "glProgramUniform1iv", 31, -1 },
+   // { "glProgramUniform2iv", 31, -1 },
+   // { "glProgramUniform3iv", 31, -1 },
+   // { "glProgramUniform4iv", 31, -1 },
+   // { "glProgramUniform1fv", 31, -1 },
+   // { "glProgramUniform2fv", 31, -1 },
+   // { "glProgramUniform3fv", 31, -1 },
+   // { "glProgramUniform4fv", 31, -1 },
+   // { "glProgramUniformMatrix2fv", 31, -1 },
+   // { "glProgramUniformMatrix3fv", 31, -1 },
+   // { "glProgramUniformMatrix4fv", 31, -1 },
+   // { "glProgramUniformMatrix2x3fv", 31, -1 },
+   // { "glProgramUniformMatrix3x2fv", 31, -1 },
+   // { "glProgramUniformMatrix2x4fv", 31, -1 },
+   // { "glProgramUniformMatrix4x2fv", 31, -1 },
+   // { "glProgramUniformMatrix3x4fv", 31, -1 },
+   // { "glProgramUniformMatrix4x3fv", 31, -1 },
+   // { "glValidateProgramPipeline", 31, -1 },
+   // { "glGetProgramPipelineInfoLog", 31, -1 },
+
+   // We check for the aliased EXT versions in GLES 3
+   // { "glProgramUniform1ui", 31, -1 },
+   // { "glProgramUniform2ui", 31, -1 },
+   // { "glProgramUniform3ui", 31, -1 },
+   // { "glProgramUniform4ui", 31, -1 },
+   // { "glProgramUniform1uiv", 31, -1 },
+   // { "glProgramUniform2uiv", 31, -1 },
+   // { "glProgramUniform3uiv", 31, -1 },
+   // { "glProgramUniform4uiv", 31, -1 },
+
+   { "glBindImageTexture", 31, -1 },
+   { "glGetBooleani_v", 31, -1 },
+   { "glMemoryBarrier", 31, -1 },
+
+   // FINISHME: This function has not been implemented yet.
+   // { "glMemoryBarrierByRegion", 31, -1 },
+
+   { "glTexStorage2DMultisample", 31, -1 },
+   { "glGetMultisamplefv", 31, -1 },
+   { "glSampleMaski", 31, -1 },
+   { "glGetTexLevelParameteriv", 31, -1 },
+   { "glGetTexLevelParameterfv", 31, -1 },
+   { "glBindVertexBuffer", 31, -1 },
+   { "glVertexAttribFormat", 31, -1 },
+   { "glVertexAttribIFormat", 31, -1 },
+   { "glVertexAttribBinding", 31, -1 },
+   { "glVertexBindingDivisor", 31, -1 },
+
+   { NULL, 0, -1 },
+ };
index ec521e6c6e599f25a67031b77d8406e78cd9e566..3edafc0f776f41693e7c1e4096a255bc904360e3 100644 (file)
@@ -646,7 +646,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
       if (pname == GL_TEXTURE_ENV_COLOR) {
          if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
             _mesa_update_state(ctx);
-         if (_mesa_get_clamp_fragment_color(ctx))
+         if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
             COPY_4FV( params, texUnit->EnvColor );
          else
             COPY_4FV( params, texUnit->EnvColorUnclamped );
index 7bc1da7f805b8e5e9f87367c27bbd166b0718a7b..3d85615fa45e38c5d06efe682382ce05120e09e5 100644 (file)
@@ -222,7 +222,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
       }
    }
 
-   if (ctx->Extensions.ARB_stencil_texturing) {
+   if (ctx->Extensions.ARB_texture_stencil8) {
       switch (internalFormat) {
       case GL_STENCIL_INDEX:
       case GL_STENCIL_INDEX1:
index b5d42d3047f8a81f7ff8214801e2eb709909899d..d74134f41b189551c85d8bdda7b17df439c6b20c 100644 (file)
@@ -1709,7 +1709,7 @@ get_tex_parameterfv(struct gl_context *ctx,
 
          if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
             _mesa_update_state_locked(ctx);
-         if (_mesa_get_clamp_fragment_color(ctx)) {
+         if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
             params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
             params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
             params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
index cd87a27d2dbd762f53b998b796655d2c6fcfe576..6b0aed4ea1a92751f1ea6c84f6437e780325b973 100644 (file)
@@ -167,7 +167,7 @@ static const struct internal_format_class_info s3tc_compatible_internal_formats[
  * \return VIEW_CLASS if internalformat found in table, false otherwise.
  */
 static GLenum
-lookup_view_class(struct gl_context *ctx, GLenum internalformat)
+lookup_view_class(const struct gl_context *ctx, GLenum internalformat)
 {
    GLuint i;
 
@@ -176,9 +176,11 @@ lookup_view_class(struct gl_context *ctx, GLenum internalformat)
          return compatible_internal_formats[i].view_class;
    }
 
-   if (ctx->Extensions.EXT_texture_compression_s3tc && ctx->Extensions.EXT_texture_sRGB) {
+   if (ctx->Extensions.EXT_texture_compression_s3tc &&
+       ctx->Extensions.EXT_texture_sRGB) {
       for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) {
-         if (s3tc_compatible_internal_formats[i].internal_format == internalformat)
+         if (s3tc_compatible_internal_formats[i].internal_format
+             == internalformat)
             return s3tc_compatible_internal_formats[i].view_class;
       }
    }
@@ -226,7 +228,8 @@ initialize_texture_fields(struct gl_context *ctx,
                                     0, internalFormat, texFormat);
       }
 
-      _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
+      _mesa_next_mipmap_level_size(target, 0,
+                                   levelWidth, levelHeight, levelDepth,
                                    &levelWidth, &levelHeight, &levelDepth);
    }
 
@@ -320,8 +323,8 @@ target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)
  * If an error is found, record it with _mesa_error()
  * \return false if any error, true otherwise.
  */
-GLboolean
-_mesa_texture_view_compatible_format(struct gl_context *ctx,
+bool
+_mesa_texture_view_compatible_format(const struct gl_context *ctx,
                                      GLenum origInternalFormat,
                                      GLenum newInternalFormat)
 {
@@ -334,15 +337,16 @@ _mesa_texture_view_compatible_format(struct gl_context *ctx,
     * or an INVALID_OPERATION error is generated.
     */
    if (origInternalFormat == newInternalFormat)
-      return GL_TRUE;
+      return true;
 
    origViewClass = lookup_view_class(ctx, origInternalFormat);
    newViewClass = lookup_view_class(ctx, newInternalFormat);
    if ((origViewClass == newViewClass) && origViewClass != false)
-      return GL_TRUE;
+      return true;
 
-   return GL_FALSE;
+   return false;
 }
+
 /**
  * Helper function for TexStorage and teximagemultisample to set immutable
  * texture state needed by ARB_texture_view.
@@ -357,17 +361,19 @@ _mesa_set_texture_view_state(struct gl_context *ctx,
    /* Get a reference to what will become this View's base level */
    texImage = _mesa_select_tex_image(texObj, target, 0);
 
-   /* When an immutable texture is created via glTexStorage or glTexImageMultisample,
+   /* When an immutable texture is created via glTexStorage or
+    * glTexImageMultisample,
     * TEXTURE_IMMUTABLE_FORMAT becomes TRUE.
     * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels.
     * If the texture target is TEXTURE_1D_ARRAY then
     * TEXTURE_VIEW_NUM_LAYERS becomes height.
     * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY,
-    * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes depth.
+    * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes
+    * depth.
     * If the texture target is TEXTURE_CUBE_MAP, then
     * TEXTURE_VIEW_NUM_LAYERS becomes 6.
     * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1.
-    * 
+    *
     * ARB_texture_multisample: Multisample textures do
     * not have multiple image levels.
     */
@@ -401,7 +407,6 @@ _mesa_set_texture_view_state(struct gl_context *ctx,
    case GL_TEXTURE_CUBE_MAP:
       texObj->NumLayers = 6;
       break;
-
    }
 }
 
@@ -435,16 +440,20 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
                   minlevel, numlevels, minlayer, numlayers);
 
    if (origtexture == 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
+      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
+                  origtexture);
       return;
    }
 
    /* Need original texture information to validate arguments */
    origTexObj = _mesa_lookup_texture(ctx, origtexture);
 
-   /* If <origtexture> is not the name of a texture, INVALID_VALUE is generated. */
+   /* If <origtexture> is not the name of a texture, INVALID_VALUE
+    * is generated.
+    */
    if (!origTexObj) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
+      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
+                  origtexture);
       return;
    }
 
@@ -452,7 +461,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
     * INVALID_OPERATION is generated.
     */
    if (!origTexObj->Immutable) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture not immutable)");
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(origtexture not immutable)");
       return;
    }
 
@@ -467,7 +477,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
     */
    texObj = _mesa_lookup_texture(ctx, texture);
    if (texObj == NULL) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u non-gen name)", texture);
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(texture = %u non-gen name)", texture);
       return;
    }
 
@@ -475,7 +486,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
     * the error INVALID_OPERATION is generated.
     */
    if (texObj->Target) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u already bound)", texture);
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(texture = %u already bound)", texture);
       return;
    }
 
@@ -484,33 +496,35 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
       return; /* error was recorded */
    }
 
-   /* minlevel and minlayer are relative to the view of origtexture
+   /* minlevel and minlayer are relative to the view of origtexture.
     * If minlevel or minlayer is greater than level or layer, respectively,
-    * of origtexture return INVALID_VALUE.
+    * return INVALID_VALUE.
     */
    newViewMinLevel = origTexObj->MinLevel + minlevel;
    newViewMinLayer = origTexObj->MinLayer + minlayer;
    if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) {
       _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glTextureView(new minlevel (%d) > orig minlevel (%d) + orig numlevels (%d))",
+                  "glTextureView(new minlevel (%d) > orig minlevel (%d)"
+                  " + orig numlevels (%d))",
                   newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels);
       return;
    }
 
    if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) {
       _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glTextureView(new minlayer (%d) > orig minlayer (%d) + orig numlayers (%d))",
+                  "glTextureView(new minlayer (%d) > orig minlayer (%d)"
+                  " + orig numlayers (%d))",
                   newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers);
       return;
    }
 
    if (!_mesa_texture_view_compatible_format(ctx,
-                                             origTexObj->Image[0][0]->InternalFormat,
-                                             internalformat)) {
+                                   origTexObj->Image[0][0]->InternalFormat,
+                                   internalformat)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glTextureView(internalformat %s not compatible with origtexture %s)",
-                  _mesa_lookup_enum_by_nr(internalformat),
-                  _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));
+          "glTextureView(internalformat %s not compatible with origtexture %s)",
+          _mesa_lookup_enum_by_nr(internalformat),
+          _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));
       return;
    }
 
@@ -569,14 +583,16 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
    dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
                                                  width, height, depth, 0);
    if (!dimensionsOK) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid width or height or depth)");
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(invalid width or height or depth)");
       return;
    }
 
    sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
                                           width, height, depth, 0);
    if (!sizeOK) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid texture size)");
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(invalid texture size)");
       return;
    }
 
@@ -591,17 +607,19 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
    case GL_TEXTURE_RECTANGLE:
    case GL_TEXTURE_2D_MULTISAMPLE:
       if (numlayers != 1) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", numlayers);
+         _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)",
+                     numlayers);
          return;
       }
       break;
 
    case GL_TEXTURE_CUBE_MAP:
-      /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped <numlayers>
-       * must be equal to 6.
+      /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped
+       * <numlayers> must be equal to 6.
        */
       if (newViewNumLayers != 6) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(clamped numlayers %d != 6)",
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glTextureView(clamped numlayers %d != 6)",
                      newViewNumLayers);
          return;
       }
@@ -615,7 +633,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
        */
       if ((newViewNumLayers % 6) != 0) {
          _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glTextureView(clamped numlayers %d is not a multiple of 6)",
+                     "glTextureView(clamped numlayers %d is not"
+                     " a multiple of 6)",
                      newViewNumLayers);
          return;
       }
@@ -628,7 +647,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
     */
    if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
        (origTexImage->Width != origTexImage->Height)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture width (%d) != height (%d))",
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(origtexture width (%d) != height (%d))",
                   origTexImage->Width, origTexImage->Height);
       return;
    }
@@ -662,7 +682,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
    texObj->ImmutableLevels = origTexObj->ImmutableLevels;
    texObj->Target = target;
 
-   if (ctx->Driver.TextureView != NULL && !ctx->Driver.TextureView(ctx, texObj, origTexObj)) {
+   if (ctx->Driver.TextureView != NULL &&
+       !ctx->Driver.TextureView(ctx, texObj, origTexObj)) {
       return; /* driver recorded error */
    }
 }
index 549a13cd809fda8d0326c4e6a27b6d1d834b36d0..59e24b68dd016a7780ca2c49d5873b45669e475a 100644 (file)
@@ -29,8 +29,8 @@
 #ifndef TEXTUREVIEW_H
 #define TEXTUREVIEW_H
 
-GLboolean
-_mesa_texture_view_compatible_format(struct gl_context *ctx,
+bool
+_mesa_texture_view_compatible_format(const struct gl_context *ctx,
                                      GLenum origInternalFormat,
                                      GLenum newInternalFormat);
 
@@ -41,7 +41,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
                   GLuint minlayer, GLuint numlayers);
 
 extern void
-_mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_object *texObj,
-                       GLenum target, GLuint levels);
+_mesa_set_texture_view_state(struct gl_context *ctx,
+                             struct gl_texture_object *texObj,
+                             GLenum target, GLuint levels);
 
 #endif /* TEXTUREVIEW_H */
index 728bd1bac101d6adf187555d59413ecc520475fc..cab5083e81b38e2babecbe98e091624a8bc32cff 100644 (file)
@@ -237,6 +237,13 @@ validate_uniform_parameters(struct gl_context *ctx,
 
    struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
 
+   /* Even though no location is assigned to a built-in uniform and this
+    * function should already have returned NULL, this test makes it explicit
+    * that we are not allowing to update the value of a built-in.
+    */
+   if (uni->builtin)
+      return NULL;
+
    if (uni->array_elements == 0) {
       if (count > 1) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1028,6 +1035,10 @@ _mesa_get_uniform_location(struct gl_shader_program *shProg,
    if (!found)
       return GL_INVALID_INDEX;
 
+   /* If the uniform is built-in, fail. */
+   if (shProg->UniformStorage[location].builtin)
+      return GL_INVALID_INDEX;
+
    /* If the uniform is an array, fail if the index is out of bounds.
     * (A negative index is caught above.)  This also fails if the uniform
     * is not an array, but the user is trying to index it, because
@@ -1047,7 +1058,7 @@ _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
                                 char *errMsg, size_t errMsgLength)
 {
    /* Shader does not have samplers. */
-   if (shProg->NumUserUniformStorage == 0)
+   if (shProg->NumUniformStorage == 0)
       return true;
 
    if (!shProg->SamplersValidated) {
@@ -1087,7 +1098,7 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
       if (!shProg[idx])
          continue;
 
-      for (unsigned i = 0; i < shProg[idx]->NumUserUniformStorage; i++) {
+      for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++) {
          const struct gl_uniform_storage *const storage =
             &shProg[idx]->UniformStorage[i];
          const glsl_type *const t = (storage->type->is_array())
index 55fa2357e38033d0813a3632bda75384753671c9..bd7b05e207afb021d99f3352108dfb02efaf4f3e 100644 (file)
@@ -343,10 +343,6 @@ void GLAPIENTRY
 _mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count,
                                 GLboolean transpose, const GLdouble *value);
 
-long
-_mesa_parse_program_resource_name(const GLchar *name,
-                                  const GLchar **out_base_name_end);
-
 unsigned
 _mesa_get_uniform_location(struct gl_shader_program *shProg,
                           const GLchar *name, unsigned *offset);
index 7389037ae853133ed60d5449a8cbbc656086999c..ebdd9eaf02e2def570c6d878a2ddd08946498067 100644 (file)
@@ -2309,10 +2309,10 @@ print_array(const char *name, GLint index, const struct gl_client_array *array)
       fprintf(stderr, "  %s[%d]: ", name, index);
    else
       fprintf(stderr, "  %s: ", name);
-   fprintf(stderr, "Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu)\n",
-         array->Ptr, array->Type, array->Size,
-         array->_ElementSize, array->StrideB,
-         array->BufferObj->Name, (unsigned long) array->BufferObj->Size);
+   fprintf(stderr, "Ptr=%p, Type=%s, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu)\n",
+           array->Ptr, _mesa_lookup_enum_by_nr(array->Type), array->Size,
+           array->_ElementSize, array->StrideB, array->BufferObj->Name,
+           (unsigned long) array->BufferObj->Size);
 }
 
 
index 699a0de46c2d6e65bd0aa3628216cb497ed9c359..8bc00ace5c483b3741d34fb26f884f34a68b4e8d 100644 (file)
@@ -51,31 +51,51 @@ check_for_ending(const char *string, const char *ending)
  * fwd_context is only valid if version > 0
  */
 static void
-get_gl_override(int *version, bool *fwd_context, bool *compat_context)
+get_gl_override(gl_api api, int *version, bool *fwd_context,
+                bool *compat_context)
 {
-   const char *env_var = "MESA_GL_VERSION_OVERRIDE";
+   const char *env_var = (api == API_OPENGL_CORE || api == API_OPENGL_COMPAT)
+      ? "MESA_GL_VERSION_OVERRIDE" : "MESA_GLES_VERSION_OVERRIDE";
    const char *version_str;
    int major, minor, n;
-   static int override_version = -1;
-   static bool fc_suffix = false;
-   static bool compat_suffix = false;
+   static struct override_info {
+      int version;
+      bool fc_suffix;
+      bool compat_suffix;
+   } override[] = {
+      { -1, false, false},
+      { -1, false, false},
+      { -1, false, false},
+      { -1, false, false},
+   };
 
-   if (override_version < 0) {
-      override_version = 0;
+   STATIC_ASSERT(ARRAY_SIZE(override) == API_OPENGL_LAST + 1);
+
+   if (api == API_OPENGLES)
+      goto exit;
+
+   if (override[api].version < 0) {
+      override[api].version = 0;
 
       version_str = getenv(env_var);
       if (version_str) {
-         fc_suffix = check_for_ending(version_str, "FC");
-         compat_suffix = check_for_ending(version_str, "COMPAT");
+         override[api].fc_suffix = check_for_ending(version_str, "FC");
+         override[api].compat_suffix = check_for_ending(version_str, "COMPAT");
 
          n = sscanf(version_str, "%u.%u", &major, &minor);
          if (n != 2) {
             fprintf(stderr, "error: invalid value for %s: %s\n",
                     env_var, version_str);
-            override_version = 0;
+            override[api].version = 0;
          } else {
-            override_version = major * 10 + minor;
-            if (override_version < 30 && fc_suffix) {
+            override[api].version = major * 10 + minor;
+
+            /* There is no such thing as compatibility or forward-compatible for
+             * OpenGL ES 2.0 or 3.x APIs.
+             */
+            if ((override[api].version < 30 && override[api].fc_suffix) ||
+                (api == API_OPENGLES2 && (override[api].fc_suffix ||
+                                          override[api].compat_suffix))) {
                fprintf(stderr, "error: invalid value for %s: %s\n",
                        env_var, version_str);
             }
@@ -83,9 +103,10 @@ get_gl_override(int *version, bool *fwd_context, bool *compat_context)
       }
    }
 
-   *version = override_version;
-   *fwd_context = fc_suffix;
-   *compat_context = compat_suffix;
+exit:
+   *version = override[api].version;
+   *fwd_context = override[api].fc_suffix;
+   *compat_context = override[api].compat_suffix;
 }
 
 /**
@@ -130,18 +151,26 @@ _mesa_override_gl_version_contextless(struct gl_constants *consts,
    int version;
    bool fwd_context, compat_context;
 
-   get_gl_override(&version, &fwd_context, &compat_context);
+   get_gl_override(*apiOut, &version, &fwd_context, &compat_context);
 
    if (version > 0) {
       *versionOut = version;
-      if (version >= 30 && fwd_context) {
-         *apiOut = API_OPENGL_CORE;
-         consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
-      } else if (version >= 31 && !compat_context) {
-         *apiOut = API_OPENGL_CORE;
-      } else {
-         *apiOut = API_OPENGL_COMPAT;
+
+      /* If the API is a desktop API, adjust the context flags.  We may also
+       * need to modify the API depending on the version.  For example, Mesa
+       * does not support a GL 3.3 compatibility profile.
+       */
+      if (*apiOut == API_OPENGL_CORE || *apiOut == API_OPENGL_COMPAT) {
+         if (version >= 30 && fwd_context) {
+            *apiOut = API_OPENGL_CORE;
+            consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
+         } else if (version >= 31 && !compat_context) {
+            *apiOut = API_OPENGL_CORE;
+         } else {
+            *apiOut = API_OPENGL_COMPAT;
+         }
       }
+
       return true;
    }
    return false;
@@ -156,22 +185,6 @@ _mesa_override_gl_version(struct gl_context *ctx)
    }
 }
 
-/**
- * Returns the gl override value
- *
- * version > 0 indicates there is an override requested
- */
-int
-_mesa_get_gl_version_override(void)
-{
-   int version;
-   bool fwd_context, compat_context;
-
-   get_gl_override(&version, &fwd_context, &compat_context);
-
-   return version;
-}
-
 /**
  * Override the context's GLSL version if the environment variable
  * MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
@@ -433,7 +446,23 @@ compute_version_es2(const struct gl_extensions *extensions)
                          extensions->EXT_texture_snorm &&
                          extensions->NV_primitive_restart &&
                          extensions->OES_depth_texture_cube_map);
-   if (ver_3_0) {
+   const bool ver_3_1 = (ver_3_0 &&
+                         extensions->ARB_arrays_of_arrays &&
+                         extensions->ARB_compute_shader &&
+                         extensions->ARB_draw_indirect &&
+                         false /*extensions->ARB_framebuffer_no_attachments*/ &&
+                         extensions->ARB_shader_atomic_counters &&
+                         extensions->ARB_shader_image_load_store &&
+                         false /*extensions->ARB_shader_image_size*/ &&
+                         false /*extensions->ARB_shader_storage_buffer_object*/ &&
+                         extensions->ARB_shading_language_packing &&
+                         extensions->ARB_stencil_texturing &&
+                         extensions->ARB_gpu_shader5 &&
+                         extensions->EXT_shader_integer_mix);
+
+   if (ver_3_1) {
+      return 31;
+   } else if (ver_3_0) {
       return 30;
    } else if (ver_2_0) {
       return 20;
index 450a0e31d3d23907bf595916ceac8eefd2c9239d..ee7cb7501eb48a30b4dde1f0a8b4704ae5dc4c5a 100644 (file)
@@ -47,7 +47,4 @@ _mesa_override_gl_version(struct gl_context *ctx);
 extern void
 _mesa_override_glsl_version(struct gl_constants *consts);
 
-extern int
-_mesa_get_gl_version_override(void);
-
 #endif /* VERSION_H */
index d7ef7e278cd5220fb249507056ddb810d70e7f91..81bf4c589eac28057ad965a64dbcaac6038fbeec 100644 (file)
@@ -207,7 +207,7 @@ install_vtxfmt(struct gl_context *ctx, struct _glapi_table *tab,
       SET_VertexAttribP4uiv(tab, vfmt->VertexAttribP4uiv);
    }
 
-   if (_mesa_is_desktop_gl(ctx)) {
+   if (ctx->API == API_OPENGL_CORE) {
       SET_VertexAttribL1d(tab, vfmt->VertexAttribL1d);
       SET_VertexAttribL2d(tab, vfmt->VertexAttribL2d);
       SET_VertexAttribL3d(tab, vfmt->VertexAttribL3d);
diff --git a/src/mesa/program/dummy_errors.c b/src/mesa/program/dummy_errors.c
new file mode 100644 (file)
index 0000000..d69f54d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright Â© 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include "main/errors.h"
+
+void
+_mesa_error_no_memory(const char *caller)
+{
+   fprintf(stderr, "Mesa error: out of memory in %s", caller);
+}
index fceed712bdb47d75d97005e84eaa77c883877fe2..3bffe90ff1f190a96bfe61a4823aa42cd8c91326 100644 (file)
@@ -262,6 +262,7 @@ public:
    virtual void visit(ir_if *);
    virtual void visit(ir_emit_vertex *);
    virtual void visit(ir_end_primitive *);
+   virtual void visit(ir_barrier *);
    /*@}*/
 
    src_reg result;
@@ -405,7 +406,7 @@ ir_to_mesa_visitor::emit_dp(ir_instruction *ir,
                            dst_reg dst, src_reg src0, src_reg src1,
                            unsigned elements)
 {
-   static const gl_inst_opcode dot_opcodes[] = {
+   static const enum prog_opcode dot_opcodes[] = {
       OPCODE_DP2, OPCODE_DP3, OPCODE_DP4
    };
 
@@ -2118,6 +2119,12 @@ ir_to_mesa_visitor::visit(ir_end_primitive *)
    assert(!"Geometry shaders not supported.");
 }
 
+void
+ir_to_mesa_visitor::visit(ir_barrier *)
+{
+   unreachable("GLSL barrier() not supported.");
+}
+
 ir_to_mesa_visitor::ir_to_mesa_visitor()
 {
    result.file = PROGRAM_UNDEFINED;
@@ -2407,9 +2414,14 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
       if (!found)
         continue;
 
+      struct gl_uniform_storage *storage =
+         &shader_program->UniformStorage[location];
+
+      /* Do not associate any uniform storage to built-in uniforms */
+      if (storage->builtin)
+         continue;
+
       if (location != last_location) {
-        struct gl_uniform_storage *storage =
-           &shader_program->UniformStorage[location];
         enum gl_uniform_driver_format format = uniform_native;
 
         unsigned columns = 0;
@@ -2722,7 +2734,7 @@ get_mesa_program(struct gl_context *ctx,
       mesa_inst->Opcode = inst->op;
       mesa_inst->CondUpdate = inst->cond_update;
       if (inst->saturate)
-        mesa_inst->SaturateMode = SATURATE_ZERO_ONE;
+        mesa_inst->Saturate = GL_TRUE;
       mesa_inst->DstReg.File = inst->dst.file;
       mesa_inst->DstReg.Index = inst->dst.index;
       mesa_inst->DstReg.CondMask = inst->dst.cond_mask;
index 16e8e340d8d93b0221b4ae1e2c8d3e6a028aa530..46260b5488242897045971c7a956482fb4eaed8a 100644 (file)
@@ -397,7 +397,7 @@ store_vector4(const struct prog_instruction *inst,
               struct gl_program_machine *machine, const GLfloat value[4])
 {
    const struct prog_dst_register *dstReg = &(inst->DstReg);
-   const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
+   const GLboolean clamp = inst->Saturate;
    GLuint writeMask = dstReg->WriteMask;
    GLfloat clampedValue[4];
    GLfloat *dst = get_dst_register_pointer(dstReg, machine);
index f9ebe4e8fd2e05293a5a829cc2eb48b0817e0aa3..21ef35337f65b994d220d4e571e06d033e7b2e6f 100644 (file)
@@ -55,7 +55,7 @@ _mesa_init_instructions(struct prog_instruction *inst, GLuint count)
       inst[i].DstReg.CondMask = COND_TR;
       inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
 
-      inst[i].SaturateMode = SATURATE_OFF;
+      inst[i].Saturate = GL_FALSE;
       inst[i].Precision = FLOAT32;
    }
 }
@@ -114,7 +114,7 @@ _mesa_free_instructions(struct prog_instruction *inst, GLuint count)
  */
 struct instruction_info
 {
-   gl_inst_opcode Opcode;
+   enum prog_opcode Opcode;
    const char *Name;
    GLuint NumSrcRegs;
    GLuint NumDstRegs;
@@ -198,7 +198,7 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = {
  * Return the number of src registers for the given instruction/opcode.
  */
 GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode)
+_mesa_num_inst_src_regs(enum prog_opcode opcode)
 {
    assert(opcode < MAX_OPCODE);
    assert(opcode == InstInfo[opcode].Opcode);
@@ -211,7 +211,7 @@ _mesa_num_inst_src_regs(gl_inst_opcode opcode)
  * Return the number of dst registers for the given instruction/opcode.
  */
 GLuint
-_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
+_mesa_num_inst_dst_regs(enum prog_opcode opcode)
 {
    assert(opcode < MAX_OPCODE);
    assert(opcode == InstInfo[opcode].Opcode);
@@ -221,7 +221,7 @@ _mesa_num_inst_dst_regs(gl_inst_opcode opcode)
 
 
 GLboolean
-_mesa_is_tex_instruction(gl_inst_opcode opcode)
+_mesa_is_tex_instruction(enum prog_opcode opcode)
 {
    return (opcode == OPCODE_TEX ||
            opcode == OPCODE_TXB ||
@@ -285,7 +285,7 @@ _mesa_check_soa_dependencies(const struct prog_instruction *inst)
  * Return string name for given program opcode.
  */
 const char *
-_mesa_opcode_string(gl_inst_opcode opcode)
+_mesa_opcode_string(enum prog_opcode opcode)
 {
    if (opcode < MAX_OPCODE)
       return InstInfo[opcode].Name;
index 96da198f86db22403d23309fccca8a511d89f26d..d56f96cfaa1d7828538398719e3cabd91ff7b379 100644 (file)
 /*@}*/
 
 
-/**
- * Saturation modes when storing values.
- */
-/*@{*/
-#define SATURATE_OFF            0
-#define SATURATE_ZERO_ONE       1
-/*@}*/
-
-
 /**
  * Per-component negation masks
  */
 /**
  * Program instruction opcodes for vertex, fragment and geometry programs.
  */
-typedef enum prog_opcode {
+enum prog_opcode {
                      /* ARB_vp   ARB_fp   NV_vp   NV_fp     GLSL */
                      /*------------------------------------------*/
    OPCODE_NOP = 0,   /*                                      X   */
@@ -213,7 +204,7 @@ typedef enum prog_opcode {
    OPCODE_TRUNC,     /*                                      X   */
    OPCODE_XPD,       /*   X        X                             */
    MAX_OPCODE
-} gl_inst_opcode;
+};
 
 
 /**
@@ -300,7 +291,7 @@ struct prog_dst_register
  */
 struct prog_instruction
 {
-   gl_inst_opcode Opcode;
+   enum prog_opcode Opcode;
    struct prog_src_register SrcReg[3];
    struct prog_dst_register DstReg;
 
@@ -327,15 +318,12 @@ struct prog_instruction
    GLuint CondDst:1;
 
    /**
-    * Saturate each value of the vectored result to the range [0,1] or the
-    * range [-1,1].  \c SSAT mode (i.e., saturation to the range [-1,1]) is
-    * only available in NV_fragment_program2 mode.
-    * Value is one of the SATURATE_* tokens.
+    * Saturate each value of the vectored result to the range [0,1].
     *
     * \since
     * NV_fragment_program_option, NV_vertex_program3.
     */
-   GLuint SaturateMode:2;
+   GLuint Saturate:1;
 
    /**
     * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
@@ -368,9 +356,6 @@ struct prog_instruction
     */
    GLint BranchTarget;
 
-   /** for driver use (try to remove someday) */
-   GLint Aux;
-
    /** for debugging purposes */
    const char *Comment;
 };
@@ -394,19 +379,19 @@ extern void
 _mesa_free_instructions(struct prog_instruction *inst, GLuint count);
 
 extern GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+_mesa_num_inst_src_regs(enum prog_opcode opcode);
 
 extern GLuint
-_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
+_mesa_num_inst_dst_regs(enum prog_opcode opcode);
 
 extern GLboolean
-_mesa_is_tex_instruction(gl_inst_opcode opcode);
+_mesa_is_tex_instruction(enum prog_opcode opcode);
 
 extern GLboolean
 _mesa_check_soa_dependencies(const struct prog_instruction *inst);
 
 extern const char *
-_mesa_opcode_string(gl_inst_opcode opcode);
+_mesa_opcode_string(enum prog_opcode opcode);
 
 
 #ifdef __cplusplus
index 6d4485acb65935cb0f89f0eb755b28a289f0553a..f9e9035fc3e4a788ea5a1649fab9d2c46e858809 100644 (file)
@@ -478,7 +478,7 @@ can_upward_mov_be_modifed(const struct prog_instruction *mov)
    return
       can_downward_mov_be_modifed(mov) &&
       mov->DstReg.File == PROGRAM_TEMPORARY &&
-      mov->SaturateMode == SATURATE_OFF;
+      !mov->Saturate;
 }
 
 
@@ -653,7 +653,7 @@ _mesa_merge_mov_into_inst(struct prog_instruction *inst,
    if (mask != (inst->DstReg.WriteMask & mask))
       return GL_FALSE;
 
-   inst->SaturateMode |= mov->SaturateMode;
+   inst->Saturate |= mov->Saturate;
 
    /* Depending on the instruction, we may need to recompute the swizzles.
     * Also, some other instructions (like TEX) are not linear. We will only
index d588d07ffe418b6aadc0f682b183713155db38a4..e4faa63c06f995dd58d158619a660f2e9ca882e4 100644 (file)
@@ -600,7 +600,7 @@ _mesa_fprint_alu_instruction(FILE *f,
       fprintf(f, ".C");
 
    /* frag prog only */
-   if (inst->SaturateMode == SATURATE_ZERO_ONE)
+   if (inst->Saturate)
       fprintf(f, "_SAT");
 
    fprintf(f, " ");
@@ -658,7 +658,7 @@ _mesa_fprint_instruction_opt(FILE *f,
    switch (inst->Opcode) {
    case OPCODE_SWZ:
       fprintf(f, "SWZ");
-      if (inst->SaturateMode == SATURATE_ZERO_ONE)
+      if (inst->Saturate)
          fprintf(f, "_SAT");
       fprintf(f, " ");
       fprint_dst_reg(f, &inst->DstReg, mode, prog);
@@ -675,7 +675,7 @@ _mesa_fprint_instruction_opt(FILE *f,
    case OPCODE_TXB:
    case OPCODE_TXD:
       fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
-      if (inst->SaturateMode == SATURATE_ZERO_ONE)
+      if (inst->Saturate)
          fprintf(f, "_SAT");
       fprintf(f, " ");
       fprint_dst_reg(f, &inst->DstReg, mode, prog);
@@ -864,7 +864,7 @@ _mesa_fprint_program_opt(FILE *f,
       else
          fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
       break;
-   case MESA_GEOMETRY_PROGRAM:
+   case GL_GEOMETRY_PROGRAM_NV:
       fprintf(f, "# Geometry Shader\n");
    }
 
index 0c0c87faa280163497ea3cd2e56787c3df4322fd..bdb335e4ba3ab1c62b4f7c2581e406bb364f6d4a 100644 (file)
@@ -244,14 +244,14 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
       {
          /* state[1] is the texture unit */
          const GLuint unit = (GLuint) state[1];
-         if (_mesa_get_clamp_fragment_color(ctx))
+         if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
             COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
          else
             COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped);
       }
       return;
    case STATE_FOG_COLOR:
-      if (_mesa_get_clamp_fragment_color(ctx))
+      if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
          COPY_4V(value, ctx->Fog.Color);
       else
          COPY_4V(value, ctx->Fog.ColorUnclamped);
index 6c5fa51ec612968ab64071fbe9feff2b52a9edfa..d54f934247da773eb22768a5ccb49df9dcc29f46 100644 (file)
@@ -47,6 +47,7 @@ struct ptn_compile {
    nir_builder build;
    bool error;
 
+   nir_variable *parameters;
    nir_variable *input_vars[VARYING_SLOT_MAX];
    nir_variable *output_vars[VARYING_SLOT_MAX];
    nir_register **output_regs;
@@ -112,21 +113,6 @@ ptn_get_dest(struct ptn_compile *c, const struct prog_dst_register *prog_dst)
    return dest;
 }
 
-/**
- * Multiply the contents of the ADDR register by 4 to convert from the number
- * of vec4s to the number of floating point components.
- */
-static nir_ssa_def *
-ptn_addr_reg_value(struct ptn_compile *c)
-{
-   nir_builder *b = &c->build;
-   nir_alu_src src;
-   memset(&src, 0, sizeof(src));
-   src.src = nir_src_for_reg(c->addr_reg);
-
-   return nir_imul(b, nir_fmov_alu(b, src, 1), nir_imm_int(b, 4));
-}
-
 static nir_ssa_def *
 ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
 {
@@ -180,27 +166,38 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
          }
          /* FALLTHROUGH */
       case PROGRAM_STATE_VAR: {
-         nir_intrinsic_op load_op =
-            prog_src->RelAddr ? nir_intrinsic_load_uniform_indirect :
-                                nir_intrinsic_load_uniform;
-         nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, load_op);
+         nir_intrinsic_instr *load =
+            nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
          nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
          load->num_components = 4;
 
-         /* Multiply src->Index by 4 to scale from # of vec4s to components. */
-         load->const_index[0] = 4 * prog_src->Index;
-         load->const_index[1] = 1;
+         load->variables[0] = nir_deref_var_create(load, c->parameters);
+         nir_deref_array *deref_arr =
+            nir_deref_array_create(load->variables[0]);
+         deref_arr->deref.type = glsl_vec4_type();
+         load->variables[0]->deref.child = &deref_arr->deref;
 
          if (prog_src->RelAddr) {
-            nir_ssa_def *reladdr = ptn_addr_reg_value(c);
+            deref_arr->deref_array_type = nir_deref_array_type_indirect;
+
+            nir_alu_src addr_src = { NIR_SRC_INIT };
+            addr_src.src = nir_src_for_reg(c->addr_reg);
+            nir_ssa_def *reladdr = nir_imov_alu(b, addr_src, 1);
+
             if (prog_src->Index < 0) {
                /* This is a negative offset which should be added to the address
                 * register's value.
                 */
-               reladdr = nir_iadd(b, reladdr, nir_imm_int(b, load->const_index[0]));
-               load->const_index[0] = 0;
+               reladdr = nir_iadd(b, reladdr, nir_imm_int(b, prog_src->Index));
+
+               deref_arr->base_offset = 0;
+            } else {
+               deref_arr->base_offset = prog_src->Index;
             }
-            load->src[0] = nir_src_for_ssa(reladdr);
+            deref_arr->indirect = nir_src_for_ssa(reladdr);
+         } else {
+            deref_arr->deref_array_type = nir_deref_array_type_direct;
+            deref_arr->base_offset = prog_src->Index;
          }
 
          nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
@@ -700,7 +697,7 @@ static const nir_op op_trans[MAX_OPCODE] = {
    [OPCODE_ADD] = nir_op_fadd,
    [OPCODE_ARL] = 0,
    [OPCODE_CMP] = 0,
-   [OPCODE_COS] = nir_op_fcos,
+   [OPCODE_COS] = 0,
    [OPCODE_DDX] = nir_op_fddx,
    [OPCODE_DDY] = nir_op_fddy,
    [OPCODE_DP2] = 0,
@@ -709,11 +706,11 @@ static const nir_op op_trans[MAX_OPCODE] = {
    [OPCODE_DPH] = 0,
    [OPCODE_DST] = 0,
    [OPCODE_END] = 0,
-   [OPCODE_EX2] = nir_op_fexp2,
+   [OPCODE_EX2] = 0,
    [OPCODE_EXP] = 0,
    [OPCODE_FLR] = nir_op_ffloor,
    [OPCODE_FRC] = nir_op_ffract,
-   [OPCODE_LG2] = nir_op_flog2,
+   [OPCODE_LG2] = 0,
    [OPCODE_LIT] = 0,
    [OPCODE_LOG] = 0,
    [OPCODE_LRP] = 0,
@@ -722,15 +719,15 @@ static const nir_op op_trans[MAX_OPCODE] = {
    [OPCODE_MIN] = nir_op_fmin,
    [OPCODE_MOV] = nir_op_fmov,
    [OPCODE_MUL] = nir_op_fmul,
-   [OPCODE_POW] = nir_op_fpow,
-   [OPCODE_RCP] = nir_op_frcp,
+   [OPCODE_POW] = 0,
+   [OPCODE_RCP] = 0,
 
-   [OPCODE_RSQ] = nir_op_frsq,
+   [OPCODE_RSQ] = 0,
    [OPCODE_SCS] = 0,
    [OPCODE_SEQ] = 0,
    [OPCODE_SGE] = 0,
    [OPCODE_SGT] = 0,
-   [OPCODE_SIN] = nir_op_fsin,
+   [OPCODE_SIN] = 0,
    [OPCODE_SLE] = 0,
    [OPCODE_SLT] = 0,
    [OPCODE_SNE] = 0,
@@ -767,7 +764,8 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
 
    switch (op) {
    case OPCODE_RSQ:
-      ptn_move_dest(b, dest, nir_frsq(b, ptn_channel(b, src[0], X)));
+      ptn_move_dest(b, dest,
+                    nir_frsq(b, nir_fabs(b, ptn_channel(b, src[0], X))));
       break;
 
    case OPCODE_RCP:
@@ -894,7 +892,7 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
       break;
 
    default:
-      if (op_trans[op] != 0 || op == OPCODE_MOV) {
+      if (op_trans[op] != 0) {
          ptn_alu(b, op_trans[op], dest, src);
       } else {
          fprintf(stderr, "unknown opcode: %s\n", _mesa_opcode_string(op));
@@ -903,8 +901,8 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
       break;
    }
 
-   if (prog_inst->SaturateMode) {
-      assert(prog_inst->SaturateMode == SATURATE_ZERO_ONE);
+   if (prog_inst->Saturate) {
+      assert(prog_inst->Saturate);
       assert(!dest.dest.is_ssa);
       ptn_move_dest(b, dest, nir_fsat(b, ptn_src_for_dest(c, &dest)));
    }
@@ -926,10 +924,23 @@ ptn_add_output_stores(struct ptn_compile *c)
    foreach_list_typed(nir_variable, var, node, &b->shader->outputs) {
       nir_intrinsic_instr *store =
          nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
-      store->num_components = 4;
+      store->num_components = glsl_get_vector_elements(var->type);
       store->variables[0] =
          nir_deref_var_create(store, c->output_vars[var->data.location]);
-      store->src[0].reg.reg = c->output_regs[var->data.location];
+
+      if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
+          var->data.location == FRAG_RESULT_DEPTH) {
+         /* result.depth has this strange convention of being the .z component of
+          * a vec4 with undefined .xyw components.  We resolve it to a scalar, to
+          * match GLSL's gl_FragDepth and the expectations of most backends.
+          */
+         nir_alu_src alu_src = { NIR_SRC_INIT };
+         alu_src.src = nir_src_for_reg(c->output_regs[FRAG_RESULT_DEPTH]);
+         alu_src.swizzle[0] = SWIZZLE_Z;
+         store->src[0] = nir_src_for_ssa(nir_fmov_alu(b, alu_src, 1));
+      } else {
+         store->src[0].reg.reg = c->output_regs[var->data.location];
+      }
       nir_instr_insert_after_cf_list(c->build.cf_node_list, &store->instr);
    }
 }
@@ -1022,7 +1033,10 @@ setup_registers_and_variables(struct ptn_compile *c)
       reg->num_components = 4;
 
       nir_variable *var = rzalloc(shader, nir_variable);
-      var->type = glsl_vec4_type();
+      if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB && i == FRAG_RESULT_DEPTH)
+         var->type = glsl_float_type();
+      else
+         var->type = glsl_vec4_type();
       var->data.mode = nir_var_shader_out;
       var->name = ralloc_asprintf(var, "out_%d", i);
 
@@ -1057,13 +1071,11 @@ setup_registers_and_variables(struct ptn_compile *c)
    }
    reg->num_components = 1;
    c->addr_reg = reg;
-
-   /* Set the number of uniforms */
-   shader->num_uniforms = 4 * c->prog->Parameters->NumParameters;
 }
 
 struct nir_shader *
-prog_to_nir(const struct gl_program *prog, const nir_shader_compiler_options *options)
+prog_to_nir(const struct gl_program *prog,
+            const nir_shader_compiler_options *options)
 {
    struct ptn_compile *c;
    struct nir_shader *s;
@@ -1076,6 +1088,14 @@ prog_to_nir(const struct gl_program *prog, const nir_shader_compiler_options *op
       goto fail;
    c->prog = prog;
 
+   c->parameters = rzalloc(s, nir_variable);
+   c->parameters->type = glsl_array_type(glsl_vec4_type(),
+                                            prog->Parameters->NumParameters);
+   c->parameters->name = "parameters";
+   c->parameters->data.read_only = true;
+   c->parameters->data.mode = nir_var_uniform;
+   exec_list_push_tail(&s->uniforms, &c->parameters->node);
+
    nir_function *func = nir_function_create(s, "main");
    nir_function_overload *overload = nir_function_overload_create(func);
    nir_function_impl *impl = nir_function_impl_create(overload);
index fb61f4d360d500cebe57dd7518a91f775e47db0b..c13e61b1630c6b737b66d502aac56b8e68440966 100644 (file)
@@ -97,13 +97,6 @@ _mesa_init_program(struct gl_context *ctx)
    assert(ctx->FragmentProgram.Current);
    ctx->FragmentProgram.Cache = _mesa_new_program_cache();
 
-   ctx->GeometryProgram.Enabled = GL_FALSE;
-   /* right now by default we don't have a geometry program */
-   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
-                            NULL);
-
-   _mesa_reference_compprog(ctx, &ctx->ComputeProgram.Current, NULL);
-
    /* XXX probably move this stuff */
    ctx->ATIFragmentShader.Enabled = GL_FALSE;
    ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
@@ -122,8 +115,6 @@ _mesa_free_program_data(struct gl_context *ctx)
    _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
    _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
-   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
-   _mesa_reference_compprog(ctx, &ctx->ComputeProgram.Current, NULL);
 
    /* XXX probably move this stuff */
    if (ctx->ATIFragmentShader.Current) {
@@ -153,9 +144,6 @@ _mesa_update_default_objects_program(struct gl_context *ctx)
                             ctx->Shared->DefaultFragmentProgram);
    assert(ctx->FragmentProgram.Current);
 
-   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
-                      ctx->Shared->DefaultGeometryProgram);
-
    /* XXX probably move this stuff */
    if (ctx->ATIFragmentShader.Current) {
       ctx->ATIFragmentShader.Current->RefCount--;
@@ -340,7 +328,7 @@ _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
                                          CALLOC_STRUCT(gl_fragment_program),
                                          target, id );
       break;
-   case MESA_GEOMETRY_PROGRAM:
+   case GL_GEOMETRY_PROGRAM_NV:
       prog = _mesa_init_geometry_program(ctx,
                                          CALLOC_STRUCT(gl_geometry_program),
                                          target, id);
@@ -426,8 +414,8 @@ _mesa_reference_program_(struct gl_context *ctx,
       else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
          assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
                 prog->Target == GL_FRAGMENT_PROGRAM_NV);
-      else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
-         assert(prog->Target == MESA_GEOMETRY_PROGRAM);
+      else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
+         assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
    }
 #endif
 
@@ -439,7 +427,7 @@ _mesa_reference_program_(struct gl_context *ctx,
       printf("Program %p ID=%u Target=%s  Refcount-- to %d\n",
              *ptr, (*ptr)->Id,
              ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
-              ((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
+              ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV ? "GP" : "FP")),
              (*ptr)->RefCount - 1);
 #endif
       assert((*ptr)->RefCount > 0);
@@ -464,7 +452,7 @@ _mesa_reference_program_(struct gl_context *ctx,
       printf("Program %p ID=%u Target=%s  Refcount++ to %d\n",
              prog, prog->Id,
              (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
-              (prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
+              (prog->Target == GL_GEOMETRY_PROGRAM_NV ? "GP" : "FP")),
              prog->RefCount);
 #endif
       /*mtx_unlock(&prog->Mutex);*/
@@ -554,7 +542,7 @@ _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
          fpc->PixelCenterInteger = fp->PixelCenterInteger;
       }
       break;
-   case MESA_GEOMETRY_PROGRAM:
+   case GL_GEOMETRY_PROGRAM_NV:
       {
          const struct gl_geometry_program *gp = gl_geometry_program_const(prog);
          struct gl_geometry_program *gpc = gl_geometry_program(clone);
index 716b83d2d07955e13e9bcbab2025d68cb8813d0d..635f5d09d6016f2001b1f484bf22157a7369b0aa 100644 (file)
@@ -84,7 +84,7 @@ static void asm_instruction_set_operands(struct asm_instruction *inst,
     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     const struct asm_src_register *src1, const struct asm_src_register *src2);
 
-static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+static struct asm_instruction *asm_instruction_ctor(enum prog_opcode op,
     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     const struct asm_src_register *src1, const struct asm_src_register *src2);
 
@@ -139,7 +139,7 @@ static struct asm_instruction *asm_instruction_copy_ctor(
    gl_state_index state[STATE_LENGTH];
    int negate;
    struct asm_vector vector;
-   gl_inst_opcode opcode;
+   enum prog_opcode opcode;
 
    struct {
       unsigned swz;
@@ -2275,7 +2275,7 @@ asm_instruction_set_operands(struct asm_instruction *inst,
 
 
 struct asm_instruction *
-asm_instruction_ctor(gl_inst_opcode op,
+asm_instruction_ctor(enum prog_opcode op,
                     const struct prog_dst_register *dst,
                     const struct asm_src_register *src0,
                     const struct asm_src_register *src1,
@@ -2308,7 +2308,7 @@ asm_instruction_copy_ctor(const struct prog_instruction *base,
       inst->Base.Opcode = base->Opcode;
       inst->Base.CondUpdate = base->CondUpdate;
       inst->Base.CondDst = base->CondDst;
-      inst->Base.SaturateMode = base->SaturateMode;
+      inst->Base.Saturate = base->Saturate;
       inst->Base.Precision = base->Precision;
 
       asm_instruction_set_operands(inst, dst, src0, src1, src2);
index a9e36404580f145ceecd9ac7b19e0aa9e3fb3f17..32b54afc57b75ebcc4d641560b3423954a90b4c0 100644 (file)
@@ -40,7 +40,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
 {
    inst->CondUpdate = 0;
    inst->CondDst = 0;
-   inst->SaturateMode = SATURATE_OFF;
+   inst->Saturate = GL_FALSE;
    inst->Precision = FLOAT32;
 
 
@@ -82,7 +82,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
     */
    if (state->mode == ARB_fragment) {
       if (strcmp(suffix, "_SAT") == 0) {
-        inst->SaturateMode = SATURATE_ZERO_ONE;
+        inst->Saturate = GL_TRUE;
         suffix += 4;
       }
    }
index e82c68a530524d7fd3167b02b0b4cad01dcf9028..af78150d5949cea8f6718e8b0ec3887fa70022cf 100644 (file)
@@ -305,7 +305,7 @@ _mesa_append_fog_code(struct gl_context *ctx,
          /* change the instruction to write to colorTemp w/ clamping */
          inst->DstReg.File = PROGRAM_TEMPORARY;
          inst->DstReg.Index = colorTemp;
-         inst->SaturateMode = saturate;
+         inst->Saturate = saturate;
          /* don't break (may be several writes to result.color) */
       }
       inst++;
@@ -331,7 +331,7 @@ _mesa_append_fog_code(struct gl_context *ctx,
       inst->SrcReg[2].File = PROGRAM_STATE_VAR;
       inst->SrcReg[2].Index = fogPRefOpt;
       inst->SrcReg[2].Swizzle = SWIZZLE_YYYY;
-      inst->SaturateMode = SATURATE_ZERO_ONE;
+      inst->Saturate = GL_TRUE;
       inst++;
    }
    else {
@@ -374,7 +374,7 @@ _mesa_append_fog_code(struct gl_context *ctx,
       inst->SrcReg[0].Index = fogFactorTemp;
       inst->SrcReg[0].Negate = NEGATE_XYZW;
       inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
-      inst->SaturateMode = SATURATE_ZERO_ONE;
+      inst->Saturate = GL_TRUE;
       inst++;
    }
    /* LRP result.color.xyz, fogFactorTemp.xxxx, colorTemp, fogColorRef; */
index b195c55b347e4fa8ee534433e9732615c2605fe1..ae883a2535e32ad98931632d4e5b406de1cf67f7 100644 (file)
@@ -134,7 +134,10 @@ update_framebuffer_state( struct st_context *st )
    else {
       strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
       if (strb) {
-         assert(strb->surface);
+         if (strb->is_rtt) {
+            /* rendering to a GL texture, may have to update surface */
+            st_update_renderbuffer_surface(st, strb);
+         }
          pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
          update_framebuffer_size(framebuffer, strb->surface);
       }
index 629f54f25dea20c356c88fb3bec4ae738f43126c..ad8d2624fc959d247f0f1c8f70db3ac4b9604171 100644 (file)
@@ -189,7 +189,7 @@ update_gp( struct st_context *st )
    }
 
    stgp = st_geometry_program(st->ctx->GeometryProgram._Current);
-   assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM);
+   assert(stgp->Base.Base.Target == GL_GEOMETRY_PROGRAM_NV);
 
    memset(&key, 0, sizeof(key));
    key.st = st;
index 2107ab167399083be37f0b7a42c38a56b2732cd9..c881e194f70f426dfb82f29d486422a437f99e64 100644 (file)
@@ -452,6 +452,8 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_save_fragment_shader(cso);
    cso_save_stream_outputs(cso);
    cso_save_vertex_shader(cso);
+   cso_save_tessctrl_shader(cso);
+   cso_save_tesseval_shader(cso);
    cso_save_geometry_shader(cso);
    cso_save_vertex_elements(cso);
    cso_save_aux_vertex_buffer_slot(cso);
@@ -466,7 +468,9 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    /* vertex shader state: position + texcoord pass-through */
    cso_set_vertex_shader_handle(cso, st->bitmap.vs);
 
-   /* geometry shader state: disabled */
+   /* disable other shaders */
+   cso_set_tessctrl_shader_handle(cso, NULL);
+   cso_set_tesseval_shader_handle(cso, NULL);
    cso_set_geometry_shader_handle(cso, NULL);
 
    /* user samplers, plus our bitmap sampler */
@@ -536,6 +540,8 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_restore_viewport(cso);
    cso_restore_fragment_shader(cso);
    cso_restore_vertex_shader(cso);
+   cso_restore_tessctrl_shader(cso);
+   cso_restore_tesseval_shader(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_vertex_elements(cso);
    cso_restore_aux_vertex_buffer_slot(cso);
index bbaedd108f6c55d81d27f188fdd571856c44e80f..6d9371852c5bdc37625a0ec31ef9008447078fce 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "st_context.h"
 #include "st_texture.h"
+#include "st_cb_bitmap.h"
 #include "st_cb_blit.h"
 #include "st_cb_fbo.h"
 #include "st_atom.h"
@@ -93,6 +94,9 @@ st_BlitFramebuffer(struct gl_context *ctx,
 
    st_validate_state(st);
 
+   /* Make sure bitmap rendering has landed in the framebuffers */
+   st_flush_bitmap_cache(st);
+
    clip.srcX0 = srcX0;
    clip.srcY0 = srcY0;
    clip.srcX1 = srcX1;
index f10e9063ac7877ecc3ef353a74c0a419d503d477..137fac8a9a90c9b38c095572739007e77ae2059a 100644 (file)
@@ -265,6 +265,8 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
    cso_save_fragment_shader(st->cso_context);
    cso_save_stream_outputs(st->cso_context);
    cso_save_vertex_shader(st->cso_context);
+   cso_save_tessctrl_shader(st->cso_context);
+   cso_save_tesseval_shader(st->cso_context);
    cso_save_geometry_shader(st->cso_context);
    cso_save_vertex_elements(st->cso_context);
    cso_save_aux_vertex_buffer_slot(st->cso_context);
@@ -347,6 +349,8 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
    }
 
    set_fragment_shader(st);
+   cso_set_tessctrl_shader_handle(st->cso_context, NULL);
+   cso_set_tesseval_shader_handle(st->cso_context, NULL);
 
    if (num_layers > 1)
       set_vertex_shader_layered(st);
@@ -371,6 +375,8 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
    cso_restore_viewport(st->cso_context);
    cso_restore_fragment_shader(st->cso_context);
    cso_restore_vertex_shader(st->cso_context);
+   cso_restore_tessctrl_shader(st->cso_context);
+   cso_restore_tesseval_shader(st->cso_context);
    cso_restore_geometry_shader(st->cso_context);
    cso_restore_vertex_elements(st->cso_context);
    cso_restore_aux_vertex_buffer_slot(st->cso_context);
index 3edf31bad52d490c26a382cc977ad2722b25ffb6..a6a98c83aa63f06b72102ec21e5bb0664452afc7 100644 (file)
@@ -693,6 +693,8 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_save_fragment_shader(cso);
    cso_save_stream_outputs(cso);
    cso_save_vertex_shader(cso);
+   cso_save_tessctrl_shader(cso);
+   cso_save_tesseval_shader(cso);
    cso_save_geometry_shader(cso);
    cso_save_vertex_elements(cso);
    cso_save_aux_vertex_buffer_slot(cso);
@@ -746,7 +748,9 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    /* vertex shader state: position + texcoord pass-through */
    cso_set_vertex_shader_handle(cso, driver_vp);
 
-   /* geometry shader state: disabled */
+   /* disable other shaders */
+   cso_set_tessctrl_shader_handle(cso, NULL);
+   cso_set_tesseval_shader_handle(cso, NULL);
    cso_set_geometry_shader_handle(cso, NULL);
 
    /* texture sampling state: */
@@ -816,6 +820,8 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
    cso_restore_fragment_shader(cso);
    cso_restore_vertex_shader(cso);
+   cso_restore_tessctrl_shader(cso);
+   cso_restore_tesseval_shader(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_vertex_elements(cso);
    cso_restore_aux_vertex_buffer_slot(cso);
index 1420b96e55a47ecc1e2ce2ddb4555a3baac5f5ed..2af4f6d4cf63e44c60fb6ff3e483be09a70dbfab 100644 (file)
@@ -229,6 +229,8 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
    cso_save_viewport(cso);
    cso_save_stream_outputs(cso);
    cso_save_vertex_shader(cso);
+   cso_save_tessctrl_shader(cso);
+   cso_save_tesseval_shader(cso);
    cso_save_geometry_shader(cso);
    cso_save_vertex_elements(cso);
    cso_save_aux_vertex_buffer_slot(cso);
@@ -238,6 +240,8 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
                                semantic_names, semantic_indexes);
       cso_set_vertex_shader_handle(cso, vs);
    }
+   cso_set_tessctrl_shader_handle(cso, NULL);
+   cso_set_tesseval_shader_handle(cso, NULL);
    cso_set_geometry_shader_handle(cso, NULL);
 
    for (i = 0; i < numAttribs; i++) {
@@ -279,6 +283,8 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
    /* restore state */
    cso_restore_viewport(cso);
    cso_restore_vertex_shader(cso);
+   cso_restore_tessctrl_shader(cso);
+   cso_restore_tesseval_shader(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_vertex_elements(cso);
    cso_restore_aux_vertex_buffer_slot(cso);
index 296ea1e0d29c873030911f226112374f62dcc0c5..0399eef720459fe65f764501cc6524d5d4a2361a 100644 (file)
@@ -842,7 +842,7 @@ void st_init_fbo_functions(struct dd_function_table *functions)
    functions->NewFramebuffer = st_new_framebuffer;
    functions->NewRenderbuffer = st_new_renderbuffer;
    functions->BindFramebuffer = st_bind_framebuffer;
-   functions->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
+   functions->FramebufferRenderbuffer = _mesa_FramebufferRenderbuffer_sw;
    functions->RenderTexture = st_render_texture;
    functions->FinishRenderTexture = st_finish_render_texture;
    functions->ValidateFramebuffer = st_validate_framebuffer;
index ca51eeee366c0c734029cf76aa4ac142a9bcf0b4..82affd2de3eebd7005d80b4aa20b4a1e4dd17359 100644 (file)
@@ -141,11 +141,44 @@ static void st_glFinish(struct gl_context *ctx)
 }
 
 
-void st_init_flush_functions(struct dd_function_table *functions)
+/**
+ * Query information about GPU resets observed by this context
+ *
+ * Called via \c dd_function_table::GetGraphicsResetStatus.
+ */
+static GLenum
+st_get_graphics_reset_status(struct gl_context *ctx)
+{
+   struct st_context *st = st_context(ctx);
+   enum pipe_reset_status status;
+
+   status = st->pipe->get_device_reset_status(st->pipe);
+
+   switch (status) {
+   case PIPE_NO_RESET:
+      return GL_NO_ERROR;
+   case PIPE_GUILTY_CONTEXT_RESET:
+      return GL_GUILTY_CONTEXT_RESET_ARB;
+   case PIPE_INNOCENT_CONTEXT_RESET:
+      return GL_INNOCENT_CONTEXT_RESET_ARB;
+   case PIPE_UNKNOWN_CONTEXT_RESET:
+      return GL_UNKNOWN_CONTEXT_RESET_ARB;
+   default:
+      assert(0);
+      return GL_NO_ERROR;
+   }
+}
+
+
+void st_init_flush_functions(struct pipe_screen *screen,
+                             struct dd_function_table *functions)
 {
    functions->Flush = st_glFlush;
    functions->Finish = st_glFinish;
 
+   if (screen->get_param(screen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY))
+      functions->GetGraphicsResetStatus = st_get_graphics_reset_status;
+
    /* Windows opengl32.dll calls glFinish prior to every swapbuffers.
     * This is unnecessary and degrades performance.  Luckily we have some
     * scope to work around this, as the externally-visible behaviour of
index 84ffc63ae131eb37b84262558c8c630b92b29f28..f92dcd56b64c36c02c7ff60dbd953c6443be1adc 100644 (file)
@@ -37,7 +37,8 @@ struct pipe_fence_handle;
 struct st_context;
 
 extern void
-st_init_flush_functions(struct dd_function_table *functions);
+st_init_flush_functions(struct pipe_screen *screen,
+                        struct dd_function_table *functions);
 
 extern void
 st_flush(struct st_context *st,
index c382d7d2ca3e6588469664a208dffcdb1581ac9a..6aa7d5796d9f1945b57080e2262104262c6e6b00 100644 (file)
@@ -65,7 +65,7 @@ st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog)
    case GL_FRAGMENT_PROGRAM_ARB:
       st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
       break;
-   case MESA_GEOMETRY_PROGRAM:
+   case GL_GEOMETRY_PROGRAM_NV:
       st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
       break;
    }
@@ -105,7 +105,7 @@ st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
       return _mesa_init_fragment_program(ctx, &prog->Base, target, id);
    }
 
-   case MESA_GEOMETRY_PROGRAM: {
+   case GL_GEOMETRY_PROGRAM_NV: {
       struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
       return _mesa_init_geometry_program(ctx, &prog->Base, target, id);
    }
@@ -135,7 +135,7 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
             free_glsl_to_tgsi_visitor(stvp->glsl_to_tgsi);
       }
       break;
-   case MESA_GEOMETRY_PROGRAM:
+   case GL_GEOMETRY_PROGRAM_NV:
       {
          struct st_geometry_program *stgp =
             (struct st_geometry_program *) prog;
@@ -198,7 +198,7 @@ st_program_string_notify( struct gl_context *ctx,
       if (st->fp == stfp)
         st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    }
-   else if (target == MESA_GEOMETRY_PROGRAM) {
+   else if (target == GL_GEOMETRY_PROGRAM_NV) {
       struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
 
       st_release_gp_variants(st, stgp);
index bfb9c8406bdaae89a09ebc71e4905b33f4a26c08..ed9ed0f1b6c6b1e928eb74657ff2b197543d65a2 100644 (file)
@@ -321,7 +321,7 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
    struct st_context *st;
 
    memset(&funcs, 0, sizeof(funcs));
-   st_init_driver_functions(&funcs);
+   st_init_driver_functions(pipe->screen, &funcs);
 
    ctx = _mesa_create_context(api, visual, shareCtx, &funcs);
    if (!ctx) {
@@ -376,12 +376,6 @@ void st_destroy_context( struct st_context *st )
    }
    pipe_surface_reference(&st->state.framebuffer.zsbuf, NULL);
 
-   pipe->set_index_buffer(pipe, NULL);
-
-   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
-      pipe->set_constant_buffer(pipe, i, 0, NULL);
-   }
-
    _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
 
    _vbo_DestroyContext(st->ctx);
@@ -401,7 +395,8 @@ void st_destroy_context( struct st_context *st )
 }
 
 
-void st_init_driver_functions(struct dd_function_table *functions)
+void st_init_driver_functions(struct pipe_screen *screen,
+                              struct dd_function_table *functions)
 {
    _mesa_init_shader_object_functions(functions);
    _mesa_init_sampler_object_functions(functions);
@@ -429,7 +424,7 @@ void st_init_driver_functions(struct dd_function_table *functions)
    st_init_readpixels_functions(functions);
    st_init_texture_functions(functions);
    st_init_texture_barrier_functions(functions);
-   st_init_flush_functions(functions);
+   st_init_flush_functions(screen, functions);
    st_init_string_functions(functions);
    st_init_viewport_functions(functions);
 
index 8a9504bb7c19049566cda7749440ff3985ec4c5e..dac5a4b90069b8b88609b93a383966c1deb82c8e 100644 (file)
@@ -237,7 +237,8 @@ struct st_framebuffer
 };
 
 
-extern void st_init_driver_functions(struct dd_function_table *functions);
+extern void st_init_driver_functions(struct pipe_screen *screen,
+                                     struct dd_function_table *functions);
 
 void st_invalidate_state(struct gl_context * ctx, GLuint new_state);
 
index 488f6ead20147704b96b143020cc8d97b0323768..8b43582c14b4fcb6b8f1b9ef0047cbee5ea6a14d 100644 (file)
@@ -141,7 +141,7 @@ check_uniforms(struct gl_context *ctx)
       if (shProg[j] == NULL || !shProg[j]->LinkStatus)
         continue;
 
-      for (i = 0; i < shProg[j]->NumUserUniformStorage; i++) {
+      for (i = 0; i < shProg[j]->NumUniformStorage; i++) {
          const struct gl_uniform_storage *u = &shProg[j]->UniformStorage[i];
          if (!u->initialized) {
             _mesa_warning(ctx,
index 1fea8600a75d0fdc13dd5e47f2eca7450e8bbcb0..25e30c7deb26c2a1341c84fcb85905e8d541e01c 100644 (file)
                            (1 << PROGRAM_CONSTANT) |     \
                            (1 << PROGRAM_UNIFORM))
 
-/**
- * Maximum number of arrays
- */
-#define MAX_ARRAYS        256
-
 #define MAX_GLSL_TEXTURE_OFFSET 4
 
 class st_src_reg;
@@ -89,6 +84,7 @@ public:
       this->reladdr2 = NULL;
       this->has_index2 = false;
       this->double_reg2 = false;
+      this->array_id = 0;
    }
 
    st_src_reg(gl_register_file file, int index, int type)
@@ -103,6 +99,7 @@ public:
       this->reladdr2 = NULL;
       this->has_index2 = false;
       this->double_reg2 = false;
+      this->array_id = 0;
    }
 
    st_src_reg(gl_register_file file, int index, int type, int index2D)
@@ -117,6 +114,7 @@ public:
       this->reladdr2 = NULL;
       this->has_index2 = false;
       this->double_reg2 = false;
+      this->array_id = 0;
    }
 
    st_src_reg()
@@ -131,6 +129,7 @@ public:
       this->reladdr2 = NULL;
       this->has_index2 = false;
       this->double_reg2 = false;
+      this->array_id = 0;
    }
 
    explicit st_src_reg(st_dst_reg reg);
@@ -150,6 +149,7 @@ public:
     * currently used for input mapping only.
     */
    bool double_reg2;
+   unsigned array_id;
 };
 
 class st_dst_reg {
@@ -162,6 +162,7 @@ public:
       this->cond_mask = COND_TR;
       this->reladdr = NULL;
       this->type = type;
+      this->array_id = 0;
    }
 
    st_dst_reg(gl_register_file file, int writemask, int type)
@@ -172,6 +173,7 @@ public:
       this->cond_mask = COND_TR;
       this->reladdr = NULL;
       this->type = type;
+      this->array_id = 0;
    }
 
    st_dst_reg()
@@ -182,6 +184,7 @@ public:
       this->writemask = 0;
       this->cond_mask = COND_TR;
       this->reladdr = NULL;
+      this->array_id = 0;
    }
 
    explicit st_dst_reg(st_src_reg reg);
@@ -193,6 +196,7 @@ public:
    int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
    /** Register index should be offset by the integer in this reg. */
    st_src_reg *reladdr;
+   unsigned array_id;
 };
 
 st_src_reg::st_src_reg(st_dst_reg reg)
@@ -207,6 +211,7 @@ st_src_reg::st_src_reg(st_dst_reg reg)
    this->reladdr2 = NULL;
    this->has_index2 = false;
    this->double_reg2 = false;
+   this->array_id = reg.array_id;
 }
 
 st_dst_reg::st_dst_reg(st_src_reg reg)
@@ -217,6 +222,7 @@ st_dst_reg::st_dst_reg(st_src_reg reg)
    this->writemask = WRITEMASK_XYZW;
    this->cond_mask = COND_TR;
    this->reladdr = reg.reladdr;
+   this->array_id = reg.array_id;
 }
 
 class glsl_to_tgsi_instruction : public exec_node {
@@ -233,6 +239,7 @@ public:
    st_src_reg sampler; /**< sampler register */
    int sampler_array_size; /**< 1-based size of sampler array, 1 if not array */
    int tex_target; /**< One of TEXTURE_*_INDEX */
+   glsl_base_type tex_type;
    GLboolean tex_shadow;
 
    st_src_reg tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
@@ -244,8 +251,9 @@ public:
 
 class variable_storage : public exec_node {
 public:
-   variable_storage(ir_variable *var, gl_register_file file, int index)
-      : file(file), index(index), var(var)
+   variable_storage(ir_variable *var, gl_register_file file, int index,
+                    unsigned array_id = 0)
+      : file(file), index(index), var(var), array_id(array_id)
    {
       /* empty */
    }
@@ -253,6 +261,7 @@ public:
    gl_register_file file;
    int index;
    ir_variable *var; /* variable that maps to this, if any */
+   unsigned array_id;
 };
 
 class immediate_storage : public exec_node {
@@ -302,6 +311,15 @@ public:
    st_src_reg return_reg;
 };
 
+static st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR);
+static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR);
+
+struct array_decl {
+   unsigned mesa_index;
+   unsigned array_id;
+   unsigned array_size;
+};
+
 struct glsl_to_tgsi_visitor : public ir_visitor {
 public:
    glsl_to_tgsi_visitor();
@@ -317,11 +335,19 @@ public:
 
    int next_temp;
 
-   unsigned array_sizes[MAX_ARRAYS];
+   unsigned *array_sizes;
+   unsigned max_num_arrays;
    unsigned next_array;
 
+   struct array_decl input_arrays[PIPE_MAX_SHADER_INPUTS];
+   unsigned num_input_arrays;
+   struct array_decl output_arrays[PIPE_MAX_SHADER_OUTPUTS];
+   unsigned num_output_arrays;
+
    int num_address_regs;
    int samplers_used;
+   glsl_base_type sampler_types[PIPE_MAX_SAMPLERS];
+   int sampler_targets[PIPE_MAX_SAMPLERS];   /**< One of TGSI_TEXTURE_* */
    bool indirect_addr_consts;
    int wpos_transform_const;
 
@@ -372,6 +398,7 @@ public:
    virtual void visit(ir_if *);
    virtual void visit(ir_emit_vertex *);
    virtual void visit(ir_end_primitive *);
+   virtual void visit(ir_barrier *);
    /*@}*/
 
    st_src_reg result;
@@ -390,31 +417,19 @@ public:
    /** List of glsl_to_tgsi_instruction */
    exec_list instructions;
 
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op);
-
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
-                                  st_dst_reg dst, st_src_reg src0);
-
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
-                                  st_dst_reg dst, st_dst_reg dst1,
-                                  st_src_reg src0);
+   glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, unsigned op,
+                                      st_dst_reg dst = undef_dst,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src);
 
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
-                                  st_dst_reg dst, st_src_reg src0, st_src_reg src1);
-
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
-                                  st_dst_reg dst,
-                                  st_src_reg src0, st_src_reg src1, st_src_reg src2);
-
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
-                                  st_dst_reg dst,
-                                  st_src_reg src0, st_src_reg src1,
-                                  st_src_reg src2, st_src_reg src3);
-
-   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
-                                  st_dst_reg dst, st_dst_reg dst1,
-                                  st_src_reg src0, st_src_reg src1,
-                                  st_src_reg src2, st_src_reg src3);
+   glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, unsigned op,
+                                      st_dst_reg dst, st_dst_reg dst1,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src);
 
    unsigned get_opcode(ir_instruction *ir, unsigned op,
                     st_dst_reg dst,
@@ -468,10 +483,6 @@ public:
    void *mem_ctx;
 };
 
-static st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR);
-
-static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR);
-
 static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 0);
 static st_dst_reg address_reg2 = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 1);
 static st_dst_reg sampler_reladdr = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 2);
@@ -526,10 +537,10 @@ num_inst_src_regs(unsigned opcode)
 }
 
 glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
-                           st_dst_reg dst, st_dst_reg dst1,
-                           st_src_reg src0, st_src_reg src1,
-                           st_src_reg src2, st_src_reg src3)
+glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
+                               st_dst_reg dst, st_dst_reg dst1,
+                               st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3)
 {
    glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
    int num_reladdr = 0, i, j;
@@ -571,6 +582,10 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
    inst->src[3] = src3;
    inst->ir = ir;
    inst->dead_mask = 0;
+   /* default to float, for paths where this is not initialized
+    * (since 0==UINT which is likely wrong):
+    */
+   inst->tex_type = GLSL_TYPE_FLOAT;
 
    inst->function = NULL;
 
@@ -716,48 +731,12 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
 }
 
 glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
-                           st_dst_reg dst,
-                           st_src_reg src0, st_src_reg src1,
-                           st_src_reg src2, st_src_reg src3)
+glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
+                               st_dst_reg dst,
+                               st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3)
 {
-   return emit(ir, op, dst, undef_dst, src0, src1, src2, src3);
-}
-
-glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
-                           st_dst_reg dst, st_src_reg src0,
-                           st_src_reg src1, st_src_reg src2)
-{
-   return emit(ir, op, dst, undef_dst, src0, src1, src2, undef_src);
-}
-
-glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
-                           st_dst_reg dst, st_src_reg src0, st_src_reg src1)
-{
-   return emit(ir, op, dst, undef_dst, src0, src1, undef_src, undef_src);
-}
-
-glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
-                           st_dst_reg dst, st_src_reg src0)
-{
-   assert(dst.writemask != 0);
-   return emit(ir, op, dst, undef_dst, src0, undef_src, undef_src, undef_src);
-}
-
-glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
-                           st_dst_reg dst, st_dst_reg dst1, st_src_reg src0)
-{
-   return emit(ir, op, dst, dst1, src0, undef_src, undef_src, undef_src);
-}
-
-glsl_to_tgsi_instruction *
-glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op)
-{
-   return emit(ir, op, undef_dst, undef_dst, undef_src, undef_src, undef_src, undef_src);
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3);
 }
 
 /**
@@ -879,7 +858,7 @@ glsl_to_tgsi_visitor::emit_dp(ir_instruction *ir,
       TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4
    };
 
-   return emit(ir, dot_opcodes[elements - 2], dst, src0, src1);
+   return emit_asm(ir, dot_opcodes[elements - 2], dst, src0, src1);
 }
 
 /**
@@ -929,7 +908,7 @@ glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op,
                                    src1_swiz, src1_swiz);
 
       dst.writemask = this_mask;
-      emit(ir, op, dst, src0, src1);
+      emit_asm(ir, op, dst, src0, src1);
       done_mask |= this_mask;
    }
 }
@@ -958,7 +937,7 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
    if (dst.index >= this->num_address_regs)
       this->num_address_regs = dst.index + 1;
 
-   emit(NULL, op, dst, src0);
+   emit_asm(NULL, op, dst, src0);
 }
 
 int
@@ -1142,6 +1121,12 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
    if (!options->EmitNoIndirectTemp &&
        (type->is_array() || type->is_matrix())) {
 
+      if (next_array >= max_num_arrays) {
+         max_num_arrays += 32;
+         array_sizes = (unsigned*)
+            realloc(array_sizes, sizeof(array_sizes[0]) * max_num_arrays);
+      }
+
       src.file = PROGRAM_ARRAY;
       src.index = next_array << 16 | 0x8000;
       array_sizes[next_array] = type_size(type);
@@ -1242,7 +1227,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
              */
             st_src_reg src(PROGRAM_STATE_VAR, index, GLSL_TYPE_FLOAT);
             src.swizzle = slots[i].swizzle;
-            emit(ir, TGSI_OPCODE_MOV, dst, src);
+            emit_asm(ir, TGSI_OPCODE_MOV, dst, src);
             /* even a float takes up a whole vec4 reg in a struct/array. */
             dst.index++;
          }
@@ -1261,11 +1246,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
 void
 glsl_to_tgsi_visitor::visit(ir_loop *ir)
 {
-   emit(NULL, TGSI_OPCODE_BGNLOOP);
+   emit_asm(NULL, TGSI_OPCODE_BGNLOOP);
 
    visit_exec_list(&ir->body_instructions, this);
 
-   emit(NULL, TGSI_OPCODE_ENDLOOP);
+   emit_asm(NULL, TGSI_OPCODE_ENDLOOP);
 }
 
 void
@@ -1273,10 +1258,10 @@ glsl_to_tgsi_visitor::visit(ir_loop_jump *ir)
 {
    switch (ir->mode) {
    case ir_loop_jump::jump_break:
-      emit(NULL, TGSI_OPCODE_BRK);
+      emit_asm(NULL, TGSI_OPCODE_BRK);
       break;
    case ir_loop_jump::jump_continue:
-      emit(NULL, TGSI_OPCODE_CONT);
+      emit_asm(NULL, TGSI_OPCODE_CONT);
       break;
    }
 }
@@ -1330,7 +1315,7 @@ glsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
    this->result = get_temp(ir->type);
    result_dst = st_dst_reg(this->result);
    result_dst.writemask = (1 << ir->type->vector_elements) - 1;
-   emit(ir, TGSI_OPCODE_MAD, result_dst, a, b, c);
+   emit_asm(ir, TGSI_OPCODE_MAD, result_dst, a, b, c);
 
    return true;
 }
@@ -1370,7 +1355,7 @@ glsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operan
    b.negate = ~b.negate;
 
    this->result = get_temp(ir->type);
-   emit(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a);
+   emit_asm(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a);
 
    return true;
 }
@@ -1388,7 +1373,7 @@ glsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir,
    if (*num_reladdr != 1) {
       st_src_reg temp = get_temp(glsl_type::vec4_type);
 
-      emit(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg);
+      emit_asm(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg);
       *reg = temp;
    }
 
@@ -1464,7 +1449,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
    switch (ir->operation) {
    case ir_unop_logic_not:
       if (result_dst.type != GLSL_TYPE_FLOAT)
-         emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
       else {
          /* Previously 'SEQ dst, src, 0.0' was used for this.  However, many
           * older GPUs implement SEQ using multiple instructions (i915 uses two
@@ -1472,24 +1457,24 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
           * 0.0 and 1.0, 1-x also implements !x.
           */
          op[0].negate = ~op[0].negate;
-         emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0));
+         emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0));
       }
       break;
    case ir_unop_neg:
       if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT)
-         emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
       else if (result_dst.type == GLSL_TYPE_DOUBLE)
-         emit(ir, TGSI_OPCODE_DNEG, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_DNEG, result_dst, op[0]);
       else {
          op[0].negate = ~op[0].negate;
          result_src = op[0];
       }
       break;
    case ir_unop_abs:
-      emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
       break;
    case ir_unop_sign:
-      emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_SSG, result_dst, op[0]);
       break;
    case ir_unop_rcp:
       emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]);
@@ -1513,17 +1498,17 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       break;
    case ir_unop_saturate: {
       glsl_to_tgsi_instruction *inst;
-      inst = emit(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
+      inst = emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
       inst->saturate = true;
       break;
    }
 
    case ir_unop_dFdx:
    case ir_unop_dFdx_coarse:
-      emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_DDX, result_dst, op[0]);
       break;
    case ir_unop_dFdx_fine:
-      emit(ir, TGSI_OPCODE_DDX_FINE, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_DDX_FINE, result_dst, op[0]);
       break;
    case ir_unop_dFdy:
    case ir_unop_dFdy_coarse:
@@ -1547,18 +1532,18 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
 
       st_src_reg temp = get_temp(glsl_type::vec4_type);
 
-      emit(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]);
-      emit(ir, ir->operation == ir_unop_dFdy_fine ?
+      emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]);
+      emit_asm(ir, ir->operation == ir_unop_dFdy_fine ?
            TGSI_OPCODE_DDY_FINE : TGSI_OPCODE_DDY, result_dst, temp);
       break;
    }
 
    case ir_unop_frexp_sig:
-      emit(ir, TGSI_OPCODE_DFRACEXP, result_dst, undef_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_DFRACEXP, result_dst, undef_dst, op[0]);
       break;
 
    case ir_unop_frexp_exp:
-      emit(ir, TGSI_OPCODE_DFRACEXP, undef_dst, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_DFRACEXP, undef_dst, result_dst, op[0]);
       break;
 
    case ir_unop_noise: {
@@ -1568,50 +1553,50 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
        * place to do this is in the GL state tracker, not the poor
        * driver.
        */
-      emit(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5));
+      emit_asm(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5));
       break;
    }
 
    case ir_binop_add:
-      emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
       break;
    case ir_binop_sub:
-      emit(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]);
       break;
 
    case ir_binop_mul:
-      emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
       break;
    case ir_binop_div:
       if (result_dst.type == GLSL_TYPE_FLOAT || result_dst.type == GLSL_TYPE_DOUBLE)
          assert(!"not reached: should be handled by ir_div_to_mul_rcp");
       else
-         emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]);
       break;
    case ir_binop_mod:
       if (result_dst.type == GLSL_TYPE_FLOAT)
          assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
       else
-         emit(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]);
       break;
 
    case ir_binop_less:
-      emit(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]);
       break;
    case ir_binop_greater:
-      emit(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]);
+      emit_asm(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]);
       break;
    case ir_binop_lequal:
-      emit(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]);
+      emit_asm(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]);
       break;
    case ir_binop_gequal:
-      emit(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]);
       break;
    case ir_binop_equal:
-      emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
       break;
    case ir_binop_nequal:
-      emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
       break;
    case ir_binop_all_equal:
       /* "==" operator producing a scalar boolean. */
@@ -1625,7 +1610,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
             st_dst_reg temp_dst = st_dst_reg(temp);
             st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp);
 
-            emit(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]);
+            emit_asm(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]);
 
             /* Emit 1-3 AND operations to combine the SEQ results. */
             switch (ir->operands[0]->type->vector_elements) {
@@ -1635,24 +1620,24 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                temp_dst.writemask = WRITEMASK_Y;
                temp1.swizzle = SWIZZLE_YYYY;
                temp2.swizzle = SWIZZLE_ZZZZ;
-               emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
+               emit_asm(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
                break;
             case 4:
                temp_dst.writemask = WRITEMASK_X;
                temp1.swizzle = SWIZZLE_XXXX;
                temp2.swizzle = SWIZZLE_YYYY;
-               emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
+               emit_asm(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
                temp_dst.writemask = WRITEMASK_Y;
                temp1.swizzle = SWIZZLE_ZZZZ;
                temp2.swizzle = SWIZZLE_WWWW;
-               emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
+               emit_asm(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
             }
 
             temp1.swizzle = SWIZZLE_XXXX;
             temp2.swizzle = SWIZZLE_YYYY;
-            emit(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2);
+            emit_asm(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2);
          } else {
-            emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
+            emit_asm(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
 
             /* After the dot-product, the value will be an integer on the
              * range [0,4].  Zero becomes 1.0, and positive values become zero.
@@ -1665,10 +1650,10 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
              */
             st_src_reg sge_src = result_src;
             sge_src.negate = ~sge_src.negate;
-            emit(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0));
+            emit_asm(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0));
          }
       } else {
-         emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
       }
       break;
    case ir_binop_any_nequal:
@@ -1678,7 +1663,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
          st_src_reg temp = get_temp(native_integers ?
                                     glsl_type::uvec4_type :
                                     glsl_type::vec4_type);
-         emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
 
          if (native_integers) {
             st_dst_reg temp_dst = st_dst_reg(temp);
@@ -1692,22 +1677,22 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                temp_dst.writemask = WRITEMASK_Y;
                temp1.swizzle = SWIZZLE_YYYY;
                temp2.swizzle = SWIZZLE_ZZZZ;
-               emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
+               emit_asm(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
                break;
             case 4:
                temp_dst.writemask = WRITEMASK_X;
                temp1.swizzle = SWIZZLE_XXXX;
                temp2.swizzle = SWIZZLE_YYYY;
-               emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
+               emit_asm(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
                temp_dst.writemask = WRITEMASK_Y;
                temp1.swizzle = SWIZZLE_ZZZZ;
                temp2.swizzle = SWIZZLE_WWWW;
-               emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
+               emit_asm(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
             }
 
             temp1.swizzle = SWIZZLE_XXXX;
             temp2.swizzle = SWIZZLE_YYYY;
-            emit(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2);
+            emit_asm(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2);
          } else {
             /* After the dot-product, the value will be an integer on the
              * range [0,4].  Zero stays zero, and positive values become 1.0.
@@ -1726,11 +1711,11 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                 */
                st_src_reg slt_src = result_src;
                slt_src.negate = ~slt_src.negate;
-               emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
+               emit_asm(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
             }
          }
       } else {
-         emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
       }
       break;
 
@@ -1763,7 +1748,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                                           GET_SWZ(op0_swizzle, 3),
                                           GET_SWZ(op0_swizzle, 3),
                                           GET_SWZ(op0_swizzle, 3));
-            emit(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]);
+            emit_asm(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]);
             accum = st_src_reg(result_dst);
             accum.swizzle = dst_swizzle;
             /* fallthrough */
@@ -1772,7 +1757,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                                           GET_SWZ(op0_swizzle, 2),
                                           GET_SWZ(op0_swizzle, 2),
                                           GET_SWZ(op0_swizzle, 2));
-            emit(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]);
+            emit_asm(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]);
             accum = st_src_reg(result_dst);
             accum.swizzle = dst_swizzle;
             /* fallthrough */
@@ -1781,7 +1766,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                                           GET_SWZ(op0_swizzle, 1),
                                           GET_SWZ(op0_swizzle, 1),
                                           GET_SWZ(op0_swizzle, 1));
-            emit(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]);
+            emit_asm(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]);
             break;
          default:
             assert(!"Unexpected vector size");
@@ -1807,11 +1792,11 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
              */
             st_src_reg slt_src = result_src;
             slt_src.negate = ~slt_src.negate;
-            emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
+            emit_asm(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
          }
          else {
             /* Use SNE 0 if integers are being used as boolean values. */
-            emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0));
+            emit_asm(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0));
          }
       }
       break;
@@ -1819,9 +1804,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
 
    case ir_binop_logic_xor:
       if (native_integers)
-         emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
       else
-         emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
       break;
 
    case ir_binop_logic_or: {
@@ -1830,13 +1815,13 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
           * instruction.
           */
          assert(native_integers);
-         emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
       } else {
          /* After the addition, the value will be an integer on the
           * range [0,2].  Zero stays zero, and positive values become 1.0.
           */
          glsl_to_tgsi_instruction *add =
-            emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
+            emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
          if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
             /* The clamping to [0,1] can be done for free in the fragment
              * shader with a saturate if floats are being used as boolean values.
@@ -1849,7 +1834,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
              */
             st_src_reg slt_src = result_src;
             slt_src.negate = ~slt_src.negate;
-            emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
+            emit_asm(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
          }
       }
       break;
@@ -1861,9 +1846,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
        * actual AND opcode.
        */
       if (native_integers)
-         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
       else
-         emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
       break;
 
    case ir_binop_dot:
@@ -1879,10 +1864,10 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       } else {
          /* sqrt(x) = x * rsq(x). */
          emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
-         emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]);
+         emit_asm(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]);
          /* For incoming channels <= 0, set the result to 0. */
          op[0].negate = ~op[0].negate;
-         emit(ir, TGSI_OPCODE_CMP, result_dst,
+         emit_asm(ir, TGSI_OPCODE_CMP, result_dst,
               op[0], result_src, st_src_reg_for_float(0.0));
       }
       break;
@@ -1891,13 +1876,13 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       break;
    case ir_unop_i2f:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_I2F, result_dst, op[0]);
          break;
       }
       /* fallthrough to next case otherwise */
    case ir_unop_b2f:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_float(1.0));
+         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_float(1.0));
          break;
       }
       /* fallthrough to next case otherwise */
@@ -1912,7 +1897,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
           * GLSL requires that int(bool) return 1 for true and 0 for false.
           * This conversion is done with AND, but it could be done with NEG.
           */
-         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1));
+         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1));
       } else {
          /* Booleans and integers are both stored as floats when native
           * integers are disabled.
@@ -1922,15 +1907,15 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       break;
    case ir_unop_f2i:
       if (native_integers)
-         emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_F2I, result_dst, op[0]);
       else
-         emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
       break;
    case ir_unop_f2u:
       if (native_integers)
-         emit(ir, TGSI_OPCODE_F2U, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_F2U, result_dst, op[0]);
       else
-         emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
       break;
    case ir_unop_bitcast_f2i:
       result_src = op[0];
@@ -1946,38 +1931,38 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       result_src.type = GLSL_TYPE_FLOAT;
       break;
    case ir_unop_f2b:
-      emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
+      emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
       break;
    case ir_unop_d2b:
-      emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_double(0.0));
+      emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_double(0.0));
       break;
    case ir_unop_i2b:
       if (native_integers)
-         emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_USNE, result_dst, op[0], st_src_reg_for_int(0));
       else
-         emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
+         emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
       break;
    case ir_unop_trunc:
-      emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
       break;
    case ir_unop_ceil:
-      emit(ir, TGSI_OPCODE_CEIL, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_CEIL, result_dst, op[0]);
       break;
    case ir_unop_floor:
-      emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_FLR, result_dst, op[0]);
       break;
    case ir_unop_round_even:
-      emit(ir, TGSI_OPCODE_ROUND, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_ROUND, result_dst, op[0]);
       break;
    case ir_unop_fract:
-      emit(ir, TGSI_OPCODE_FRC, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_FRC, result_dst, op[0]);
       break;
 
    case ir_binop_min:
-      emit(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]);
       break;
    case ir_binop_max:
-      emit(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]);
       break;
    case ir_binop_pow:
       emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]);
@@ -1985,37 +1970,37 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
 
    case ir_unop_bit_not:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
          break;
       }
    case ir_unop_u2f:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]);
+         emit_asm(ir, TGSI_OPCODE_U2F, result_dst, op[0]);
          break;
       }
    case ir_binop_lshift:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_SHL, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_SHL, result_dst, op[0], op[1]);
          break;
       }
    case ir_binop_rshift:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_ISHR, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_ISHR, result_dst, op[0], op[1]);
          break;
       }
    case ir_binop_bit_and:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
          break;
       }
    case ir_binop_bit_xor:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
          break;
       }
    case ir_binop_bit_or:
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
          break;
       }
 
@@ -2045,7 +2030,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       }
       else {
          /* Relative/variable index into constant buffer */
-         emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1],
+         emit_asm(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1],
               st_src_reg_for_int(4));
          cbuf.reladdr = ralloc(mem_ctx, st_src_reg);
          memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg));
@@ -2078,88 +2063,88 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
                                        const_offset % 16 / 4);
 
       if (ir->type->base_type == GLSL_TYPE_BOOL) {
-         emit(ir, TGSI_OPCODE_USNE, result_dst, cbuf, st_src_reg_for_int(0));
+         emit_asm(ir, TGSI_OPCODE_USNE, result_dst, cbuf, st_src_reg_for_int(0));
       } else {
-         emit(ir, TGSI_OPCODE_MOV, result_dst, cbuf);
+         emit_asm(ir, TGSI_OPCODE_MOV, result_dst, cbuf);
       }
       break;
    }
    case ir_triop_lrp:
       /* note: we have to reorder the three args here */
-      emit(ir, TGSI_OPCODE_LRP, result_dst, op[2], op[1], op[0]);
+      emit_asm(ir, TGSI_OPCODE_LRP, result_dst, op[2], op[1], op[0]);
       break;
    case ir_triop_csel:
       if (this->ctx->Const.NativeIntegers)
-         emit(ir, TGSI_OPCODE_UCMP, result_dst, op[0], op[1], op[2]);
+         emit_asm(ir, TGSI_OPCODE_UCMP, result_dst, op[0], op[1], op[2]);
       else {
          op[0].negate = ~op[0].negate;
-         emit(ir, TGSI_OPCODE_CMP, result_dst, op[0], op[1], op[2]);
+         emit_asm(ir, TGSI_OPCODE_CMP, result_dst, op[0], op[1], op[2]);
       }
       break;
    case ir_triop_bitfield_extract:
-      emit(ir, TGSI_OPCODE_IBFE, result_dst, op[0], op[1], op[2]);
+      emit_asm(ir, TGSI_OPCODE_IBFE, result_dst, op[0], op[1], op[2]);
       break;
    case ir_quadop_bitfield_insert:
-      emit(ir, TGSI_OPCODE_BFI, result_dst, op[0], op[1], op[2], op[3]);
+      emit_asm(ir, TGSI_OPCODE_BFI, result_dst, op[0], op[1], op[2], op[3]);
       break;
    case ir_unop_bitfield_reverse:
-      emit(ir, TGSI_OPCODE_BREV, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_BREV, result_dst, op[0]);
       break;
    case ir_unop_bit_count:
-      emit(ir, TGSI_OPCODE_POPC, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_POPC, result_dst, op[0]);
       break;
    case ir_unop_find_msb:
-      emit(ir, TGSI_OPCODE_IMSB, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_IMSB, result_dst, op[0]);
       break;
    case ir_unop_find_lsb:
-      emit(ir, TGSI_OPCODE_LSB, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_LSB, result_dst, op[0]);
       break;
    case ir_binop_imul_high:
-      emit(ir, TGSI_OPCODE_IMUL_HI, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_IMUL_HI, result_dst, op[0], op[1]);
       break;
    case ir_triop_fma:
       /* In theory, MAD is incorrect here. */
       if (have_fma)
-         emit(ir, TGSI_OPCODE_FMA, result_dst, op[0], op[1], op[2]);
+         emit_asm(ir, TGSI_OPCODE_FMA, result_dst, op[0], op[1], op[2]);
       else
-         emit(ir, TGSI_OPCODE_MAD, result_dst, op[0], op[1], op[2]);
+         emit_asm(ir, TGSI_OPCODE_MAD, result_dst, op[0], op[1], op[2]);
       break;
    case ir_unop_interpolate_at_centroid:
-      emit(ir, TGSI_OPCODE_INTERP_CENTROID, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_INTERP_CENTROID, result_dst, op[0]);
       break;
    case ir_binop_interpolate_at_offset:
-      emit(ir, TGSI_OPCODE_INTERP_OFFSET, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_INTERP_OFFSET, result_dst, op[0], op[1]);
       break;
    case ir_binop_interpolate_at_sample:
-      emit(ir, TGSI_OPCODE_INTERP_SAMPLE, result_dst, op[0], op[1]);
+      emit_asm(ir, TGSI_OPCODE_INTERP_SAMPLE, result_dst, op[0], op[1]);
       break;
 
    case ir_unop_d2f:
-      emit(ir, TGSI_OPCODE_D2F, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_D2F, result_dst, op[0]);
       break;
    case ir_unop_f2d:
-      emit(ir, TGSI_OPCODE_F2D, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_F2D, result_dst, op[0]);
       break;
    case ir_unop_d2i:
-      emit(ir, TGSI_OPCODE_D2I, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_D2I, result_dst, op[0]);
       break;
    case ir_unop_i2d:
-      emit(ir, TGSI_OPCODE_I2D, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_I2D, result_dst, op[0]);
       break;
    case ir_unop_d2u:
-      emit(ir, TGSI_OPCODE_D2U, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_D2U, result_dst, op[0]);
       break;
    case ir_unop_u2d:
-      emit(ir, TGSI_OPCODE_U2D, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_U2D, result_dst, op[0]);
       break;
    case ir_unop_unpack_double_2x32:
    case ir_unop_pack_double_2x32:
-      emit(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
+      emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
       break;
 
    case ir_binop_ldexp:
       if (ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE) {
-         emit(ir, TGSI_OPCODE_DLDEXP, result_dst, op[0], op[1]);
+         emit_asm(ir, TGSI_OPCODE_DLDEXP, result_dst, op[0], op[1]);
       } else {
          assert(!"Invalid ldexp for non-double opcode in glsl_to_tgsi_visitor::visit()");
       }
@@ -2243,11 +2228,38 @@ glsl_to_tgsi_visitor::visit(ir_swizzle *ir)
    this->result = src;
 }
 
+/* Test if the variable is an array. Note that geometry and
+ * tessellation shader inputs are outputs are always arrays (except
+ * for patch inputs), so only the array element type is considered.
+ */
+static bool
+is_inout_array(unsigned stage, ir_variable *var, bool *is_2d)
+{
+   const glsl_type *type = var->type;
+
+   if ((stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_in) ||
+       (stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out))
+      return false;
+
+   *is_2d = false;
+
+   if (stage == MESA_SHADER_GEOMETRY && var->data.mode == ir_var_shader_in) {
+      if (!var->type->is_array())
+         return false; /* a system value probably */
+
+      type = var->type->fields.array;
+      *is_2d = true;
+   }
+
+   return type->is_array() || type->is_matrix();
+}
+
 void
 glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
 {
    variable_storage *entry = find_variable_storage(ir->var);
    ir_variable *var = ir->var;
+   bool is_2d;
 
    if (!entry) {
       switch (var->data.mode) {
@@ -2263,16 +2275,56 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
           * user-defined varyings.
           */
          assert(var->data.location != -1);
-         entry = new(mem_ctx) variable_storage(var,
-                                               PROGRAM_INPUT,
-                                               var->data.location);
+
+         if (is_inout_array(shader->Stage, var, &is_2d)) {
+            struct array_decl *decl = &input_arrays[num_input_arrays];
+
+            decl->mesa_index = var->data.location;
+            decl->array_id = num_input_arrays + 1;
+            if (is_2d)
+               decl->array_size = type_size(var->type->fields.array);
+            else
+               decl->array_size = type_size(var->type);
+            num_input_arrays++;
+
+            entry = new(mem_ctx) variable_storage(var,
+                                                  PROGRAM_INPUT,
+                                                  var->data.location,
+                                                  decl->array_id);
+         }
+         else {
+            entry = new(mem_ctx) variable_storage(var,
+                                                  PROGRAM_INPUT,
+                                                  var->data.location);
+         }
+         this->variables.push_tail(entry);
          break;
       case ir_var_shader_out:
          assert(var->data.location != -1);
-         entry = new(mem_ctx) variable_storage(var,
-                                               PROGRAM_OUTPUT,
-                                               var->data.location
-                                               + var->data.index);
+
+         if (is_inout_array(shader->Stage, var, &is_2d)) {
+            struct array_decl *decl = &output_arrays[num_output_arrays];
+
+            decl->mesa_index = var->data.location;
+            decl->array_id = num_output_arrays + 1;
+            if (is_2d)
+               decl->array_size = type_size(var->type->fields.array);
+            else
+               decl->array_size = type_size(var->type);
+            num_output_arrays++;
+
+            entry = new(mem_ctx) variable_storage(var,
+                                                  PROGRAM_OUTPUT,
+                                                  var->data.location,
+                                                  decl->array_id);
+         }
+         else {
+            entry = new(mem_ctx) variable_storage(var,
+                                                  PROGRAM_OUTPUT,
+                                                  var->data.location
+                                                  + var->data.index);
+         }
+         this->variables.push_tail(entry);
          break;
       case ir_var_system_value:
          entry = new(mem_ctx) variable_storage(var,
@@ -2296,10 +2348,43 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
    }
 
    this->result = st_src_reg(entry->file, entry->index, var->type);
+   this->result.array_id = entry->array_id;
    if (!native_integers)
       this->result.type = GLSL_TYPE_FLOAT;
 }
 
+static void
+shrink_array_declarations(struct array_decl *arrays, unsigned count,
+                          GLbitfield64 usage_mask)
+{
+   unsigned i, j;
+
+   /* Fix array declarations by removing unused array elements at both ends
+    * of the arrays. For example, mat4[3] where only mat[1] is used.
+    */
+   for (i = 0; i < count; i++) {
+      struct array_decl *decl = &arrays[i];
+
+      /* Shrink the beginning. */
+      for (j = 0; j < decl->array_size; j++) {
+         if (usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
+            break;
+
+         decl->mesa_index++;
+         decl->array_size--;
+         j--;
+      }
+
+      /* Shrink the end. */
+      for (j = decl->array_size-1; j >= 0; j--) {
+         if (usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
+            break;
+
+         decl->array_size--;
+      }
+   }
+}
+
 void
 glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
 {
@@ -2341,7 +2426,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
          index_reg = get_temp(native_integers ?
                               glsl_type::int_type : glsl_type::float_type);
 
-         emit(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg),
+         emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg),
               this->result, st_src_reg_for_type(index_reg.type, element_size));
       }
 
@@ -2352,7 +2437,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
          st_src_reg accum_reg = get_temp(native_integers ?
                                 glsl_type::int_type : glsl_type::float_type);
 
-         emit(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg),
+         emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg),
               index_reg, *src.reladdr);
 
          index_reg = accum_reg;
@@ -2589,16 +2674,16 @@ glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type *
       l_src.swizzle = swizzle_for_size(type->vector_elements);
 
       if (native_integers) {
-         emit(ir, TGSI_OPCODE_UCMP, *l, *cond,
+         emit_asm(ir, TGSI_OPCODE_UCMP, *l, *cond,
               cond_swap ? l_src : *r,
               cond_swap ? *r : l_src);
       } else {
-         emit(ir, TGSI_OPCODE_CMP, *l, *cond,
+         emit_asm(ir, TGSI_OPCODE_CMP, *l, *cond,
               cond_swap ? l_src : *r,
               cond_swap ? *r : l_src);
       }
    } else {
-      emit(ir, TGSI_OPCODE_MOV, *l, *r);
+      emit_asm(ir, TGSI_OPCODE_MOV, *l, *r);
    }
    l->index++;
    r->index++;
@@ -2679,7 +2764,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
        */
       glsl_to_tgsi_instruction *inst, *new_inst;
       inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
-      new_inst = emit(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]);
+      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]);
       new_inst->saturate = inst->saturate;
       inst->dead_mask = inst->dst[0].writemask;
    } else {
@@ -2717,7 +2802,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
          src = this->result;
 
          for (i = 0; i < (unsigned int)size; i++) {
-            emit(ir, TGSI_OPCODE_MOV, temp, src);
+            emit_asm(ir, TGSI_OPCODE_MOV, temp, src);
 
             src.index++;
             temp.index++;
@@ -2739,7 +2824,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
          ir->array_elements[i]->accept(this);
          src = this->result;
          for (int j = 0; j < size; j++) {
-            emit(ir, TGSI_OPCODE_MOV, temp, src);
+            emit_asm(ir, TGSI_OPCODE_MOV, temp, src);
 
             src.index++;
             temp.index++;
@@ -2764,7 +2849,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
                                   ir->type->vector_elements,
                                   GL_FLOAT,
                                   &src.swizzle);
-         emit(ir, TGSI_OPCODE_MOV, mat_column, src);
+         emit_asm(ir, TGSI_OPCODE_MOV, mat_column, src);
 
          mat_column.index++;
       }
@@ -2889,7 +2974,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
          l.cond_mask = COND_TR;
 
          for (i = 0; i < type_size(param->type); i++) {
-            emit(ir, TGSI_OPCODE_MOV, l, r);
+            emit_asm(ir, TGSI_OPCODE_MOV, l, r);
             l.index++;
             r.index++;
          }
@@ -2897,7 +2982,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
    }
 
    /* Emit call instruction */
-   call_inst = emit(ir, TGSI_OPCODE_CAL);
+   call_inst = emit_asm(ir, TGSI_OPCODE_CAL);
    call_inst->function = entry;
 
    /* Process out parameters. */
@@ -2922,7 +3007,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
          st_dst_reg l = st_dst_reg(this->result);
 
          for (i = 0; i < type_size(param->type); i++) {
-            emit(ir, TGSI_OPCODE_MOV, l, r);
+            emit_asm(ir, TGSI_OPCODE_MOV, l, r);
             l.index++;
             r.index++;
          }
@@ -2965,7 +3050,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
       coord = get_temp(glsl_type::vec4_type);
       coord_dst = st_dst_reg(coord);
       coord_dst.writemask = (1 << ir->coordinate->type->vector_elements) - 1;
-      emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
+      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
    }
 
    if (ir->projector) {
@@ -3074,7 +3159,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
       if (opcode == TGSI_OPCODE_TEX) {
          /* Slot the projector in as the last component of the coord. */
          coord_dst.writemask = WRITEMASK_W;
-         emit(ir, TGSI_OPCODE_MOV, coord_dst, projector);
+         emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, projector);
          coord_dst.writemask = WRITEMASK_XYZW;
          opcode = TGSI_OPCODE_TXP;
       } else {
@@ -3086,7 +3171,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
           * projective divide now.
           */
          coord_dst.writemask = WRITEMASK_W;
-         emit(ir, TGSI_OPCODE_RCP, coord_dst, projector);
+         emit_asm(ir, TGSI_OPCODE_RCP, coord_dst, projector);
 
          /* In the case where we have to project the coordinates "by hand,"
           * the shadow comparator value must also be projected.
@@ -3105,14 +3190,14 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
             assert(!sampler_type->sampler_array);
 
             tmp_dst.writemask = WRITEMASK_Z;
-            emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result);
+            emit_asm(ir, TGSI_OPCODE_MOV, tmp_dst, this->result);
 
             tmp_dst.writemask = WRITEMASK_XY;
-            emit(ir, TGSI_OPCODE_MOV, tmp_dst, coord);
+            emit_asm(ir, TGSI_OPCODE_MOV, tmp_dst, coord);
          }
 
          coord_dst.writemask = WRITEMASK_XYZ;
-         emit(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w);
+         emit_asm(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w);
 
          coord_dst.writemask = WRITEMASK_XYZW;
          coord.swizzle = SWIZZLE_XYZW;
@@ -3133,7 +3218,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
          cube_sc = get_temp(glsl_type::float_type);
          cube_sc_dst = st_dst_reg(cube_sc);
          cube_sc_dst.writemask = WRITEMASK_X;
-         emit(ir, TGSI_OPCODE_MOV, cube_sc_dst, this->result);
+         emit_asm(ir, TGSI_OPCODE_MOV, cube_sc_dst, this->result);
          cube_sc_dst.writemask = WRITEMASK_X;
       }
       else {
@@ -3144,20 +3229,20 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
          } else {
             coord_dst.writemask = WRITEMASK_Z;
          }
-         emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
+         emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
          coord_dst.writemask = WRITEMASK_XYZW;
       }
    }
 
    if (ir->op == ir_txf_ms) {
       coord_dst.writemask = WRITEMASK_W;
-      emit(ir, TGSI_OPCODE_MOV, coord_dst, sample_index);
+      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, sample_index);
       coord_dst.writemask = WRITEMASK_XYZW;
    } else if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB ||
        opcode == TGSI_OPCODE_TXF) {
       /* TGSI stores LOD or LOD bias in the last channel of the coords. */
       coord_dst.writemask = WRITEMASK_W;
-      emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info);
+      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, lod_info);
       coord_dst.writemask = WRITEMASK_XYZW;
    }
 
@@ -3167,30 +3252,30 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
    }
 
    if (opcode == TGSI_OPCODE_TXD)
-      inst = emit(ir, opcode, result_dst, coord, dx, dy);
+      inst = emit_asm(ir, opcode, result_dst, coord, dx, dy);
    else if (opcode == TGSI_OPCODE_TXQ) {
       if (ir->op == ir_query_levels) {
          /* the level is stored in W */
-         inst = emit(ir, opcode, st_dst_reg(levels_src), lod_info);
+         inst = emit_asm(ir, opcode, st_dst_reg(levels_src), lod_info);
          result_dst.writemask = WRITEMASK_X;
          levels_src.swizzle = SWIZZLE_WWWW;
-         emit(ir, TGSI_OPCODE_MOV, result_dst, levels_src);
+         emit_asm(ir, TGSI_OPCODE_MOV, result_dst, levels_src);
       } else
-         inst = emit(ir, opcode, result_dst, lod_info);
+         inst = emit_asm(ir, opcode, result_dst, lod_info);
    } else if (opcode == TGSI_OPCODE_TXF) {
-      inst = emit(ir, opcode, result_dst, coord);
+      inst = emit_asm(ir, opcode, result_dst, coord);
    } else if (opcode == TGSI_OPCODE_TXL2 || opcode == TGSI_OPCODE_TXB2) {
-      inst = emit(ir, opcode, result_dst, coord, lod_info);
+      inst = emit_asm(ir, opcode, result_dst, coord, lod_info);
    } else if (opcode == TGSI_OPCODE_TEX2) {
-      inst = emit(ir, opcode, result_dst, coord, cube_sc);
+      inst = emit_asm(ir, opcode, result_dst, coord, cube_sc);
    } else if (opcode == TGSI_OPCODE_TG4) {
       if (is_cube_array && ir->shadow_comparitor) {
-         inst = emit(ir, opcode, result_dst, coord, cube_sc);
+         inst = emit_asm(ir, opcode, result_dst, coord, cube_sc);
       } else {
-         inst = emit(ir, opcode, result_dst, coord, component);
+         inst = emit_asm(ir, opcode, result_dst, coord, component);
       }
    } else
-      inst = emit(ir, opcode, result_dst, coord);
+      inst = emit_asm(ir, opcode, result_dst, coord);
 
    if (ir->shadow_comparitor)
       inst->tex_shadow = GL_TRUE;
@@ -3246,6 +3331,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
       assert(!"Should not get here.");
    }
 
+   inst->tex_type = ir->type->base_type;
+
    this->result = result_src;
 }
 
@@ -3264,13 +3351,13 @@ glsl_to_tgsi_visitor::visit(ir_return *ir)
       l = st_dst_reg(current_function->return_reg);
 
       for (i = 0; i < type_size(current_function->sig->return_type); i++) {
-         emit(ir, TGSI_OPCODE_MOV, l, r);
+         emit_asm(ir, TGSI_OPCODE_MOV, l, r);
          l.index++;
          r.index++;
       }
    }
 
-   emit(ir, TGSI_OPCODE_RET);
+   emit_asm(ir, TGSI_OPCODE_RET);
 }
 
 void
@@ -3283,16 +3370,16 @@ glsl_to_tgsi_visitor::visit(ir_discard *ir)
       /* Convert the bool condition to a float so we can negate. */
       if (native_integers) {
          st_src_reg temp = get_temp(ir->condition->type);
-         emit(ir, TGSI_OPCODE_AND, st_dst_reg(temp),
+         emit_asm(ir, TGSI_OPCODE_AND, st_dst_reg(temp),
               condition, st_src_reg_for_float(1.0));
          condition = temp;
       }
 
       condition.negate = ~condition.negate;
-      emit(ir, TGSI_OPCODE_KILL_IF, undef_dst, condition);
+      emit_asm(ir, TGSI_OPCODE_KILL_IF, undef_dst, condition);
    } else {
       /* unconditional kil */
-      emit(ir, TGSI_OPCODE_KILL);
+      emit_asm(ir, TGSI_OPCODE_KILL);
    }
 }
 
@@ -3307,18 +3394,18 @@ glsl_to_tgsi_visitor::visit(ir_if *ir)
 
    if_opcode = native_integers ? TGSI_OPCODE_UIF : TGSI_OPCODE_IF;
 
-   if_inst = emit(ir->condition, if_opcode, undef_dst, this->result);
+   if_inst = emit_asm(ir->condition, if_opcode, undef_dst, this->result);
 
    this->instructions.push_tail(if_inst);
 
    visit_exec_list(&ir->then_instructions, this);
 
    if (!ir->else_instructions.is_empty()) {
-      emit(ir->condition, TGSI_OPCODE_ELSE);
+      emit_asm(ir->condition, TGSI_OPCODE_ELSE);
       visit_exec_list(&ir->else_instructions, this);
    }
 
-   if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF);
+   if_inst = emit_asm(ir->condition, TGSI_OPCODE_ENDIF);
 }
 
 
@@ -3328,7 +3415,7 @@ glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir)
    assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);
 
    ir->stream->accept(this);
-   emit(ir, TGSI_OPCODE_EMIT, undef_dst, this->result);
+   emit_asm(ir, TGSI_OPCODE_EMIT, undef_dst, this->result);
 }
 
 void
@@ -3337,14 +3424,24 @@ glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
    assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);
 
    ir->stream->accept(this);
-   emit(ir, TGSI_OPCODE_ENDPRIM, undef_dst, this->result);
+   emit_asm(ir, TGSI_OPCODE_ENDPRIM, undef_dst, this->result);
+}
+
+void
+glsl_to_tgsi_visitor::visit(ir_barrier *ir)
+{
+   unreachable("Not implemented!");
 }
 
 glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
 {
    result.file = PROGRAM_UNDEFINED;
    next_temp = 1;
+   array_sizes = NULL;
+   max_num_arrays = 0;
    next_array = 0;
+   num_input_arrays = 0;
+   num_output_arrays = 0;
    next_signature_id = 1;
    num_immediates = 0;
    current_function = NULL;
@@ -3366,6 +3463,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
 
 glsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
 {
+   free(array_sizes);
    ralloc_free(mem_ctx);
 }
 
@@ -3387,7 +3485,13 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
    foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) {
       if (is_tex_instruction(inst->op)) {
          for (int i = 0; i < inst->sampler_array_size; i++) {
-            v->samplers_used |= 1 << (inst->sampler.index + i);
+            unsigned idx = inst->sampler.index + i;
+            v->samplers_used |= 1 << idx;
+
+            debug_assert(idx < (int)ARRAY_SIZE(v->sampler_types));
+            v->sampler_types[idx] = inst->tex_type;
+            v->sampler_targets[idx] =
+               st_translate_texture_target(inst->tex_target, inst->tex_shadow);
 
             if (inst->tex_shadow) {
                prog->ShadowSamplers |= 1 << (inst->sampler.index + i);
@@ -3734,6 +3838,7 @@ glsl_to_tgsi_visitor::copy_propagate(void)
             inst->src[r].index2D = first->src[0].index2D;
             inst->src[r].has_index2 = first->src[0].has_index2;
             inst->src[r].double_reg2 = first->src[0].double_reg2;
+            inst->src[r].array_id = first->src[0].array_id;
 
             int swizzle = 0;
             for (int i = 0; i < 4; i++) {
@@ -4177,7 +4282,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
    coord = st_src_reg(PROGRAM_INPUT, VARYING_SLOT_TEX0, glsl_type::vec2_type);
    src0 = v->get_temp(glsl_type::vec4_type);
    dst0 = st_dst_reg(src0);
-   inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord);
+   inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, dst0, coord);
    inst->sampler_array_size = 1;
    inst->tex_target = TEXTURE_2D_INDEX;
 
@@ -4201,7 +4306,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
       /* MAD colorTemp, colorTemp, scale, bias; */
       scale = st_src_reg(PROGRAM_STATE_VAR, scale_p, GLSL_TYPE_FLOAT);
       bias = st_src_reg(PROGRAM_STATE_VAR, bias_p, GLSL_TYPE_FLOAT);
-      inst = v->emit(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias);
+      inst = v->emit_asm(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias);
    }
 
    if (pixel_maps) {
@@ -4209,6 +4314,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
       st_dst_reg temp_dst = st_dst_reg(temp);
 
       assert(st->pixel_xfer.pixelmap_texture);
+      (void) st;
 
       /* With a little effort, we can do four pixel map look-ups with
        * two TEX instructions:
@@ -4216,7 +4322,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
 
       /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */
       temp_dst.writemask = WRITEMASK_XY; /* write R,G */
-      inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
+      inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
       inst->sampler.index = 1;
       inst->sampler_array_size = 1;
       inst->tex_target = TEXTURE_2D_INDEX;
@@ -4224,7 +4330,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
       /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */
       src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W);
       temp_dst.writemask = WRITEMASK_ZW; /* write B,A */
-      inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
+      inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
       inst->sampler.index = 1;
       inst->sampler_array_size = 1;
       inst->tex_target = TEXTURE_2D_INDEX;
@@ -4233,7 +4339,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
       v->samplers_used |= (1 << 1);
 
       /* MOV colorTemp, temp; */
-      inst = v->emit(NULL, TGSI_OPCODE_MOV, dst0, temp);
+      inst = v->emit_asm(NULL, TGSI_OPCODE_MOV, dst0, temp);
    }
 
    /* Now copy the instructions from the original glsl_to_tgsi_visitor into the
@@ -4256,7 +4362,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
             prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
       }
 
-      newinst = v->emit(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
+      newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
       newinst->tex_target = inst->tex_target;
       newinst->sampler_array_size = inst->sampler_array_size;
    }
@@ -4306,7 +4412,7 @@ get_bitmap_visitor(struct st_fragment_program *fp,
    coord = st_src_reg(PROGRAM_INPUT, VARYING_SLOT_TEX0, glsl_type::vec2_type);
    src0 = v->get_temp(glsl_type::vec4_type);
    dst0 = st_dst_reg(src0);
-   inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord);
+   inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, dst0, coord);
    inst->sampler.index = samplerIndex;
    inst->sampler_array_size = 1;
    inst->tex_target = TEXTURE_2D_INDEX;
@@ -4319,7 +4425,7 @@ get_bitmap_visitor(struct st_fragment_program *fp,
    src0.negate = NEGATE_XYZW;
    if (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM)
       src0.swizzle = SWIZZLE_XXXX;
-   inst = v->emit(NULL, TGSI_OPCODE_KILL_IF, undef_dst, src0);
+   inst = v->emit_asm(NULL, TGSI_OPCODE_KILL_IF, undef_dst, src0);
 
    /* Now copy the instructions from the original glsl_to_tgsi_visitor into the
     * new visitor. */
@@ -4336,7 +4442,7 @@ get_bitmap_visitor(struct st_fragment_program *fp,
             prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
       }
 
-      newinst = v->emit(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
+      newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
       newinst->tex_target = inst->tex_target;
       newinst->sampler_array_size = inst->sampler_array_size;
    }
@@ -4362,7 +4468,8 @@ struct st_translate {
    unsigned temps_size;
    struct ureg_dst *temps;
 
-   struct ureg_dst arrays[MAX_ARRAYS];
+   struct ureg_dst *arrays;
+   unsigned num_temp_arrays;
    struct ureg_src *constants;
    int num_constants;
    struct ureg_src *immediates;
@@ -4373,7 +4480,9 @@ struct st_translate {
    struct ureg_src samplers[PIPE_MAX_SAMPLERS];
    struct ureg_src systemValues[SYSTEM_VALUE_MAX];
    struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
-   unsigned array_sizes[MAX_ARRAYS];
+   unsigned *array_sizes;
+   struct array_decl *input_arrays;
+   struct array_decl *output_arrays;
 
    const GLuint *inputMapping;
    const GLuint *outputMapping;
@@ -4497,9 +4606,8 @@ emit_immediate(struct st_translate *t,
  * Map a glsl_to_tgsi dst register to a TGSI ureg_dst register.
  */
 static struct ureg_dst
-dst_register(struct st_translate *t,
-             gl_register_file file,
-             GLuint index)
+dst_register(struct st_translate *t, gl_register_file file, unsigned index,
+             unsigned array_id)
 {
    unsigned array;
 
@@ -4530,7 +4638,7 @@ dst_register(struct st_translate *t,
    case PROGRAM_ARRAY:
       array = index >> 16;
 
-      assert(array < ARRAY_SIZE(t->arrays));
+      assert(array < t->num_temp_arrays);
 
       if (ureg_dst_is_undef(t->arrays[array]))
          t->arrays[array] = ureg_DECL_array_temporary(
@@ -4540,16 +4648,25 @@ dst_register(struct st_translate *t,
                                    (int)(index & 0xFFFF) - 0x8000);
 
    case PROGRAM_OUTPUT:
-      if (t->procType == TGSI_PROCESSOR_VERTEX)
-         assert(index < VARYING_SLOT_MAX);
-      else if (t->procType == TGSI_PROCESSOR_FRAGMENT)
-         assert(index < FRAG_RESULT_MAX);
-      else
-         assert(index < VARYING_SLOT_MAX);
+      if (!array_id) {
+         if (t->procType == TGSI_PROCESSOR_FRAGMENT)
+            assert(index < FRAG_RESULT_MAX);
+         else
+            assert(index < VARYING_SLOT_MAX);
 
-      assert(t->outputMapping[index] < ARRAY_SIZE(t->outputs));
+         assert(t->outputMapping[index] < ARRAY_SIZE(t->outputs));
+         assert(t->outputs[t->outputMapping[index]].File != TGSI_FILE_NULL);
+         return t->outputs[t->outputMapping[index]];
+      }
+      else {
+         struct array_decl *decl = &t->output_arrays[array_id-1];
+         unsigned mesa_index = decl->mesa_index;
+         int slot = t->outputMapping[mesa_index];
 
-      return t->outputs[t->outputMapping[index]];
+         assert(slot != -1 && t->outputs[slot].File == TGSI_FILE_OUTPUT);
+         assert(t->outputs[slot].ArrayID == array_id);
+         return ureg_dst_array_offset(t->outputs[slot], index - mesa_index);
+      }
 
    case PROGRAM_ADDRESS:
       return t->address[index];
@@ -4575,7 +4692,8 @@ src_register(struct st_translate *t, const st_src_reg *reg)
 
    case PROGRAM_TEMPORARY:
    case PROGRAM_ARRAY:
-      return ureg_src(dst_register(t, reg->file, reg->index));
+   case PROGRAM_OUTPUT:
+      return ureg_src(dst_register(t, reg->file, reg->index, reg->array_id));
 
    case PROGRAM_UNIFORM:
       assert(reg->index >= 0);
@@ -4598,12 +4716,20 @@ src_register(struct st_translate *t, const st_src_reg *reg)
        * map back to the original index and add the offset after
        * mapping. */
       index -= double_reg2;
-      assert(t->inputMapping[index] < ARRAY_SIZE(t->inputs));
-      return t->inputs[t->inputMapping[index] + double_reg2];
+      if (!reg->array_id) {
+         assert(t->inputMapping[index] < ARRAY_SIZE(t->inputs));
+         assert(t->inputs[t->inputMapping[index]].File != TGSI_FILE_NULL);
+         return t->inputs[t->inputMapping[index]];
+      }
+      else {
+         struct array_decl *decl = &t->input_arrays[reg->array_id-1];
+         unsigned mesa_index = decl->mesa_index;
+         int slot = t->inputMapping[mesa_index];
 
-   case PROGRAM_OUTPUT:
-      assert(t->outputMapping[reg->index] < ARRAY_SIZE(t->outputs));
-      return ureg_src(t->outputs[t->outputMapping[reg->index]]); /* not needed? */
+         assert(slot != -1 && t->inputs[slot].File == TGSI_FILE_INPUT);
+         assert(t->inputs[slot].ArrayID == reg->array_id);
+         return ureg_src_array_offset(t->inputs[slot], index - mesa_index);
+      }
 
    case PROGRAM_ADDRESS:
       return ureg_src(t->address[reg->index]);
@@ -4626,9 +4752,8 @@ translate_dst(struct st_translate *t,
               const st_dst_reg *dst_reg,
               bool saturate, bool clamp_color)
 {
-   struct ureg_dst dst = dst_register(t,
-                                      dst_reg->file,
-                                      dst_reg->index);
+   struct ureg_dst dst = dst_register(t, dst_reg->file, dst_reg->index,
+                                      dst_reg->array_id);
 
    if (dst.File == TGSI_FILE_NULL)
       return dst;
@@ -4738,7 +4863,7 @@ translate_tex_offset(struct st_translate *t,
       array = in_offset->index >> 16;
 
       assert(array >= 0);
-      assert(array < (int) ARRAY_SIZE(t->arrays));
+      assert(array < (int)t->num_temp_arrays);
 
       dst = t->arrays[array];
       offset.File = dst.File;
@@ -5060,6 +5185,25 @@ emit_edgeflags(struct st_translate *t)
    ureg_MOV(ureg, edge_dst, edge_src);
 }
 
+static bool
+find_array(unsigned attr, struct array_decl *arrays, unsigned count,
+           unsigned *array_id, unsigned *array_size)
+{
+   unsigned i;
+
+   for (i = 0; i < count; i++) {
+      struct array_decl *decl = &arrays[i];
+
+      if (attr == decl->mesa_index) {
+         *array_id = decl->array_id;
+         *array_size = decl->array_size;
+         assert(*array_size);
+         return true;
+      }
+   }
+   return false;
+}
+
 /**
  * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format.
  * \param program  the program to translate
@@ -5089,12 +5233,14 @@ st_translate_program(
    const struct gl_program *proginfo,
    GLuint numInputs,
    const GLuint inputMapping[],
+   const GLuint inputSlotToAttr[],
    const ubyte inputSemanticName[],
    const ubyte inputSemanticIndex[],
    const GLuint interpMode[],
    const GLuint interpLocation[],
    GLuint numOutputs,
    const GLuint outputMapping[],
+   const GLuint outputSlotToAttr[],
    const ubyte outputSemanticName[],
    const ubyte outputSemanticIndex[],
    boolean passthrough_edgeflags,
@@ -5132,25 +5278,101 @@ st_translate_program(
       goto out;
    }
 
-   memset(t, 0, sizeof *t);
-
    t->procType = procType;
    t->inputMapping = inputMapping;
    t->outputMapping = outputMapping;
    t->ureg = ureg;
+   t->num_temp_arrays = program->next_array;
+   if (t->num_temp_arrays)
+      t->arrays = (struct ureg_dst*)
+                  calloc(1, sizeof(t->arrays[0]) * t->num_temp_arrays);
 
    /*
     * Declare input attributes.
     */
-   if (procType == TGSI_PROCESSOR_FRAGMENT) {
+   switch (procType) {
+   case TGSI_PROCESSOR_FRAGMENT:
       for (i = 0; i < numInputs; i++) {
-         t->inputs[i] = ureg_DECL_fs_input_cyl_centroid(ureg,
-                                                        inputSemanticName[i],
-                                                        inputSemanticIndex[i],
-                                                        interpMode[i], 0,
-                                                        interpLocation[i]);
+         unsigned array_id = 0;
+         unsigned array_size;
+
+         if (find_array(inputSlotToAttr[i], program->input_arrays,
+                        program->num_input_arrays, &array_id, &array_size)) {
+            /* We've found an array. Declare it so. */
+            t->inputs[i] = ureg_DECL_fs_input_cyl_centroid(ureg,
+                              inputSemanticName[i], inputSemanticIndex[i],
+                              interpMode[i], 0, interpLocation[i],
+                              array_id, array_size);
+            i += array_size - 1;
+         }
+         else {
+            t->inputs[i] = ureg_DECL_fs_input_cyl_centroid(ureg,
+                              inputSemanticName[i], inputSemanticIndex[i],
+                              interpMode[i], 0, interpLocation[i], 0, 1);
+         }
+      }
+      break;
+   case TGSI_PROCESSOR_GEOMETRY:
+      for (i = 0; i < numInputs; i++) {
+         unsigned array_id = 0;
+         unsigned array_size;
+
+         if (find_array(inputSlotToAttr[i], program->input_arrays,
+                        program->num_input_arrays, &array_id, &array_size)) {
+            /* We've found an array. Declare it so. */
+            t->inputs[i] = ureg_DECL_input(ureg, inputSemanticName[i],
+                                           inputSemanticIndex[i],
+                                           array_id, array_size);
+            i += array_size - 1;
+         }
+         else {
+            t->inputs[i] = ureg_DECL_input(ureg, inputSemanticName[i],
+                                           inputSemanticIndex[i], 0, 1);
+         }
       }
+      break;
+   case TGSI_PROCESSOR_VERTEX:
+      for (i = 0; i < numInputs; i++) {
+         t->inputs[i] = ureg_DECL_vs_input(ureg, i);
+      }
+      break;
+   default:
+      assert(0);
+   }
 
+   /*
+    * Declare output attributes.
+    */
+   switch (procType) {
+   case TGSI_PROCESSOR_FRAGMENT:
+      break;
+   case TGSI_PROCESSOR_GEOMETRY:
+   case TGSI_PROCESSOR_VERTEX:
+      for (i = 0; i < numOutputs; i++) {
+         unsigned array_id = 0;
+         unsigned array_size;
+
+         if (find_array(outputSlotToAttr[i], program->output_arrays,
+                        program->num_output_arrays, &array_id, &array_size)) {
+            /* We've found an array. Declare it so. */
+            t->outputs[i] = ureg_DECL_output_array(ureg,
+                                                   outputSemanticName[i],
+                                                   outputSemanticIndex[i],
+                                                   array_id, array_size);
+            i += array_size - 1;
+         }
+         else {
+            t->outputs[i] = ureg_DECL_output(ureg,
+                                             outputSemanticName[i],
+                                             outputSemanticIndex[i]);
+         }
+      }
+      break;
+   default:
+      assert(0);
+   }
+
+   if (procType == TGSI_PROCESSOR_FRAGMENT) {
       if (proginfo->InputsRead & VARYING_BIT_POS) {
           /* Must do this after setting up t->inputs. */
           emit_wpos(st_context(ctx), t, proginfo, ureg,
@@ -5160,9 +5382,6 @@ st_translate_program(
       if (proginfo->InputsRead & VARYING_BIT_FACE)
          emit_face_var(ctx, t);
 
-      /*
-       * Declare output attributes.
-       */
       for (i = 0; i < numOutputs; i++) {
          switch (outputSemanticName[i]) {
          case TGSI_SEMANTIC_POSITION:
@@ -5198,31 +5417,8 @@ st_translate_program(
          }
       }
    }
-   else if (procType == TGSI_PROCESSOR_GEOMETRY) {
-      for (i = 0; i < numInputs; i++) {
-         t->inputs[i] = ureg_DECL_gs_input(ureg,
-                                           i,
-                                           inputSemanticName[i],
-                                           inputSemanticIndex[i]);
-      }
-
+   else if (procType == TGSI_PROCESSOR_VERTEX) {
       for (i = 0; i < numOutputs; i++) {
-         t->outputs[i] = ureg_DECL_output(ureg,
-                                          outputSemanticName[i],
-                                          outputSemanticIndex[i]);
-      }
-   }
-   else {
-      assert(procType == TGSI_PROCESSOR_VERTEX);
-
-      for (i = 0; i < numInputs; i++) {
-         t->inputs[i] = ureg_DECL_vs_input(ureg, i);
-      }
-
-      for (i = 0; i < numOutputs; i++) {
-         t->outputs[i] = ureg_DECL_output(ureg,
-                                          outputSemanticName[i],
-                                          outputSemanticIndex[i]);
          if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) {
             /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */
             ureg_MOV(ureg,
@@ -5277,9 +5473,9 @@ st_translate_program(
       }
    }
 
-   /* Copy over array sizes
-    */
-   memcpy(t->array_sizes, program->array_sizes, sizeof(unsigned) * program->next_array);
+   t->array_sizes = program->array_sizes;
+   t->input_arrays = program->input_arrays;
+   t->output_arrays = program->output_arrays;
 
    /* Emit constants and uniforms.  TGSI uses a single index space for these,
     * so we put all the translated regs in t->constants.
@@ -5355,7 +5551,26 @@ st_translate_program(
    /* texture samplers */
    for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) {
       if (program->samplers_used & (1 << i)) {
+         unsigned type;
+
          t->samplers[i] = ureg_DECL_sampler(ureg, i);
+
+         switch (program->sampler_types[i]) {
+         case GLSL_TYPE_INT:
+            type = TGSI_RETURN_TYPE_SINT;
+            break;
+         case GLSL_TYPE_UINT:
+            type = TGSI_RETURN_TYPE_UINT;
+            break;
+         case GLSL_TYPE_FLOAT:
+            type = TGSI_RETURN_TYPE_FLOAT;
+            break;
+         default:
+            unreachable("not reached");
+         }
+
+         ureg_DECL_sampler_view( ureg, i, program->sampler_targets[i],
+                                 type, type, type, type );
       }
    }
 
@@ -5375,6 +5590,7 @@ st_translate_program(
 
 out:
    if (t) {
+      free(t->arrays);
       free(t->temps);
       free(t->insn);
       free(t->labels);
@@ -5470,7 +5686,7 @@ get_mesa_program(struct gl_context *ctx,
          if (!entry->bgn_inst) {
             v->current_function = entry;
 
-            entry->bgn_inst = v->emit(NULL, TGSI_OPCODE_BGNSUB);
+            entry->bgn_inst = v->emit_asm(NULL, TGSI_OPCODE_BGNSUB);
             entry->bgn_inst->function = entry;
 
             visit_exec_list(&entry->sig->body, v);
@@ -5478,10 +5694,10 @@ get_mesa_program(struct gl_context *ctx,
             glsl_to_tgsi_instruction *last;
             last = (glsl_to_tgsi_instruction *)v->instructions.get_tail();
             if (last->op != TGSI_OPCODE_RET)
-               v->emit(NULL, TGSI_OPCODE_RET);
+               v->emit_asm(NULL, TGSI_OPCODE_RET);
 
             glsl_to_tgsi_instruction *end;
-            end = v->emit(NULL, TGSI_OPCODE_ENDSUB);
+            end = v->emit_asm(NULL, TGSI_OPCODE_ENDSUB);
             end->function = entry;
 
             progress = GL_TRUE;
@@ -5513,7 +5729,7 @@ get_mesa_program(struct gl_context *ctx,
    v->renumber_registers();
 
    /* Write the END instruction. */
-   v->emit(NULL, TGSI_OPCODE_END);
+   v->emit_asm(NULL, TGSI_OPCODE_END);
 
    if (ctx->_Shader->Flags & GLSL_DUMP) {
       _mesa_log("\n");
@@ -5528,6 +5744,10 @@ get_mesa_program(struct gl_context *ctx,
    prog->NumInstructions = 0;
 
    do_set_program_inouts(shader->ir, prog, shader->Stage);
+   shrink_array_declarations(v->input_arrays, v->num_input_arrays,
+                             prog->InputsRead);
+   shrink_array_declarations(v->output_arrays, v->num_output_arrays,
+                             prog->OutputsWritten);
    count_resources(v, prog);
 
    /* This must be done before the uniform storage is associated. */
@@ -5549,6 +5769,7 @@ get_mesa_program(struct gl_context *ctx,
     */
    _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters);
    if (!shader_program->LinkStatus) {
+      free_glsl_to_tgsi_visitor(v);
       return NULL;
    }
 
index 2cb80bcf96186235e8a0dfc20de52da7d45ae4a1..4af747fa9dec725510118fee7e29986e9a0acbd8 100644 (file)
@@ -43,12 +43,14 @@ enum pipe_error st_translate_program(
    const struct gl_program *proginfo,
    GLuint numInputs,
    const GLuint inputMapping[],
+   const GLuint inputSlotToAttr[],
    const ubyte inputSemanticName[],
    const ubyte inputSemanticIndex[],
    const GLuint interpMode[],
    const GLuint interpLocation[],
    GLuint numOutputs,
    const GLuint outputMapping[],
+   const GLuint outputSlotToAttr[],
    const ubyte outputSemanticName[],
    const ubyte outputSemanticIndex[],
    boolean passthrough_edgeflags,
index 840f76a1307bddfe3e1e0b9fcb8cd10863ea2b37..a2dee6298faeb4801f010f0da12289ad8a771b8b 100644 (file)
@@ -680,6 +680,10 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
 
    if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE)
       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
+   if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS)
+      st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
+   if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED)
+      st->ctx->Const.ResetStrategy = GL_LOSE_CONTEXT_ON_RESET_ARB;
 
    /* need to perform version check */
    if (attribs->major > 1 || attribs->minor > 0) {
@@ -920,8 +924,7 @@ static unsigned get_version(struct pipe_screen *screen,
    struct gl_extensions extensions = {0};
    GLuint version;
 
-   if ((api == API_OPENGL_COMPAT || api == API_OPENGL_CORE) &&
-       _mesa_override_gl_version_contextless(&consts, &api, &version)) {
+   if (_mesa_override_gl_version_contextless(&consts, &api, &version)) {
       return version;
    }
 
index 98d525c86c2c8596ddf408c947d1cb78e1446c61..896e239ee681b7ab896cd934b5c347d744354b43 100644 (file)
@@ -665,7 +665,7 @@ compile_instruction(
    if (num_dst) 
       dst[0] = translate_dst( t, 
                               &inst->DstReg,
-                              inst->SaturateMode,
+                              inst->Saturate,
                               clamp_dst_color_output);
 
    for (i = 0; i < num_src; i++) 
@@ -1095,10 +1095,9 @@ st_translate_mesa_program(
    }
    else if (procType == TGSI_PROCESSOR_GEOMETRY) {
       for (i = 0; i < numInputs; i++) {
-         t->inputs[i] = ureg_DECL_gs_input(ureg,
-                                           i,
-                                           inputSemanticName[i],
-                                           inputSemanticIndex[i]);
+         t->inputs[i] = ureg_DECL_input(ureg,
+                                        inputSemanticName[i],
+                                        inputSemanticIndex[i], 0, 1);
       }
 
       for (i = 0; i < numOutputs; i++) {
index a9110d3c674d54e186446a74e3839e0933a42b45..fa792bc349b1ac37386e7ae9ec0ab9c35718c365 100644 (file)
@@ -215,6 +215,7 @@ st_prepare_vertex_program(struct gl_context *ctx,
          unsigned slot = stvp->num_outputs++;
 
          stvp->result_to_output[attr] = slot;
+         stvp->output_slot_to_attr[slot] = attr;
 
          switch (attr) {
          case VARYING_SLOT_POS:
@@ -285,7 +286,8 @@ st_prepare_vertex_program(struct gl_context *ctx,
             /* fall through */
          case VARYING_SLOT_VAR0:
          default:
-            assert(attr < VARYING_SLOT_MAX);
+            assert(attr >= VARYING_SLOT_VAR0 ||
+                   (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7));
             stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
             stvp->output_semantic_index[slot] =
                st_get_generic_varying_index(st, attr);
@@ -321,7 +323,7 @@ st_translate_vertex_program(struct st_context *st,
       _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
    }
 
-   ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+   ureg = ureg_create_with_screen(TGSI_PROCESSOR_VERTEX, st->pipe->screen);
    if (ureg == NULL) {
       free(vpv);
       return NULL;
@@ -351,6 +353,7 @@ st_translate_vertex_program(struct st_context *st,
                                    /* inputs */
                                    vpv->num_inputs,
                                    stvp->input_to_index,
+                                   NULL, /* inputSlotToAttr */
                                    NULL, /* input semantic name */
                                    NULL, /* input semantic index */
                                    NULL, /* interp mode */
@@ -358,6 +361,7 @@ st_translate_vertex_program(struct st_context *st,
                                    /* outputs */
                                    num_outputs,
                                    stvp->result_to_output,
+                                   stvp->output_slot_to_attr,
                                    stvp->output_semantic_name,
                                    stvp->output_semantic_index,
                                    key->passthrough_edgeflags,
@@ -482,6 +486,7 @@ st_translate_fragment_program(struct st_context *st,
 
    GLuint outputMapping[FRAG_RESULT_MAX];
    GLuint inputMapping[VARYING_SLOT_MAX];
+   GLuint inputSlotToAttr[VARYING_SLOT_MAX];
    GLuint interpMode[PIPE_MAX_SHADER_INPUTS];  /* XXX size? */
    GLuint interpLocation[PIPE_MAX_SHADER_INPUTS];
    GLuint attr;
@@ -502,6 +507,7 @@ st_translate_fragment_program(struct st_context *st,
       return NULL;
 
    assert(!(key->bitmap && key->drawpixels));
+   memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr));
 
    if (key->bitmap) {
       /* glBitmap drawing */
@@ -543,6 +549,7 @@ st_translate_fragment_program(struct st_context *st,
          const GLuint slot = fs_num_inputs++;
 
          inputMapping[attr] = slot;
+         inputSlotToAttr[slot] = attr;
          if (stfp->Base.IsCentroid & BITFIELD64_BIT(attr))
             interpLocation[slot] = TGSI_INTERPOLATE_LOC_CENTROID;
          else if (stfp->Base.IsSample & BITFIELD64_BIT(attr))
@@ -657,7 +664,8 @@ st_translate_fragment_program(struct st_context *st,
              * consumed for the TEXi varyings, and we can base the locations of
              * the user varyings on VAR0.  Otherwise, we use TEX0 as base index.
              */
-            assert(attr >= VARYING_SLOT_TEX0);
+            assert(attr >= VARYING_SLOT_VAR0 || attr == VARYING_SLOT_PNTC ||
+                   (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7));
             input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
             input_semantic_index[slot] = st_get_generic_varying_index(st, attr);
             if (attr == VARYING_SLOT_PNTC)
@@ -732,7 +740,7 @@ st_translate_fragment_program(struct st_context *st,
       }
    }
 
-   ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+   ureg = ureg_create_with_screen(TGSI_PROCESSOR_FRAGMENT, st->pipe->screen);
    if (ureg == NULL) {
       free(variant);
       return NULL;
@@ -778,6 +786,7 @@ st_translate_fragment_program(struct st_context *st,
                            /* inputs */
                            fs_num_inputs,
                            inputMapping,
+                           inputSlotToAttr,
                            input_semantic_name,
                            input_semantic_index,
                            interpMode,
@@ -785,6 +794,7 @@ st_translate_fragment_program(struct st_context *st,
                            /* outputs */
                            fs_num_outputs,
                            outputMapping,
+                           NULL,
                            fs_output_semantic_name,
                            fs_output_semantic_index, FALSE,
                            key->clamp_color );
@@ -867,7 +877,9 @@ st_translate_geometry_program(struct st_context *st,
                               struct st_geometry_program *stgp,
                               const struct st_gp_variant_key *key)
 {
+   GLuint inputSlotToAttr[VARYING_SLOT_MAX];
    GLuint inputMapping[VARYING_SLOT_MAX];
+   GLuint outputSlotToAttr[VARYING_SLOT_MAX];
    GLuint outputMapping[VARYING_SLOT_MAX];
    struct pipe_context *pipe = st->pipe;
    GLuint attr;
@@ -890,13 +902,15 @@ st_translate_geometry_program(struct st_context *st,
    if (!gpv)
       return NULL;
 
-   ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY);
+   ureg = ureg_create_with_screen(TGSI_PROCESSOR_GEOMETRY, st->pipe->screen);
    if (ureg == NULL) {
       free(gpv);
       return NULL;
    }
 
+   memset(inputSlotToAttr, 0, sizeof(inputSlotToAttr));
    memset(inputMapping, 0, sizeof(inputMapping));
+   memset(outputSlotToAttr, 0, sizeof(outputSlotToAttr));
    memset(outputMapping, 0, sizeof(outputMapping));
 
    /*
@@ -907,6 +921,7 @@ st_translate_geometry_program(struct st_context *st,
          const GLuint slot = gs_num_inputs++;
 
          inputMapping[attr] = slot;
+         inputSlotToAttr[slot] = attr;
 
          switch (attr) {
          case VARYING_SLOT_PRIMITIVE_ID:
@@ -985,6 +1000,7 @@ st_translate_geometry_program(struct st_context *st,
          GLuint slot = gs_num_outputs++;
 
          outputMapping[attr] = slot;
+         outputSlotToAttr[slot] = attr;
 
          switch (attr) {
          case VARYING_SLOT_POS:
@@ -1080,6 +1096,7 @@ st_translate_geometry_program(struct st_context *st,
                         /* inputs */
                         gs_num_inputs,
                         inputMapping,
+                        inputSlotToAttr,
                         input_semantic_name,
                         input_semantic_index,
                         NULL,
@@ -1087,6 +1104,7 @@ st_translate_geometry_program(struct st_context *st,
                         /* outputs */
                         gs_num_outputs,
                         outputMapping,
+                        outputSlotToAttr,
                         gs_output_semantic_name,
                         gs_output_semantic_index,
                         FALSE,
@@ -1201,7 +1219,7 @@ destroy_program_variants(struct st_context *st, struct gl_program *program)
          }
       }
       break;
-   case MESA_GEOMETRY_PROGRAM:
+   case GL_GEOMETRY_PROGRAM_NV:
       {
          struct st_geometry_program *stgp =
             (struct st_geometry_program *) program;
index a2c56062d6e1a5b2309f2f3d9d5157493e483a67..bb77eb6ed6540217cf1abc1a881c4c93aafe0cec 100644 (file)
@@ -163,6 +163,7 @@ struct st_vertex_program
 
    /** Maps VARYING_SLOT_x to slot */
    GLuint result_to_output[VARYING_SLOT_MAX];
+   GLuint output_slot_to_attr[VARYING_SLOT_MAX];
    ubyte output_semantic_name[VARYING_SLOT_MAX];
    ubyte output_semantic_index[VARYING_SLOT_MAX];
    GLuint num_outputs;
index fa853c9197f1fceaa277e072f8f541a46a0cee97..4e41b3b72a88d2a392e398fbeec4e97c6669fa10 100644 (file)
@@ -72,7 +72,7 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
  * \param fb  the framebuffer object the texture is being bound to
  * \param att  the fb attachment point of the texture
  *
- * \sa _mesa_framebuffer_renderbuffer
+ * \sa _mesa_FramebufferRenderbuffer_sw
  */
 void
 _swrast_render_texture(struct gl_context *ctx,
index 5b9dd54d75a834e7f55f888f41c814802e5f95c4..bc77ba8bf9518ea180d6eec9cf4c6ad02e3186e4 100644 (file)
@@ -36,6 +36,7 @@
 #include "math/m_xform.h"
 #include "main/state.h"
 #include "main/viewport.h"
+#include "util/simple_list.h"
 
 #include "tnl.h"
 #include "t_context.h"
index 3ea775c0e4a5b092288863708dd1f88dd051e840..72b8206ec23abc713f002242b8c31d89d27ac86d 100644 (file)
@@ -1817,9 +1817,12 @@ vbo_initialize_exec_dispatch(const struct gl_context *ctx,
       SET_DrawElementsInstancedBaseVertexBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
    }
 
-   if (ctx->API == API_OPENGL_CORE) {
+   if (ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) {
       SET_DrawArraysIndirect(exec, vbo_exec_DrawArraysIndirect);
       SET_DrawElementsIndirect(exec, vbo_exec_DrawElementsIndirect);
+   }
+
+   if (ctx->API == API_OPENGL_CORE) {
       SET_MultiDrawArraysIndirect(exec, vbo_exec_MultiDrawArraysIndirect);
       SET_MultiDrawElementsIndirect(exec, vbo_exec_MultiDrawElementsIndirect);
    }
index 946034710efd6e11b70b9645458ff3d8f39b6a75..b98ce59ff77d6c6344f6147fe13214b022c7a863 100644 (file)
@@ -140,6 +140,13 @@ static inline void list_validate(struct list_head *list)
             - ((char *)&(sample)->member - (char *)(sample)))
 #endif
 
+#define list_first_entry(ptr, type, member) \
+        LIST_ENTRY(type, (ptr)->next, member)
+
+#define list_last_entry(ptr, type, member) \
+        LIST_ENTRY(type, (ptr)->prev, member)
+
+
 #define LIST_FOR_EACH_ENTRY(pos, head, member)                         \
    for (pos = NULL, pos = container_of((head)->next, pos, member);     \
        &pos->member != (head);                                         \
index 19a403aa1c1ab97232b81865395b6a569390bb21..0ea44ac6ce567a677496543118bb18e5f3b8e4d3 100644 (file)
@@ -719,10 +719,9 @@ anv_compiler_create(struct anv_device *device)
    compiler->brw->intelScreen = compiler->screen;
    compiler->screen->devinfo = &device->info;
 
-   brw_process_intel_debug_variable(compiler->brw);
+   brw_process_intel_debug_variable(compiler->screen);
 
-   if (device->info.gen >= 8 && !(INTEL_DEBUG & DEBUG_VEC4VS))
-      compiler->brw->scalar_vs = true;
+   compiler->screen->compiler = brw_compiler_create(compiler, &device->info);
 
    ctx = &compiler->brw->ctx;
    _mesa_init_shader_object_functions(&ctx->Driver);
@@ -736,7 +735,6 @@ anv_compiler_create(struct anv_device *device)
    /* Set dd::NewShader */
    brwInitFragProgFuncs(&ctx->Driver);
 
-   compiler->screen->compiler = brw_compiler_create(compiler, &device->info);
    ctx->_Shader = &compiler->pipeline;
 
    compiler->brw->precompile = false;