Merge remote branch 'origin/master' into pipe-video
authorChristian König <deathsimple@vodafone.de>
Sat, 11 Dec 2010 12:43:44 +0000 (13:43 +0100)
committerChristian König <deathsimple@vodafone.de>
Sat, 11 Dec 2010 12:43:44 +0000 (13:43 +0100)
Conflicts:
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_texture.c

666 files changed:
SConstruct
common.py
configs/linux-llvm
configure.ac
docs/GL3.txt
docs/MESA_drm_image.spec
include/VG/openvg.h
include/VG/vgext.h
include/VG/vgplatform.h
include/VG/vgu.h
src/egl/drivers/dri2/egl_dri2.c
src/egl/main/eglarray.c
src/egl/main/eglarray.h
src/egl/main/eglconfig.c
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_llvm_sample.c
src/gallium/auxiliary/draw/draw_llvm_translate.c
src/gallium/auxiliary/draw/draw_pipe_aaline.c
src/gallium/auxiliary/draw/draw_pipe_pstipple.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
src/gallium/auxiliary/draw/draw_vs_llvm.c
src/gallium/auxiliary/gallivm/lp_bld.h
src/gallium/auxiliary/gallivm/lp_bld_arit.c
src/gallium/auxiliary/gallivm/lp_bld_assert.c
src/gallium/auxiliary/gallivm/lp_bld_assert.h
src/gallium/auxiliary/gallivm/lp_bld_bitarit.c
src/gallium/auxiliary/gallivm/lp_bld_const.c
src/gallium/auxiliary/gallivm/lp_bld_const.h
src/gallium/auxiliary/gallivm/lp_bld_conv.c
src/gallium/auxiliary/gallivm/lp_bld_conv.h
src/gallium/auxiliary/gallivm/lp_bld_debug.h
src/gallium/auxiliary/gallivm/lp_bld_flow.c
src/gallium/auxiliary/gallivm/lp_bld_flow.h
src/gallium/auxiliary/gallivm/lp_bld_format.h
src/gallium/auxiliary/gallivm/lp_bld_format_aos.c
src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c
src/gallium/auxiliary/gallivm/lp_bld_gather.c
src/gallium/auxiliary/gallivm/lp_bld_gather.h
src/gallium/auxiliary/gallivm/lp_bld_init.c
src/gallium/auxiliary/gallivm/lp_bld_init.h
src/gallium/auxiliary/gallivm/lp_bld_intr.c
src/gallium/auxiliary/gallivm/lp_bld_intr.h
src/gallium/auxiliary/gallivm/lp_bld_logic.c
src/gallium/auxiliary/gallivm/lp_bld_logic.h
src/gallium/auxiliary/gallivm/lp_bld_pack.c
src/gallium/auxiliary/gallivm/lp_bld_pack.h
src/gallium/auxiliary/gallivm/lp_bld_printf.c
src/gallium/auxiliary/gallivm/lp_bld_printf.h
src/gallium/auxiliary/gallivm/lp_bld_quad.c
src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/auxiliary/gallivm/lp_bld_struct.c
src/gallium/auxiliary/gallivm/lp_bld_struct.h
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
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/gallivm/lp_bld_type.c
src/gallium/auxiliary/gallivm/lp_bld_type.h
src/gallium/auxiliary/tgsi/tgsi_exec.h
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blit.h
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_blitter.h
src/gallium/auxiliary/util/u_box.h
src/gallium/auxiliary/util/u_debug.c
src/gallium/auxiliary/util/u_debug_describe.c
src/gallium/auxiliary/util/u_debug_stack.c
src/gallium/auxiliary/util/u_debug_symbol.c
src/gallium/auxiliary/util/u_dirty_flags.h
src/gallium/auxiliary/util/u_dirty_surfaces.h
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/auxiliary/util/u_gen_mipmap.c
src/gallium/auxiliary/util/u_gen_mipmap.h
src/gallium/auxiliary/util/u_inlines.h
src/gallium/auxiliary/util/u_mempool.c [deleted file]
src/gallium/auxiliary/util/u_mempool.h [deleted file]
src/gallium/auxiliary/util/u_resource.c
src/gallium/auxiliary/util/u_sampler.c
src/gallium/auxiliary/util/u_simple_screen.h
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_simple_shaders.h
src/gallium/auxiliary/util/u_slab.c [new file with mode: 0644]
src/gallium/auxiliary/util/u_slab.h [new file with mode: 0644]
src/gallium/auxiliary/util/u_staging.c
src/gallium/auxiliary/util/u_staging.h
src/gallium/auxiliary/util/u_surface.c
src/gallium/auxiliary/util/u_surface.h
src/gallium/auxiliary/util/u_surfaces.c
src/gallium/auxiliary/util/u_surfaces.h
src/gallium/auxiliary/util/u_transfer.c
src/gallium/auxiliary/util/u_transfer.h
src/gallium/auxiliary/vl/vl_idct.c
src/gallium/docs/d3d11ddi.txt
src/gallium/docs/source/context.rst
src/gallium/docs/source/glossary.rst
src/gallium/docs/source/screen.rst
src/gallium/drivers/cell/ppu/cell_context.c
src/gallium/drivers/cell/ppu/cell_texture.c
src/gallium/drivers/failover/fo_context.c
src/gallium/drivers/galahad/glhd_context.c
src/gallium/drivers/galahad/glhd_objects.c
src/gallium/drivers/galahad/glhd_objects.h
src/gallium/drivers/galahad/glhd_screen.c
src/gallium/drivers/i915/TODO [new file with mode: 0644]
src/gallium/drivers/i915/i915_batch.h
src/gallium/drivers/i915/i915_batchbuffer.h
src/gallium/drivers/i915/i915_blit.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i915/i915_debug.c
src/gallium/drivers/i915/i915_debug.h
src/gallium/drivers/i915/i915_prim_vbuf.c
src/gallium/drivers/i915/i915_reg.h
src/gallium/drivers/i915/i915_resource.h
src/gallium/drivers/i915/i915_resource_buffer.c
src/gallium/drivers/i915/i915_resource_texture.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/i915/i915_state_emit.c
src/gallium/drivers/i915/i915_state_sampler.c
src/gallium/drivers/i915/i915_surface.c
src/gallium/drivers/i915/i915_surface.h
src/gallium/drivers/i915/i915_winsys.h
src/gallium/drivers/i965/Makefile
src/gallium/drivers/i965/SConscript
src/gallium/drivers/i965/brw_context.c
src/gallium/drivers/i965/brw_context.h
src/gallium/drivers/i965/brw_misc_state.c
src/gallium/drivers/i965/brw_pipe_clear.c
src/gallium/drivers/i965/brw_pipe_surface.c [new file with mode: 0644]
src/gallium/drivers/i965/brw_resource_buffer.c
src/gallium/drivers/i965/brw_resource_texture.c
src/gallium/drivers/i965/brw_screen.c
src/gallium/drivers/i965/brw_screen.h
src/gallium/drivers/i965/brw_screen_surface.c [deleted file]
src/gallium/drivers/identity/SConscript
src/gallium/drivers/identity/id_context.c
src/gallium/drivers/identity/id_objects.c
src/gallium/drivers/identity/id_objects.h
src/gallium/drivers/identity/id_screen.c
src/gallium/drivers/llvmpipe/Makefile
src/gallium/drivers/llvmpipe/lp_bld_alpha.c
src/gallium/drivers/llvmpipe/lp_bld_alpha.h
src/gallium/drivers/llvmpipe/lp_bld_blend.h
src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
src/gallium/drivers/llvmpipe/lp_bld_depth.c
src/gallium/drivers/llvmpipe/lp_bld_depth.h
src/gallium/drivers/llvmpipe/lp_bld_interp.c
src/gallium/drivers/llvmpipe/lp_bld_interp.h
src/gallium/drivers/llvmpipe/lp_context.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_flush.c
src/gallium/drivers/llvmpipe/lp_flush.h
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_rast.c
src/gallium/drivers/llvmpipe/lp_rast_priv.h
src/gallium/drivers/llvmpipe/lp_scene.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_screen.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup.h
src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
src/gallium/drivers/llvmpipe/lp_state_derived.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_state_fs.h
src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
src/gallium/drivers/llvmpipe/lp_state_setup.c
src/gallium/drivers/llvmpipe/lp_state_setup.h
src/gallium/drivers/llvmpipe/lp_state_surface.c
src/gallium/drivers/llvmpipe/lp_surface.c
src/gallium/drivers/llvmpipe/lp_test.h
src/gallium/drivers/llvmpipe/lp_test_blend.c
src/gallium/drivers/llvmpipe/lp_test_conv.c
src/gallium/drivers/llvmpipe/lp_test_format.c
src/gallium/drivers/llvmpipe/lp_test_main.c
src/gallium/drivers/llvmpipe/lp_test_printf.c
src/gallium/drivers/llvmpipe/lp_test_round.c
src/gallium/drivers/llvmpipe/lp_test_sincos.c
src/gallium/drivers/llvmpipe/lp_tex_sample.c
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/llvmpipe/lp_texture.h
src/gallium/drivers/noop/noop_pipe.c
src/gallium/drivers/noop/noop_state.c
src/gallium/drivers/nv50/nv50_buffer.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_miptree.c
src/gallium/drivers/nv50/nv50_resource.c
src/gallium/drivers/nv50/nv50_resource.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_transfer.c
src/gallium/drivers/nv50/nv50_transfer.h
src/gallium/drivers/nvfx/nv30_fragtex.c
src/gallium/drivers/nvfx/nv40_fragtex.c
src/gallium/drivers/nvfx/nvfx_buffer.c
src/gallium/drivers/nvfx/nvfx_fragtex.c
src/gallium/drivers/nvfx/nvfx_miptree.c
src/gallium/drivers/nvfx/nvfx_resource.c
src/gallium/drivers/nvfx/nvfx_resource.h
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/nvfx/nvfx_state_fb.c
src/gallium/drivers/nvfx/nvfx_surface.c
src/gallium/drivers/nvfx/nvfx_transfer.c
src/gallium/drivers/nvfx/nvfx_transfer.h
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_chipset.c
src/gallium/drivers/r300/r300_chipset.h
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_cs.h
src/gallium/drivers/r300/r300_debug.c
src/gallium/drivers/r300/r300_defines.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_flush.c
src/gallium/drivers/r300/r300_fs.c
src/gallium/drivers/r300/r300_hyperz.c
src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/r300/r300_reg.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_render_stencilref.c
src/gallium/drivers/r300/r300_render_translate.c
src/gallium/drivers/r300/r300_resource.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_screen.h
src/gallium/drivers/r300/r300_screen_buffer.c
src/gallium/drivers/r300/r300_screen_buffer.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_texture.c
src/gallium/drivers/r300/r300_texture.h
src/gallium/drivers/r300/r300_texture_desc.c
src/gallium/drivers/r300/r300_texture_desc.h
src/gallium/drivers/r300/r300_tgsi_to_rc.c
src/gallium/drivers/r300/r300_transfer.c
src/gallium/drivers/r300/r300_transfer.h
src/gallium/drivers/r300/r300_vs.c
src/gallium/drivers/r300/r300_winsys.h
src/gallium/drivers/r600/Makefile
src/gallium/drivers/r600/SConscript
src/gallium/drivers/r600/eg_asm.c
src/gallium/drivers/r600/eg_state_inlines.h
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/evergreend.h
src/gallium/drivers/r600/r600.h
src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_asm.h
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_buffer.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_resource.h
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/r600/r600_state_inlines.h
src/gallium/drivers/r600/r600_texture.c
src/gallium/drivers/r600/r600_translate.c
src/gallium/drivers/r600/r600_upload.c [new file with mode: 0644]
src/gallium/drivers/rbug/rbug_context.c
src/gallium/drivers/rbug/rbug_core.c
src/gallium/drivers/rbug/rbug_objects.c
src/gallium/drivers/rbug/rbug_objects.h
src/gallium/drivers/rbug/rbug_screen.c
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_flush.c
src/gallium/drivers/softpipe/sp_flush.h
src/gallium/drivers/softpipe/sp_limits.h [new file with mode: 0644]
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.h
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/softpipe/sp_texture.h
src/gallium/drivers/softpipe/sp_tile_cache.c
src/gallium/drivers/softpipe/sp_tile_cache.h
src/gallium/drivers/softpipe/sp_video_context.c
src/gallium/drivers/svga/SConscript
src/gallium/drivers/svga/svga_cmd.c
src/gallium/drivers/svga/svga_context.c
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_pipe_blit.c
src/gallium/drivers/svga/svga_resource_buffer.c
src/gallium/drivers/svga/svga_resource_texture.c
src/gallium/drivers/svga/svga_resource_texture.h
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/svga/svga_state_need_swtnl.c
src/gallium/drivers/svga/svga_state_tss.c
src/gallium/drivers/svga/svga_surface.c
src/gallium/drivers/svga/svga_surface.h
src/gallium/drivers/trace/tr_context.c
src/gallium/drivers/trace/tr_dump_state.c
src/gallium/drivers/trace/tr_dump_state.h
src/gallium/drivers/trace/tr_screen.c
src/gallium/drivers/trace/tr_texture.c
src/gallium/drivers/trace/tr_texture.h
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_screen.h
src/gallium/include/pipe/p_state.h
src/gallium/include/pipe/p_video_context.h
src/gallium/include/state_tracker/st_api.h
src/gallium/include/state_tracker/xlib_sw_winsys.h
src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
src/gallium/state_trackers/dri/common/dri_screen.c
src/gallium/state_trackers/dri/common/dri_screen.h
src/gallium/state_trackers/dri/drm/dri2.c
src/gallium/state_trackers/dri/sw/drisw.c
src/gallium/state_trackers/egl/common/egl_g3d.h
src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/egl_g3d_image.c
src/gallium/state_trackers/egl/common/egl_g3d_st.c
src/gallium/state_trackers/egl/common/native_helper.c
src/gallium/state_trackers/egl/drm/native_drm.c
src/gallium/state_trackers/egl/x11/native_dri2.c
src/gallium/state_trackers/glx/xlib/xm_st.c
src/gallium/state_trackers/python/p_context.i
src/gallium/state_trackers/python/p_state.i
src/gallium/state_trackers/python/p_texture.i
src/gallium/state_trackers/python/st_device.c
src/gallium/state_trackers/python/st_device.h
src/gallium/state_trackers/python/st_sample.c
src/gallium/state_trackers/vega/.gitignore [new file with mode: 0644]
src/gallium/state_trackers/vega/Makefile
src/gallium/state_trackers/vega/SConscript
src/gallium/state_trackers/vega/api.c
src/gallium/state_trackers/vega/api.h
src/gallium/state_trackers/vega/api_filters.c
src/gallium/state_trackers/vega/api_images.c
src/gallium/state_trackers/vega/api_masks.c
src/gallium/state_trackers/vega/api_misc.c
src/gallium/state_trackers/vega/api_params.c
src/gallium/state_trackers/vega/api_path.c
src/gallium/state_trackers/vega/api_text.c
src/gallium/state_trackers/vega/asm_fill.h
src/gallium/state_trackers/vega/asm_util.h
src/gallium/state_trackers/vega/image.c
src/gallium/state_trackers/vega/image.h
src/gallium/state_trackers/vega/mask.c
src/gallium/state_trackers/vega/matrix.h
src/gallium/state_trackers/vega/paint.c
src/gallium/state_trackers/vega/paint.h
src/gallium/state_trackers/vega/path.c
src/gallium/state_trackers/vega/path.h
src/gallium/state_trackers/vega/polygon.c
src/gallium/state_trackers/vega/renderer.c
src/gallium/state_trackers/vega/renderer.h
src/gallium/state_trackers/vega/shader.c
src/gallium/state_trackers/vega/shader.h
src/gallium/state_trackers/vega/shaders_cache.c
src/gallium/state_trackers/vega/shaders_cache.h
src/gallium/state_trackers/vega/st_inlines.h [deleted file]
src/gallium/state_trackers/vega/text.c [new file with mode: 0644]
src/gallium/state_trackers/vega/text.h [new file with mode: 0644]
src/gallium/state_trackers/vega/vg_context.c
src/gallium/state_trackers/vega/vg_context.h
src/gallium/state_trackers/vega/vg_manager.c
src/gallium/state_trackers/wgl/SConscript
src/gallium/state_trackers/wgl/stw_context.c
src/gallium/state_trackers/wgl/stw_device.c
src/gallium/state_trackers/wgl/stw_device.h
src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
src/gallium/state_trackers/wgl/stw_ext_pbuffer.c [new file with mode: 0644]
src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
src/gallium/state_trackers/wgl/stw_framebuffer.c
src/gallium/state_trackers/wgl/stw_framebuffer.h
src/gallium/state_trackers/wgl/stw_getprocaddress.c
src/gallium/state_trackers/wgl/stw_pixelformat.c
src/gallium/state_trackers/wgl/stw_st.c
src/gallium/state_trackers/wgl/stw_winsys.h
src/gallium/state_trackers/xorg/xorg_composite.c
src/gallium/state_trackers/xorg/xorg_crtc.c
src/gallium/state_trackers/xorg/xorg_dri2.c
src/gallium/state_trackers/xorg/xorg_driver.c
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/state_trackers/xorg/xorg_exa.h
src/gallium/state_trackers/xorg/xorg_renderer.c
src/gallium/state_trackers/xorg/xorg_tracker.h
src/gallium/state_trackers/xorg/xorg_xv.c
src/gallium/state_trackers/xorg/xvmc/subpicture.c
src/gallium/state_trackers/xorg/xvmc/surface.c
src/gallium/targets/egl/egl.c
src/gallium/targets/libgl-gdi/libgl_gdi.c
src/gallium/targets/xorg-vmwgfx/vmw_video.c
src/gallium/tests/graw/clear.c
src/gallium/tests/graw/fs-test.c
src/gallium/tests/graw/gs-test.c
src/gallium/tests/graw/quad-tex.c
src/gallium/tests/graw/shader-leak.c
src/gallium/tests/graw/tri-gs.c
src/gallium/tests/graw/tri-instanced.c
src/gallium/tests/graw/tri.c
src/gallium/tests/graw/vs-test.c
src/gallium/tests/python/retrace/interpreter.py
src/gallium/tests/trivial/quad-tex.c
src/gallium/tests/trivial/tri.c
src/gallium/winsys/g3dvl/dri/dri_winsys.c
src/gallium/winsys/g3dvl/vl_winsys.h
src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
src/gallium/winsys/i915/drm/i915_drm_buffer.c
src/gallium/winsys/i915/drm/i915_drm_winsys.c
src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c
src/gallium/winsys/i915/sw/i915_sw_buffer.c
src/gallium/winsys/i915/sw/i915_sw_winsys.h
src/gallium/winsys/i965/xlib/xlib_i965.c
src/gallium/winsys/r600/drm/Makefile
src/gallium/winsys/r600/drm/SConscript
src/gallium/winsys/r600/drm/evergreen_hw_context.c
src/gallium/winsys/r600/drm/r600.c
src/gallium/winsys/r600/drm/r600_bo.c
src/gallium/winsys/r600/drm/r600_bomgr.c [new file with mode: 0644]
src/gallium/winsys/r600/drm/r600_drm.c
src/gallium/winsys/r600/drm/r600_hw_context.c
src/gallium/winsys/r600/drm/r600_priv.h
src/gallium/winsys/r600/drm/r600d.h
src/gallium/winsys/r600/drm/radeon_bo_pb.c [deleted file]
src/gallium/winsys/r600/drm/radeon_pciid.c
src/gallium/winsys/radeon/drm/Makefile
src/gallium/winsys/radeon/drm/SConscript
src/gallium/winsys/radeon/drm/radeon_buffer.h [deleted file]
src/gallium/winsys/radeon/drm/radeon_drm.c [deleted file]
src/gallium/winsys/radeon/drm/radeon_drm.h [deleted file]
src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
src/gallium/winsys/radeon/drm/radeon_drm_buffer.h [new file with mode: 0644]
src/gallium/winsys/radeon/drm/radeon_drm_common.c [new file with mode: 0644]
src/gallium/winsys/radeon/drm/radeon_drm_public.h
src/gallium/winsys/radeon/drm/radeon_r300.c
src/gallium/winsys/radeon/drm/radeon_r300.h [deleted file]
src/gallium/winsys/radeon/drm/radeon_winsys.h
src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
src/glsl/Makefile
src/glsl/SConscript
src/glsl/ast.h
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/builtin_function.cpp
src/glsl/builtins/tools/generate_builtins.py
src/glsl/glcpp/glcpp-parse.c
src/glsl/glcpp/glcpp-parse.y
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_symbol_table.cpp
src/glsl/glsl_symbol_table.h
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_clone.cpp
src/glsl/ir_function_can_inline.cpp
src/glsl/ir_import_prototypes.cpp
src/glsl/ir_optimization.h
src/glsl/ir_print_visitor.cpp
src/glsl/ir_reader.cpp
src/glsl/ir_set_program_inouts.cpp
src/glsl/ir_variable.cpp
src/glsl/link_functions.cpp
src/glsl/linker.cpp
src/glsl/loop_unroll.cpp
src/glsl/lower_discard.cpp [new file with mode: 0644]
src/glsl/lower_instructions.cpp
src/glsl/lower_jumps.cpp
src/glsl/main.cpp
src/glsl/opt_algebraic.cpp
src/glsl/opt_discard_simplification.cpp [new file with mode: 0644]
src/mapi/glapi/SConscript
src/mapi/glapi/gen/gl_x86-64_asm.py
src/mapi/glapi/gen/gl_x86_asm.py
src/mapi/glapi/glapi_getproc.c
src/mapi/glapi/glapi_x86-64.S
src/mapi/glapi/glapi_x86.S
src/mapi/mapi/mapi.c
src/mapi/mapi/mapi_abi.py
src/mapi/mapi/mapi_tmp.h
src/mapi/mapi/stub.c
src/mapi/mapi/table.h
src/mapi/mapi/u_current.c
src/mapi/mapi/u_thread.c
src/mapi/mapi/u_thread.h
src/mapi/vgapi/Makefile
src/mapi/vgapi/SConscript
src/mapi/vgapi/vgapi.csv
src/mapi/vgapi/vgapi_defines.h [deleted file]
src/mesa/SConscript
src/mesa/drivers/common/meta.c
src/mesa/drivers/dri/i915/i915_context.c
src/mesa/drivers/dri/i915/i915_fragprog.c
src/mesa/drivers/dri/i965/Makefile
src/mesa/drivers/dri/i965/brw_cc.c
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_curbe.c
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_disasm.c
src/mesa/drivers/dri/i965/brw_eu.c
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
src/mesa/drivers/dri/i965/brw_gs.c
src/mesa/drivers/dri/i965/brw_misc_state.c
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_structs.h
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h
src/mesa/drivers/dri/i965/brw_vs_emit.c
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_fp.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c [deleted file]
src/mesa/drivers/dri/i965/brw_wm_iz.c
src/mesa/drivers/dri/i965/brw_wm_pass0.c
src/mesa/drivers/dri/i965/brw_wm_pass1.c
src/mesa/drivers/dri/i965/brw_wm_pass2.c
src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
src/mesa/drivers/dri/i965/brw_wm_state.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_cc.c
src/mesa/drivers/dri/i965/gen6_clip_state.c
src/mesa/drivers/dri/i965/gen6_sf_state.c
src/mesa/drivers/dri/i965/gen6_urb.c
src/mesa/drivers/dri/i965/gen6_vs_state.c
src/mesa/drivers/dri/i965/gen6_wm_state.c
src/mesa/drivers/dri/intel/intel_batchbuffer.c
src/mesa/drivers/dri/intel/intel_context.c
src/mesa/drivers/dri/intel/intel_context.h
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_tex_format.c
src/mesa/drivers/dri/r200/r200_maos_arrays.c
src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/radeon_code.h
src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
src/mesa/drivers/dri/r300/compiler/radeon_program.c
src/mesa/drivers/dri/r300/compiler/radeon_program.h
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
src/mesa/drivers/dri/r300/compiler/radeon_program_print.c
src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c
src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c
src/mesa/drivers/dri/r600/evergreen_chip.c
src/mesa/drivers/dri/r600/evergreen_state.c
src/mesa/drivers/dri/r600/evergreen_tex.c
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/r600/r700_assembler.c
src/mesa/drivers/dri/radeon/radeon_chipset.h
src/mesa/drivers/dri/radeon/radeon_common_context.c
src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/sis/server/sis_dri.h
src/mesa/drivers/dri/tdfx/tdfx_context.h
src/mesa/drivers/dri/unichrome/server/via_dri.h
src/mesa/drivers/windows/gdi/InitCritSections.cpp
src/mesa/drivers/x11/glxheader.h
src/mesa/drivers/x11/xm_api.c
src/mesa/drivers/x11/xm_buffer.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/drivers/x11/xm_glide.c
src/mesa/drivers/x11/xm_image.c
src/mesa/drivers/x11/xm_line.c
src/mesa/drivers/x11/xm_span.c
src/mesa/drivers/x11/xmesa.h
src/mesa/drivers/x11/xmesaP.h
src/mesa/main/APIspec.xml
src/mesa/main/compiler.h
src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/extensions.c
src/mesa/main/fbobject.c
src/mesa/main/formats.c
src/mesa/main/formats.h
src/mesa/main/get.c
src/mesa/main/image.c
src/mesa/main/imports.c
src/mesa/main/mtypes.h
src/mesa/main/pack.c
src/mesa/main/pack.h
src/mesa/main/shaderapi.c
src/mesa/main/shaderobj.c
src/mesa/main/shaderobj.h
src/mesa/main/syncobj.h
src/mesa/main/texcompress.h
src/mesa/main/texcompress_s3tc.h
src/mesa/main/texenvprogram.h
src/mesa/main/texformat.h
src/mesa/main/texgetimage.c
src/mesa/main/texgetimage.h
src/mesa/main/teximage.c
src/mesa/main/texobj.c
src/mesa/main/texobj.h
src/mesa/main/texrender.h
src/mesa/main/transformfeedback.h
src/mesa/main/varray.c
src/mesa/main/varray.h
src/mesa/main/viewport.h
src/mesa/math/m_debug_clip.c
src/mesa/program/arbprogparse.h
src/mesa/program/ir_to_mesa.cpp
src/mesa/program/prog_instruction.h
src/mesa/program/prog_print.c
src/mesa/program/prog_print.h
src/mesa/program/prog_statevars.c
src/mesa/program/prog_statevars.h
src/mesa/program/program.c
src/mesa/program/program.h
src/mesa/program/symbol_table.c
src/mesa/program/symbol_table.h
src/mesa/state_tracker/st_atom_constbuf.c
src/mesa/state_tracker/st_atom_framebuffer.c
src/mesa/state_tracker/st_atom_pixeltransfer.c
src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_cb_accum.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_cb_blit.c
src/mesa/state_tracker/st_cb_bufferobjects.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_extensions.c
src/mesa/state_tracker/st_gen_mipmap.c
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_texture.c
src/mesa/swrast/s_blend.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_readpix.c
src/mesa/swrast/s_texcombine.c
src/mesa/swrast/s_texfilter.c
src/mesa/vbo/vbo.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_save.h
src/mesa/vbo/vbo_save_api.c

index c6198041fb0cff49b695423ac5eaece4fe2217ab..8880d851e645541e95ca3990ddb55646993016d4 100644 (file)
@@ -32,7 +32,6 @@ import common
 
 opts = Variables('config.py')
 common.AddOptions(opts)
-opts.Add(EnumVariable('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
 
 env = Environment(
        options = opts,
index b7749c925dfc3db0d7734cdd0462edc5016e15bd..78e2d0fb24f112ffd0a76dcbe301026917077193 100644 (file)
--- a/common.py
+++ b/common.py
@@ -91,3 +91,4 @@ def AddOptions(opts):
        opts.Add(BoolOption('llvm', 'use LLVM', default_llvm))
        opts.Add(BoolOption('debug', 'DEPRECATED: debug build', 'yes'))
        opts.Add(BoolOption('profile', 'DEPRECATED: profile build', 'no'))
+       opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
index 6aa434032dc46368a9069d784bcf2ae1f3bdb222..22de0662ee1b235708801efbe746422ff4ddf340 100644 (file)
@@ -15,7 +15,7 @@ ARCH_FLAGS = -mmmx -msse -msse2 -mstackrealign
 DEFINES += -DNDEBUG -DGALLIUM_LLVMPIPE -DHAVE_UDIS86
 
 # override -std=c99
-CFLAGS += -std=gnu99 -D__STDC_CONSTANT_MACROS
+CFLAGS += -std=gnu99
 
 LLVM_VERSION := $(shell llvm-config --version)
 
@@ -30,7 +30,7 @@ else
 endif
 
 ifeq ($(MESA_LLVM),1)
-#  LLVM_CFLAGS=`llvm-config --cflags`
+  LLVM_CFLAGS=`llvm-config --cppflags`
   LLVM_CXXFLAGS=`llvm-config --cxxflags backend bitreader engine ipo interpreter instrumentation` -Wno-long-long
   LLVM_LDFLAGS = $(shell llvm-config --ldflags backend bitreader engine ipo interpreter instrumentation)
   LLVM_LIBS = $(shell llvm-config --libs backend bitwriter bitreader engine ipo interpreter instrumentation)
index 79e134b4254bac8851ffdf7600be192a3ba06f02..df51ce205b1488a64318871be4e976d37cb0ffdd 100644 (file)
@@ -1565,7 +1565,7 @@ AC_ARG_ENABLE([gallium-llvm],
 if test "x$enable_gallium_llvm" = xyes; then
     if test "x$LLVM_CONFIG" != xno; then
        LLVM_VERSION=`$LLVM_CONFIG --version`
-       LLVM_CFLAGS=`$LLVM_CONFIG --cflags`
+       LLVM_CFLAGS=`$LLVM_CONFIG --cppflags`
        LLVM_LIBS="`$LLVM_CONFIG --libs jit interpreter nativecodegen bitwriter` -lstdc++"
 
        if test "x$HAS_UDIS86" != xno; then
index 8628a6e88dd441b86fa811ba466ec5465ec18554..fb22739b6c7c779fe18bc8d4fa2a29b776063a51 100644 (file)
@@ -94,6 +94,18 @@ GL_ARB_texture_buffer_object_rgb32                   not started
 GL_ARB_texture_cube_map_array                        not started
 GL_ARB_texture_gather                                not started
 GL_ARB_transform_feedback2                           not started
+GL_ARB_transform_feedback3                           not started
+
+
+GL 4.1:
+
+GLSL 4.1                                             not started
+GL_ARB_ES2_compatibility                             not started
+GL_ARB_get_program_binary                            not started
+GL_ARB_separate_shader_objects                       some infrastructure done
+GL_ARB_shader_precision                              not started
+GL_ARB_vertex_attrib_64bit                           not started
+GL_ARB_viewport_array                                not started
 
 
 
index 118501c3d3e833029d9bb48627ba92347be3ffd2..c9853a7fd0f1dd6e4a77453666b351d4b47f836c 100644 (file)
@@ -83,7 +83,7 @@ Additions to the EGL 1.4 Specification:
         EGLImageKHR eglCreateDRMImageMESA(EGLDisplay dpy,
                                           const EGLint *attrib_list);
 
-    In the attribute list, pass EGL_WIDTH, EGL_EIGHT and format and
+    In the attribute list, pass EGL_WIDTH, EGL_HEIGHT and format and
     use in the attrib list using EGL_DRM_BUFFER_FORMAT_MESA and
     EGL_DRM_BUFFER_USE_MESA.  The only format specified by this
     extension is EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, where each pixel
index 60167e45d67fd26956b6b40d41b2126a29dfa0f4..86d54d6e01f4d368ea0c7089d7e5b09349da5a5d 100644 (file)
@@ -1,8 +1,8 @@
-/* $Revision: 6822 $ on $Date:: 2008-10-30 05:14:19 -0400 #$ */
+/* $Revision: 9203 $ on $Date:: 2009-10-07 02:21:52 -0700 #$ */
 
 /*------------------------------------------------------------------------
  *
- * OpenVG 1.0.1 Reference Implementation
+ * OpenVG 1.1 Reference Implementation
  * -------------------------------------
  *
  * Copyright (c) 2008 The Khronos Group Inc.
@@ -28,7 +28,7 @@
  *
  *//**
  * \file
- * \brief      OpenVG 1.0.1 API.
+ * \brief      OpenVG 1.1 API.
  *//*-------------------------------------------------------------------*/
 
 #ifndef _OPENVG_H
@@ -42,6 +42,7 @@ extern "C" {
 
 #define OPENVG_VERSION_1_0             1
 #define OPENVG_VERSION_1_0_1   1
+#define OPENVG_VERSION_1_1             2
 
 #ifndef VG_MAXSHORT
 #define VG_MAXSHORT 0x7FFF
@@ -55,10 +56,12 @@ extern "C" {
 #define VG_MAX_ENUM 0x7FFFFFFF
 #endif
 
-typedef long VGHandle;
+typedef VGuint VGHandle;
 
 typedef VGHandle VGPath;
 typedef VGHandle VGImage;
+typedef VGHandle VGMaskLayer;
+typedef VGHandle VGFont;
 typedef VGHandle VGPaint;
 
 #define VG_INVALID_HANDLE ((VGHandle)0)
@@ -96,6 +99,10 @@ typedef enum {
   /* Scissoring rectangles */
   VG_SCISSOR_RECTS                            = 0x1106,
 
+  /* Color Transformation */
+  VG_COLOR_TRANSFORM                          = 0x1170,
+  VG_COLOR_TRANSFORM_VALUES                   = 0x1171,
+
   /* Stroke parameters */
   VG_STROKE_LINE_WIDTH                        = 0x1110,
   VG_STROKE_CAP_STYLE                         = 0x1111,
@@ -111,6 +118,9 @@ typedef enum {
   /* Color for vgClear */
   VG_CLEAR_COLOR                              = 0x1121,
 
+  /* Glyph origin */
+  VG_GLYPH_ORIGIN                             = 0x1122,
+
   /* Enable/disable alpha masking and scissoring */
   VG_MASKING                                  = 0x1130,
   VG_SCISSORING                               = 0x1131,
@@ -165,6 +175,7 @@ typedef enum {
   VG_MATRIX_IMAGE_USER_TO_SURFACE             = 0x1401,
   VG_MATRIX_FILL_PAINT_TO_USER                = 0x1402,
   VG_MATRIX_STROKE_PAINT_TO_USER              = 0x1403,
+  VG_MATRIX_GLYPH_USER_TO_SURFACE             = 0x1404,
 
   VG_MATRIX_MODE_FORCE_SIZE                   = VG_MAX_ENUM
 } VGMatrixMode;
@@ -365,6 +376,8 @@ typedef enum {
   VG_lL_8                                     = 10,
   VG_A_8                                      = 11,
   VG_BW_1                                     = 12,
+  VG_A_1                                      = 13,
+  VG_A_4                                      = 14,
 
   /* {A,X}RGB channel ordering */
   VG_sXRGB_8888                               =  0 | (1 << 6),
@@ -448,6 +461,12 @@ typedef enum {
   VG_BLEND_MODE_FORCE_SIZE                    = VG_MAX_ENUM
 } VGBlendMode;
 
+typedef enum {
+  VG_FONT_NUM_GLYPHS                          = 0x2F00,
+
+  VG_FONT_PARAM_TYPE_FORCE_SIZE               = VG_MAX_ENUM
+} VGFontParamType;
+
 typedef enum {
   VG_IMAGE_FORMAT_QUERY                       = 0x2100,
   VG_PATH_DATATYPE_QUERY                      = 0x2101,
@@ -541,8 +560,22 @@ VG_API_CALL void VG_API_ENTRY vgShear(VGfloat shx, VGfloat shy) VG_API_EXIT;
 VG_API_CALL void VG_API_ENTRY vgRotate(VGfloat angle) VG_API_EXIT;
 
 /* Masking and Clearing */
-VG_API_CALL void VG_API_ENTRY vgMask(VGImage mask, VGMaskOperation operation,
-                        VGint x, VGint y, VGint width, VGint height) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgMask(VGHandle mask, VGMaskOperation operation,
+                                     VGint x, VGint y,
+                                     VGint width, VGint height) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgRenderToMask(VGPath path,
+                                            VGbitfield paintModes,
+                                            VGMaskOperation operation) VG_API_EXIT;
+VG_API_CALL VGMaskLayer VG_API_ENTRY vgCreateMaskLayer(VGint width, VGint height) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgDestroyMaskLayer(VGMaskLayer maskLayer) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgFillMaskLayer(VGMaskLayer maskLayer,
+                                             VGint x, VGint y,
+                                             VGint width, VGint height,
+                                             VGfloat value) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgCopyMask(VGMaskLayer maskLayer,
+                                        VGint dx, VGint dy,
+                                        VGint sx, VGint sy,
+                                        VGint width, VGint height) VG_API_EXIT;
 VG_API_CALL void VG_API_ENTRY vgClear(VGint x, VGint y, VGint width, VGint height) VG_API_EXIT;
 
 /* Paths */
@@ -636,6 +669,33 @@ VG_API_CALL void VG_API_ENTRY vgCopyPixels(VGint dx, VGint dy,
                               VGint sx, VGint sy,
                               VGint width, VGint height) VG_API_EXIT;
 
+/* Text */
+VG_API_CALL VGFont VG_API_ENTRY vgCreateFont(VGint glyphCapacityHint) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgDestroyFont(VGFont font) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgSetGlyphToPath(VGFont font,
+                                              VGuint glyphIndex,
+                                              VGPath path,
+                                              VGboolean isHinted,
+                                              const VGfloat glyphOrigin [2],
+                                              const VGfloat escapement[2]) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgSetGlyphToImage(VGFont font,
+                                               VGuint glyphIndex,
+                                               VGImage image,
+                                               const VGfloat glyphOrigin [2],
+                                               const VGfloat escapement[2]) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgClearGlyph(VGFont font,VGuint glyphIndex) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgDrawGlyph(VGFont font, 
+                                         VGuint glyphIndex,
+                                         VGbitfield paintModes,
+                                         VGboolean allowAutoHinting) VG_API_EXIT;
+VG_API_CALL void VG_API_ENTRY vgDrawGlyphs(VGFont font,
+                                          VGint glyphCount,
+                                          const VGuint *glyphIndices,
+                                          const VGfloat *adjustments_x,
+                                          const VGfloat *adjustments_y,
+                                          VGbitfield paintModes,
+                                          VGboolean allowAutoHinting) VG_API_EXIT;
+
 /* Image Filters */
 VG_API_CALL void VG_API_ENTRY vgColorMatrix(VGImage dst, VGImage src,
                                const VGfloat * matrix) VG_API_EXIT;
index 97e3e779e19c44772d9e31d4adf66c3825889372..9ff32344820d1707c91094d101534a254058880b 100644 (file)
-/* $Revision: 6810 $ on $Date:: 2008-10-29 10:31:37 -0400 #$ */\r
-\r
-/*------------------------------------------------------------------------\r
- * \r
- * VG extensions Reference Implementation\r
- * -------------------------------------\r
- *\r
- * Copyright (c) 2008 The Khronos Group Inc.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a\r
- * copy of this software and /or associated documentation files\r
- * (the "Materials "), to deal in the Materials without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Materials,\r
- * and to permit persons to whom the Materials are furnished to do so,\r
- * subject to the following conditions: \r
- *\r
- * The above copyright notice and this permission notice shall be included \r
- * in all copies or substantial portions of the Materials. \r
- *\r
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR\r
- * THE USE OR OTHER DEALINGS IN THE MATERIALS.\r
- *\r
- *//**\r
- * \file\r
- * \brief      VG extensions\r
- *//*-------------------------------------------------------------------*/\r
-\r
-\r
-\r
-#ifndef _VGEXT_H\r
-#define _VGEXT_H\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#include <VG/openvg.h>\r
-#include <VG/vgu.h>\r
-\r
-#ifndef VG_API_ENTRYP\r
-#   define VG_API_ENTRYP VG_API_ENTRY*\r
-#endif\r
-\r
-#ifndef VGU_API_ENTRYP\r
-#   define VGU_API_ENTRYP VGU_API_ENTRY*\r
-#endif\r
-\r
-/*-------------------------------------------------------------------------------\r
- * KHR extensions\r
- *------------------------------------------------------------------------------*/\r
-\r
-typedef enum  {\r
-\r
-#ifndef VG_KHR_iterative_average_blur\r
-  VG_MAX_AVERAGE_BLUR_DIMENSION_KHR        = 0x116B,\r
-  VG_AVERAGE_BLUR_DIMENSION_RESOLUTION_KHR = 0x116C,\r
-  VG_MAX_AVERAGE_BLUR_ITERATIONS_KHR       = 0x116D,\r
-#endif\r
-\r
-  VG_PARAM_TYPE_KHR_FORCE_SIZE             = VG_MAX_ENUM\r
-} VGParamTypeKHR;\r
-\r
-#ifndef VG_KHR_EGL_image\r
-#define VG_KHR_EGL_image 1\r
-/* VGEGLImageKHR is an opaque handle to an EGLImage */\r
-typedef void* VGeglImageKHR; \r
-\r
-#ifdef VG_VGEXT_PROTOTYPES\r
-VG_API_CALL VGImage VG_API_ENTRY vgCreateEGLImageTargetKHR(VGeglImageKHR image);\r
-#endif\r
-typedef VGImage (VG_API_ENTRYP PFNVGCREATEEGLIMAGETARGETKHRPROC) (VGeglImageKHR image);\r
-\r
-#endif\r
-\r
-\r
-#ifndef VG_KHR_iterative_average_blur\r
-#define VG_KHR_iterative_average_blur 1\r
-\r
-#ifdef VG_VGEXT_PROTOTYPES\r
-VG_API_CALL void vgIterativeAverageBlurKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGTilingMode tilingMode);\r
-#endif \r
-typedef void (VG_API_ENTRYP PFNVGITERATIVEAVERAGEBLURKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGTilingMode tilingMode);\r
-\r
-#endif\r
-\r
-\r
-#ifndef VG_KHR_advanced_blending\r
-#define VG_KHR_advanced_blending 1\r
-\r
-typedef enum {\r
-  VG_BLEND_OVERLAY_KHR        = 0x2010,\r
-  VG_BLEND_HARDLIGHT_KHR      = 0x2011,\r
-  VG_BLEND_SOFTLIGHT_SVG_KHR  = 0x2012,\r
-  VG_BLEND_SOFTLIGHT_KHR      = 0x2013,\r
-  VG_BLEND_COLORDODGE_KHR     = 0x2014,\r
-  VG_BLEND_COLORBURN_KHR      = 0x2015,\r
-  VG_BLEND_DIFFERENCE_KHR     = 0x2016,\r
-  VG_BLEND_SUBTRACT_KHR       = 0x2017,\r
-  VG_BLEND_INVERT_KHR         = 0x2018,\r
-  VG_BLEND_EXCLUSION_KHR      = 0x2019,\r
-  VG_BLEND_LINEARDODGE_KHR    = 0x201a,\r
-  VG_BLEND_LINEARBURN_KHR     = 0x201b,\r
-  VG_BLEND_VIVIDLIGHT_KHR     = 0x201c,\r
-  VG_BLEND_LINEARLIGHT_KHR    = 0x201d,\r
-  VG_BLEND_PINLIGHT_KHR       = 0x201e,\r
-  VG_BLEND_HARDMIX_KHR        = 0x201f,\r
-  VG_BLEND_CLEAR_KHR          = 0x2020,\r
-  VG_BLEND_DST_KHR            = 0x2021,\r
-  VG_BLEND_SRC_OUT_KHR        = 0x2022,\r
-  VG_BLEND_DST_OUT_KHR        = 0x2023,\r
-  VG_BLEND_SRC_ATOP_KHR       = 0x2024,\r
-  VG_BLEND_DST_ATOP_KHR       = 0x2025,\r
-  VG_BLEND_XOR_KHR            = 0x2026,\r
-\r
-  VG_BLEND_MODE_KHR_FORCE_SIZE= VG_MAX_ENUM\r
-} VGBlendModeKHR;\r
-#endif\r
-\r
-#ifndef VG_KHR_parametric_filter\r
-#define VG_KHR_parametric_filter 1 \r
-\r
-typedef enum {\r
-  VG_PF_OBJECT_VISIBLE_FLAG_KHR = (1 << 0),\r
-  VG_PF_KNOCKOUT_FLAG_KHR       = (1 << 1),\r
-  VG_PF_OUTER_FLAG_KHR          = (1 << 2),\r
-  VG_PF_INNER_FLAG_KHR          = (1 << 3),\r
-\r
-  VG_PF_TYPE_KHR_FORCE_SIZE     = VG_MAX_ENUM\r
-} VGPfTypeKHR;\r
-\r
-typedef enum {\r
-  VGU_IMAGE_IN_USE_ERROR           = 0xF010,\r
-\r
-  VGU_ERROR_CODE_KHR_FORCE_SIZE    = VG_MAX_ENUM\r
-} VGUErrorCodeKHR;\r
-\r
-#ifdef VG_VGEXT_PROTOTYPES\r
-VG_API_CALL void VG_API_ENTRY vgParametricFilterKHR(VGImage dst,VGImage src,VGImage blur,VGfloat strength,VGfloat offsetX,VGfloat offsetY,VGbitfield filterFlags,VGPaint highlightPaint,VGPaint shadowPaint);\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguDropShadowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint shadowColorRGBA);\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGlowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint glowColorRGBA) ;\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguBevelKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint highlightColorRGBA,VGuint shadowColorRGBA);\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGradientGlowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* glowColorRampStops);\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGradientBevelKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* bevelColorRampStops);\r
-#endif\r
-typedef void (VG_API_ENTRYP PFNVGPARAMETRICFILTERKHRPROC) (VGImage dst,VGImage src,VGImage blur,VGfloat strength,VGfloat offsetX,VGfloat offsetY,VGbitfield filterFlags,VGPaint highlightPaint,VGPaint shadowPaint);\r
-typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUDROPSHADOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint shadowColorRGBA);\r
-typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGLOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint glowColorRGBA);\r
-typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUBEVELKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint highlightColorRGBA,VGuint shadowColorRGBA);\r
-typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGRADIENTGLOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* glowColorRampStops);\r
-typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGRADIENTBEVELKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* bevelColorRampStops);\r
-\r
-#endif\r
-\r
-\r
-/*-------------------------------------------------------------------------------\r
- * NDS extensions\r
- *------------------------------------------------------------------------------*/\r
-\r
-#ifndef VG_NDS_paint_generation\r
-#define VG_NDS_paint_generation 1\r
-\r
-typedef enum { \r
-  VG_PAINT_COLOR_RAMP_LINEAR_NDS            = 0x1A10,\r
-  VG_COLOR_MATRIX_NDS                       = 0x1A11,\r
-  VG_PAINT_COLOR_TRANSFORM_LINEAR_NDS       = 0x1A12,\r
-\r
-  VG_PAINT_PARAM_TYPE_NDS_FORCE_SIZE        = VG_MAX_ENUM\r
-} VGPaintParamTypeNds;\r
-\r
-typedef enum {\r
-  VG_DRAW_IMAGE_COLOR_MATRIX_NDS            = 0x1F10,\r
-\r
-  VG_IMAGE_MODE_NDS_FORCE_SIZE              = VG_MAX_ENUM\r
-} VGImageModeNds;\r
-#endif \r
-\r
-\r
-#ifndef VG_NDS_projective_geometry\r
-#define VG_NDS_projective_geometry 1\r
-\r
-typedef enum {\r
-  VG_CLIP_MODE_NDS                          = 0x1180,\r
-  VG_CLIP_LINES_NDS                         = 0x1181,\r
-  VG_MAX_CLIP_LINES_NDS                     = 0x1182,\r
-\r
-  VG_PARAM_TYPE_NDS_FORCE_SIZE        = VG_MAX_ENUM\r
-} VGParamTypeNds;\r
-\r
-typedef enum {\r
-  VG_CLIPMODE_NONE_NDS                      = 0x3000,\r
-  VG_CLIPMODE_CLIP_CLOSED_NDS               = 0x3001,\r
-  VG_CLIPMODE_CLIP_OPEN_NDS                 = 0x3002,\r
-  VG_CLIPMODE_CULL_NDS                      = 0x3003,\r
-\r
-  VG_CLIPMODE_NDS_FORCE_SIZE = VG_MAX_ENUM\r
-} VGClipModeNds;\r
-\r
-typedef enum {\r
-  VG_RQUAD_TO_NDS              = ( 13 << 1 ),\r
-  VG_RCUBIC_TO_NDS             = ( 14 << 1 ),\r
-  \r
-  VG_PATH_SEGMENT_NDS_FORCE_SIZE = VG_MAX_ENUM\r
-} VGPathSegmentNds;\r
-\r
-typedef enum {\r
-  VG_RQUAD_TO_ABS_NDS            = (VG_RQUAD_TO_NDS  | VG_ABSOLUTE),\r
-  VG_RQUAD_TO_REL_NDS            = (VG_RQUAD_TO_NDS  | VG_RELATIVE),\r
-  VG_RCUBIC_TO_ABS_NDS           = (VG_RCUBIC_TO_NDS | VG_ABSOLUTE),\r
-  VG_RCUBIC_TO_REL_NDS           = (VG_RCUBIC_TO_NDS | VG_RELATIVE),\r
-\r
-  VG_PATH_COMMAND_NDS_FORCE_SIZE = VG_MAX_ENUM\r
-} VGPathCommandNds;\r
-\r
-#ifdef VG_VGEXT_PROTOTYPES\r
-VG_API_CALL void VG_API_ENTRY vgProjectiveMatrixNDS(VGboolean enable) ;\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguTransformClipLineNDS(const VGfloat Ain,const VGfloat Bin,const VGfloat Cin,const VGfloat* matrix,const VGboolean inverse,VGfloat* Aout,VGfloat* Bout,VGfloat* Cout);\r
-#endif \r
-typedef void (VG_API_ENTRYP PFNVGPROJECTIVEMATRIXNDSPROC) (VGboolean enable) ;\r
-typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUTRANSFORMCLIPLINENDSPROC) (const VGfloat Ain,const VGfloat Bin,const VGfloat Cin,const VGfloat* matrix,const VGboolean inverse,VGfloat* Aout,VGfloat* Bout,VGfloat* Cout);\r
-\r
-#endif\r
-\r
-#ifdef __cplusplus \r
-} /* extern "C" */\r
-#endif\r
-\r
-#endif /* _VGEXT_H */\r
+/* $Revision: 6810 $ on $Date:: 2008-10-29 07:31:37 -0700 #$ */
+
+/*------------------------------------------------------------------------
+ * 
+ * VG extensions Reference Implementation
+ * -------------------------------------
+ *
+ * Copyright (c) 2008 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 "Materials "), to deal in the Materials without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Materials,
+ * and to permit persons to whom the Materials are 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 Materials. 
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 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 MATERIALS OR
+ * THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//**
+ * \file
+ * \brief      VG extensions
+ *//*-------------------------------------------------------------------*/
+
+
+
+#ifndef _VGEXT_H
+#define _VGEXT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <VG/openvg.h>
+#include <VG/vgu.h>
+
+#ifndef VG_API_ENTRYP
+#   define VG_API_ENTRYP VG_API_ENTRY*
+#endif
+
+#ifndef VGU_API_ENTRYP
+#   define VGU_API_ENTRYP VGU_API_ENTRY*
+#endif
+
+/*-------------------------------------------------------------------------------
+ * KHR extensions
+ *------------------------------------------------------------------------------*/
+
+typedef enum  {
+
+#ifndef VG_KHR_iterative_average_blur
+  VG_MAX_AVERAGE_BLUR_DIMENSION_KHR        = 0x116B,
+  VG_AVERAGE_BLUR_DIMENSION_RESOLUTION_KHR = 0x116C,
+  VG_MAX_AVERAGE_BLUR_ITERATIONS_KHR       = 0x116D,
+#endif
+
+  VG_PARAM_TYPE_KHR_FORCE_SIZE             = VG_MAX_ENUM
+} VGParamTypeKHR;
+
+#ifndef VG_KHR_EGL_image
+#define VG_KHR_EGL_image 1
+/* VGEGLImageKHR is an opaque handle to an EGLImage */
+typedef void* VGeglImageKHR; 
+
+#ifdef VG_VGEXT_PROTOTYPES
+VG_API_CALL VGImage VG_API_ENTRY vgCreateEGLImageTargetKHR(VGeglImageKHR image);
+#endif
+typedef VGImage (VG_API_ENTRYP PFNVGCREATEEGLIMAGETARGETKHRPROC) (VGeglImageKHR image);
+
+#endif
+
+
+#ifndef VG_KHR_iterative_average_blur
+#define VG_KHR_iterative_average_blur 1
+
+#ifdef VG_VGEXT_PROTOTYPES
+VG_API_CALL void vgIterativeAverageBlurKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGTilingMode tilingMode);
+#endif 
+typedef void (VG_API_ENTRYP PFNVGITERATIVEAVERAGEBLURKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGTilingMode tilingMode);
+
+#endif
+
+
+#ifndef VG_KHR_advanced_blending
+#define VG_KHR_advanced_blending 1
+
+typedef enum {
+  VG_BLEND_OVERLAY_KHR        = 0x2010,
+  VG_BLEND_HARDLIGHT_KHR      = 0x2011,
+  VG_BLEND_SOFTLIGHT_SVG_KHR  = 0x2012,
+  VG_BLEND_SOFTLIGHT_KHR      = 0x2013,
+  VG_BLEND_COLORDODGE_KHR     = 0x2014,
+  VG_BLEND_COLORBURN_KHR      = 0x2015,
+  VG_BLEND_DIFFERENCE_KHR     = 0x2016,
+  VG_BLEND_SUBTRACT_KHR       = 0x2017,
+  VG_BLEND_INVERT_KHR         = 0x2018,
+  VG_BLEND_EXCLUSION_KHR      = 0x2019,
+  VG_BLEND_LINEARDODGE_KHR    = 0x201a,
+  VG_BLEND_LINEARBURN_KHR     = 0x201b,
+  VG_BLEND_VIVIDLIGHT_KHR     = 0x201c,
+  VG_BLEND_LINEARLIGHT_KHR    = 0x201d,
+  VG_BLEND_PINLIGHT_KHR       = 0x201e,
+  VG_BLEND_HARDMIX_KHR        = 0x201f,
+  VG_BLEND_CLEAR_KHR          = 0x2020,
+  VG_BLEND_DST_KHR            = 0x2021,
+  VG_BLEND_SRC_OUT_KHR        = 0x2022,
+  VG_BLEND_DST_OUT_KHR        = 0x2023,
+  VG_BLEND_SRC_ATOP_KHR       = 0x2024,
+  VG_BLEND_DST_ATOP_KHR       = 0x2025,
+  VG_BLEND_XOR_KHR            = 0x2026,
+
+  VG_BLEND_MODE_KHR_FORCE_SIZE= VG_MAX_ENUM
+} VGBlendModeKHR;
+#endif
+
+#ifndef VG_KHR_parametric_filter
+#define VG_KHR_parametric_filter 1 
+
+typedef enum {
+  VG_PF_OBJECT_VISIBLE_FLAG_KHR = (1 << 0),
+  VG_PF_KNOCKOUT_FLAG_KHR       = (1 << 1),
+  VG_PF_OUTER_FLAG_KHR          = (1 << 2),
+  VG_PF_INNER_FLAG_KHR          = (1 << 3),
+
+  VG_PF_TYPE_KHR_FORCE_SIZE     = VG_MAX_ENUM
+} VGPfTypeKHR;
+
+typedef enum {
+  VGU_IMAGE_IN_USE_ERROR           = 0xF010,
+
+  VGU_ERROR_CODE_KHR_FORCE_SIZE    = VG_MAX_ENUM
+} VGUErrorCodeKHR;
+
+#ifdef VG_VGEXT_PROTOTYPES
+VG_API_CALL void VG_API_ENTRY vgParametricFilterKHR(VGImage dst,VGImage src,VGImage blur,VGfloat strength,VGfloat offsetX,VGfloat offsetY,VGbitfield filterFlags,VGPaint highlightPaint,VGPaint shadowPaint);
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguDropShadowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint shadowColorRGBA);
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGlowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint glowColorRGBA) ;
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguBevelKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint highlightColorRGBA,VGuint shadowColorRGBA);
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGradientGlowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* glowColorRampStops);
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGradientBevelKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* bevelColorRampStops);
+#endif
+typedef void (VG_API_ENTRYP PFNVGPARAMETRICFILTERKHRPROC) (VGImage dst,VGImage src,VGImage blur,VGfloat strength,VGfloat offsetX,VGfloat offsetY,VGbitfield filterFlags,VGPaint highlightPaint,VGPaint shadowPaint);
+typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUDROPSHADOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint shadowColorRGBA);
+typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGLOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint glowColorRGBA);
+typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUBEVELKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint highlightColorRGBA,VGuint shadowColorRGBA);
+typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGRADIENTGLOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* glowColorRampStops);
+typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGRADIENTBEVELKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* bevelColorRampStops);
+
+#endif
+
+
+/*-------------------------------------------------------------------------------
+ * NDS extensions
+ *------------------------------------------------------------------------------*/
+
+#ifndef VG_NDS_paint_generation
+#define VG_NDS_paint_generation 1
+
+typedef enum { 
+  VG_PAINT_COLOR_RAMP_LINEAR_NDS            = 0x1A10,
+  VG_COLOR_MATRIX_NDS                       = 0x1A11,
+  VG_PAINT_COLOR_TRANSFORM_LINEAR_NDS       = 0x1A12,
+
+  VG_PAINT_PARAM_TYPE_NDS_FORCE_SIZE        = VG_MAX_ENUM
+} VGPaintParamTypeNds;
+
+typedef enum {
+  VG_DRAW_IMAGE_COLOR_MATRIX_NDS            = 0x1F10,
+
+  VG_IMAGE_MODE_NDS_FORCE_SIZE              = VG_MAX_ENUM
+} VGImageModeNds;
+#endif 
+
+
+#ifndef VG_NDS_projective_geometry
+#define VG_NDS_projective_geometry 1
+
+typedef enum {
+  VG_CLIP_MODE_NDS                          = 0x1180,
+  VG_CLIP_LINES_NDS                         = 0x1181,
+  VG_MAX_CLIP_LINES_NDS                     = 0x1182,
+
+  VG_PARAM_TYPE_NDS_FORCE_SIZE        = VG_MAX_ENUM
+} VGParamTypeNds;
+
+typedef enum {
+  VG_CLIPMODE_NONE_NDS                      = 0x3000,
+  VG_CLIPMODE_CLIP_CLOSED_NDS               = 0x3001,
+  VG_CLIPMODE_CLIP_OPEN_NDS                 = 0x3002,
+  VG_CLIPMODE_CULL_NDS                      = 0x3003,
+
+  VG_CLIPMODE_NDS_FORCE_SIZE = VG_MAX_ENUM
+} VGClipModeNds;
+
+typedef enum {
+  VG_RQUAD_TO_NDS              = ( 13 << 1 ),
+  VG_RCUBIC_TO_NDS             = ( 14 << 1 ),
+  
+  VG_PATH_SEGMENT_NDS_FORCE_SIZE = VG_MAX_ENUM
+} VGPathSegmentNds;
+
+typedef enum {
+  VG_RQUAD_TO_ABS_NDS            = (VG_RQUAD_TO_NDS  | VG_ABSOLUTE),
+  VG_RQUAD_TO_REL_NDS            = (VG_RQUAD_TO_NDS  | VG_RELATIVE),
+  VG_RCUBIC_TO_ABS_NDS           = (VG_RCUBIC_TO_NDS | VG_ABSOLUTE),
+  VG_RCUBIC_TO_REL_NDS           = (VG_RCUBIC_TO_NDS | VG_RELATIVE),
+
+  VG_PATH_COMMAND_NDS_FORCE_SIZE = VG_MAX_ENUM
+} VGPathCommandNds;
+
+#ifdef VG_VGEXT_PROTOTYPES
+VG_API_CALL void VG_API_ENTRY vgProjectiveMatrixNDS(VGboolean enable) ;
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguTransformClipLineNDS(const VGfloat Ain,const VGfloat Bin,const VGfloat Cin,const VGfloat* matrix,const VGboolean inverse,VGfloat* Aout,VGfloat* Bout,VGfloat* Cout);
+#endif 
+typedef void (VG_API_ENTRYP PFNVGPROJECTIVEMATRIXNDSPROC) (VGboolean enable) ;
+typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUTRANSFORMCLIPLINENDSPROC) (const VGfloat Ain,const VGfloat Bin,const VGfloat Cin,const VGfloat* matrix,const VGboolean inverse,VGfloat* Aout,VGfloat* Bout,VGfloat* Cout);
+
+#endif
+
+#ifdef __cplusplus 
+} /* extern "C" */
+#endif
+
+#endif /* _VGEXT_H */
index 71dee68b9d4c1cf4ab0885e85786daa5068cf12d..aa1829f6c707710c022c166a9a8df4190145e4a3 100644 (file)
@@ -1,92 +1,92 @@
-/* $Revision: 6810 $ on $Date:: 2008-10-29 10:31:37 -0400 #$ */\r
-\r
-/*------------------------------------------------------------------------\r
- *\r
- * VG platform specific header Reference Implementation\r
- * ----------------------------------------------------\r
- *\r
- * Copyright (c) 2008 The Khronos Group Inc.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a\r
- * copy of this software and /or associated documentation files\r
- * (the "Materials "), to deal in the Materials without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Materials,\r
- * and to permit persons to whom the Materials are furnished to do so,\r
- * subject to the following conditions: \r
- *\r
- * The above copyright notice and this permission notice shall be included \r
- * in all copies or substantial portions of the Materials. \r
- *\r
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR\r
- * THE USE OR OTHER DEALINGS IN THE MATERIALS.\r
- *\r
- *//**\r
- * \file\r
- * \brief VG platform specific header\r
- *//*-------------------------------------------------------------------*/\r
-\r
-#ifndef _VGPLATFORM_H\r
-#define _VGPLATFORM_H\r
-\r
-#include <KHR/khrplatform.h>\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#ifndef VG_API_CALL \r
-#if defined(OPENVG_STATIC_LIBRARY)\r
-#      define VG_API_CALL\r
-#else\r
-#      define VG_API_CALL KHRONOS_APICALL\r
-#endif /* defined OPENVG_STATIC_LIBRARY */\r
-#endif /* ifndef VG_API_CALL */\r
-\r
-#ifndef VGU_API_CALL \r
-#if defined(OPENVG_STATIC_LIBRARY)\r
-#      define VGU_API_CALL\r
-#else\r
-#      define VGU_API_CALL KHRONOS_APICALL\r
-#endif /* defined OPENVG_STATIC_LIBRARY */\r
-#endif /* ifndef VGU_API_CALL */\r
-\r
-\r
-#ifndef VG_API_ENTRY\r
-#define VG_API_ENTRY\r
-#endif\r
-\r
-#ifndef VG_API_EXIT\r
-#define VG_API_EXIT\r
-#endif\r
-\r
-#ifndef VGU_API_ENTRY\r
-#define VGU_API_ENTRY\r
-#endif\r
-\r
-#ifndef VGU_API_EXIT\r
-#define VGU_API_EXIT\r
-#endif\r
-\r
-typedef float          VGfloat;\r
-typedef signed char    VGbyte;\r
-typedef unsigned char  VGubyte;\r
-typedef signed short   VGshort;\r
-typedef signed int     VGint;\r
-typedef unsigned int   VGuint;\r
-typedef unsigned int   VGbitfield;\r
-\r
-#ifndef VG_VGEXT_PROTOTYPES\r
-#define VG_VGEXT_PROTOTYPES\r
-#endif \r
-\r
-#ifdef __cplusplus \r
-} /* extern "C" */\r
-#endif\r
-\r
-#endif /* _VGPLATFORM_H */\r
+/* $Revision: 6810 $ on $Date:: 2008-10-29 07:31:37 -0700 #$ */
+
+/*------------------------------------------------------------------------
+ *
+ * VG platform specific header Reference Implementation
+ * ----------------------------------------------------
+ *
+ * Copyright (c) 2008 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 "Materials "), to deal in the Materials without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Materials,
+ * and to permit persons to whom the Materials are 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 Materials. 
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 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 MATERIALS OR
+ * THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//**
+ * \file
+ * \brief VG platform specific header
+ *//*-------------------------------------------------------------------*/
+
+#ifndef _VGPLATFORM_H
+#define _VGPLATFORM_H
+
+#include <KHR/khrplatform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef VG_API_CALL 
+#if defined(OPENVG_STATIC_LIBRARY)
+#      define VG_API_CALL
+#else
+#      define VG_API_CALL KHRONOS_APICALL
+#endif /* defined OPENVG_STATIC_LIBRARY */
+#endif /* ifndef VG_API_CALL */
+
+#ifndef VGU_API_CALL 
+#if defined(OPENVG_STATIC_LIBRARY)
+#      define VGU_API_CALL
+#else
+#      define VGU_API_CALL KHRONOS_APICALL
+#endif /* defined OPENVG_STATIC_LIBRARY */
+#endif /* ifndef VGU_API_CALL */
+
+
+#ifndef VG_API_ENTRY
+#define VG_API_ENTRY
+#endif
+
+#ifndef VG_API_EXIT
+#define VG_API_EXIT
+#endif
+
+#ifndef VGU_API_ENTRY
+#define VGU_API_ENTRY
+#endif
+
+#ifndef VGU_API_EXIT
+#define VGU_API_EXIT
+#endif
+
+typedef float          VGfloat;
+typedef signed char    VGbyte;
+typedef unsigned char  VGubyte;
+typedef signed short   VGshort;
+typedef signed int     VGint;
+typedef unsigned int   VGuint;
+typedef unsigned int   VGbitfield;
+
+#ifndef VG_VGEXT_PROTOTYPES
+#define VG_VGEXT_PROTOTYPES
+#endif 
+
+#ifdef __cplusplus 
+} /* extern "C" */
+#endif
+
+#endif /* _VGPLATFORM_H */
index 2799684e5e7eb2c38e7fd2f0874ecb033595e704..da81da938d5c8c731f2c0006ceefa9e339e3f358 100644 (file)
-/* $Revision: 6810 $ on $Date:: 2008-10-29 10:31:37 -0400 #$ */\r
-\r
-/*------------------------------------------------------------------------\r
- * \r
- * VGU 1.0.1 Reference Implementation\r
- * -------------------------------------\r
- *\r
- * Copyright (c) 2008 The Khronos Group Inc.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a\r
- * copy of this software and /or associated documentation files\r
- * (the "Materials "), to deal in the Materials without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Materials,\r
- * and to permit persons to whom the Materials are furnished to do so,\r
- * subject to the following conditions: \r
- *\r
- * The above copyright notice and this permission notice shall be included \r
- * in all copies or substantial portions of the Materials. \r
- *\r
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR\r
- * THE USE OR OTHER DEALINGS IN THE MATERIALS.\r
- *\r
- *//**\r
- * \file\r
- * \brief      VGU 1.0.1 API.\r
- *//*-------------------------------------------------------------------*/\r
-\r
-#ifndef _VGU_H\r
-#define _VGU_H\r
-\r
-#ifdef __cplusplus \r
-extern "C" { \r
-#endif\r
-\r
-#include <VG/openvg.h>\r
-\r
-#define VGU_VERSION_1_0 1\r
-\r
-#ifndef VGU_API_CALL\r
-#      error VGU_API_CALL must be defined\r
-#endif\r
-\r
-#ifndef VGU_API_ENTRY\r
-#   error VGU_API_ENTRY must be defined \r
-#endif\r
-\r
-#ifndef VGU_API_EXIT\r
-#   error VGU_API_EXIT must be defined \r
-#endif\r
-\r
-\r
-typedef enum {\r
-  VGU_NO_ERROR                                 = 0,\r
-  VGU_BAD_HANDLE_ERROR                         = 0xF000,\r
-  VGU_ILLEGAL_ARGUMENT_ERROR                   = 0xF001,\r
-  VGU_OUT_OF_MEMORY_ERROR                      = 0xF002,\r
-  VGU_PATH_CAPABILITY_ERROR                    = 0xF003,\r
-  VGU_BAD_WARP_ERROR                           = 0xF004,\r
-\r
-  VGU_ERROR_CODE_FORCE_SIZE                    = VG_MAX_ENUM\r
-} VGUErrorCode;\r
-\r
-typedef enum {\r
-  VGU_ARC_OPEN                                 = 0xF100,\r
-  VGU_ARC_CHORD                                = 0xF101,\r
-  VGU_ARC_PIE                                  = 0xF102,\r
-\r
-  VGU_ARC_TYPE_FORCE_SIZE                      = VG_MAX_ENUM\r
-} VGUArcType;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguLine(VGPath path,\r
-                                  VGfloat x0, VGfloat y0,\r
-                                  VGfloat x1, VGfloat y1) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguPolygon(VGPath path,\r
-                                     const VGfloat * points, VGint count,\r
-                                     VGboolean closed) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguRect(VGPath path,\r
-                                  VGfloat x, VGfloat y,\r
-                                  VGfloat width, VGfloat height) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguRoundRect(VGPath path,\r
-                                       VGfloat x, VGfloat y,\r
-                                       VGfloat width, VGfloat height,\r
-                                       VGfloat arcWidth, VGfloat arcHeight) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguEllipse(VGPath path,\r
-                                     VGfloat cx, VGfloat cy,\r
-                                     VGfloat width, VGfloat height) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguArc(VGPath path,\r
-                                 VGfloat x, VGfloat y,\r
-                                 VGfloat width, VGfloat height,\r
-                                 VGfloat startAngle, VGfloat angleExtent,\r
-                                 VGUArcType arcType) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,\r
-                                                     VGfloat sx1, VGfloat sy1,\r
-                                                     VGfloat sx2, VGfloat sy2,\r
-                                                     VGfloat sx3, VGfloat sy3,\r
-                                                     VGfloat * matrix) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,\r
-                                                     VGfloat dx1, VGfloat dy1,\r
-                                                     VGfloat dx2, VGfloat dy2,\r
-                                                     VGfloat dx3, VGfloat dy3,\r
-                                                     VGfloat * matrix) VGU_API_EXIT;\r
-\r
-VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,\r
-                                                   VGfloat dx1, VGfloat dy1,\r
-                                                   VGfloat dx2, VGfloat dy2,\r
-                                                   VGfloat dx3, VGfloat dy3,\r
-                                                   VGfloat sx0, VGfloat sy0,\r
-                                                   VGfloat sx1, VGfloat sy1,\r
-                                                   VGfloat sx2, VGfloat sy2,\r
-                                                   VGfloat sx3, VGfloat sy3,\r
-                                                   VGfloat * matrix) VGU_API_EXIT;\r
-\r
-#ifdef __cplusplus \r
-} /* extern "C" */\r
-#endif\r
-\r
-#endif /* #ifndef _VGU_H */\r
+/* $Revision: 6810 $ on $Date:: 2008-10-29 07:31:37 -0700 #$ */
+
+/*------------------------------------------------------------------------
+ * 
+ * VGU 1.1 Reference Implementation
+ * -------------------------------------
+ *
+ * Copyright (c) 2008 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 "Materials "), to deal in the Materials without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Materials,
+ * and to permit persons to whom the Materials are 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 Materials. 
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 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 MATERIALS OR
+ * THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//**
+ * \file
+ * \brief      VGU 1.1 API.
+ *//*-------------------------------------------------------------------*/
+
+#ifndef _VGU_H
+#define _VGU_H
+
+#ifdef __cplusplus 
+extern "C" { 
+#endif
+
+#include <VG/openvg.h>
+
+#define VGU_VERSION_1_0 1
+#define VGU_VERSION_1_1 2
+
+#ifndef VGU_API_CALL
+#      error VGU_API_CALL must be defined
+#endif
+
+#ifndef VGU_API_ENTRY
+#   error VGU_API_ENTRY must be defined 
+#endif
+
+#ifndef VGU_API_EXIT
+#   error VGU_API_EXIT must be defined 
+#endif
+
+
+typedef enum {
+  VGU_NO_ERROR                                 = 0,
+  VGU_BAD_HANDLE_ERROR                         = 0xF000,
+  VGU_ILLEGAL_ARGUMENT_ERROR                   = 0xF001,
+  VGU_OUT_OF_MEMORY_ERROR                      = 0xF002,
+  VGU_PATH_CAPABILITY_ERROR                    = 0xF003,
+  VGU_BAD_WARP_ERROR                           = 0xF004,
+
+  VGU_ERROR_CODE_FORCE_SIZE                    = VG_MAX_ENUM
+} VGUErrorCode;
+
+typedef enum {
+  VGU_ARC_OPEN                                 = 0xF100,
+  VGU_ARC_CHORD                                = 0xF101,
+  VGU_ARC_PIE                                  = 0xF102,
+
+  VGU_ARC_TYPE_FORCE_SIZE                      = VG_MAX_ENUM
+} VGUArcType;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguLine(VGPath path,
+                                  VGfloat x0, VGfloat y0,
+                                  VGfloat x1, VGfloat y1) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguPolygon(VGPath path,
+                                     const VGfloat * points, VGint count,
+                                     VGboolean closed) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguRect(VGPath path,
+                                  VGfloat x, VGfloat y,
+                                  VGfloat width, VGfloat height) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguRoundRect(VGPath path,
+                                       VGfloat x, VGfloat y,
+                                       VGfloat width, VGfloat height,
+                                       VGfloat arcWidth, VGfloat arcHeight) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguEllipse(VGPath path,
+                                     VGfloat cx, VGfloat cy,
+                                     VGfloat width, VGfloat height) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguArc(VGPath path,
+                                 VGfloat x, VGfloat y,
+                                 VGfloat width, VGfloat height,
+                                 VGfloat startAngle, VGfloat angleExtent,
+                                 VGUArcType arcType) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
+                                                     VGfloat sx1, VGfloat sy1,
+                                                     VGfloat sx2, VGfloat sy2,
+                                                     VGfloat sx3, VGfloat sy3,
+                                                     VGfloat * matrix) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,
+                                                     VGfloat dx1, VGfloat dy1,
+                                                     VGfloat dx2, VGfloat dy2,
+                                                     VGfloat dx3, VGfloat dy3,
+                                                     VGfloat * matrix) VGU_API_EXIT;
+
+VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,
+                                                   VGfloat dx1, VGfloat dy1,
+                                                   VGfloat dx2, VGfloat dy2,
+                                                   VGfloat dx3, VGfloat dy3,
+                                                   VGfloat sx0, VGfloat sy0,
+                                                   VGfloat sx1, VGfloat sy1,
+                                                   VGfloat sx2, VGfloat sy2,
+                                                   VGfloat sx3, VGfloat sy3,
+                                                   VGfloat * matrix) VGU_API_EXIT;
+
+#ifdef __cplusplus 
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef _VGU_H */
index a83f32b0d1b7d9533b39c8959f7c1d1b07871f40..6f40ab951f97ca7c4290367c4e6a31cd95e6e7d2 100644 (file)
@@ -1648,7 +1648,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
       dri2_destroy_surface(drv, disp, old_dsurf);
       dri2_destroy_surface(drv, disp, old_rsurf);
       if (old_ctx) {
-        dri2_dpy->core->unbindContext(dri2_egl_context(old_ctx)->dri_context);
+         /* unbind the old context only when there is no new context bound */
+         if (!ctx) {
+            __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context;
+            dri2_dpy->core->unbindContext(old_cctx);
+         }
          /* no destroy? */
          _eglPutContext(old_ctx);
       }
index d686fa162d5ecdbc3766bd176aea17f47efe4ca4..fe2f1a7f32fcd4988896d1dbf62b5f451f3d013d 100644 (file)
@@ -118,38 +118,39 @@ _eglFindArray(_EGLArray *array, void *elem)
 
 
 /**
- * Filter an array and return the filtered data.  The returned data pointer
- * should be freed.
+ * Filter an array and return the number of filtered elements.
  */
-void **
-_eglFilterArray(_EGLArray *array, EGLint *size,
+EGLint
+_eglFilterArray(_EGLArray *array, void **data, EGLint size,
                 _EGLArrayForEach filter, void *filter_data)
 {
-   void **data;
    EGLint count = 0, i;
 
-   if (!array) {
-      *size = 0;
-      return malloc(0);
-   }
-
-   data = malloc(array->Size * sizeof(array->Elements[0]));
-   if (!data)
-      return NULL;
+   if (!array)
+      return 0;
 
    if (filter) {
       for (i = 0; i < array->Size; i++) {
-         if (filter(array->Elements[i], filter_data))
-            data[count++] = array->Elements[i];
+         if (filter(array->Elements[i], filter_data)) {
+            if (data && count < size)
+               data[count] = array->Elements[i];
+            count++;
+         }
+         if (data && count >= size)
+            break;
       }
    }
    else {
-      memcpy(data, array->Elements, array->Size * sizeof(array->Elements[0]));
+      if (data) {
+         count = (size < array->Size) ? size : array->Size;
+         memcpy(data, array->Elements, count * sizeof(array->Elements[0]));
+      }
+      else {
+         count = array->Size;
+      }
    }
 
-   *size = count;
-
-   return data;
+   return count;
 }
 
 
index c8309fb066a760be3e0554ff01002382d4a31ae4..a88189a62524e921e0020ed4a36c8d66baf33aaa 100644 (file)
@@ -37,8 +37,8 @@ void *
 _eglFindArray(_EGLArray *array, void *elem);
 
 
-PUBLIC void **
-_eglFilterArray(_EGLArray *array, EGLint *size,
+PUBLIC EGLint
+_eglFilterArray(_EGLArray *array, void **data, EGLint size,
                 _EGLArrayForEach filter, void *filter_data);
 
 
index fec94fb20cd52f70086e39f27fa65d99961aa260..5b377b7f610d68be9a70654414a178079a47cb44 100644 (file)
@@ -697,11 +697,22 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
    if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
       return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
 
-   configList = (_EGLConfig **) _eglFilterArray(disp->Configs, &count,
+   /* get the number of matched configs */
+   count = _eglFilterArray(disp->Configs, NULL, 0,
          (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
+   if (!count) {
+      *num_configs = count;
+      return EGL_TRUE;
+   }
+
+   configList = malloc(sizeof(*configList) * count);
    if (!configList)
       return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
 
+   /* get the matched configs */
+   _eglFilterArray(disp->Configs, (void **) configList, count,
+         (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
+
    /* perform sorting of configs */
    if (configs && count) {
       _eglSortConfigs((const _EGLConfig **) configList, count,
index 997478f06644b49daabc5548cc32a9cba2624992..6cf1ddd43fe7aaa9d7039892ad101fc8a0e85087 100644 (file)
@@ -128,12 +128,12 @@ C_SOURCES = \
        util/u_linkage.c \
        util/u_network.c \
        util/u_math.c \
-       util/u_mempool.c \
        util/u_mm.c \
        util/u_rect.c \
        util/u_ringbuffer.c \
        util/u_sampler.c \
        util/u_simple_shaders.c \
+       util/u_slab.c \
        util/u_snprintf.c \
        util/u_staging.c \
        util/u_surface.c \
@@ -184,7 +184,7 @@ GALLIVM_SOURCES = \
         draw/draw_pt_fetch_shade_pipeline_llvm.c
 
 GALLIVM_CPP_SOURCES = \
-    gallivm/lp_bld_misc.cpp
+       gallivm/lp_bld_misc.cpp
 
 GENERATED_SOURCES = \
        indices/u_indices_gen.c \
@@ -202,9 +202,6 @@ CPP_SOURCES += \
 endif
 
 
-LIBRARY_DEFINES += -D__STDC_CONSTANT_MACROS
-
-
 include ../Makefile.template
 
 
index 4b9059d9aa3a56ff34f7232be4aa79871df0f297..e6806d9a723160138b81c9b0f58baacd1e0aeb5a 100644 (file)
@@ -175,13 +175,13 @@ source = [
     'util/u_linkage.c',
     'util/u_network.c',
     'util/u_math.c',
-    'util/u_mempool.c',
     'util/u_mm.c',
     'util/u_rect.c',
     'util/u_resource.c',
     'util/u_ringbuffer.c',
     'util/u_sampler.c',
     'util/u_simple_shaders.c',
+    'util/u_slab.c',
     'util/u_snprintf.c',
     'util/u_staging.c',
     'util/u_surface.c',
index 39d82f3289251ea2442d1b8789cc17059719f837..73d5b6e403fb96022557fd0b327daf8f1086c8bb 100644 (file)
@@ -63,19 +63,32 @@ draw_get_option_use_llvm(void)
 }
 #endif
 
-struct draw_context *draw_create( struct pipe_context *pipe )
+
+
+/**
+ * Create new draw module context.
+ */
+struct draw_context *
+draw_create(struct pipe_context *pipe)
+{
+   return draw_create_gallivm(pipe, NULL);
+}
+
+
+
+/**
+ * Create new draw module context with gallivm state for LLVM JIT.
+ */
+struct draw_context *
+draw_create_gallivm(struct pipe_context *pipe, struct gallivm_state *gallivm)
 {
    struct draw_context *draw = CALLOC_STRUCT( draw_context );
    if (draw == NULL)
       goto fail;
 
 #if HAVE_LLVM
-   if(draw_get_option_use_llvm())
-   {
-      lp_build_init();
-      assert(lp_build_engine);
-      draw->engine = lp_build_engine;
-      draw->llvm = draw_llvm_create(draw);
+   if (draw_get_option_use_llvm() && gallivm) {
+      draw->llvm = draw_llvm_create(draw, gallivm);
    }
 #endif
 
@@ -91,6 +104,8 @@ fail:
    return NULL;
 }
 
+
+
 boolean draw_init(struct draw_context *draw)
 {
    /*
index ff4f753604fb0072277bf7fc1465cad658f33c5e..a0b217e4d33b4c05a5d6a81e4c5cbfb741673d54 100644 (file)
@@ -48,10 +48,15 @@ struct draw_vertex_shader;
 struct draw_geometry_shader;
 struct draw_fragment_shader;
 struct tgsi_sampler;
+struct gallivm_state;
+
 
 
 struct draw_context *draw_create( struct pipe_context *pipe );
 
+struct draw_context *
+draw_create_gallivm(struct pipe_context *pipe, struct gallivm_state *gallivm);
+
 void draw_destroy( struct draw_context *draw );
 
 void draw_flush(struct draw_context *draw);
index 2b5f01cda74c4091d77e0faf39eea1883e40578f..943ec44bcde47296b725b546d4673bcbca6849a9 100644 (file)
@@ -42,6 +42,7 @@
 #include "gallivm/lp_bld_printf.h"
 #include "gallivm/lp_bld_intr.h"
 #include "gallivm/lp_bld_init.h"
+#include "gallivm/lp_bld_type.h"
 
 #include "tgsi/tgsi_exec.h"
 #include "tgsi/tgsi_dump.h"
 #include "util/u_math.h"
 #include "util/u_pointer.h"
 #include "util/u_string.h"
+#include "util/u_simple_list.h"
 
-#include <llvm-c/Transforms/Scalar.h>
 
 #define DEBUG_STORE 0
 
-/* generates the draw jit function */
+
+/**
+ * This function is called by the gallivm "garbage collector" when
+ * the LLVM global data structures are freed.  We must free all LLVM-related
+ * data.  Specifically, all JIT'd shader variants.
+ */
+static void
+draw_llvm_garbage_collect_callback(void *cb_data)
+{
+   struct draw_llvm *llvm = (struct draw_llvm *) cb_data;
+   struct draw_llvm_variant_list_item *li;
+
+   /* free all shader variants */
+   li = first_elem(&llvm->vs_variants_list);
+   while (!at_end(&llvm->vs_variants_list, li)) {
+      struct draw_llvm_variant_list_item *next = next_elem(li);
+      draw_llvm_destroy_variant(li->base);
+      li = next;
+   }
+
+   /* Null-out these pointers so they get remade next time they're needed.
+    * See the accessor functions below.
+    */
+   llvm->context_ptr_type = NULL;
+   llvm->buffer_ptr_type = NULL;
+   llvm->vb_ptr_type = NULL;
+   llvm->vertex_header_ptr_type = NULL;
+}
+
+
 static void
 draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var);
+
 static void
 draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *var);
 
-static void
-init_globals(struct draw_llvm *llvm)
+
+/**
+ * Create LLVM type for struct draw_jit_texture
+ */
+static LLVMTypeRef
+create_jit_texture_type(struct gallivm_state *gallivm)
 {
+   LLVMTargetDataRef target = gallivm->target;
    LLVMTypeRef texture_type;
+   LLVMTypeRef elem_types[DRAW_JIT_TEXTURE_NUM_FIELDS];
+   LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context);
+
+   elem_types[DRAW_JIT_TEXTURE_WIDTH]  =
+   elem_types[DRAW_JIT_TEXTURE_HEIGHT] =
+   elem_types[DRAW_JIT_TEXTURE_DEPTH] =
+   elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = int32_type;
+   elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] =
+   elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
+      LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS);
+   elem_types[DRAW_JIT_TEXTURE_DATA] =
+      LLVMArrayType(LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0),
+                    PIPE_MAX_TEXTURE_LEVELS);
+   elem_types[DRAW_JIT_TEXTURE_MIN_LOD] =
+   elem_types[DRAW_JIT_TEXTURE_MAX_LOD] =
+   elem_types[DRAW_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(gallivm->context);
+   elem_types[DRAW_JIT_TEXTURE_BORDER_COLOR] = 
+      LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
+
+   texture_type = LLVMStructTypeInContext(gallivm->context, elem_types,
+                                          Elements(elem_types), 0);
+
+   /* Make sure the target's struct layout cache doesn't return
+    * stale/invalid data.
+    */
+   LLVMInvalidateStructLayout(gallivm->target, texture_type);
+
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, width,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_WIDTH);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_HEIGHT);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_DEPTH);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_LAST_LEVEL);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_ROW_STRIDE);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_IMG_STRIDE);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_DATA);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, min_lod,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_MIN_LOD);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, max_lod,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_MAX_LOD);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, lod_bias,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_LOD_BIAS);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, border_color,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_BORDER_COLOR);
+
+   LP_CHECK_STRUCT_SIZE(struct draw_jit_texture, target, texture_type);
+
+   return texture_type;
+}
 
-   /* struct draw_jit_texture */
-   {
-      LLVMTypeRef elem_types[DRAW_JIT_TEXTURE_NUM_FIELDS];
-
-      elem_types[DRAW_JIT_TEXTURE_WIDTH]  = LLVMInt32Type();
-      elem_types[DRAW_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
-      elem_types[DRAW_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
-      elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
-      elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] =
-         LLVMArrayType(LLVMInt32Type(), PIPE_MAX_TEXTURE_LEVELS);
-      elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
-         LLVMArrayType(LLVMInt32Type(), PIPE_MAX_TEXTURE_LEVELS);
-      elem_types[DRAW_JIT_TEXTURE_DATA] =
-         LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
-                       PIPE_MAX_TEXTURE_LEVELS);
-      elem_types[DRAW_JIT_TEXTURE_MIN_LOD] = LLVMFloatType();
-      elem_types[DRAW_JIT_TEXTURE_MAX_LOD] = LLVMFloatType();
-      elem_types[DRAW_JIT_TEXTURE_LOD_BIAS] = LLVMFloatType();
-      elem_types[DRAW_JIT_TEXTURE_BORDER_COLOR] = 
-         LLVMArrayType(LLVMFloatType(), 4);
-
-      texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
-
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, width,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_WIDTH);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_HEIGHT);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_DEPTH);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_LAST_LEVEL);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_ROW_STRIDE);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_IMG_STRIDE);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_DATA);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, min_lod,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_MIN_LOD);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, max_lod,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_MAX_LOD);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, lod_bias,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_LOD_BIAS);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, border_color,
-                             llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_BORDER_COLOR);
-      LP_CHECK_STRUCT_SIZE(struct draw_jit_texture,
-                           llvm->target, texture_type);
-
-      LLVMAddTypeName(llvm->module, "texture", texture_type);
-   }
 
+/**
+ * Create LLVM type for struct draw_jit_texture
+ */
+static LLVMTypeRef
+create_jit_context_type(struct gallivm_state *gallivm,
+                        LLVMTypeRef texture_type)
+{
+   LLVMTargetDataRef target = gallivm->target;
+   LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context);
+   LLVMTypeRef elem_types[5];
+   LLVMTypeRef context_type;
+
+   elem_types[0] = LLVMPointerType(float_type, 0); /* vs_constants */
+   elem_types[1] = LLVMPointerType(float_type, 0); /* gs_constants */
+   elem_types[2] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, 4), 12), 0); /* planes */
+   elem_types[3] = LLVMPointerType(float_type, 0); /* viewport */
+   elem_types[4] = LLVMArrayType(texture_type,
+                                 PIPE_MAX_VERTEX_SAMPLERS); /* textures */
+
+   context_type = LLVMStructTypeInContext(gallivm->context, elem_types,
+                                          Elements(elem_types), 0);
+
+   LLVMInvalidateStructLayout(gallivm->target, context_type);
+
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, vs_constants,
+                          target, context_type, 0);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, gs_constants,
+                          target, context_type, 1);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes,
+                          target, context_type, 2);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,
+                          target, context_type,
+                          DRAW_JIT_CTX_TEXTURES);
+   LP_CHECK_STRUCT_SIZE(struct draw_jit_context,
+                        target, context_type);
+
+   return context_type;
+}
 
-   /* struct draw_jit_context */
-   {
-      LLVMTypeRef elem_types[5];
-      LLVMTypeRef context_type;
-
-      elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
-      elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* gs_constants */
-      elem_types[2] = LLVMPointerType(LLVMArrayType(LLVMArrayType(LLVMFloatType(), 4), 12), 0); /* planes */
-      elem_types[3] = LLVMPointerType(LLVMFloatType(), 0); /* viewport */
-      elem_types[4] = LLVMArrayType(texture_type,
-                                    PIPE_MAX_VERTEX_SAMPLERS); /* textures */
-
-      context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
-
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, vs_constants,
-                             llvm->target, context_type, 0);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, gs_constants,
-                             llvm->target, context_type, 1);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes,
-                             llvm->target, context_type, 2);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,
-                             llvm->target, context_type,
-                             DRAW_JIT_CTX_TEXTURES);
-      LP_CHECK_STRUCT_SIZE(struct draw_jit_context,
-                           llvm->target, context_type);
-
-      LLVMAddTypeName(llvm->module, "draw_jit_context", context_type);
-
-      llvm->context_ptr_type = LLVMPointerType(context_type, 0);
-   }
-   {
-      LLVMTypeRef buffer_ptr = LLVMPointerType(LLVMIntType(8), 0);
-      llvm->buffer_ptr_type = LLVMPointerType(buffer_ptr, 0);
-   }
-   /* struct pipe_vertex_buffer */
-   {
-      LLVMTypeRef elem_types[4];
-      LLVMTypeRef vb_type;
 
-      elem_types[0] = LLVMInt32Type();
-      elem_types[1] = LLVMInt32Type();
-      elem_types[2] = LLVMInt32Type();
-      elem_types[3] = LLVMPointerType(LLVMOpaqueType(), 0); /* vs_constants */
+/**
+ * Create LLVM type for struct pipe_vertex_buffer
+ */
+static LLVMTypeRef
+create_jit_vertex_buffer_type(struct gallivm_state *gallivm)
+{
+   LLVMTargetDataRef target = gallivm->target;
+   LLVMTypeRef elem_types[4];
+   LLVMTypeRef vb_type;
 
-      vb_type = LLVMStructType(elem_types, Elements(elem_types), 0);
+   elem_types[0] =
+   elem_types[1] =
+   elem_types[2] = LLVMInt32TypeInContext(gallivm->context);
+   elem_types[3] = LLVMPointerType(LLVMOpaqueTypeInContext(gallivm->context), 0); /* vs_constants */
 
-      LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride,
-                             llvm->target, vb_type, 0);
-      LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer_offset,
-                             llvm->target, vb_type, 2);
-      LP_CHECK_STRUCT_SIZE(struct pipe_vertex_buffer,
-                           llvm->target, vb_type);
+   vb_type = LLVMStructTypeInContext(gallivm->context, elem_types,
+                                     Elements(elem_types), 0);
 
-      LLVMAddTypeName(llvm->module, "pipe_vertex_buffer", vb_type);
+   LLVMInvalidateStructLayout(gallivm->target, vb_type);
 
-      llvm->vb_ptr_type = LLVMPointerType(vb_type, 0);
-   }
+   LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride,
+                          target, vb_type, 0);
+   LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer_offset,
+                          target, vb_type, 2);
+
+   LP_CHECK_STRUCT_SIZE(struct pipe_vertex_buffer, target, vb_type);
+
+   return vb_type;
 }
 
+
+/**
+ * Create LLVM type for struct vertex_header;
+ */
 static LLVMTypeRef
-create_vertex_header(struct draw_llvm *llvm, int data_elems)
+create_jit_vertex_header(struct gallivm_state *gallivm, int data_elems)
 {
-   /* struct vertex_header */
+   LLVMTargetDataRef target = gallivm->target;
    LLVMTypeRef elem_types[3];
    LLVMTypeRef vertex_header;
    char struct_name[24];
 
    util_snprintf(struct_name, 23, "vertex_header%d", data_elems);
 
-   elem_types[0]  = LLVMIntType(32);
-   elem_types[1]  = LLVMArrayType(LLVMFloatType(), 4);
+   elem_types[0]  = LLVMIntTypeInContext(gallivm->context, 32);
+   elem_types[1]  = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
    elem_types[2]  = LLVMArrayType(elem_types[1], data_elems);
 
-   vertex_header = LLVMStructType(elem_types, Elements(elem_types), 0);
+   vertex_header = LLVMStructTypeInContext(gallivm->context, elem_types,
+                                           Elements(elem_types), 0);
+
+   LLVMInvalidateStructLayout(gallivm->target, vertex_header);
 
    /* these are bit-fields and we can't take address of them
       LP_CHECK_MEMBER_OFFSET(struct vertex_header, clipmask,
-      llvm->target, vertex_header,
+      target, vertex_header,
       DRAW_JIT_VERTEX_CLIPMASK);
       LP_CHECK_MEMBER_OFFSET(struct vertex_header, edgeflag,
-      llvm->target, vertex_header,
+      target, vertex_header,
       DRAW_JIT_VERTEX_EDGEFLAG);
       LP_CHECK_MEMBER_OFFSET(struct vertex_header, pad,
-      llvm->target, vertex_header,
+      target, vertex_header,
       DRAW_JIT_VERTEX_PAD);
       LP_CHECK_MEMBER_OFFSET(struct vertex_header, vertex_id,
-      llvm->target, vertex_header,
+      target, vertex_header,
       DRAW_JIT_VERTEX_VERTEX_ID);
    */
    LP_CHECK_MEMBER_OFFSET(struct vertex_header, clip,
-                          llvm->target, vertex_header,
+                          target, vertex_header,
                           DRAW_JIT_VERTEX_CLIP);
    LP_CHECK_MEMBER_OFFSET(struct vertex_header, data,
-                          llvm->target, vertex_header,
+                          target, vertex_header,
                           DRAW_JIT_VERTEX_DATA);
 
-   LLVMAddTypeName(llvm->module, struct_name, vertex_header);
+   LLVMAddTypeName(gallivm->module, struct_name, vertex_header);
 
-   return LLVMPointerType(vertex_header, 0);
+   return vertex_header;
 }
 
-struct draw_llvm *
-draw_llvm_create(struct draw_context *draw)
+
+/**
+ * Create LLVM types for various structures.
+ */
+static void
+create_jit_types(struct draw_llvm *llvm)
 {
-   struct draw_llvm *llvm;
+   struct gallivm_state *gallivm = llvm->gallivm;
+   LLVMTypeRef texture_type, context_type, buffer_type, vb_type;
 
-   llvm = CALLOC_STRUCT( draw_llvm );
-   if (!llvm)
-      return NULL;
+   texture_type = create_jit_texture_type(gallivm);
+   LLVMAddTypeName(gallivm->module, "texture", texture_type);
 
-   llvm->draw = draw;
-   llvm->engine = draw->engine;
+   context_type = create_jit_context_type(gallivm, texture_type);
+   LLVMAddTypeName(gallivm->module, "draw_jit_context", context_type);
+   llvm->context_ptr_type = LLVMPointerType(context_type, 0);
 
-   debug_assert(llvm->engine);
+   buffer_type = LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0);
+   LLVMAddTypeName(gallivm->module, "buffer", buffer_type);
+   llvm->buffer_ptr_type = LLVMPointerType(buffer_type, 0);
 
-   llvm->module = LLVMModuleCreateWithName("draw_llvm");
-   llvm->provider = LLVMCreateModuleProviderForExistingModule(llvm->module);
+   vb_type = create_jit_vertex_buffer_type(gallivm);
+   LLVMAddTypeName(gallivm->module, "pipe_vertex_buffer", vb_type);
+   llvm->vb_ptr_type = LLVMPointerType(vb_type, 0);
+}
 
-   LLVMAddModuleProvider(llvm->engine, llvm->provider);
 
-   llvm->target = LLVMGetExecutionEngineTargetData(llvm->engine);
+static LLVMTypeRef
+get_context_ptr_type(struct draw_llvm *llvm)
+{
+   if (!llvm->context_ptr_type)
+      create_jit_types(llvm);
+   return llvm->context_ptr_type;
+}
 
-   llvm->pass = LLVMCreateFunctionPassManager(llvm->provider);
-   LLVMAddTargetData(llvm->target, llvm->pass);
 
-   if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
-      /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-       * but there are more on SVN. */
-      /* TODO: Add more passes */
+static LLVMTypeRef
+get_buffer_ptr_type(struct draw_llvm *llvm)
+{
+   if (!llvm->buffer_ptr_type)
+      create_jit_types(llvm);
+   return llvm->buffer_ptr_type;
+}
 
-      LLVMAddCFGSimplificationPass(llvm->pass);
 
-      if (HAVE_LLVM >= 0x207 && sizeof(void*) == 4) {
-         /* For LLVM >= 2.7 and 32-bit build, use this order of passes to
-          * avoid generating bad code.
-          * Test with piglit glsl-vs-sqrt-zero test.
-          */
-         LLVMAddConstantPropagationPass(llvm->pass);
-         LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
-      }
-      else {
-         LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
-         LLVMAddConstantPropagationPass(llvm->pass);
-      }
+static LLVMTypeRef
+get_vb_ptr_type(struct draw_llvm *llvm)
+{
+   if (!llvm->vb_ptr_type)
+      create_jit_types(llvm);
+   return llvm->vb_ptr_type;
+}
 
-      LLVMAddInstructionCombiningPass(llvm->pass);
-      LLVMAddGVNPass(llvm->pass);
-   } else {
-      /* We need at least this pass to prevent the backends to fail in
-       * unexpected ways.
-       */
-      LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
-   }
+static LLVMTypeRef
+get_vertex_header_ptr_type(struct draw_llvm *llvm)
+{
+   if (!llvm->vertex_header_ptr_type)
+      create_jit_types(llvm);
+   return llvm->vertex_header_ptr_type;
+}
 
-   init_globals(llvm);
+
+/**
+ * Create per-context LLVM info.
+ */
+struct draw_llvm *
+draw_llvm_create(struct draw_context *draw, struct gallivm_state *gallivm)
+{
+   struct draw_llvm *llvm;
+
+   llvm = CALLOC_STRUCT( draw_llvm );
+   if (!llvm)
+      return NULL;
+
+   lp_build_init();
+
+   llvm->draw = draw;
+   llvm->gallivm = gallivm;
 
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
-      LLVMDumpModule(llvm->module);
+      LLVMDumpModule(llvm->gallivm->module);
    }
 
    llvm->nr_variants = 0;
    make_empty_list(&llvm->vs_variants_list);
 
+   gallivm_register_garbage_collector_callback(
+                              draw_llvm_garbage_collect_callback, llvm);
+
    return llvm;
 }
 
+
+/**
+ * Free per-context LLVM info.
+ */
 void
 draw_llvm_destroy(struct draw_llvm *llvm)
 {
-   LLVMDisposePassManager(llvm->pass);
+   gallivm_remove_garbage_collector_callback(
+                              draw_llvm_garbage_collect_callback, llvm);
 
+   /* XXX free other draw_llvm data? */
    FREE(llvm);
 }
 
+
+/**
+ * Create LLVM-generated code for a vertex shader.
+ */
 struct draw_llvm_variant *
 draw_llvm_create_variant(struct draw_llvm *llvm,
                         unsigned num_inputs,
@@ -310,6 +404,7 @@ draw_llvm_create_variant(struct draw_llvm *llvm,
    struct draw_llvm_variant *variant;
    struct llvm_vertex_shader *shader =
       llvm_vertex_shader(llvm->draw->vs.vertex_shader);
+   LLVMTypeRef vertex_header;
 
    variant = MALLOC(sizeof *variant +
                    shader->variant_key_size -
@@ -321,7 +416,9 @@ draw_llvm_create_variant(struct draw_llvm *llvm,
 
    memcpy(&variant->key, key, shader->variant_key_size);
 
-   llvm->vertex_header_ptr_type = create_vertex_header(llvm, num_inputs);
+   vertex_header = create_jit_vertex_header(llvm->gallivm, num_inputs);
+
+   llvm->vertex_header_ptr_type = LLVMPointerType(vertex_header, 0);
 
    draw_llvm_generate(llvm, variant);
    draw_llvm_generate_elts(llvm, variant);
@@ -345,7 +442,7 @@ generate_vs(struct draw_llvm *llvm,
 {
    const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens;
    struct lp_type vs_type;
-   LLVMValueRef consts_ptr = draw_jit_context_vs_constants(builder, context_ptr);
+   LLVMValueRef consts_ptr = draw_jit_context_vs_constants(llvm->gallivm, context_ptr);
    struct lp_build_sampler_soa *sampler = 0;
 
    memset(&vs_type, 0, sizeof vs_type);
@@ -366,7 +463,7 @@ generate_vs(struct draw_llvm *llvm,
        llvm->draw->num_samplers)
       sampler = draw_sampler;
 
-   lp_build_tgsi_soa(builder,
+   lp_build_tgsi_soa(llvm->gallivm,
                      tokens,
                      vs_type,
                      NULL /*struct lp_build_mask_context *mask*/,
@@ -384,20 +481,20 @@ static void print_vectorf(LLVMBuilderRef builder,
 {
    LLVMValueRef val[4];
    val[0] = LLVMBuildExtractElement(builder, vec,
-                                    LLVMConstInt(LLVMInt32Type(), 0, 0), "");
+                                    lp_build_const_int32(gallivm, 0), "");
    val[1] = LLVMBuildExtractElement(builder, vec,
-                                    LLVMConstInt(LLVMInt32Type(), 1, 0), "");
+                                    lp_build_const_int32(gallivm, 1), "");
    val[2] = LLVMBuildExtractElement(builder, vec,
-                                    LLVMConstInt(LLVMInt32Type(), 2, 0), "");
+                                    lp_build_const_int32(gallivm, 2), "");
    val[3] = LLVMBuildExtractElement(builder, vec,
-                                    LLVMConstInt(LLVMInt32Type(), 3, 0), "");
+                                    lp_build_const_int32(gallivm, 3), "");
    lp_build_printf(builder, "vector = [%f, %f, %f, %f]\n",
                    val[0], val[1], val[2], val[3]);
 }
 #endif
 
 static void
-generate_fetch(LLVMBuilderRef builder,
+generate_fetch(struct gallivm_state *gallivm,
                LLVMValueRef vbuffers_ptr,
                LLVMValueRef *res,
                struct pipe_vertex_element *velem,
@@ -405,19 +502,22 @@ generate_fetch(LLVMBuilderRef builder,
                LLVMValueRef index,
                LLVMValueRef instance_id)
 {
-   LLVMValueRef indices = LLVMConstInt(LLVMInt64Type(), velem->vertex_buffer_index, 0);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef indices =
+      LLVMConstInt(LLVMInt64TypeInContext(gallivm->context),
+                   velem->vertex_buffer_index, 0);
    LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr,
                                            &indices, 1, "");
-   LLVMValueRef vb_stride = draw_jit_vbuffer_stride(builder, vbuf);
-   LLVMValueRef vb_max_index = draw_jit_vbuffer_max_index(builder, vbuf);
-   LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(builder, vbuf);
+   LLVMValueRef vb_stride = draw_jit_vbuffer_stride(gallivm, vbuf);
+   LLVMValueRef vb_max_index = draw_jit_vbuffer_max_index(gallivm, vbuf);
+   LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, vbuf);
    LLVMValueRef cond;
    LLVMValueRef stride;
 
    if (velem->instance_divisor) {
       /* array index = instance_id / instance_divisor */
       index = LLVMBuildUDiv(builder, instance_id,
-                            LLVMConstInt(LLVMInt32Type(), velem->instance_divisor, 0),
+                            lp_build_const_int32(gallivm, velem->instance_divisor),
                             "instance_divisor");
    }
 
@@ -433,23 +533,24 @@ generate_fetch(LLVMBuilderRef builder,
                          vb_buffer_offset,
                          "");
    stride = LLVMBuildAdd(builder, stride,
-                         LLVMConstInt(LLVMInt32Type(), velem->src_offset, 0),
+                         lp_build_const_int32(gallivm, velem->src_offset),
                          "");
 
    /*lp_build_printf(builder, "vbuf index = %d, stride is %d\n", indices, stride);*/
    vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, "");
 
-   *res = draw_llvm_translate_from(builder, vbuffer_ptr, velem->src_format);
+   *res = draw_llvm_translate_from(gallivm, vbuffer_ptr, velem->src_format);
 }
 
 static LLVMValueRef
-aos_to_soa(LLVMBuilderRef builder,
+aos_to_soa(struct gallivm_state *gallivm,
            LLVMValueRef val0,
            LLVMValueRef val1,
            LLVMValueRef val2,
            LLVMValueRef val3,
            LLVMValueRef channel)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef ex, res;
 
    ex = LLVMBuildExtractElement(builder, val0,
@@ -457,38 +558,39 @@ aos_to_soa(LLVMBuilderRef builder,
    res = LLVMBuildInsertElement(builder,
                                 LLVMConstNull(LLVMTypeOf(val0)),
                                 ex,
-                                LLVMConstInt(LLVMInt32Type(), 0, 0),
+                                lp_build_const_int32(gallivm, 0),
                                 "");
 
    ex = LLVMBuildExtractElement(builder, val1,
                                 channel, "");
    res = LLVMBuildInsertElement(builder,
                                 res, ex,
-                                LLVMConstInt(LLVMInt32Type(), 1, 0),
+                                lp_build_const_int32(gallivm, 1),
                                 "");
 
    ex = LLVMBuildExtractElement(builder, val2,
                                 channel, "");
    res = LLVMBuildInsertElement(builder,
                                 res, ex,
-                                LLVMConstInt(LLVMInt32Type(), 2, 0),
+                                lp_build_const_int32(gallivm, 2),
                                 "");
 
    ex = LLVMBuildExtractElement(builder, val3,
                                 channel, "");
    res = LLVMBuildInsertElement(builder,
                                 res, ex,
-                                LLVMConstInt(LLVMInt32Type(), 3, 0),
+                                lp_build_const_int32(gallivm, 3),
                                 "");
 
    return res;
 }
 
 static void
-soa_to_aos(LLVMBuilderRef builder,
+soa_to_aos(struct gallivm_state *gallivm,
            LLVMValueRef soa[NUM_CHANNELS],
            LLVMValueRef aos[NUM_CHANNELS])
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef comp;
    int i = 0;
 
@@ -498,29 +600,29 @@ soa_to_aos(LLVMBuilderRef builder,
    aos[1] = aos[2] = aos[3] = aos[0];
 
    for (i = 0; i < NUM_CHANNELS; ++i) {
-      LLVMValueRef channel = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef channel = lp_build_const_int32(gallivm, i);
 
       comp = LLVMBuildExtractElement(builder, soa[i],
-                                     LLVMConstInt(LLVMInt32Type(), 0, 0), "");
+                                     lp_build_const_int32(gallivm, 0), "");
       aos[0] = LLVMBuildInsertElement(builder, aos[0], comp, channel, "");
 
       comp = LLVMBuildExtractElement(builder, soa[i],
-                                     LLVMConstInt(LLVMInt32Type(), 1, 0), "");
+                                     lp_build_const_int32(gallivm, 1), "");
       aos[1] = LLVMBuildInsertElement(builder, aos[1], comp, channel, "");
 
       comp = LLVMBuildExtractElement(builder, soa[i],
-                                     LLVMConstInt(LLVMInt32Type(), 2, 0), "");
+                                     lp_build_const_int32(gallivm, 2), "");
       aos[2] = LLVMBuildInsertElement(builder, aos[2], comp, channel, "");
 
       comp = LLVMBuildExtractElement(builder, soa[i],
-                                     LLVMConstInt(LLVMInt32Type(), 3, 0), "");
+                                     lp_build_const_int32(gallivm, 3), "");
       aos[3] = LLVMBuildInsertElement(builder, aos[3], comp, channel, "");
 
    }
 }
 
 static void
-convert_to_soa(LLVMBuilderRef builder,
+convert_to_soa(struct gallivm_state *gallivm,
                LLVMValueRef (*aos)[NUM_CHANNELS],
                LLVMValueRef (*soa)[NUM_CHANNELS],
                int num_attribs)
@@ -535,36 +637,37 @@ convert_to_soa(LLVMBuilderRef builder,
       LLVMValueRef val2 = aos[i][2];
       LLVMValueRef val3 = aos[i][3];
 
-      soa[i][0] = aos_to_soa(builder, val0, val1, val2, val3,
-                             LLVMConstInt(LLVMInt32Type(), 0, 0));
-      soa[i][1] = aos_to_soa(builder, val0, val1, val2, val3,
-                             LLVMConstInt(LLVMInt32Type(), 1, 0));
-      soa[i][2] = aos_to_soa(builder, val0, val1, val2, val3,
-                             LLVMConstInt(LLVMInt32Type(), 2, 0));
-      soa[i][3] = aos_to_soa(builder, val0, val1, val2, val3,
-                             LLVMConstInt(LLVMInt32Type(), 3, 0));
+      soa[i][0] = aos_to_soa(gallivm, val0, val1, val2, val3,
+                             lp_build_const_int32(gallivm, 0));
+      soa[i][1] = aos_to_soa(gallivm, val0, val1, val2, val3,
+                             lp_build_const_int32(gallivm, 1));
+      soa[i][2] = aos_to_soa(gallivm, val0, val1, val2, val3,
+                             lp_build_const_int32(gallivm, 2));
+      soa[i][3] = aos_to_soa(gallivm, val0, val1, val2, val3,
+                             lp_build_const_int32(gallivm, 3));
    }
 }
 
 static void
-store_aos(LLVMBuilderRef builder,
+store_aos(struct gallivm_state *gallivm,
           LLVMValueRef io_ptr,
           LLVMValueRef index,
           LLVMValueRef value,
           LLVMValueRef clipmask)
 {
-   LLVMValueRef id_ptr = draw_jit_header_id(builder, io_ptr);
-   LLVMValueRef data_ptr = draw_jit_header_data(builder, io_ptr);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef id_ptr = draw_jit_header_id(gallivm, io_ptr);
+   LLVMValueRef data_ptr = draw_jit_header_data(gallivm, io_ptr);
    LLVMValueRef indices[3];
    LLVMValueRef val, shift;
 
-   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indices[0] = lp_build_const_int32(gallivm, 0);
    indices[1] = index;
-   indices[2] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indices[2] = lp_build_const_int32(gallivm, 0);
 
    /* initialize vertex id:16 = 0xffff, pad:3 = 0, edgeflag:1 = 1 */
-   val = LLVMConstInt(LLVMInt32Type(), 0xffff1, 0); 
-   shift  = LLVMConstInt(LLVMInt32Type(), 12, 0);          
+   val = lp_build_const_int32(gallivm, 0xffff1);
+   shift = lp_build_const_int32(gallivm, 12);
    val = LLVMBuildShl(builder, val, shift, "");
    /* add clipmask:12 */   
    val = LLVMBuildOr(builder, val, clipmask, "");               
@@ -580,7 +683,7 @@ store_aos(LLVMBuilderRef builder,
    /*lp_build_printf(builder, " ---- %p storing at %d (%p)  ", io_ptr, index, data_ptr);
      print_vectorf(builder, value);*/
    data_ptr = LLVMBuildBitCast(builder, data_ptr,
-                               LLVMPointerType(LLVMArrayType(LLVMVectorType(LLVMFloatType(), 4), 0), 0),
+                               LLVMPointerType(LLVMArrayType(LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4), 0), 0),
                                "datavec");
    data_ptr = LLVMBuildGEP(builder, data_ptr, indices, 2, "");
 
@@ -592,10 +695,10 @@ store_aos(LLVMBuilderRef builder,
       LLVMValueRef gep0, gep1, gep2, gep3;
       data_ptr = LLVMBuildGEP(builder, data_ptr, indices, 3, "");
 
-      idx0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-      idx1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-      idx2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-      idx3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+      idx0 = lp_build_const_int32(gallivm, 0);
+      idx1 = lp_build_const_int32(gallivm, 1);
+      idx2 = lp_build_const_int32(gallivm, 2);
+      idx3 = lp_build_const_int32(gallivm, 3);
 
       x = LLVMBuildExtractElement(builder, value,
                                   idx0, "");
@@ -622,18 +725,19 @@ store_aos(LLVMBuilderRef builder,
 }
 
 static void
-store_aos_array(LLVMBuilderRef builder,
+store_aos_array(struct gallivm_state *gallivm,
                 LLVMValueRef io_ptr,
                 LLVMValueRef aos[NUM_CHANNELS],
                 int attrib,
                 int num_outputs,
                 LLVMValueRef clipmask)
 {
-   LLVMValueRef attr_index = LLVMConstInt(LLVMInt32Type(), attrib, 0);
-   LLVMValueRef ind0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   LLVMValueRef ind1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-   LLVMValueRef ind2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-   LLVMValueRef ind3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef attr_index = lp_build_const_int32(gallivm, attrib);
+   LLVMValueRef ind0 = lp_build_const_int32(gallivm, 0);
+   LLVMValueRef ind1 = lp_build_const_int32(gallivm, 1);
+   LLVMValueRef ind2 = lp_build_const_int32(gallivm, 2);
+   LLVMValueRef ind3 = lp_build_const_int32(gallivm, 3);
    LLVMValueRef io0_ptr, io1_ptr, io2_ptr, io3_ptr;
    LLVMValueRef clipmask0, clipmask1, clipmask2, clipmask3;
    
@@ -662,20 +766,21 @@ store_aos_array(LLVMBuilderRef builder,
                    io_ptr, ind0, ind1, ind2, ind3, clipmask0, clipmask1, clipmask2, clipmask3);
 #endif
    /* store for each of the 4 vertices */
-   store_aos(builder, io0_ptr, attr_index, aos[0], clipmask0);
-   store_aos(builder, io1_ptr, attr_index, aos[1], clipmask1);
-   store_aos(builder, io2_ptr, attr_index, aos[2], clipmask2);
-   store_aos(builder, io3_ptr, attr_index, aos[3], clipmask3);
+   store_aos(gallivm, io0_ptr, attr_index, aos[0], clipmask0);
+   store_aos(gallivm, io1_ptr, attr_index, aos[1], clipmask1);
+   store_aos(gallivm, io2_ptr, attr_index, aos[2], clipmask2);
+   store_aos(gallivm, io3_ptr, attr_index, aos[3], clipmask3);
 }
 
 static void
-convert_to_aos(LLVMBuilderRef builder,
+convert_to_aos(struct gallivm_state *gallivm,
                LLVMValueRef io,
                LLVMValueRef (*outputs)[NUM_CHANNELS],
                LLVMValueRef clipmask,
                int num_outputs,
                int max_vertices)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    unsigned chan, attrib;
 
 #if DEBUG_STORE
@@ -696,8 +801,8 @@ convert_to_aos(LLVMBuilderRef builder,
          } else
             soa[chan] = 0;
       }
-      soa_to_aos(builder, soa, aos);
-      store_aos_array(builder,
+      soa_to_aos(gallivm, soa, aos);
+      store_aos_array(gallivm,
                       io,
                       aos,
                       attrib,
@@ -715,10 +820,11 @@ convert_to_aos(LLVMBuilderRef builder,
  * rather than extracting each element one by one.
  */
 static void
-store_clip(LLVMBuilderRef builder,
+store_clip(struct gallivm_state *gallivm,
            LLVMValueRef io_ptr,           
            LLVMValueRef (*outputs)[NUM_CHANNELS])
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef out[4];
    LLVMValueRef indices[2]; 
    LLVMValueRef io0_ptr, io1_ptr, io2_ptr, io3_ptr;
@@ -727,13 +833,13 @@ store_clip(LLVMBuilderRef builder,
    LLVMValueRef out0elem, out1elem, out2elem, out3elem;
    int i;
 
-   LLVMValueRef ind0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   LLVMValueRef ind1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-   LLVMValueRef ind2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-   LLVMValueRef ind3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+   LLVMValueRef ind0 = lp_build_const_int32(gallivm, 0);
+   LLVMValueRef ind1 = lp_build_const_int32(gallivm, 1);
+   LLVMValueRef ind2 = lp_build_const_int32(gallivm, 2);
+   LLVMValueRef ind3 = lp_build_const_int32(gallivm, 3);
    
-   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   indices[1] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indices[0] =
+   indices[1] = lp_build_const_int32(gallivm, 0);
    
    out[0] = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 x1 x2 x3*/
    out[1] = LLVMBuildLoad(builder, outputs[0][1], ""); /*y0 y1 y2 y3*/
@@ -745,29 +851,21 @@ store_clip(LLVMBuilderRef builder,
    io2_ptr = LLVMBuildGEP(builder, io_ptr, &ind2, 1, "");
    io3_ptr = LLVMBuildGEP(builder, io_ptr, &ind3, 1, "");
 
-   clip_ptr0 = draw_jit_header_clip(builder, io0_ptr);
-   clip_ptr1 = draw_jit_header_clip(builder, io1_ptr);
-   clip_ptr2 = draw_jit_header_clip(builder, io2_ptr);
-   clip_ptr3 = draw_jit_header_clip(builder, io3_ptr);
+   clip_ptr0 = draw_jit_header_clip(gallivm, io0_ptr);
+   clip_ptr1 = draw_jit_header_clip(gallivm, io1_ptr);
+   clip_ptr2 = draw_jit_header_clip(gallivm, io2_ptr);
+   clip_ptr3 = draw_jit_header_clip(gallivm, io3_ptr);
 
    for (i = 0; i<4; i++){
-      clip0_ptr = LLVMBuildGEP(builder, clip_ptr0,
-                               indices, 2, ""); //x0
-      clip1_ptr = LLVMBuildGEP(builder, clip_ptr1,
-                               indices, 2, ""); //x1
-      clip2_ptr = LLVMBuildGEP(builder, clip_ptr2,
-                               indices, 2, ""); //x2
-      clip3_ptr = LLVMBuildGEP(builder, clip_ptr3,
-                               indices, 2, ""); //x3
-
-      out0elem = LLVMBuildExtractElement(builder, out[i],
-                                         ind0, ""); //x0
-      out1elem = LLVMBuildExtractElement(builder, out[i],
-                                         ind1, ""); //x1
-      out2elem = LLVMBuildExtractElement(builder, out[i],
-                                         ind2, ""); //x2
-      out3elem = LLVMBuildExtractElement(builder, out[i],
-                                         ind3, ""); //x3
+      clip0_ptr = LLVMBuildGEP(builder, clip_ptr0, indices, 2, ""); /* x0 */
+      clip1_ptr = LLVMBuildGEP(builder, clip_ptr1, indices, 2, ""); /* x1 */
+      clip2_ptr = LLVMBuildGEP(builder, clip_ptr2, indices, 2, ""); /* x2 */
+      clip3_ptr = LLVMBuildGEP(builder, clip_ptr3, indices, 2, ""); /* x3 */
+
+      out0elem = LLVMBuildExtractElement(builder, out[i], ind0, ""); /* x0 */
+      out1elem = LLVMBuildExtractElement(builder, out[i], ind1, ""); /* x1 */
+      out2elem = LLVMBuildExtractElement(builder, out[i], ind2, ""); /* x2 */
+      out3elem = LLVMBuildExtractElement(builder, out[i], ind3, ""); /* x3 */
   
       LLVMBuildStore(builder, out0elem, clip0_ptr);
       LLVMBuildStore(builder, out1elem, clip1_ptr);
@@ -781,16 +879,19 @@ store_clip(LLVMBuilderRef builder,
 
 /* Equivalent of _mm_set1_ps(a)
  */
-static LLVMValueRef vec4f_from_scalar(LLVMBuilderRef bld,
-                                     LLVMValueRef a,
-                                     const char *name)
+static LLVMValueRef
+vec4f_from_scalar(struct gallivm_state *gallivm,
+                  LLVMValueRef a,
+                  const char *name)
 {
-   LLVMValueRef res = LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4));
+   LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context);
+   LLVMValueRef res = LLVMGetUndef(LLVMVectorType(float_type, 4));
    int i;
 
    for(i = 0; i < 4; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      res = LLVMBuildInsertElement(bld, res, a, index, i == 3 ? name : "");
+      LLVMValueRef index = lp_build_const_int32(gallivm, i);
+      res = LLVMBuildInsertElement(gallivm->builder, res, a,
+                                   index, i == 3 ? name : "");
    }
 
    return res;
@@ -806,10 +907,11 @@ generate_viewport(struct draw_llvm *llvm,
                   LLVMValueRef context_ptr)
 {
    int i;
+   struct gallivm_state *gallivm = llvm->gallivm;
    struct lp_type f32_type = lp_type_float_vec(32);
    LLVMValueRef out3 = LLVMBuildLoad(builder, outputs[0][3], ""); /*w0 w1 w2 w3*/   
-   LLVMValueRef const1 = lp_build_const_vec(f32_type, 1.0);       /*1.0 1.0 1.0 1.0*/ 
-   LLVMValueRef vp_ptr = draw_jit_context_viewport(builder, context_ptr);
+   LLVMValueRef const1 = lp_build_const_vec(gallivm, f32_type, 1.0);       /*1.0 1.0 1.0 1.0*/ 
+   LLVMValueRef vp_ptr = draw_jit_context_viewport(gallivm, context_ptr);
 
    /* for 1/w convention*/
    out3 = LLVMBuildFDiv(builder, const1, out3, "");
@@ -824,14 +926,14 @@ generate_viewport(struct draw_llvm *llvm,
       LLVMValueRef trans_i;
       LLVMValueRef index;
       
-      index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      index = lp_build_const_int32(gallivm, i);
       scale_i = LLVMBuildGEP(builder, vp_ptr, &index, 1, "");
 
-      index = LLVMConstInt(LLVMInt32Type(), i+4, 0);
+      index = lp_build_const_int32(gallivm, i+4);
       trans_i = LLVMBuildGEP(builder, vp_ptr, &index, 1, "");
 
-      scale = vec4f_from_scalar(builder, LLVMBuildLoad(builder, scale_i, ""), "scale");
-      trans = vec4f_from_scalar(builder, LLVMBuildLoad(builder, trans_i, ""), "trans");
+      scale = vec4f_from_scalar(gallivm, LLVMBuildLoad(builder, scale_i, ""), "scale");
+      trans = vec4f_from_scalar(gallivm, LLVMBuildLoad(builder, trans_i, ""), "trans");
 
       /* divide by w */
       out = LLVMBuildFMul(builder, out, out3, "");
@@ -851,7 +953,7 @@ generate_viewport(struct draw_llvm *llvm,
  * Returns clipmask as 4xi32 bitmask for the 4 vertices
  */
 static LLVMValueRef 
-generate_clipmask(LLVMBuilderRef builder,
+generate_clipmask(struct gallivm_state *gallivm,
                   LLVMValueRef (*outputs)[NUM_CHANNELS],
                   boolean clip_xy,
                   boolean clip_z,
@@ -860,6 +962,7 @@ generate_clipmask(LLVMBuilderRef builder,
                   unsigned nr,
                   LLVMValueRef context_ptr)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef mask; /* stores the <4xi32> clipmasks */     
    LLVMValueRef test, temp; 
    LLVMValueRef zero, shift;
@@ -870,10 +973,10 @@ generate_clipmask(LLVMBuilderRef builder,
 
    struct lp_type f32_type = lp_type_float_vec(32); 
 
-   mask = lp_build_const_int_vec(lp_type_int_vec(32), 0);
-   temp = lp_build_const_int_vec(lp_type_int_vec(32), 0);
-   zero = lp_build_const_vec(f32_type, 0);                    /* 0.0f 0.0f 0.0f 0.0f */
-   shift = lp_build_const_int_vec(lp_type_int_vec(32), 1);    /* 1 1 1 1 */
+   mask = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 0);
+   temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 0);
+   zero = lp_build_const_vec(gallivm, f32_type, 0);                    /* 0.0f 0.0f 0.0f 0.0f */
+   shift = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 1);    /* 1 1 1 1 */
 
    /* Assuming position stored at output[0] */
    pos_x = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 x1 x2 x3*/
@@ -884,92 +987,92 @@ generate_clipmask(LLVMBuilderRef builder,
    /* Cliptest, for hardwired planes */
    if (clip_xy){
       /* plane 1 */
-      test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w);
+      test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w);
       temp = shift;
       test = LLVMBuildAnd(builder, test, temp, ""); 
       mask = test;
    
       /* plane 2 */
       test = LLVMBuildFAdd(builder, pos_x, pos_w, "");
-      test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test);
+      test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, test);
       temp = LLVMBuildShl(builder, temp, shift, "");
       test = LLVMBuildAnd(builder, test, temp, ""); 
       mask = LLVMBuildOr(builder, mask, test, "");
    
       /* plane 3 */
-      test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_y, pos_w);
+      test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_y, pos_w);
       temp = LLVMBuildShl(builder, temp, shift, "");
       test = LLVMBuildAnd(builder, test, temp, ""); 
       mask = LLVMBuildOr(builder, mask, test, "");
 
       /* plane 4 */
       test = LLVMBuildFAdd(builder, pos_y, pos_w, "");
-      test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test);
+      test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, test);
       temp = LLVMBuildShl(builder, temp, shift, "");
       test = LLVMBuildAnd(builder, test, temp, ""); 
       mask = LLVMBuildOr(builder, mask, test, "");
    }
 
    if (clip_z){
-      temp = lp_build_const_int_vec(lp_type_int_vec(32), 16);
+      temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 16);
       if (clip_halfz){
          /* plane 5 */
-         test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, pos_z);
+         test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, pos_z);
          test = LLVMBuildAnd(builder, test, temp, ""); 
          mask = LLVMBuildOr(builder, mask, test, "");
       }  
       else{
          /* plane 5 */
          test = LLVMBuildFAdd(builder, pos_z, pos_w, "");
-         test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test);
+         test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, test);
          test = LLVMBuildAnd(builder, test, temp, ""); 
          mask = LLVMBuildOr(builder, mask, test, "");
       }
       /* plane 6 */
-      test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_z, pos_w);
+      test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_z, pos_w);
       temp = LLVMBuildShl(builder, temp, shift, "");
       test = LLVMBuildAnd(builder, test, temp, ""); 
       mask = LLVMBuildOr(builder, mask, test, "");
    }   
 
    if (clip_user){
-      LLVMValueRef planes_ptr = draw_jit_context_planes(builder, context_ptr);
+      LLVMValueRef planes_ptr = draw_jit_context_planes(gallivm, context_ptr);
       LLVMValueRef indices[3];
-      temp = lp_build_const_int_vec(lp_type_int_vec(32), 32);
+      temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 32);
 
       /* userclip planes */
       for (i = 6; i < nr; i++) {
-         indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
-         indices[1] = LLVMConstInt(LLVMInt32Type(), i, 0);
+         indices[0] = lp_build_const_int32(gallivm, 0);
+         indices[1] = lp_build_const_int32(gallivm, i);
 
-         indices[2] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+         indices[2] = lp_build_const_int32(gallivm, 0);
          plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
          plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_x");
-         planes = vec4f_from_scalar(builder, plane1, "plane4_x");
+         planes = vec4f_from_scalar(gallivm, plane1, "plane4_x");
          sum = LLVMBuildFMul(builder, planes, pos_x, "");
 
-         indices[2] = LLVMConstInt(LLVMInt32Type(), 1, 0);
+         indices[2] = lp_build_const_int32(gallivm, 1);
          plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
          plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_y"); 
-         planes = vec4f_from_scalar(builder, plane1, "plane4_y");
+         planes = vec4f_from_scalar(gallivm, plane1, "plane4_y");
          test = LLVMBuildFMul(builder, planes, pos_y, "");
          sum = LLVMBuildFAdd(builder, sum, test, "");
          
-         indices[2] = LLVMConstInt(LLVMInt32Type(), 2, 0);
+         indices[2] = lp_build_const_int32(gallivm, 2);
          plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
          plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_z"); 
-         planes = vec4f_from_scalar(builder, plane1, "plane4_z");
+         planes = vec4f_from_scalar(gallivm, plane1, "plane4_z");
          test = LLVMBuildFMul(builder, planes, pos_z, "");
          sum = LLVMBuildFAdd(builder, sum, test, "");
 
-         indices[2] = LLVMConstInt(LLVMInt32Type(), 3, 0);
+         indices[2] = lp_build_const_int32(gallivm, 3);
          plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
          plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_w"); 
-         planes = vec4f_from_scalar(builder, plane1, "plane4_w");
+         planes = vec4f_from_scalar(gallivm, plane1, "plane4_w");
          test = LLVMBuildFMul(builder, planes, pos_w, "");
          sum = LLVMBuildFAdd(builder, sum, test, "");
 
-         test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, sum);
+         test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, sum);
          temp = LLVMBuildShl(builder, temp, shift, "");
          test = LLVMBuildAnd(builder, test, temp, ""); 
          mask = LLVMBuildOr(builder, mask, test, "");
@@ -983,17 +1086,18 @@ generate_clipmask(LLVMBuilderRef builder,
  * Used zero/non-zero i32 value to represent boolean 
  */
 static void
-clipmask_bool(LLVMBuilderRef builder, 
+clipmask_bool(struct gallivm_state *gallivm,
               LLVMValueRef clipmask,
               LLVMValueRef ret_ptr)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef ret = LLVMBuildLoad(builder, ret_ptr, "");   
    LLVMValueRef temp;
    int i;
 
    for (i=0; i<4; i++){   
       temp = LLVMBuildExtractElement(builder, clipmask,
-                                     LLVMConstInt(LLVMInt32Type(), i, 0) , "");
+                                     lp_build_const_int32(gallivm, i) , "");
       ret = LLVMBuildOr(builder, ret, temp, "");
    }
    
@@ -1003,6 +1107,9 @@ clipmask_bool(LLVMBuilderRef builder,
 static void
 draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 {
+   struct gallivm_state *gallivm = llvm->gallivm;
+   LLVMContextRef context = gallivm->context;
+   LLVMTypeRef int32_type = LLVMInt32TypeInContext(context);
    LLVMTypeRef arg_types[8];
    LLVMTypeRef func_type;
    LLVMValueRef context_ptr;
@@ -1025,18 +1132,19 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
                              variant->key.clip_z  ||
                              variant->key.clip_user;
    
-   arg_types[0] = llvm->context_ptr_type;           /* context */
-   arg_types[1] = llvm->vertex_header_ptr_type;     /* vertex_header */
-   arg_types[2] = llvm->buffer_ptr_type;            /* vbuffers */
-   arg_types[3] = LLVMInt32Type();                  /* start */
-   arg_types[4] = LLVMInt32Type();                  /* count */
-   arg_types[5] = LLVMInt32Type();                  /* stride */
-   arg_types[6] = llvm->vb_ptr_type;                /* pipe_vertex_buffer's */
-   arg_types[7] = LLVMInt32Type();                  /* instance_id */
-
-   func_type = LLVMFunctionType(LLVMInt32Type(), arg_types, Elements(arg_types), 0);
-
-   variant->function = LLVMAddFunction(llvm->module, "draw_llvm_shader", func_type);
+   arg_types[0] = get_context_ptr_type(llvm);       /* context */
+   arg_types[1] = get_vertex_header_ptr_type(llvm); /* vertex_header */
+   arg_types[2] = get_buffer_ptr_type(llvm);        /* vbuffers */
+   arg_types[3] = int32_type;                       /* start */
+   arg_types[4] = int32_type;                       /* count */
+   arg_types[5] = int32_type;                       /* stride */
+   arg_types[6] = get_vb_ptr_type(llvm);            /* pipe_vertex_buffer's */
+   arg_types[7] = int32_type;                       /* instance_id */
+
+   func_type = LLVMFunctionType(int32_type, arg_types, Elements(arg_types), 0);
+
+   variant->function = LLVMAddFunction(gallivm->module, "draw_llvm_shader",
+                                       func_type);
    LLVMSetFunctionCallConv(variant->function, LLVMCCallConv);
    for(i = 0; i < Elements(arg_types); ++i)
       if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
@@ -1064,19 +1172,20 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
     * Function body
     */
 
-   block = LLVMAppendBasicBlock(variant->function, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(gallivm->context, variant->function, "entry");
+   builder = gallivm->builder;
+   assert(builder);
    LLVMPositionBuilderAtEnd(builder, block);
 
-   lp_build_context_init(&bld, builder, lp_type_int(32));
+   lp_build_context_init(&bld, llvm->gallivm, lp_type_int(32));
 
    end = lp_build_add(&bld, start, count);
 
-   step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
+   step = lp_build_const_int32(gallivm, max_vertices);
 
    /* function will return non-zero i32 value if any clipped vertices */     
-   ret_ptr = lp_build_alloca(builder, LLVMInt32Type(), "");   
-   LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), ret_ptr);
+   ret_ptr = lp_build_alloca(gallivm, int32_type, "");   
+   LLVMBuildStore(builder, lp_build_const_int32(gallivm, 0), ret_ptr);
 
    /* code generated texture sampling */
    sampler = draw_llvm_sampler_soa_create(
@@ -1087,7 +1196,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    lp_build_printf(builder, "start = %d, end = %d, step = %d\n",
                    start, end, step);
 #endif
-   lp_build_loop_begin(builder, start, &lp_loop);
+   lp_build_loop_begin(&lp_loop, llvm->gallivm, start);
    {
       LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
       LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS] = { { 0 } };
@@ -1105,20 +1214,18 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
          LLVMValueRef true_index = LLVMBuildAdd(
             builder,
             lp_loop.counter,
-            LLVMConstInt(LLVMInt32Type(), i, 0), "");
+            lp_build_const_int32(gallivm, i), "");
          for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
             struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];
-            LLVMValueRef vb_index = LLVMConstInt(LLVMInt32Type(),
-                                                 velem->vertex_buffer_index,
-                                                 0);
+            LLVMValueRef vb_index = lp_build_const_int32(gallivm, velem->vertex_buffer_index);
             LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr,
                                            &vb_index, 1, "");
-            generate_fetch(builder, vbuffers_ptr,
+            generate_fetch(llvm->gallivm, vbuffers_ptr,
                            &aos_attribs[j][i], velem, vb, true_index,
                            instance_id);
          }
       }
-      convert_to_soa(builder, aos_attribs, inputs,
+      convert_to_soa(gallivm, aos_attribs, inputs,
                      draw->pt.nr_vertex_elements);
 
       ptr_aos = (const LLVMValueRef (*)[NUM_CHANNELS]) inputs;
@@ -1130,12 +1237,12 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
                   sampler);
 
       /* store original positions in clip before further manipulation */
-      store_clip(builder, io, outputs);
+      store_clip(gallivm, io, outputs);
 
       /* do cliptest */
       if (enable_cliptest){
          /* allocate clipmask, assign it integer type */
-         clipmask = generate_clipmask(builder, outputs,
+         clipmask = generate_clipmask(gallivm, outputs,
                                       variant->key.clip_xy,
                                       variant->key.clip_z, 
                                       variant->key.clip_user,
@@ -1143,10 +1250,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
                                       variant->key.nr_planes,
                                       context_ptr);
          /* return clipping boolean value for function */
-         clipmask_bool(builder, clipmask, ret_ptr);
+         clipmask_bool(gallivm, clipmask, ret_ptr);
       }
       else{
-         clipmask = lp_build_const_int_vec(lp_type_int_vec(32), 0);    
+         clipmask = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 0);    
       }
       
       /* do viewport mapping */
@@ -1155,20 +1262,18 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
       }
 
       /* store clipmask in vertex header and positions in data */
-      convert_to_aos(builder, io, outputs, clipmask,
+      convert_to_aos(gallivm, io, outputs, clipmask,
                      draw->vs.vertex_shader->info.num_outputs,
                      max_vertices);
    }
 
-   lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop);
+   lp_build_loop_end_cond(&lp_loop, end, step, LLVMIntUGE);
 
    sampler->destroy(sampler);
 
    ret = LLVMBuildLoad(builder, ret_ptr,"");
    LLVMBuildRet(builder, ret);
       
-   LLVMDisposeBuilder(builder);
-
    /*
     * Translate the LLVM IR into machine code.
     */
@@ -1179,14 +1284,14 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    }
 #endif
 
-   LLVMRunFunctionPassManager(llvm->pass, variant->function);
+   LLVMRunFunctionPassManager(gallivm->passmgr, variant->function);
 
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
       lp_debug_dump_value(variant->function);
       debug_printf("\n");
    }
 
-   code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function);
+   code = LLVMGetPointerToGlobal(gallivm->engine, variant->function);
    variant->jit_func = (draw_jit_vert_func)pointer_to_func(code);
 
    if (gallivm_debug & GALLIVM_DEBUG_ASM) {
@@ -1199,6 +1304,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 static void
 draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 {
+   struct gallivm_state *gallivm = llvm->gallivm;
+   LLVMContextRef context = gallivm->context;
+   LLVMTypeRef int32_type = LLVMInt32TypeInContext(context);
    LLVMTypeRef arg_types[8];
    LLVMTypeRef func_type;
    LLVMValueRef context_ptr;
@@ -1222,18 +1330,18 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
                              variant->key.clip_z  ||
                              variant->key.clip_user;
    
-   arg_types[0] = llvm->context_ptr_type;               /* context */
-   arg_types[1] = llvm->vertex_header_ptr_type;         /* vertex_header */
-   arg_types[2] = llvm->buffer_ptr_type;                /* vbuffers */
-   arg_types[3] = LLVMPointerType(LLVMInt32Type(), 0);  /* fetch_elts * */
-   arg_types[4] = LLVMInt32Type();                      /* fetch_count */
-   arg_types[5] = LLVMInt32Type();                      /* stride */
-   arg_types[6] = llvm->vb_ptr_type;                    /* pipe_vertex_buffer's */
-   arg_types[7] = LLVMInt32Type();                      /* instance_id */
-
-   func_type = LLVMFunctionType(LLVMInt32Type(), arg_types, Elements(arg_types), 0);
-
-   variant->function_elts = LLVMAddFunction(llvm->module, "draw_llvm_shader_elts", func_type);
+   arg_types[0] = get_context_ptr_type(llvm);           /* context */
+   arg_types[1] = get_vertex_header_ptr_type(llvm);     /* vertex_header */
+   arg_types[2] = get_buffer_ptr_type(llvm);            /* vbuffers */
+   arg_types[3] = LLVMPointerType(int32_type, 0);       /* fetch_elts * */
+   arg_types[4] = int32_type;                           /* fetch_count */
+   arg_types[5] = int32_type;                           /* stride */
+   arg_types[6] = get_vb_ptr_type(llvm);                /* pipe_vertex_buffer's */
+   arg_types[7] = int32_type;                           /* instance_id */
+
+   func_type = LLVMFunctionType(int32_type, arg_types, Elements(arg_types), 0);
+
+   variant->function_elts = LLVMAddFunction(gallivm->module, "draw_llvm_shader_elts", func_type);
    LLVMSetFunctionCallConv(variant->function_elts, LLVMCCallConv);
    for(i = 0; i < Elements(arg_types); ++i)
       if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
@@ -1262,13 +1370,13 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
     * Function body
     */
 
-   block = LLVMAppendBasicBlock(variant->function_elts, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(gallivm->context, variant->function_elts, "entry");
+   builder = gallivm->builder;
    LLVMPositionBuilderAtEnd(builder, block);
 
-   lp_build_context_init(&bld, builder, lp_type_int(32));
+   lp_build_context_init(&bld, gallivm, lp_type_int(32));
 
-   step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
+   step = lp_build_const_int32(gallivm, max_vertices);
 
    /* code generated texture sampling */
    sampler = draw_llvm_sampler_soa_create(
@@ -1276,14 +1384,14 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
       context_ptr);
 
    fetch_max = LLVMBuildSub(builder, fetch_count,
-                            LLVMConstInt(LLVMInt32Type(), 1, 0),
+                            lp_build_const_int32(gallivm, 1),
                             "fetch_max");
 
    /* function returns non-zero i32 value if any clipped vertices */
-   ret_ptr = lp_build_alloca(builder, LLVMInt32Type(), ""); 
-   LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), ret_ptr);
+   ret_ptr = lp_build_alloca(gallivm, int32_type, ""); 
+   LLVMBuildStore(builder, lp_build_const_int32(gallivm, 0), ret_ptr);
 
-   lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), &lp_loop);
+   lp_build_loop_begin(&lp_loop, gallivm, lp_build_const_int32(gallivm, 0));
    {
       LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
       LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS] = { { 0 } };
@@ -1301,7 +1409,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
          LLVMValueRef true_index = LLVMBuildAdd(
             builder,
             lp_loop.counter,
-            LLVMConstInt(LLVMInt32Type(), i, 0), "");
+            lp_build_const_int32(gallivm, i), "");
          LLVMValueRef fetch_ptr;
 
          /* make sure we're not out of bounds which can happen
@@ -1314,17 +1422,15 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
          true_index = LLVMBuildLoad(builder, fetch_ptr, "fetch_elt");
          for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
             struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];
-            LLVMValueRef vb_index = LLVMConstInt(LLVMInt32Type(),
-                                                 velem->vertex_buffer_index,
-                                                 0);
+            LLVMValueRef vb_index = lp_build_const_int32(gallivm, velem->vertex_buffer_index);
             LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr,
                                            &vb_index, 1, "");
-            generate_fetch(builder, vbuffers_ptr,
+            generate_fetch(gallivm, vbuffers_ptr,
                            &aos_attribs[j][i], velem, vb, true_index,
                            instance_id);
          }
       }
-      convert_to_soa(builder, aos_attribs, inputs,
+      convert_to_soa(gallivm, aos_attribs, inputs,
                      draw->pt.nr_vertex_elements);
 
       ptr_aos = (const LLVMValueRef (*)[NUM_CHANNELS]) inputs;
@@ -1336,12 +1442,12 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
                   sampler);
 
       /* store original positions in clip before further manipulation */
-      store_clip(builder, io, outputs);
+      store_clip(gallivm, io, outputs);
 
       /* do cliptest */
       if (enable_cliptest){
          /* allocate clipmask, assign it integer type */
-         clipmask = generate_clipmask(builder, outputs,
+         clipmask = generate_clipmask(gallivm, outputs,
                                       variant->key.clip_xy,
                                       variant->key.clip_z, 
                                       variant->key.clip_user,
@@ -1349,10 +1455,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
                                       variant->key.nr_planes,
                                       context_ptr);
          /* return clipping boolean value for function */
-         clipmask_bool(builder, clipmask, ret_ptr);
+         clipmask_bool(gallivm, clipmask, ret_ptr);
       }
       else{
-         clipmask = lp_build_const_int_vec(lp_type_int_vec(32), 0);
+         clipmask = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 0);
       }
       
       /* do viewport mapping */
@@ -1364,20 +1470,18 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
        * original positions in clip 
        * and transformed positions in data 
        */   
-      convert_to_aos(builder, io, outputs, clipmask,
+      convert_to_aos(gallivm, io, outputs, clipmask,
                      draw->vs.vertex_shader->info.num_outputs,
                      max_vertices);
    }
 
-   lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop);
+   lp_build_loop_end_cond(&lp_loop, fetch_count, step, LLVMIntUGE);
 
    sampler->destroy(sampler);
 
    ret = LLVMBuildLoad(builder, ret_ptr,"");   
    LLVMBuildRet(builder, ret);
    
-   LLVMDisposeBuilder(builder);
-
    /*
     * Translate the LLVM IR into machine code.
     */
@@ -1388,14 +1492,14 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    }
 #endif
 
-   LLVMRunFunctionPassManager(llvm->pass, variant->function_elts);
+   LLVMRunFunctionPassManager(gallivm->passmgr, variant->function_elts);
 
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
       lp_debug_dump_value(variant->function_elts);
       debug_printf("\n");
    }
 
-   code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function_elts);
+   code = LLVMGetPointerToGlobal(gallivm->engine, variant->function_elts);
    variant->jit_func_elts = (draw_jit_vert_func_elts)pointer_to_func(code);
 
    if (gallivm_debug & GALLIVM_DEBUG_ASM) {
@@ -1504,19 +1608,16 @@ void
 draw_llvm_destroy_variant(struct draw_llvm_variant *variant)
 {
    struct draw_llvm *llvm = variant->llvm;
-   struct draw_context *draw = llvm->draw;
 
    if (variant->function_elts) {
-      if (variant->function_elts)
-         LLVMFreeMachineCodeForFunction(draw->engine,
-                                        variant->function_elts);
+      LLVMFreeMachineCodeForFunction(llvm->gallivm->engine,
+                                     variant->function_elts);
       LLVMDeleteFunction(variant->function_elts);
    }
 
    if (variant->function) {
-      if (variant->function)
-         LLVMFreeMachineCodeForFunction(draw->engine,
-                                        variant->function);
+      LLVMFreeMachineCodeForFunction(llvm->gallivm->engine,
+                                     variant->function);
       LLVMDeleteFunction(variant->function);
    }
 
index c3c30c07c644d34396aab016bfe624b2d594245d..9f038f1f04d641f9e4d69f5ddbb154188eef20eb 100644 (file)
@@ -103,41 +103,41 @@ struct draw_jit_context
 };
 
 
-#define draw_jit_context_vs_constants(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 0, "vs_constants")
+#define draw_jit_context_vs_constants(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, 0, "vs_constants")
 
-#define draw_jit_context_gs_constants(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 1, "gs_constants")
+#define draw_jit_context_gs_constants(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, 1, "gs_constants")
 
-#define draw_jit_context_planes(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 2, "planes")
+#define draw_jit_context_planes(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, 2, "planes")
 
-#define draw_jit_context_viewport(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 3, "viewport")
+#define draw_jit_context_viewport(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, 3, "viewport")
 
 #define DRAW_JIT_CTX_TEXTURES 4
 
-#define draw_jit_context_textures(_builder, _ptr) \
-   lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")
+#define draw_jit_context_textures(_gallivm, _ptr) \
+   lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")
 
-#define draw_jit_header_id(_builder, _ptr)              \
-   lp_build_struct_get_ptr(_builder, _ptr, 0, "id")
+#define draw_jit_header_id(_gallivm, _ptr)              \
+   lp_build_struct_get_ptr(_gallivm, _ptr, 0, "id")
 
-#define draw_jit_header_clip(_builder, _ptr) \
-   lp_build_struct_get_ptr(_builder, _ptr, 1, "clip")
+#define draw_jit_header_clip(_gallivm, _ptr) \
+   lp_build_struct_get_ptr(_gallivm, _ptr, 1, "clip")
 
-#define draw_jit_header_data(_builder, _ptr)            \
-   lp_build_struct_get_ptr(_builder, _ptr, 2, "data")
+#define draw_jit_header_data(_gallivm, _ptr)            \
+   lp_build_struct_get_ptr(_gallivm, _ptr, 2, "data")
 
 
-#define draw_jit_vbuffer_stride(_builder, _ptr)         \
-   lp_build_struct_get(_builder, _ptr, 0, "stride")
+#define draw_jit_vbuffer_stride(_gallivm, _ptr)         \
+   lp_build_struct_get(_gallivm, _ptr, 0, "stride")
 
-#define draw_jit_vbuffer_max_index(_builder, _ptr)      \
-   lp_build_struct_get(_builder, _ptr, 1, "max_index")
+#define draw_jit_vbuffer_max_index(_gallivm, _ptr)      \
+   lp_build_struct_get(_gallivm, _ptr, 1, "max_index")
 
-#define draw_jit_vbuffer_offset(_builder, _ptr)         \
-   lp_build_struct_get(_builder, _ptr, 2, "buffer_offset")
+#define draw_jit_vbuffer_offset(_gallivm, _ptr)         \
+   lp_build_struct_get(_gallivm, _ptr, 2, "buffer_offset")
 
 
 typedef int
@@ -229,7 +229,6 @@ struct draw_llvm_variant
 
    /* key is variable-sized, must be last */
    struct draw_llvm_variant_key key;
-   /* key is variable-sized, must be last */
 };
 
 struct llvm_vertex_shader {
@@ -246,21 +245,19 @@ struct draw_llvm {
 
    struct draw_jit_context jit_context;
 
+   struct gallivm_state *gallivm;
+
    struct draw_llvm_variant_list_item vs_variants_list;
    int nr_variants;
 
-   LLVMModuleRef module;
-   LLVMExecutionEngineRef engine;
-   LLVMModuleProviderRef provider;
-   LLVMTargetDataRef target;
-   LLVMPassManagerRef pass;
-
+   /* LLVM JIT builder types */
    LLVMTypeRef context_ptr_type;
-   LLVMTypeRef vertex_header_ptr_type;
    LLVMTypeRef buffer_ptr_type;
    LLVMTypeRef vb_ptr_type;
+   LLVMTypeRef vertex_header_ptr_type;
 };
 
+
 static INLINE struct llvm_vertex_shader *
 llvm_vertex_shader(struct draw_vertex_shader *vs)
 {
@@ -269,7 +266,7 @@ llvm_vertex_shader(struct draw_vertex_shader *vs)
 
 
 struct draw_llvm *
-draw_llvm_create(struct draw_context *draw);
+draw_llvm_create(struct draw_context *draw, struct gallivm_state *gallivm);
 
 void
 draw_llvm_destroy(struct draw_llvm *llvm);
@@ -286,7 +283,7 @@ struct draw_llvm_variant_key *
 draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store);
 
 LLVMValueRef
-draw_llvm_translate_from(LLVMBuilderRef builder,
+draw_llvm_translate_from(struct gallivm_state *gallivm,
                          LLVMValueRef vbuffer,
                          enum pipe_format from_format);
 
index ac1fbb179c6b4a4b076d04d90d567557bc8e6035..574c7cc452f9d9d4c443ca9996d8a05ec45cd578 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "pipe/p_defines.h"
 #include "pipe/p_shader_tokens.h"
+#include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_debug.h"
 #include "gallivm/lp_bld_type.h"
 #include "gallivm/lp_bld_sample.h"
@@ -84,12 +85,13 @@ struct draw_llvm_sampler_soa
  */
 static LLVMValueRef
 draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
-                         LLVMBuilderRef builder,
+                         struct gallivm_state *gallivm,
                          unsigned unit,
                          unsigned member_index,
                          const char *member_name,
                          boolean emit_load)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct draw_llvm_sampler_dynamic_state *state =
       (struct draw_llvm_sampler_dynamic_state *)base;
    LLVMValueRef indices[4];
@@ -99,13 +101,13 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
    debug_assert(unit < PIPE_MAX_VERTEX_SAMPLERS);
 
    /* context[0] */
-   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indices[0] = lp_build_const_int32(gallivm, 0);
    /* context[0].textures */
-   indices[1] = LLVMConstInt(LLVMInt32Type(), DRAW_JIT_CTX_TEXTURES, 0);
+   indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_TEXTURES);
    /* context[0].textures[unit] */
-   indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+   indices[2] = lp_build_const_int32(gallivm, unit);
    /* context[0].textures[unit].member */
-   indices[3] = LLVMConstInt(LLVMInt32Type(), member_index, 0);
+   indices[3] = lp_build_const_int32(gallivm, member_index);
 
    ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
 
@@ -132,10 +134,10 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
 #define DRAW_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load)  \
    static LLVMValueRef \
    draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
-                              LLVMBuilderRef builder,                   \
+                              struct gallivm_state *gallivm,               \
                               unsigned unit)                            \
    { \
-      return draw_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
+      return draw_llvm_texture_member(base, gallivm, unit, _index, #_name, _emit_load ); \
    }
 
 
@@ -165,7 +167,7 @@ draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
  */
 static void
 draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
-                                       LLVMBuilderRef builder,
+                                       struct gallivm_state *gallivm,
                                        struct lp_type type,
                                        unsigned unit,
                                        unsigned num_coords,
@@ -180,7 +182,7 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
 
    assert(unit < PIPE_MAX_VERTEX_SAMPLERS);
 
-   lp_build_sample_soa(builder,
+   lp_build_sample_soa(gallivm,
                        &sampler->dynamic_state.static_state[unit],
                        &sampler->dynamic_state.base,
                        type,
index 5171327ce2d2e5ccb6572b629113dfbaa66dc0aa..77d0af7473351217fcf36d7944bfb018837e1bb0 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "draw_llvm.h"
 
+#include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_struct.h"
 #include "gallivm/lp_bld_format.h"
 #include "gallivm/lp_bld_debug.h"
 #define DRAW_DBG 0
 
 static  LLVMValueRef
-from_64_float(LLVMBuilderRef builder, LLVMValueRef val)
+from_64_float(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMDoubleType(), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   return LLVMBuildFPTrunc(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMDoubleTypeInContext(gallivm->context), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   return LLVMBuildFPTrunc(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 static LLVMValueRef
-from_32_float(LLVMBuilderRef builder, LLVMValueRef val)
+from_32_float(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMFloatType(), 0) , "");
-   return LLVMBuildLoad(builder, bc, "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0) , "");
+   return LLVMBuildLoad(gallivm->builder, bc, "");
 }
 
 static INLINE LLVMValueRef
-from_8_uscaled(LLVMBuilderRef builder, LLVMValueRef val)
+from_8_uscaled(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, val, "");
-   return LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, val, "");
+   return LLVMBuildUIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 static INLINE LLVMValueRef
-from_16_uscaled(LLVMBuilderRef builder, LLVMValueRef val)
+from_16_uscaled(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(16), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   return LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 16), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   return LLVMBuildUIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 static INLINE LLVMValueRef
-from_32_uscaled(LLVMBuilderRef builder, LLVMValueRef val)
+from_32_uscaled(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(32), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   return LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 32), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   return LLVMBuildUIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 static INLINE LLVMValueRef
-from_8_sscaled(LLVMBuilderRef builder, LLVMValueRef val)
+from_8_sscaled(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, val, "");
-   return LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, val, "");
+   return LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 static INLINE LLVMValueRef
-from_16_sscaled(LLVMBuilderRef builder, LLVMValueRef val)
+from_16_sscaled(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(16), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   return LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 16), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   return LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 static INLINE LLVMValueRef
-from_32_sscaled(LLVMBuilderRef builder, LLVMValueRef val)
+from_32_sscaled(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(32), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   return LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 32), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   return LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 }
 
 
 static INLINE LLVMValueRef
-from_8_unorm(LLVMBuilderRef builder, LLVMValueRef val)
+from_8_unorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, val, "");
-   LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 255.), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, val, "");
+   LLVMValueRef uscaled = LLVMBuildUIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 255.), "");
 }
 
 static INLINE LLVMValueRef
-from_16_unorm(LLVMBuilderRef builder, LLVMValueRef val)
+from_16_unorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(16), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 65535.), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 16), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   LLVMValueRef uscaled = LLVMBuildUIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 65535.), "");
 }
 
 static INLINE LLVMValueRef
-from_32_unorm(LLVMBuilderRef builder, LLVMValueRef val)
+from_32_unorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(32), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 32), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   LLVMValueRef uscaled = LLVMBuildUIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 4294967295.), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 4294967295.), "");
 }
 
 static INLINE LLVMValueRef
-from_8_snorm(LLVMBuilderRef builder, LLVMValueRef val)
+from_8_snorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, val, "");
-   LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 127.0), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, val, "");
+   LLVMValueRef uscaled = LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 127.0), "");
 }
 
 static INLINE LLVMValueRef
-from_16_snorm(LLVMBuilderRef builder, LLVMValueRef val)
+from_16_snorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(16), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 32767.0f), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 16), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   LLVMValueRef uscaled = LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 32767.0f), "");
 }
 
 static INLINE LLVMValueRef
-from_32_snorm(LLVMBuilderRef builder, LLVMValueRef val)
+from_32_snorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(32), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 32), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   LLVMValueRef uscaled = LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 2147483647.0), "");
 }
 
 static INLINE LLVMValueRef
-from_32_fixed(LLVMBuilderRef builder, LLVMValueRef val)
+from_32_fixed(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef bc = LLVMBuildBitCast(builder, val,
-                                      LLVMPointerType(LLVMIntType(32), 0) , "");
-   LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
-   LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
+   LLVMValueRef bc = LLVMBuildBitCast(gallivm->builder, val,
+                                      LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 32), 0) , "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, bc, "");
+   LLVMValueRef uscaled = LLVMBuildSIToFP(gallivm->builder, l, LLVMFloatTypeInContext(gallivm->context), "");
 
-   return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 65536.0), "");
+   return LLVMBuildFDiv(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 65536.0), "");
 }
 
 static LLVMValueRef
-to_64_float(LLVMBuilderRef builder, LLVMValueRef fp)
+to_64_float(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPExt(builder, l, LLVMDoubleType(), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPExt(gallivm->builder, l, LLVMDoubleTypeInContext(gallivm->context), "");
 }
 
 static LLVMValueRef
-to_32_float(LLVMBuilderRef builder, LLVMValueRef fp)
+to_32_float(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   return LLVMBuildLoad(builder, fp, "");
+   return LLVMBuildLoad(gallivm->builder, fp, "");
 }
 
 static INLINE LLVMValueRef
-to_8_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
+to_8_uscaled(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPToUI(builder, l, LLVMIntType(8), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPToUI(gallivm->builder, l, LLVMIntTypeInContext(gallivm->context, 8), "");
 }
 
 static INLINE LLVMValueRef
-to_16_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
+to_16_uscaled(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPToUI(builder, l, LLVMIntType(16), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPToUI(gallivm->builder, l, LLVMIntTypeInContext(gallivm->context, 16), "");
 }
 
 static INLINE LLVMValueRef
-to_32_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
+to_32_uscaled(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPToUI(gallivm->builder, l, LLVMIntTypeInContext(gallivm->context, 32), "");
 }
 
 static INLINE LLVMValueRef
-to_8_sscaled(LLVMBuilderRef builder, LLVMValueRef fp)
+to_8_sscaled(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPToSI(builder, l, LLVMIntType(8), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPToSI(gallivm->builder, l, LLVMIntTypeInContext(gallivm->context, 8), "");
 }
 
 static INLINE LLVMValueRef
-to_16_sscaled(LLVMBuilderRef builder, LLVMValueRef fp)
+to_16_sscaled(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPToSI(builder, l, LLVMIntType(16), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPToSI(gallivm->builder, l, LLVMIntTypeInContext(gallivm->context, 16), "");
 }
 
 static INLINE LLVMValueRef
-to_32_sscaled(LLVMBuilderRef builder, LLVMValueRef fp)
+to_32_sscaled(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   return LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   return LLVMBuildFPToSI(gallivm->builder, l, LLVMIntTypeInContext(gallivm->context, 32), "");
 }
 
 static INLINE LLVMValueRef
-to_8_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
+to_8_unorm(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(8), "");
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 255.), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   LLVMValueRef uscaled = LLVMBuildFPToUI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 8), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 255.), "");
 }
 
 static INLINE LLVMValueRef
-to_16_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
+to_16_unorm(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 65535.), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   LLVMValueRef uscaled = LLVMBuildFPToUI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 32), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 65535.), "");
 }
 
 static INLINE LLVMValueRef
-to_32_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
+to_32_unorm(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   LLVMValueRef uscaled = LLVMBuildFPToUI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 32), "");
 
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 4294967295.), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 4294967295.), "");
 }
 
 static INLINE LLVMValueRef
-to_8_snorm(LLVMBuilderRef builder, LLVMValueRef val)
+to_8_snorm(struct gallivm_state *gallivm, LLVMValueRef val)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, val, "");
-   LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(8), "");
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 127.0), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, val, "");
+   LLVMValueRef uscaled = LLVMBuildFPToSI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 8), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 127.0), "");
 }
 
 static INLINE LLVMValueRef
-to_16_snorm(LLVMBuilderRef builder, LLVMValueRef fp)
+to_16_snorm(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(16), "");
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 32767.0f), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   LLVMValueRef uscaled = LLVMBuildFPToSI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 16), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 32767.0f), "");
 }
 
 static INLINE LLVMValueRef
-to_32_snorm(LLVMBuilderRef builder, LLVMValueRef fp)
+to_32_snorm(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   LLVMValueRef uscaled = LLVMBuildFPToSI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 32), "");
 
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 2147483647.0), "");
 }
 
 static INLINE LLVMValueRef
-to_32_fixed(LLVMBuilderRef builder, LLVMValueRef fp)
+to_32_fixed(struct gallivm_state *gallivm, LLVMValueRef fp)
 {
-   LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
-   LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
+   LLVMValueRef l = LLVMBuildLoad(gallivm->builder, fp, "");
+   LLVMValueRef uscaled = LLVMBuildFPToSI(gallivm->builder, l,
+                                          LLVMIntTypeInContext(gallivm->context, 32), "");
 
-   return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(LLVMFloatType(), 65536.0), "");
+   return LLVMBuildFMul(gallivm->builder, uscaled,
+                        lp_build_const_float(gallivm, 65536.0), "");
 }
 
-typedef LLVMValueRef (*from_func)(LLVMBuilderRef, LLVMValueRef);
-typedef  LLVMValueRef (*to_func)(LLVMBuilderRef, LLVMValueRef);
+typedef LLVMValueRef (*from_func)(struct gallivm_state *, LLVMValueRef);
+typedef  LLVMValueRef (*to_func)(struct gallivm_state *, LLVMValueRef);
 
 /* so that underneath can avoid function calls which are prohibited
  * for static initialization we need this conversion */
@@ -294,21 +302,21 @@ enum ll_type {
 };
 
 static INLINE LLVMTypeRef
-ll_type_to_llvm(enum ll_type type)
+ll_type_to_llvm(struct gallivm_state *gallivm, enum ll_type type)
 {
    switch (type) {
    case LL_Double:
-      return LLVMDoubleType();
+      return LLVMDoubleTypeInContext(gallivm->context);
    case LL_Float:
-      return LLVMFloatType();
+      return LLVMFloatTypeInContext(gallivm->context);
    case LL_Int32:
-      return LLVMInt32Type();
+      return LLVMInt32TypeInContext(gallivm->context);
    case LL_Int16:
-      return LLVMIntType(16);
+      return LLVMIntTypeInContext(gallivm->context, 16);
    case LL_Int8:
-      return LLVMIntType(8);
+      return LLVMIntTypeInContext(gallivm->context, 8);
    }
-   return LLVMIntType(8);
+   return LLVMIntTypeInContext(gallivm->context, 8);
 }
 
 static INLINE int
@@ -414,42 +422,42 @@ struct draw_llvm_translate {
 
 
 static LLVMValueRef
-fetch(LLVMBuilderRef builder,
+fetch(struct gallivm_state *gallivm,
       LLVMValueRef ptr, int val_size, int nr_components,
       from_func func)
 {
    int i;
    int offset = 0;
-   LLVMValueRef res = LLVMConstNull(
-      LLVMVectorType(LLVMFloatType(), 4));
+   LLVMValueRef res =
+      LLVMConstNull(LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4));
    LLVMValueRef defaults[4];
 
-   defaults[0] = LLVMConstReal(LLVMFloatType(), 0);
-   defaults[1] = LLVMConstReal(LLVMFloatType(), 0);
-   defaults[2] = LLVMConstReal(LLVMFloatType(), 0);
-   defaults[3] = LLVMConstReal(LLVMFloatType(), 1);
+   defaults[0] =
+   defaults[1] =
+   defaults[2] = lp_build_const_float(gallivm, 0.0);
+   defaults[3] = lp_build_const_float(gallivm, 1.0);
 
    for (i = 0; i < nr_components; ++i) {
-      LLVMValueRef src_index = LLVMConstInt(LLVMInt32Type(), offset, 0);
-      LLVMValueRef dst_index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef src_index = lp_build_const_int32(gallivm, offset);
+      LLVMValueRef dst_index = lp_build_const_int32(gallivm, i);
       LLVMValueRef src_tmp;
       LLVMValueRef component;
 
-      src_tmp = LLVMBuildGEP(builder, ptr, &src_index, 1, "src_tmp");
+      src_tmp = LLVMBuildGEP(gallivm->builder, ptr, &src_index, 1, "src_tmp");
 
       /* convert src_tmp to float */
-      component = func(builder, src_tmp);
+      component = func(gallivm, src_tmp);
 
       /* vec.comp = component */
-      res = LLVMBuildInsertElement(builder,
+      res = LLVMBuildInsertElement(gallivm->builder,
                                    res,
                                    component,
                                    dst_index, "");
       offset += val_size;
    }
    for (; i < 4; ++i) {
-      LLVMValueRef dst_index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      res = LLVMBuildInsertElement(builder,
+      LLVMValueRef dst_index = lp_build_const_int32(gallivm, i);
+      res = LLVMBuildInsertElement(gallivm->builder,
                                    res,
                                    defaults[i],
                                    dst_index, "");
@@ -459,7 +467,7 @@ fetch(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-draw_llvm_translate_from(LLVMBuilderRef builder,
+draw_llvm_translate_from(struct gallivm_state *gallivm,
                          LLVMValueRef vbuffer,
                          enum pipe_format from_format)
 {
@@ -476,7 +484,7 @@ draw_llvm_translate_from(LLVMBuilderRef builder,
    for (i = 0; i < Elements(translates); ++i) {
       if (translates[i].format == from_format) {
          /*LLVMTypeRef type = ll_type_to_llvm(translates[i].type);*/
-         return fetch(builder,
+         return fetch(gallivm,
                       vbuffer,
                       ll_type_size(translates[i].type),
                       translates[i].num_components,
@@ -493,6 +501,6 @@ draw_llvm_translate_from(LLVMBuilderRef builder,
     */
 
    format_desc = util_format_description(from_format);
-   zero = LLVMConstNull(LLVMInt32Type());
-   return lp_build_fetch_rgba_aos(builder, format_desc, type, vbuffer, zero, zero, zero);
+   zero = LLVMConstNull(LLVMInt32TypeInContext(gallivm->context));
+   return lp_build_fetch_rgba_aos(gallivm, format_desc, type, vbuffer, zero, zero, zero);
 }
index d1aba763098e9e4977edd19a9aac74d5e0fa9bbb..0851b9acc0d4db457260fdcc14ba9095d1a589d0 100644 (file)
@@ -406,6 +406,7 @@ aaline_create_texture(struct aaline_stage *aaline)
    texTemp.width0 = 1 << MAX_TEXTURE_LEVEL;
    texTemp.height0 = 1 << MAX_TEXTURE_LEVEL;
    texTemp.depth0 = 1;
+   texTemp.array_size = 1;
    texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
 
    aaline->texture = screen->resource_create(screen, &texTemp);
@@ -441,10 +442,10 @@ aaline_create_texture(struct aaline_stage *aaline)
       /* This texture is new, no need to flush. 
        */
       transfer = pipe->get_transfer(pipe,
-                                   aaline->texture,
-                                   u_subresource(0, level), 
-                                   PIPE_TRANSFER_WRITE,
-                                   &box);
+                                    aaline->texture,
+                                    level,
+                                    PIPE_TRANSFER_WRITE,
+                                    &box);
 
       data = pipe->transfer_map(pipe, transfer);
       if (data == NULL)
index ed9a53e154dbe4bcf4aaff82dd98cf2c9afb7055..f5515c1df76c57161a7dc9cb6e5ce0b2010081e8 100644 (file)
@@ -393,8 +393,8 @@ pstip_update_texture(struct pstip_stage *pstip)
     */
    pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL );
 
-   transfer = pipe_get_transfer(pipe, pstip->texture, 0, 0, 0,
-                                   PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
+   transfer = pipe_get_transfer(pipe, pstip->texture, 0, 0,
+                                PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
    data = pipe->transfer_map(pipe, transfer);
 
    /*
@@ -440,6 +440,7 @@ pstip_create_texture(struct pstip_stage *pstip)
    texTemp.width0 = 32;
    texTemp.height0 = 32;
    texTemp.depth0 = 1;
+   texTemp.array_size = 1;
    texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
 
    pstip->texture = screen->resource_create(screen, &texTemp);
index 54163d7f9ebdcd59bd896d608410a4f24053a563..06ed4d60ef287c34d2ae2a3ffd9660db0f80cabe 100644 (file)
@@ -286,7 +286,6 @@ struct draw_context
 
 #ifdef HAVE_LLVM
    struct draw_llvm *llvm;
-   LLVMExecutionEngineRef engine;
 #endif
 
    struct pipe_sampler_view *sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
index a53a768d02990e4d4d4b6ac787f39ae2478dd913..2e3afb22c4867d0359d6cb11219ae894f946ba4c 100644 (file)
@@ -34,6 +34,7 @@
 #include "draw/draw_pt.h"
 #include "draw/draw_vs.h"
 #include "draw/draw_llvm.h"
+#include "gallivm/lp_bld_init.h"
 
 
 struct llvm_middle_end {
@@ -72,19 +73,18 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    struct draw_llvm_variant_list_item *li;
    unsigned i;
    unsigned instance_id_index = ~0;
-
-
-   unsigned out_prim = (draw->gs.geometry_shader ? 
-                        draw->gs.geometry_shader->output_primitive :
-                        in_prim);
+   const unsigned out_prim = (draw->gs.geometry_shader ? 
+                              draw->gs.geometry_shader->output_primitive :
+                              in_prim);
 
    /* Add one to num_outputs because the pipeline occasionally tags on
     * an additional texcoord, eg for AA lines.
     */
-   unsigned nr = MAX2( shader->base.info.num_inputs,
-                      shader->base.info.num_outputs + 1 );
+   const unsigned nr = MAX2( shader->base.info.num_inputs,
+                             shader->base.info.num_outputs + 1 );
 
    /* Scan for instanceID system value.
+    * XXX but we never use instance_id_index?!
     */
    for (i = 0; i < shader->base.info.num_inputs; i++) {
       if (shader->base.info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
@@ -133,9 +133,10 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    
    key = draw_llvm_make_variant_key(fpme->llvm, store);
 
+   /* Search shader's list of variants for the key */
    li = first_elem(&shader->variants);
-   while(!at_end(&shader->variants, li)) {
-      if(memcmp(&li->base->key, key, shader->variant_key_size) == 0) {
+   while (!at_end(&shader->variants, li)) {
+      if (memcmp(&li->base->key, key, shader->variant_key_size) == 0) {
          variant = li->base;
          break;
       }
@@ -143,10 +144,16 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    }
 
    if (variant) {
+      /* found the variant, move to head of global list (for LRU) */
       move_to_head(&fpme->llvm->vs_variants_list, &variant->list_item_global);
    }
    else {
+      /* Need to create new variant */
       unsigned i;
+
+      /* First check if we've created too many variants.  If so, free
+       * 25% of the LRU to avoid using too much memory.
+       */
       if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) {
          /*
           * XXX: should we flush here ?
@@ -422,7 +429,7 @@ draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw)
 {
    struct llvm_middle_end *fpme = 0;
 
-   if (!draw->engine)
+   if (!draw->llvm->gallivm->engine)
       return NULL;
 
    fpme = CALLOC_STRUCT( llvm_middle_end );
index fa9992db78324f9ffd2f6f595cc95c6a878530d7..de074be09264714acf59c64ac5473d54ca8555c7 100644 (file)
@@ -65,19 +65,7 @@ static void
 vs_llvm_delete( struct draw_vertex_shader *dvs )
 {
    struct llvm_vertex_shader *shader = llvm_vertex_shader(dvs);
-   struct pipe_fence_handle *fence = NULL;
    struct draw_llvm_variant_list_item *li;
-   struct pipe_context *pipe = dvs->draw->pipe;
-
-   /*
-    * XXX: This might be not neccessary at all.
-    */
-   pipe->flush(pipe, 0, &fence);
-   if (fence) {
-      pipe->screen->fence_finish(pipe->screen, fence, 0);
-      pipe->screen->fence_reference(pipe->screen, &fence, NULL);
-   }
-
 
    li = first_elem(&shader->variants);
    while(!at_end(&shader->variants, li)) {
index 8103bc917fc7f9d1a95f9e2b319c5c9cd2931445..ee05c6ba01d999ea271718dabc03d82d033c8ff8 100644 (file)
 #endif
 
 
+/**
+ * Redefine these LLVM entrypoints as invalid macros to make sure we
+ * don't accidentally use them.  We need to use the functions which
+ * take an explicit LLVMContextRef parameter.
+ */
+#define LLVMInt1Type ILLEGAL_LLVM_FUNCTION
+#define LLVMInt8Type ILLEGAL_LLVM_FUNCTION
+#define LLVMInt16Type ILLEGAL_LLVM_FUNCTION
+#define LLVMInt32Type ILLEGAL_LLVM_FUNCTION
+#define LLVMInt64Type ILLEGAL_LLVM_FUNCTION
+#define LLVMIntType ILLEGAL_LLVM_FUNCTION
+#define LLVMFloatType ILLEGAL_LLVM_FUNCTION
+#define LLVMDoubleType ILLEGAL_LLVM_FUNCTION
+#define LLVMX86FP80Type ILLEGAL_LLVM_FUNCTION
+#define LLVMFP128Type ILLEGAL_LLVM_FUNCTION
+#define LLVMPPCFP128Type ILLEGAL_LLVM_FUNCTION
+#define LLVMStructType ILLEGAL_LLVM_FUNCTION
+#define LLVMVoidType ILLEGAL_LLVM_FUNCTION
+#define LLVMLabelType ILLEGAL_LLVM_FUNCTION
+#define LLVMOpaqueType ILLEGAL_LLVM_FUNCTION
+#define LLVMUnionType ILLEGAL_LLVM_FUNCTION
+#define LLVMMDString ILLEGAL_LLVM_FUNCTION
+#define LLVMMDNode ILLEGAL_LLVM_FUNCTION
+#define LLVMConstString ILLEGAL_LLVM_FUNCTION
+#define LLVMConstStruct ILLEGAL_LLVM_FUNCTION
+#define LLVMAppendBasicBlock ILLEGAL_LLVM_FUNCTION
+#define LLVMInsertBasicBlock ILLEGAL_LLVM_FUNCTION
+#define LLVMCreateBuilder ILLEGAL_LLVM_FUNCTION
+
 #endif /* LP_BLD_H */
index f9a12a41a1b6c4d669a4305d106506594c610a14..02b3bde789398d9eee014211c0075ff36f433931 100644 (file)
@@ -53,6 +53,7 @@
 
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
 #include "lp_bld_intr.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_pack.h"
@@ -74,6 +75,7 @@ lp_build_min_simple(struct lp_build_context *bld,
                     LLVMValueRef a,
                     LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    const char *intrinsic = NULL;
    LLVMValueRef cond;
@@ -107,7 +109,7 @@ lp_build_min_simple(struct lp_build_context *bld,
    }
 
    if(intrinsic)
-      return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+      return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
 
    cond = lp_build_cmp(bld, PIPE_FUNC_LESS, a, b);
    return lp_build_select(bld, cond, a, b);
@@ -123,6 +125,7 @@ lp_build_max_simple(struct lp_build_context *bld,
                     LLVMValueRef a,
                     LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    const char *intrinsic = NULL;
    LLVMValueRef cond;
@@ -156,7 +159,7 @@ lp_build_max_simple(struct lp_build_context *bld,
    }
 
    if(intrinsic)
-      return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+      return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
 
    cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, b);
    return lp_build_select(bld, cond, a, b);
@@ -170,6 +173,7 @@ LLVMValueRef
 lp_build_comp(struct lp_build_context *bld,
               LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(lp_check_value(type, a));
@@ -183,7 +187,7 @@ lp_build_comp(struct lp_build_context *bld,
       if(LLVMIsConstant(a))
          return LLVMConstNot(a);
       else
-         return LLVMBuildNot(bld->builder, a, "");
+         return LLVMBuildNot(builder, a, "");
    }
 
    if(LLVMIsConstant(a))
@@ -193,9 +197,9 @@ lp_build_comp(struct lp_build_context *bld,
           return LLVMConstSub(bld->one, a);
    else
       if (type.floating)
-         return LLVMBuildFSub(bld->builder, bld->one, a, "");
+         return LLVMBuildFSub(builder, bld->one, a, "");
       else
-         return LLVMBuildSub(bld->builder, bld->one, a, "");
+         return LLVMBuildSub(builder, bld->one, a, "");
 }
 
 
@@ -207,6 +211,7 @@ lp_build_add(struct lp_build_context *bld,
              LLVMValueRef a,
              LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -236,7 +241,7 @@ lp_build_add(struct lp_build_context *bld,
       }
    
       if(intrinsic)
-         return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+         return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
    }
 
    if(LLVMIsConstant(a) && LLVMIsConstant(b))
@@ -246,9 +251,9 @@ lp_build_add(struct lp_build_context *bld,
          res = LLVMConstAdd(a, b);
    else
       if (type.floating)
-         res = LLVMBuildFAdd(bld->builder, a, b, "");
+         res = LLVMBuildFAdd(builder, a, b, "");
       else
-         res = LLVMBuildAdd(bld->builder, a, b, "");
+         res = LLVMBuildAdd(builder, a, b, "");
 
    /* clamp to ceiling of 1.0 */
    if(bld->type.norm && (bld->type.floating || bld->type.fixed))
@@ -265,6 +270,7 @@ LLVMValueRef
 lp_build_sum_vector(struct lp_build_context *bld,
                     LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef index, res;
    unsigned i;
@@ -277,19 +283,19 @@ lp_build_sum_vector(struct lp_build_context *bld,
 
    assert(!bld->type.norm);
 
-   index = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   res = LLVMBuildExtractElement(bld->builder, a, index, "");
+   index = lp_build_const_int32(bld->gallivm, 0);
+   res = LLVMBuildExtractElement(builder, a, index, "");
 
    for (i = 1; i < type.length; i++) {
-      index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      index = lp_build_const_int32(bld->gallivm, i);
       if (type.floating)
-         res = LLVMBuildFAdd(bld->builder, res,
-                            LLVMBuildExtractElement(bld->builder,
+         res = LLVMBuildFAdd(builder, res,
+                            LLVMBuildExtractElement(builder,
                                                     a, index, ""),
                             "");
       else
-         res = LLVMBuildAdd(bld->builder, res,
-                            LLVMBuildExtractElement(bld->builder,
+         res = LLVMBuildAdd(builder, res,
+                            LLVMBuildExtractElement(builder,
                                                     a, index, ""),
                             "");
    }
@@ -306,6 +312,7 @@ lp_build_sub(struct lp_build_context *bld,
              LLVMValueRef a,
              LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -335,7 +342,7 @@ lp_build_sub(struct lp_build_context *bld,
       }
    
       if(intrinsic)
-         return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+         return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
    }
 
    if(LLVMIsConstant(a) && LLVMIsConstant(b))
@@ -345,9 +352,9 @@ lp_build_sub(struct lp_build_context *bld,
          res = LLVMConstSub(a, b);
    else
       if (type.floating)
-         res = LLVMBuildFSub(bld->builder, a, b, "");
+         res = LLVMBuildFSub(builder, a, b, "");
       else
-         res = LLVMBuildSub(bld->builder, a, b, "");
+         res = LLVMBuildSub(builder, a, b, "");
 
    if(bld->type.norm && (bld->type.floating || bld->type.fixed))
       res = lp_build_max_simple(bld, res, bld->zero);
@@ -398,10 +405,11 @@ lp_build_sub(struct lp_build_context *bld,
  *     http://www.stereopsis.com/doubleblend.html
  */
 static LLVMValueRef
-lp_build_mul_u8n(LLVMBuilderRef builder,
+lp_build_mul_u8n(struct gallivm_state *gallivm,
                  struct lp_type i16_type,
                  LLVMValueRef a, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef c8;
    LLVMValueRef ab;
 
@@ -409,12 +417,12 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
    assert(lp_check_value(i16_type, a));
    assert(lp_check_value(i16_type, b));
 
-   c8 = lp_build_const_int_vec(i16_type, 8);
+   c8 = lp_build_const_int_vec(gallivm, i16_type, 8);
    
 #if 0
    
    /* a*b/255 ~= (a*(b + 1)) >> 256 */
-   b = LLVMBuildAdd(builder, b, lp_build_const_int_vec(i16_type, 1), "");
+   b = LLVMBuildAdd(builder, b, lp_build_const_int_vec(gallium, i16_type, 1), "");
    ab = LLVMBuildMul(builder, a, b, "");
 
 #else
@@ -422,7 +430,7 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
    /* ab/255 ~= (ab + (ab >> 8) + 0x80) >> 8 */
    ab = LLVMBuildMul(builder, a, b, "");
    ab = LLVMBuildAdd(builder, ab, LLVMBuildLShr(builder, ab, c8, ""), "");
-   ab = LLVMBuildAdd(builder, ab, lp_build_const_int_vec(i16_type, 0x80), "");
+   ab = LLVMBuildAdd(builder, ab, lp_build_const_int_vec(gallivm, i16_type, 0x80), "");
 
 #endif
    
@@ -440,6 +448,7 @@ lp_build_mul(struct lp_build_context *bld,
              LLVMValueRef a,
              LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef shift;
    LLVMValueRef res;
@@ -463,14 +472,14 @@ lp_build_mul(struct lp_build_context *bld,
          struct lp_type i16_type = lp_wider_type(type);
          LLVMValueRef al, ah, bl, bh, abl, abh, ab;
 
-         lp_build_unpack2(bld->builder, type, i16_type, a, &al, &ah);
-         lp_build_unpack2(bld->builder, type, i16_type, b, &bl, &bh);
+         lp_build_unpack2(bld->gallivm, type, i16_type, a, &al, &ah);
+         lp_build_unpack2(bld->gallivm, type, i16_type, b, &bl, &bh);
 
          /* PMULLW, PSRLW, PADDW */
-         abl = lp_build_mul_u8n(bld->builder, i16_type, al, bl);
-         abh = lp_build_mul_u8n(bld->builder, i16_type, ah, bh);
+         abl = lp_build_mul_u8n(bld->gallivm, i16_type, al, bl);
+         abh = lp_build_mul_u8n(bld->gallivm, i16_type, ah, bh);
 
-         ab = lp_build_pack2(bld->builder, i16_type, type, abl, abh);
+         ab = lp_build_pack2(bld->gallivm, i16_type, type, abl, abh);
          
          return ab;
       }
@@ -480,7 +489,7 @@ lp_build_mul(struct lp_build_context *bld,
    }
 
    if(type.fixed)
-      shift = lp_build_const_int_vec(type, type.width/2);
+      shift = lp_build_const_int_vec(bld->gallivm, type, type.width/2);
    else
       shift = NULL;
 
@@ -498,14 +507,14 @@ lp_build_mul(struct lp_build_context *bld,
    }
    else {
       if (type.floating)
-         res = LLVMBuildFMul(bld->builder, a, b, "");
+         res = LLVMBuildFMul(builder, a, b, "");
       else
-         res = LLVMBuildMul(bld->builder, a, b, "");
+         res = LLVMBuildMul(builder, a, b, "");
       if(shift) {
          if(type.sign)
-            res = LLVMBuildAShr(bld->builder, res, shift, "");
+            res = LLVMBuildAShr(builder, res, shift, "");
          else
-            res = LLVMBuildLShr(bld->builder, res, shift, "");
+            res = LLVMBuildLShr(builder, res, shift, "");
       }
    }
 
@@ -521,6 +530,7 @@ lp_build_mul_imm(struct lp_build_context *bld,
                  LLVMValueRef a,
                  int b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef factor;
 
    assert(lp_check_value(bld->type, a));
@@ -550,20 +560,20 @@ lp_build_mul_imm(struct lp_build_context *bld,
           * for Inf and NaN.
           */
          unsigned mantissa = lp_mantissa(bld->type);
-         factor = lp_build_const_int_vec(bld->type, (unsigned long long)shift << mantissa);
-         a = LLVMBuildBitCast(bld->builder, a, lp_build_int_vec_type(bld->type), "");
-         a = LLVMBuildAdd(bld->builder, a, factor, "");
-         a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(bld->type), "");
+         factor = lp_build_const_int_vec(bld->gallivm, bld->type, (unsigned long long)shift << mantissa);
+         a = LLVMBuildBitCast(builder, a, lp_build_int_vec_type(bld->type), "");
+         a = LLVMBuildAdd(builder, a, factor, "");
+         a = LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, bld->type), "");
          return a;
 #endif
       }
       else {
-         factor = lp_build_const_vec(bld->type, shift);
-         return LLVMBuildShl(bld->builder, a, factor, "");
+         factor = lp_build_const_vec(bld->gallivm, bld->type, shift);
+         return LLVMBuildShl(builder, a, factor, "");
       }
    }
 
-   factor = lp_build_const_vec(bld->type, (double)b);
+   factor = lp_build_const_vec(bld->gallivm, bld->type, (double)b);
    return lp_build_mul(bld, a, factor);
 }
 
@@ -576,6 +586,7 @@ lp_build_div(struct lp_build_context *bld,
              LLVMValueRef a,
              LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(lp_check_value(type, a));
@@ -605,11 +616,11 @@ lp_build_div(struct lp_build_context *bld,
       return lp_build_mul(bld, a, lp_build_rcp(bld, b));
 
    if (type.floating)
-      return LLVMBuildFDiv(bld->builder, a, b, "");
+      return LLVMBuildFDiv(builder, a, b, "");
    else if (type.sign)
-      return LLVMBuildSDiv(bld->builder, a, b, "");
+      return LLVMBuildSDiv(builder, a, b, "");
    else
-      return LLVMBuildUDiv(bld->builder, a, b, "");
+      return LLVMBuildUDiv(builder, a, b, "");
 }
 
 
@@ -624,6 +635,7 @@ lp_build_lerp_simple(struct lp_build_context *bld,
                      LLVMValueRef v0,
                      LLVMValueRef v1)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef delta;
    LLVMValueRef res;
 
@@ -642,7 +654,7 @@ lp_build_lerp_simple(struct lp_build_context *bld,
        * but it will be wrong for other uses. Basically we need a more
        * powerful lp_type, capable of further distinguishing the values
        * interpretation from the value storage. */
-      res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(bld->type, (1 << bld->type.width/2) - 1), "");
+      res = LLVMBuildAnd(builder, res, lp_build_const_int_vec(bld->gallivm, bld->type, (1 << bld->type.width/2) - 1), "");
    }
 
    return res;
@@ -658,6 +670,7 @@ lp_build_lerp(struct lp_build_context *bld,
               LLVMValueRef v0,
               LLVMValueRef v1)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -683,22 +696,22 @@ lp_build_lerp(struct lp_build_context *bld,
       wide_type.width  = type.width*2;
       wide_type.length = type.length/2;
 
-      lp_build_context_init(&wide_bld, bld->builder, wide_type);
+      lp_build_context_init(&wide_bld, bld->gallivm, wide_type);
 
-      lp_build_unpack2(bld->builder, type, wide_type, x,  &xl,  &xh);
-      lp_build_unpack2(bld->builder, type, wide_type, v0, &v0l, &v0h);
-      lp_build_unpack2(bld->builder, type, wide_type, v1, &v1l, &v1h);
+      lp_build_unpack2(bld->gallivm, type, wide_type, x,  &xl,  &xh);
+      lp_build_unpack2(bld->gallivm, type, wide_type, v0, &v0l, &v0h);
+      lp_build_unpack2(bld->gallivm, type, wide_type, v1, &v1l, &v1h);
 
       /*
        * Scale x from [0, 255] to [0, 256]
        */
 
-      shift = lp_build_const_int_vec(wide_type, type.width - 1);
+      shift = lp_build_const_int_vec(bld->gallivm, wide_type, type.width - 1);
 
       xl = lp_build_add(&wide_bld, xl,
-                        LLVMBuildAShr(bld->builder, xl, shift, ""));
+                        LLVMBuildAShr(builder, xl, shift, ""));
       xh = lp_build_add(&wide_bld, xh,
-                        LLVMBuildAShr(bld->builder, xh, shift, ""));
+                        LLVMBuildAShr(builder, xh, shift, ""));
 
       /*
        * Lerp both halves.
@@ -707,7 +720,7 @@ lp_build_lerp(struct lp_build_context *bld,
       resl = lp_build_lerp_simple(&wide_bld, xl, v0l, v1l);
       resh = lp_build_lerp_simple(&wide_bld, xh, v0h, v1h);
 
-      res = lp_build_pack2(bld->builder, wide_type, type, resl, resh);
+      res = lp_build_pack2(bld->gallivm, wide_type, type, resl, resh);
    } else {
       res = lp_build_lerp_simple(bld, x, v0, v1);
    }
@@ -820,8 +833,9 @@ LLVMValueRef
 lp_build_abs(struct lp_build_context *bld,
              LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
 
    assert(lp_check_value(type, a));
 
@@ -830,27 +844,27 @@ lp_build_abs(struct lp_build_context *bld,
 
    if(type.floating) {
       /* Mask out the sign bit */
-      LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
       unsigned long long absMask = ~(1ULL << (type.width - 1));
-      LLVMValueRef mask = lp_build_const_int_vec(type, ((unsigned long long) absMask));
-      a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
-      a = LLVMBuildAnd(bld->builder, a, mask, "");
-      a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
+      LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type, ((unsigned long long) absMask));
+      a = LLVMBuildBitCast(builder, a, int_vec_type, "");
+      a = LLVMBuildAnd(builder, a, mask, "");
+      a = LLVMBuildBitCast(builder, a, vec_type, "");
       return a;
    }
 
    if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) {
       switch(type.width) {
       case 8:
-         return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.b.128", vec_type, a);
+         return lp_build_intrinsic_unary(builder, "llvm.x86.ssse3.pabs.b.128", vec_type, a);
       case 16:
-         return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.w.128", vec_type, a);
+         return lp_build_intrinsic_unary(builder, "llvm.x86.ssse3.pabs.w.128", vec_type, a);
       case 32:
-         return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.d.128", vec_type, a);
+         return lp_build_intrinsic_unary(builder, "llvm.x86.ssse3.pabs.d.128", vec_type, a);
       }
    }
 
-   return lp_build_max(bld, a, LLVMBuildNeg(bld->builder, a, ""));
+   return lp_build_max(bld, a, LLVMBuildNeg(builder, a, ""));
 }
 
 
@@ -858,14 +872,16 @@ LLVMValueRef
 lp_build_negate(struct lp_build_context *bld,
                 LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
+
    assert(lp_check_value(bld->type, a));
 
 #if HAVE_LLVM >= 0x0207
    if (bld->type.floating)
-      a = LLVMBuildFNeg(bld->builder, a, "");
+      a = LLVMBuildFNeg(builder, a, "");
    else
 #endif
-      a = LLVMBuildNeg(bld->builder, a, "");
+      a = LLVMBuildNeg(builder, a, "");
 
    return a;
 }
@@ -876,6 +892,7 @@ LLVMValueRef
 lp_build_sgn(struct lp_build_context *bld,
              LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef cond;
    LLVMValueRef res;
@@ -895,20 +912,20 @@ lp_build_sgn(struct lp_build_context *bld,
       LLVMValueRef one;
       unsigned long long maskBit = (unsigned long long)1 << (type.width - 1);
 
-      int_type = lp_build_int_vec_type(type);
-      vec_type = lp_build_vec_type(type);
-      mask = lp_build_const_int_vec(type, maskBit);
+      int_type = lp_build_int_vec_type(bld->gallivm, type);
+      vec_type = lp_build_vec_type(bld->gallivm, type);
+      mask = lp_build_const_int_vec(bld->gallivm, type, maskBit);
 
       /* Take the sign bit and add it to 1 constant */
-      sign = LLVMBuildBitCast(bld->builder, a, int_type, "");
-      sign = LLVMBuildAnd(bld->builder, sign, mask, "");
+      sign = LLVMBuildBitCast(builder, a, int_type, "");
+      sign = LLVMBuildAnd(builder, sign, mask, "");
       one = LLVMConstBitCast(bld->one, int_type);
-      res = LLVMBuildOr(bld->builder, sign, one, "");
-      res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+      res = LLVMBuildOr(builder, sign, one, "");
+      res = LLVMBuildBitCast(builder, res, vec_type, "");
    }
    else
    {
-      LLVMValueRef minus_one = lp_build_const_vec(type, -1.0);
+      LLVMValueRef minus_one = lp_build_const_vec(bld->gallivm, type, -1.0);
       cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero);
       res = lp_build_select(bld, cond, bld->one, minus_one);
    }
@@ -931,11 +948,12 @@ LLVMValueRef
 lp_build_set_sign(struct lp_build_context *bld,
                   LLVMValueRef a, LLVMValueRef sign)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
-   LLVMValueRef shift = lp_build_const_int_vec(type, type.width - 1);
-   LLVMValueRef mask = lp_build_const_int_vec(type,
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+   LLVMValueRef shift = lp_build_const_int_vec(bld->gallivm, type, type.width - 1);
+   LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type,
                              ~((unsigned long long) 1 << (type.width - 1)));
    LLVMValueRef val, res;
 
@@ -943,15 +961,15 @@ lp_build_set_sign(struct lp_build_context *bld,
    assert(lp_check_value(type, a));
 
    /* val = reinterpret_cast<int>(a) */
-   val = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+   val = LLVMBuildBitCast(builder, a, int_vec_type, "");
    /* val = val & mask */
-   val = LLVMBuildAnd(bld->builder, val, mask, "");
+   val = LLVMBuildAnd(builder, val, mask, "");
    /* sign = sign << shift */
-   sign = LLVMBuildShl(bld->builder, sign, shift, "");
+   sign = LLVMBuildShl(builder, sign, shift, "");
    /* res = val | sign */
-   res = LLVMBuildOr(bld->builder, val, sign, "");
+   res = LLVMBuildOr(builder, val, sign, "");
    /* res = reinterpret_cast<float>(res) */
-   res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+   res = LLVMBuildBitCast(builder, res, vec_type, "");
 
    return res;
 }
@@ -964,12 +982,13 @@ LLVMValueRef
 lp_build_int_to_float(struct lp_build_context *bld,
                       LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
 
    assert(type.floating);
 
-   return LLVMBuildSIToFP(bld->builder, a, vec_type, "");
+   return LLVMBuildSIToFP(builder, a, vec_type, "");
 }
 
 
@@ -994,8 +1013,9 @@ lp_build_round_sse41(struct lp_build_context *bld,
                      LLVMValueRef a,
                      enum lp_build_round_sse41_mode mode)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef i32t = LLVMInt32Type();
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(bld->gallivm->context);
    const char *intrinsic;
    LLVMValueRef res;
 
@@ -1027,13 +1047,13 @@ lp_build_round_sse41(struct lp_build_context *bld,
       undef = LLVMGetUndef(vec_type);
 
       args[0] = undef;
-      args[1] = LLVMBuildInsertElement(bld->builder, undef, a, index0, "");
+      args[1] = LLVMBuildInsertElement(builder, undef, a, index0, "");
       args[2] = LLVMConstInt(i32t, mode, 0);
 
-      res = lp_build_intrinsic(bld->builder, intrinsic,
+      res = lp_build_intrinsic(builder, intrinsic,
                                vec_type, args, Elements(args));
 
-      res = LLVMBuildExtractElement(bld->builder, res, index0, "");
+      res = LLVMBuildExtractElement(builder, res, index0, "");
    }
    else {
       assert(type.width*type.length == 128);
@@ -1050,7 +1070,7 @@ lp_build_round_sse41(struct lp_build_context *bld,
          return bld->undef;
       }
 
-      res = lp_build_intrinsic_binary(bld->builder, intrinsic,
+      res = lp_build_intrinsic_binary(builder, intrinsic,
                                       bld->vec_type, a,
                                       LLVMConstInt(i32t, mode, 0));
    }
@@ -1063,9 +1083,10 @@ static INLINE LLVMValueRef
 lp_build_iround_nearest_sse2(struct lp_build_context *bld,
                              LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef i32t = LLVMInt32Type();
-   LLVMTypeRef ret_type = lp_build_int_vec_type(type);
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(bld->gallivm->context);
+   LLVMTypeRef ret_type = lp_build_int_vec_type(bld->gallivm, type);
    const char *intrinsic;
    LLVMValueRef res;
 
@@ -1089,9 +1110,9 @@ lp_build_iround_nearest_sse2(struct lp_build_context *bld,
 
       undef = LLVMGetUndef(vec_type);
 
-      arg = LLVMBuildInsertElement(bld->builder, undef, a, index0, "");
+      arg = LLVMBuildInsertElement(builder, undef, a, index0, "");
 
-      res = lp_build_intrinsic_unary(bld->builder, intrinsic,
+      res = lp_build_intrinsic_unary(builder, intrinsic,
                                      ret_type, arg);
    }
    else {
@@ -1099,7 +1120,7 @@ lp_build_iround_nearest_sse2(struct lp_build_context *bld,
 
       intrinsic = "llvm.x86.sse2.cvtps2dq";
 
-      res = lp_build_intrinsic_unary(bld->builder, intrinsic,
+      res = lp_build_intrinsic_unary(builder, intrinsic,
                                      ret_type, a);
    }
 
@@ -1116,6 +1137,7 @@ LLVMValueRef
 lp_build_trunc(struct lp_build_context *bld,
                LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(type.floating);
@@ -1126,11 +1148,11 @@ lp_build_trunc(struct lp_build_context *bld,
       return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE);
    }
    else {
-      LLVMTypeRef vec_type = lp_build_vec_type(type);
-      LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
       LLVMValueRef res;
-      res = LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
-      res = LLVMBuildSIToFP(bld->builder, res, vec_type, "");
+      res = LLVMBuildFPToSI(builder, a, int_vec_type, "");
+      res = LLVMBuildSIToFP(builder, res, vec_type, "");
       return res;
    }
 }
@@ -1146,6 +1168,7 @@ LLVMValueRef
 lp_build_round(struct lp_build_context *bld,
                LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(type.floating);
@@ -1156,10 +1179,10 @@ lp_build_round(struct lp_build_context *bld,
       return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST);
    }
    else {
-      LLVMTypeRef vec_type = lp_build_vec_type(type);
+      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
       LLVMValueRef res;
       res = lp_build_iround(bld, a);
-      res = LLVMBuildSIToFP(bld->builder, res, vec_type, "");
+      res = LLVMBuildSIToFP(builder, res, vec_type, "");
       return res;
    }
 }
@@ -1174,6 +1197,7 @@ LLVMValueRef
 lp_build_floor(struct lp_build_context *bld,
                LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(type.floating);
@@ -1184,10 +1208,10 @@ lp_build_floor(struct lp_build_context *bld,
       return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR);
    }
    else {
-      LLVMTypeRef vec_type = lp_build_vec_type(type);
+      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
       LLVMValueRef res;
       res = lp_build_ifloor(bld, a);
-      res = LLVMBuildSIToFP(bld->builder, res, vec_type, "");
+      res = LLVMBuildSIToFP(builder, res, vec_type, "");
       return res;
    }
 }
@@ -1202,6 +1226,7 @@ LLVMValueRef
 lp_build_ceil(struct lp_build_context *bld,
               LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(type.floating);
@@ -1212,10 +1237,10 @@ lp_build_ceil(struct lp_build_context *bld,
       return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL);
    }
    else {
-      LLVMTypeRef vec_type = lp_build_vec_type(type);
+      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
       LLVMValueRef res;
       res = lp_build_iceil(bld, a);
-      res = LLVMBuildSIToFP(bld->builder, res, vec_type, "");
+      res = LLVMBuildSIToFP(builder, res, vec_type, "");
       return res;
    }
 }
@@ -1243,13 +1268,14 @@ LLVMValueRef
 lp_build_itrunc(struct lp_build_context *bld,
                 LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
 
    assert(type.floating);
    assert(lp_check_value(type, a));
 
-   return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
+   return LLVMBuildFPToSI(builder, a, int_vec_type, "");
 }
 
 
@@ -1263,6 +1289,7 @@ LLVMValueRef
 lp_build_iround(struct lp_build_context *bld,
                 LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMTypeRef int_vec_type = bld->int_vec_type;
    LLVMValueRef res;
@@ -1282,27 +1309,28 @@ lp_build_iround(struct lp_build_context *bld,
    else {
       LLVMValueRef half;
 
-      half = lp_build_const_vec(type, 0.5);
+      half = lp_build_const_vec(bld->gallivm, type, 0.5);
 
       if (type.sign) {
          LLVMTypeRef vec_type = bld->vec_type;
-         LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
+         LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type,
+                                    (unsigned long long)1 << (type.width - 1));
          LLVMValueRef sign;
 
          /* get sign bit */
-         sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
-         sign = LLVMBuildAnd(bld->builder, sign, mask, "");
+         sign = LLVMBuildBitCast(builder, a, int_vec_type, "");
+         sign = LLVMBuildAnd(builder, sign, mask, "");
 
          /* sign * 0.5 */
-         half = LLVMBuildBitCast(bld->builder, half, int_vec_type, "");
-         half = LLVMBuildOr(bld->builder, sign, half, "");
-         half = LLVMBuildBitCast(bld->builder, half, vec_type, "");
+         half = LLVMBuildBitCast(builder, half, int_vec_type, "");
+         half = LLVMBuildOr(builder, sign, half, "");
+         half = LLVMBuildBitCast(builder, half, vec_type, "");
       }
 
-      res = LLVMBuildFAdd(bld->builder, a, half, "");
+      res = LLVMBuildFAdd(builder, a, half, "");
    }
 
-   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "");
+   res = LLVMBuildFPToSI(builder, res, int_vec_type, "");
 
    return res;
 }
@@ -1317,6 +1345,7 @@ LLVMValueRef
 lp_build_ifloor(struct lp_build_context *bld,
                 LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMTypeRef int_vec_type = bld->int_vec_type;
    LLVMValueRef res;
@@ -1335,29 +1364,34 @@ lp_build_ifloor(struct lp_build_context *bld,
          /* Take the sign bit and add it to 1 constant */
          LLVMTypeRef vec_type = bld->vec_type;
          unsigned mantissa = lp_mantissa(type);
-         LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
+         LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type,
+                                  (unsigned long long)1 << (type.width - 1));
          LLVMValueRef sign;
          LLVMValueRef offset;
 
          /* sign = a < 0 ? ~0 : 0 */
-         sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
-         sign = LLVMBuildAnd(bld->builder, sign, mask, "");
-         sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "ifloor.sign");
+         sign = LLVMBuildBitCast(builder, a, int_vec_type, "");
+         sign = LLVMBuildAnd(builder, sign, mask, "");
+         sign = LLVMBuildAShr(builder, sign,
+                              lp_build_const_int_vec(bld->gallivm, type,
+                                                     type.width - 1),
+                              "ifloor.sign");
 
          /* offset = -0.99999(9)f */
-         offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
+         offset = lp_build_const_vec(bld->gallivm, type,
+                                     -(double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
          offset = LLVMConstBitCast(offset, int_vec_type);
 
          /* offset = a < 0 ? offset : 0.0f */
-         offset = LLVMBuildAnd(bld->builder, offset, sign, "");
-         offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "ifloor.offset");
+         offset = LLVMBuildAnd(builder, offset, sign, "");
+         offset = LLVMBuildBitCast(builder, offset, vec_type, "ifloor.offset");
 
-         res = LLVMBuildFAdd(bld->builder, res, offset, "ifloor.res");
+         res = LLVMBuildFAdd(builder, res, offset, "ifloor.res");
       }
    }
 
    /* round to nearest (toward zero) */
-   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "ifloor.res");
+   res = LLVMBuildFPToSI(builder, res, int_vec_type, "ifloor.res");
 
    return res;
 }
@@ -1372,6 +1406,7 @@ LLVMValueRef
 lp_build_iceil(struct lp_build_context *bld,
                LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMTypeRef int_vec_type = bld->int_vec_type;
    LLVMValueRef res;
@@ -1389,29 +1424,34 @@ lp_build_iceil(struct lp_build_context *bld,
       LLVMValueRef offset;
 
       /* offset = 0.99999(9)f */
-      offset = lp_build_const_vec(type, (double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
+      offset = lp_build_const_vec(bld->gallivm, type,
+                                  (double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
 
       if (type.sign) {
-         LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
+         LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type,
+                                (unsigned long long)1 << (type.width - 1));
          LLVMValueRef sign;
 
          /* sign = a < 0 ? 0 : ~0 */
-         sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
-         sign = LLVMBuildAnd(bld->builder, sign, mask, "");
-         sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "iceil.sign");
-         sign = LLVMBuildNot(bld->builder, sign, "iceil.not");
+         sign = LLVMBuildBitCast(builder, a, int_vec_type, "");
+         sign = LLVMBuildAnd(builder, sign, mask, "");
+         sign = LLVMBuildAShr(builder, sign,
+                              lp_build_const_int_vec(bld->gallivm, type,
+                                                     type.width - 1),
+                              "iceil.sign");
+         sign = LLVMBuildNot(builder, sign, "iceil.not");
 
          /* offset = a < 0 ? 0.0 : offset */
          offset = LLVMConstBitCast(offset, int_vec_type);
-         offset = LLVMBuildAnd(bld->builder, offset, sign, "");
-         offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "iceil.offset");
+         offset = LLVMBuildAnd(builder, offset, sign, "");
+         offset = LLVMBuildBitCast(builder, offset, vec_type, "iceil.offset");
       }
 
-      res = LLVMBuildFAdd(bld->builder, a, offset, "iceil.res");
+      res = LLVMBuildFAdd(builder, a, offset, "iceil.res");
    }
 
    /* round to nearest (toward zero) */
-   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "iceil.res");
+   res = LLVMBuildFPToSI(builder, res, int_vec_type, "iceil.res");
 
    return res;
 }
@@ -1429,6 +1469,7 @@ lp_build_ifloor_fract(struct lp_build_context *bld,
                       LLVMValueRef *out_ipart,
                       LLVMValueRef *out_fpart)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef ipart;
 
@@ -1442,8 +1483,8 @@ lp_build_ifloor_fract(struct lp_build_context *bld,
        */
 
       ipart = lp_build_floor(bld, a);
-      *out_fpart = LLVMBuildFSub(bld->builder, a, ipart, "fpart");
-      *out_ipart = LLVMBuildFPToSI(bld->builder, ipart, bld->int_vec_type, "ipart");
+      *out_fpart = LLVMBuildFSub(builder, a, ipart, "fpart");
+      *out_ipart = LLVMBuildFPToSI(builder, ipart, bld->int_vec_type, "ipart");
    }
    else {
       /*
@@ -1451,8 +1492,8 @@ lp_build_ifloor_fract(struct lp_build_context *bld,
        */
 
       *out_ipart = lp_build_ifloor(bld, a);
-      ipart = LLVMBuildSIToFP(bld->builder, *out_ipart, bld->vec_type, "ipart");
-      *out_fpart = LLVMBuildFSub(bld->builder, a, ipart, "fpart");
+      ipart = LLVMBuildSIToFP(builder, *out_ipart, bld->vec_type, "ipart");
+      *out_fpart = LLVMBuildFSub(builder, a, ipart, "fpart");
    }
 }
 
@@ -1461,8 +1502,9 @@ LLVMValueRef
 lp_build_sqrt(struct lp_build_context *bld,
               LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
    char intrinsic[32];
 
    assert(lp_check_value(type, a));
@@ -1473,7 +1515,7 @@ lp_build_sqrt(struct lp_build_context *bld,
    assert(type.floating);
    util_snprintf(intrinsic, sizeof intrinsic, "llvm.sqrt.v%uf%u", type.length, type.width);
 
-   return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a);
+   return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
 }
 
 
@@ -1496,12 +1538,13 @@ lp_build_rcp_refine(struct lp_build_context *bld,
                     LLVMValueRef a,
                     LLVMValueRef rcp_a)
 {
-   LLVMValueRef two = lp_build_const_vec(bld->type, 2.0);
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMValueRef two = lp_build_const_vec(bld->gallivm, bld->type, 2.0);
    LLVMValueRef res;
 
-   res = LLVMBuildFMul(bld->builder, a, rcp_a, "");
-   res = LLVMBuildFSub(bld->builder, two, res, "");
-   res = LLVMBuildFMul(bld->builder, rcp_a, res, "");
+   res = LLVMBuildFMul(builder, a, rcp_a, "");
+   res = LLVMBuildFSub(builder, two, res, "");
+   res = LLVMBuildFMul(builder, rcp_a, res, "");
 
    return res;
 }
@@ -1511,6 +1554,7 @@ LLVMValueRef
 lp_build_rcp(struct lp_build_context *bld,
              LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(lp_check_value(type, a));
@@ -1545,7 +1589,7 @@ lp_build_rcp(struct lp_build_context *bld,
       LLVMValueRef res;
       unsigned i;
 
-      res = lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", bld->vec_type, a);
+      res = lp_build_intrinsic_unary(builder, "llvm.x86.sse.rcp.ps", bld->vec_type, a);
 
       for (i = 0; i < num_iterations; ++i) {
          res = lp_build_rcp_refine(bld, a, res);
@@ -1554,7 +1598,7 @@ lp_build_rcp(struct lp_build_context *bld,
       return res;
    }
 
-   return LLVMBuildFDiv(bld->builder, bld->one, a, "");
+   return LLVMBuildFDiv(builder, bld->one, a, "");
 }
 
 
@@ -1571,15 +1615,16 @@ lp_build_rsqrt_refine(struct lp_build_context *bld,
                       LLVMValueRef a,
                       LLVMValueRef rsqrt_a)
 {
-   LLVMValueRef half = lp_build_const_vec(bld->type, 0.5);
-   LLVMValueRef three = lp_build_const_vec(bld->type, 3.0);
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMValueRef half = lp_build_const_vec(bld->gallivm, bld->type, 0.5);
+   LLVMValueRef three = lp_build_const_vec(bld->gallivm, bld->type, 3.0);
    LLVMValueRef res;
 
-   res = LLVMBuildFMul(bld->builder, rsqrt_a, rsqrt_a, "");
-   res = LLVMBuildFMul(bld->builder, a, res, "");
-   res = LLVMBuildFSub(bld->builder, three, res, "");
-   res = LLVMBuildFMul(bld->builder, rsqrt_a, res, "");
-   res = LLVMBuildFMul(bld->builder, half, res, "");
+   res = LLVMBuildFMul(builder, rsqrt_a, rsqrt_a, "");
+   res = LLVMBuildFMul(builder, a, res, "");
+   res = LLVMBuildFSub(builder, three, res, "");
+   res = LLVMBuildFMul(builder, rsqrt_a, res, "");
+   res = LLVMBuildFMul(builder, half, res, "");
 
    return res;
 }
@@ -1592,6 +1637,7 @@ LLVMValueRef
 lp_build_rsqrt(struct lp_build_context *bld,
                LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(lp_check_value(type, a));
@@ -1603,7 +1649,7 @@ lp_build_rsqrt(struct lp_build_context *bld,
       LLVMValueRef res;
       unsigned i;
 
-      res = lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rsqrt.ps", bld->vec_type, a);
+      res = lp_build_intrinsic_unary(builder, "llvm.x86.sse.rsqrt.ps", bld->vec_type, a);
 
       for (i = 0; i < num_iterations; ++i) {
          res = lp_build_rsqrt_refine(bld, a, res);
@@ -1617,17 +1663,17 @@ lp_build_rsqrt(struct lp_build_context *bld,
 
 
 static inline LLVMValueRef
-lp_build_const_v4si(unsigned long value)
+lp_build_const_v4si(struct gallivm_state *gallivm, unsigned long value)
 {
-   LLVMValueRef element = LLVMConstInt(LLVMInt32Type(), value, 0);
+   LLVMValueRef element = lp_build_const_int32(gallivm, value);
    LLVMValueRef elements[4] = { element, element, element, element };
    return LLVMConstVector(elements, 4);
 }
 
 static inline LLVMValueRef
-lp_build_const_v4sf(float value)
+lp_build_const_v4sf(struct gallivm_state *gallivm, float value)
 {
-   LLVMValueRef element = LLVMConstReal(LLVMFloatType(), value);
+   LLVMValueRef element = lp_build_const_float(gallivm, value);
    LLVMValueRef elements[4] = { element, element, element, element };
    return LLVMConstVector(elements, 4);
 }
@@ -1640,17 +1686,19 @@ LLVMValueRef
 lp_build_sin(struct lp_build_context *bld,
              LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   struct gallivm_state *gallivm = bld->gallivm;
    struct lp_type int_type = lp_int_type(bld->type);
-   LLVMBuilderRef b = bld->builder;
-   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
-   LLVMTypeRef v4si = LLVMVectorType(LLVMInt32Type(), 4);
+   LLVMBuilderRef b = builder;
+   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatTypeInContext(bld->gallivm->context), 4);
+   LLVMTypeRef v4si = LLVMVectorType(LLVMInt32TypeInContext(bld->gallivm->context), 4);
 
    /*
     *  take the absolute value,
     *  x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
     */
 
-   LLVMValueRef inv_sig_mask = lp_build_const_v4si(~0x80000000);
+   LLVMValueRef inv_sig_mask = lp_build_const_v4si(bld->gallivm, ~0x80000000);
    LLVMValueRef a_v4si = LLVMBuildBitCast(b, a, v4si, "a_v4si");
 
    LLVMValueRef absi = LLVMBuildAnd(b, a_v4si, inv_sig_mask, "absi");
@@ -1660,7 +1708,7 @@ lp_build_sin(struct lp_build_context *bld,
     * extract the sign bit (upper one)
     * sign_bit = _mm_and_ps(sign_bit, *(v4sf*)_ps_sign_mask);
     */
-   LLVMValueRef sig_mask = lp_build_const_v4si(0x80000000);
+   LLVMValueRef sig_mask = lp_build_const_v4si(bld->gallivm, 0x80000000);
    LLVMValueRef sign_bit_i = LLVMBuildAnd(b, a_v4si, sig_mask, "sign_bit_i");
 
    /*
@@ -1668,7 +1716,7 @@ lp_build_sin(struct lp_build_context *bld,
     * y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
     */
    
-   LLVMValueRef FOPi = lp_build_const_v4sf(1.27323954473516);
+   LLVMValueRef FOPi = lp_build_const_v4sf(gallivm, 1.27323954473516);
    LLVMValueRef scale_y = LLVMBuildFMul(b, x_abs, FOPi, "scale_y");
 
    /*
@@ -1683,12 +1731,12 @@ lp_build_sin(struct lp_build_context *bld,
     * emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
     */
 
-   LLVMValueRef all_one = lp_build_const_v4si(1);
+   LLVMValueRef all_one = lp_build_const_v4si(bld->gallivm, 1);
    LLVMValueRef emm2_add =  LLVMBuildAdd(b, emm2_i, all_one, "emm2_add");
    /*
     * emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
     */
-   LLVMValueRef inv_one = lp_build_const_v4si(~1);
+   LLVMValueRef inv_one = lp_build_const_v4si(bld->gallivm, ~1);
    LLVMValueRef emm2_and =  LLVMBuildAnd(b, emm2_add, inv_one, "emm2_and");
 
    /*
@@ -1699,13 +1747,13 @@ lp_build_sin(struct lp_build_context *bld,
    /* get the swap sign flag
     * emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4);
     */
-   LLVMValueRef pi32_4 = lp_build_const_v4si(4);
+   LLVMValueRef pi32_4 = lp_build_const_v4si(bld->gallivm, 4);
    LLVMValueRef emm0_and =  LLVMBuildAnd(b, emm2_add, pi32_4, "emm0_and");
    
    /*
     * emm2 = _mm_slli_epi32(emm0, 29);
     */  
-   LLVMValueRef const_29 = lp_build_const_v4si(29);
+   LLVMValueRef const_29 = lp_build_const_v4si(bld->gallivm, 29);
    LLVMValueRef swap_sign_bit = LLVMBuildShl(b, emm0_and, const_29, "swap_sign_bit");
 
    /*
@@ -1718,10 +1766,11 @@ lp_build_sin(struct lp_build_context *bld,
     * emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
     */
 
-   LLVMValueRef pi32_2 = lp_build_const_v4si(2);
+   LLVMValueRef pi32_2 = lp_build_const_v4si(bld->gallivm, 2);
    LLVMValueRef emm2_3 =  LLVMBuildAnd(b, emm2_and, pi32_2, "emm2_3");
-   LLVMValueRef poly_mask = lp_build_compare(b, int_type, PIPE_FUNC_EQUAL,
-                                             emm2_3, lp_build_const_v4si(0));
+   LLVMValueRef poly_mask = lp_build_compare(bld->gallivm,
+                                             int_type, PIPE_FUNC_EQUAL,
+                                             emm2_3, lp_build_const_v4si(bld->gallivm, 0));
    /*
     *   sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
     */
@@ -1732,9 +1781,9 @@ lp_build_sin(struct lp_build_context *bld,
     * _PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4);
     * _PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8);
     */
-   LLVMValueRef DP1 = lp_build_const_v4sf(-0.78515625);
-   LLVMValueRef DP2 = lp_build_const_v4sf(-2.4187564849853515625e-4);
-   LLVMValueRef DP3 = lp_build_const_v4sf(-3.77489497744594108e-8);
+   LLVMValueRef DP1 = lp_build_const_v4sf(gallivm, -0.78515625);
+   LLVMValueRef DP2 = lp_build_const_v4sf(gallivm, -2.4187564849853515625e-4);
+   LLVMValueRef DP3 = lp_build_const_v4sf(gallivm, -3.77489497744594108e-8);
 
    /*
     * The magic pass: "Extended precision modular arithmetic" 
@@ -1769,9 +1818,9 @@ lp_build_sin(struct lp_build_context *bld,
     * _PS_CONST(coscof_p1, -1.388731625493765E-003);
     * _PS_CONST(coscof_p2,  4.166664568298827E-002);
     */
-   LLVMValueRef coscof_p0 = lp_build_const_v4sf(2.443315711809948E-005);
-   LLVMValueRef coscof_p1 = lp_build_const_v4sf(-1.388731625493765E-003);
-   LLVMValueRef coscof_p2 = lp_build_const_v4sf(4.166664568298827E-002);
+   LLVMValueRef coscof_p0 = lp_build_const_v4sf(gallivm, 2.443315711809948E-005);
+   LLVMValueRef coscof_p1 = lp_build_const_v4sf(gallivm, -1.388731625493765E-003);
+   LLVMValueRef coscof_p2 = lp_build_const_v4sf(gallivm, 4.166664568298827E-002);
 
    /*
     * y = *(v4sf*)_ps_coscof_p0;
@@ -1790,10 +1839,10 @@ lp_build_sin(struct lp_build_context *bld,
     * y = _mm_sub_ps(y, tmp);
     * y = _mm_add_ps(y, *(v4sf*)_ps_1);
     */ 
-   LLVMValueRef half = lp_build_const_v4sf(0.5);
+   LLVMValueRef half = lp_build_const_v4sf(gallivm, 0.5);
    LLVMValueRef tmp = LLVMBuildFMul(b, z, half, "tmp");
    LLVMValueRef y_9 = LLVMBuildFSub(b, y_8, tmp, "y_8");
-   LLVMValueRef one = lp_build_const_v4sf(1.0);
+   LLVMValueRef one = lp_build_const_v4sf(gallivm, 1.0);
    LLVMValueRef y_10 = LLVMBuildFAdd(b, y_9, one, "y_9");
 
    /*
@@ -1801,9 +1850,9 @@ lp_build_sin(struct lp_build_context *bld,
     * _PS_CONST(sincof_p1,  8.3321608736E-3);
     * _PS_CONST(sincof_p2, -1.6666654611E-1);
     */
-   LLVMValueRef sincof_p0 = lp_build_const_v4sf(-1.9515295891E-4);
-   LLVMValueRef sincof_p1 = lp_build_const_v4sf(8.3321608736E-3);
-   LLVMValueRef sincof_p2 = lp_build_const_v4sf(-1.6666654611E-1);
+   LLVMValueRef sincof_p0 = lp_build_const_v4sf(gallivm, -1.9515295891E-4);
+   LLVMValueRef sincof_p1 = lp_build_const_v4sf(gallivm, 8.3321608736E-3);
+   LLVMValueRef sincof_p2 = lp_build_const_v4sf(gallivm, -1.6666654611E-1);
 
    /*
     * Evaluate the second polynom  (Pi/4 <= x <= 0)
@@ -1836,7 +1885,7 @@ lp_build_sin(struct lp_build_context *bld,
    LLVMValueRef y2_i = LLVMBuildBitCast(b, y2_9, v4si, "y2_i");
    LLVMValueRef y_i = LLVMBuildBitCast(b, y_10, v4si, "y_i");
    LLVMValueRef y2_and = LLVMBuildAnd(b, y2_i, poly_mask, "y2_and");
-   LLVMValueRef inv = lp_build_const_v4si(~0);
+   LLVMValueRef inv = lp_build_const_v4si(bld->gallivm, ~0);
    LLVMValueRef poly_mask_inv = LLVMBuildXor(b, poly_mask, inv, "poly_mask_inv");
    LLVMValueRef y_and = LLVMBuildAnd(b, y_i, poly_mask_inv, "y_and");
    LLVMValueRef y_combine = LLVMBuildAdd(b, y_and, y2_and, "y_combine");
@@ -1858,17 +1907,19 @@ LLVMValueRef
 lp_build_cos(struct lp_build_context *bld,
              LLVMValueRef a)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   struct gallivm_state *gallivm = bld->gallivm;
    struct lp_type int_type = lp_int_type(bld->type);
-   LLVMBuilderRef b = bld->builder;
-   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
-   LLVMTypeRef v4si = LLVMVectorType(LLVMInt32Type(), 4);
+   LLVMBuilderRef b = builder;
+   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatTypeInContext(bld->gallivm->context), 4);
+   LLVMTypeRef v4si = LLVMVectorType(LLVMInt32TypeInContext(bld->gallivm->context), 4);
 
    /*
     *  take the absolute value,
     *  x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
     */
 
-   LLVMValueRef inv_sig_mask = lp_build_const_v4si(~0x80000000);
+   LLVMValueRef inv_sig_mask = lp_build_const_v4si(bld->gallivm, ~0x80000000);
    LLVMValueRef a_v4si = LLVMBuildBitCast(b, a, v4si, "a_v4si");
 
    LLVMValueRef absi = LLVMBuildAnd(b, a_v4si, inv_sig_mask, "absi");
@@ -1879,7 +1930,7 @@ lp_build_cos(struct lp_build_context *bld,
     * y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
     */
    
-   LLVMValueRef FOPi = lp_build_const_v4sf(1.27323954473516);
+   LLVMValueRef FOPi = lp_build_const_v4sf(gallivm, 1.27323954473516);
    LLVMValueRef scale_y = LLVMBuildFMul(b, x_abs, FOPi, "scale_y");
 
    /*
@@ -1894,12 +1945,12 @@ lp_build_cos(struct lp_build_context *bld,
     * emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
     */
 
-   LLVMValueRef all_one = lp_build_const_v4si(1);
+   LLVMValueRef all_one = lp_build_const_v4si(bld->gallivm, 1);
    LLVMValueRef emm2_add =  LLVMBuildAdd(b, emm2_i, all_one, "emm2_add");
    /*
     * emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
     */
-   LLVMValueRef inv_one = lp_build_const_v4si(~1);
+   LLVMValueRef inv_one = lp_build_const_v4si(bld->gallivm, ~1);
    LLVMValueRef emm2_and =  LLVMBuildAnd(b, emm2_add, inv_one, "emm2_and");
 
    /*
@@ -1911,22 +1962,22 @@ lp_build_cos(struct lp_build_context *bld,
    /*
     * emm2 = _mm_sub_epi32(emm2, *(v4si*)_pi32_2);
     */
-   LLVMValueRef const_2 = lp_build_const_v4si(2);
+   LLVMValueRef const_2 = lp_build_const_v4si(bld->gallivm, 2);
    LLVMValueRef emm2_2 = LLVMBuildSub(b, emm2_and, const_2, "emm2_2");
 
 
    /* get the swap sign flag
     * emm0 = _mm_andnot_si128(emm2, *(v4si*)_pi32_4);
     */
-   LLVMValueRef inv = lp_build_const_v4si(~0);
+   LLVMValueRef inv = lp_build_const_v4si(bld->gallivm, ~0);
    LLVMValueRef emm0_not = LLVMBuildXor(b, emm2_2, inv, "emm0_not");
-   LLVMValueRef pi32_4 = lp_build_const_v4si(4);
+   LLVMValueRef pi32_4 = lp_build_const_v4si(bld->gallivm, 4);
    LLVMValueRef emm0_and =  LLVMBuildAnd(b, emm0_not, pi32_4, "emm0_and");
    
    /*
     * emm2 = _mm_slli_epi32(emm0, 29);
     */  
-   LLVMValueRef const_29 = lp_build_const_v4si(29);
+   LLVMValueRef const_29 = lp_build_const_v4si(bld->gallivm, 29);
    LLVMValueRef sign_bit = LLVMBuildShl(b, emm0_and, const_29, "sign_bit");
 
    /*
@@ -1939,19 +1990,20 @@ lp_build_cos(struct lp_build_context *bld,
     * emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
     */
 
-   LLVMValueRef pi32_2 = lp_build_const_v4si(2);
+   LLVMValueRef pi32_2 = lp_build_const_v4si(bld->gallivm, 2);
    LLVMValueRef emm2_3 =  LLVMBuildAnd(b, emm2_2, pi32_2, "emm2_3");
-   LLVMValueRef poly_mask = lp_build_compare(b, int_type, PIPE_FUNC_EQUAL,
-                                            emm2_3, lp_build_const_v4si(0));
+   LLVMValueRef poly_mask = lp_build_compare(bld->gallivm,
+                                             int_type, PIPE_FUNC_EQUAL,
+                                            emm2_3, lp_build_const_v4si(bld->gallivm, 0));
 
    /*
     * _PS_CONST(minus_cephes_DP1, -0.78515625);
     * _PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4);
     * _PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8);
     */
-   LLVMValueRef DP1 = lp_build_const_v4sf(-0.78515625);
-   LLVMValueRef DP2 = lp_build_const_v4sf(-2.4187564849853515625e-4);
-   LLVMValueRef DP3 = lp_build_const_v4sf(-3.77489497744594108e-8);
+   LLVMValueRef DP1 = lp_build_const_v4sf(gallivm, -0.78515625);
+   LLVMValueRef DP2 = lp_build_const_v4sf(gallivm, -2.4187564849853515625e-4);
+   LLVMValueRef DP3 = lp_build_const_v4sf(gallivm, -3.77489497744594108e-8);
 
    /*
     * The magic pass: "Extended precision modular arithmetic" 
@@ -1986,9 +2038,9 @@ lp_build_cos(struct lp_build_context *bld,
     * _PS_CONST(coscof_p1, -1.388731625493765E-003);
     * _PS_CONST(coscof_p2,  4.166664568298827E-002);
     */
-   LLVMValueRef coscof_p0 = lp_build_const_v4sf(2.443315711809948E-005);
-   LLVMValueRef coscof_p1 = lp_build_const_v4sf(-1.388731625493765E-003);
-   LLVMValueRef coscof_p2 = lp_build_const_v4sf(4.166664568298827E-002);
+   LLVMValueRef coscof_p0 = lp_build_const_v4sf(gallivm, 2.443315711809948E-005);
+   LLVMValueRef coscof_p1 = lp_build_const_v4sf(gallivm, -1.388731625493765E-003);
+   LLVMValueRef coscof_p2 = lp_build_const_v4sf(gallivm, 4.166664568298827E-002);
 
    /*
     * y = *(v4sf*)_ps_coscof_p0;
@@ -2007,10 +2059,10 @@ lp_build_cos(struct lp_build_context *bld,
     * y = _mm_sub_ps(y, tmp);
     * y = _mm_add_ps(y, *(v4sf*)_ps_1);
     */ 
-   LLVMValueRef half = lp_build_const_v4sf(0.5);
+   LLVMValueRef half = lp_build_const_v4sf(gallivm, 0.5);
    LLVMValueRef tmp = LLVMBuildFMul(b, z, half, "tmp");
    LLVMValueRef y_9 = LLVMBuildFSub(b, y_8, tmp, "y_8");
-   LLVMValueRef one = lp_build_const_v4sf(1.0);
+   LLVMValueRef one = lp_build_const_v4sf(gallivm, 1.0);
    LLVMValueRef y_10 = LLVMBuildFAdd(b, y_9, one, "y_9");
 
    /*
@@ -2018,9 +2070,9 @@ lp_build_cos(struct lp_build_context *bld,
     * _PS_CONST(sincof_p1,  8.3321608736E-3);
     * _PS_CONST(sincof_p2, -1.6666654611E-1);
     */
-   LLVMValueRef sincof_p0 = lp_build_const_v4sf(-1.9515295891E-4);
-   LLVMValueRef sincof_p1 = lp_build_const_v4sf(8.3321608736E-3);
-   LLVMValueRef sincof_p2 = lp_build_const_v4sf(-1.6666654611E-1);
+   LLVMValueRef sincof_p0 = lp_build_const_v4sf(gallivm, -1.9515295891E-4);
+   LLVMValueRef sincof_p1 = lp_build_const_v4sf(gallivm, 8.3321608736E-3);
+   LLVMValueRef sincof_p2 = lp_build_const_v4sf(gallivm, -1.6666654611E-1);
 
    /*
     * Evaluate the second polynom  (Pi/4 <= x <= 0)
@@ -2094,7 +2146,8 @@ lp_build_exp(struct lp_build_context *bld,
              LLVMValueRef x)
 {
    /* log2(e) = 1/log(2) */
-   LLVMValueRef log2e = lp_build_const_vec(bld->type, 1.4426950408889634);
+   LLVMValueRef log2e = lp_build_const_vec(bld->gallivm, bld->type,
+                                           1.4426950408889634);
 
    assert(lp_check_value(bld->type, x));
 
@@ -2110,7 +2163,8 @@ lp_build_log(struct lp_build_context *bld,
              LLVMValueRef x)
 {
    /* log(2) */
-   LLVMValueRef log2 = lp_build_const_vec(bld->type, 0.69314718055994529);
+   LLVMValueRef log2 = lp_build_const_vec(bld->gallivm, bld->type,
+                                          0.69314718055994529);
 
    assert(lp_check_value(bld->type, x));
 
@@ -2144,7 +2198,7 @@ lp_build_polynomial(struct lp_build_context *bld,
    for (i = num_coeffs; i--; ) {
       LLVMValueRef coeff;
 
-      coeff = lp_build_const_vec(type, coeffs[i]);
+      coeff = lp_build_const_vec(bld->gallivm, type, coeffs[i]);
 
       if(res)
          res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
@@ -2198,9 +2252,10 @@ lp_build_exp2_approx(struct lp_build_context *bld,
                      LLVMValueRef *p_frac_part,
                      LLVMValueRef *p_exp2)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
    LLVMValueRef ipart = NULL;
    LLVMValueRef fpart = NULL;
    LLVMValueRef expipart = NULL;
@@ -2219,29 +2274,31 @@ lp_build_exp2_approx(struct lp_build_context *bld,
 
       assert(type.floating && type.width == 32);
 
-      x = lp_build_min(bld, x, lp_build_const_vec(type,  129.0));
-      x = lp_build_max(bld, x, lp_build_const_vec(type, -126.99999));
+      x = lp_build_min(bld, x, lp_build_const_vec(bld->gallivm, type,  129.0));
+      x = lp_build_max(bld, x, lp_build_const_vec(bld->gallivm, type, -126.99999));
 
       /* ipart = floor(x) */
       ipart = lp_build_floor(bld, x);
 
       /* fpart = x - ipart */
-      fpart = LLVMBuildFSub(bld->builder, x, ipart, "");
+      fpart = LLVMBuildFSub(builder, x, ipart, "");
    }
 
    if(p_exp2_int_part || p_exp2) {
       /* expipart = (float) (1 << ipart) */
-      ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, "");
-      expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_const_int_vec(type, 127), "");
-      expipart = LLVMBuildShl(bld->builder, expipart, lp_build_const_int_vec(type, 23), "");
-      expipart = LLVMBuildBitCast(bld->builder, expipart, vec_type, "");
+      ipart = LLVMBuildFPToSI(builder, ipart, int_vec_type, "");
+      expipart = LLVMBuildAdd(builder, ipart,
+                              lp_build_const_int_vec(bld->gallivm, type, 127), "");
+      expipart = LLVMBuildShl(builder, expipart,
+                              lp_build_const_int_vec(bld->gallivm, type, 23), "");
+      expipart = LLVMBuildBitCast(builder, expipart, vec_type, "");
    }
 
    if(p_exp2) {
       expfpart = lp_build_polynomial(bld, fpart, lp_build_exp2_polynomial,
                                      Elements(lp_build_exp2_polynomial));
 
-      res = LLVMBuildFMul(bld->builder, expipart, expfpart, "");
+      res = LLVMBuildFMul(builder, expipart, expfpart, "");
    }
 
    if(p_exp2_int_part)
@@ -2279,6 +2336,7 @@ lp_build_extract_exponent(struct lp_build_context *bld,
                           LLVMValueRef x,
                           int bias)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    unsigned mantissa = lp_mantissa(type);
    LLVMValueRef res;
@@ -2287,11 +2345,14 @@ lp_build_extract_exponent(struct lp_build_context *bld,
 
    assert(lp_check_value(bld->type, x));
 
-   x = LLVMBuildBitCast(bld->builder, x, bld->int_vec_type, "");
+   x = LLVMBuildBitCast(builder, x, bld->int_vec_type, "");
 
-   res = LLVMBuildLShr(bld->builder, x, lp_build_const_int_vec(type, mantissa), "");
-   res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(type, 255), "");
-   res = LLVMBuildSub(bld->builder, res, lp_build_const_int_vec(type, 127 - bias), "");
+   res = LLVMBuildLShr(builder, x,
+                       lp_build_const_int_vec(bld->gallivm, type, mantissa), "");
+   res = LLVMBuildAnd(builder, res,
+                      lp_build_const_int_vec(bld->gallivm, type, 255), "");
+   res = LLVMBuildSub(builder, res,
+                      lp_build_const_int_vec(bld->gallivm, type, 127 - bias), "");
 
    return res;
 }
@@ -2308,9 +2369,11 @@ LLVMValueRef
 lp_build_extract_mantissa(struct lp_build_context *bld,
                           LLVMValueRef x)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    unsigned mantissa = lp_mantissa(type);
-   LLVMValueRef mantmask = lp_build_const_int_vec(type, (1ULL << mantissa) - 1);
+   LLVMValueRef mantmask = lp_build_const_int_vec(bld->gallivm, type,
+                                                  (1ULL << mantissa) - 1);
    LLVMValueRef one = LLVMConstBitCast(bld->one, bld->int_vec_type);
    LLVMValueRef res;
 
@@ -2318,12 +2381,12 @@ lp_build_extract_mantissa(struct lp_build_context *bld,
 
    assert(type.floating);
 
-   x = LLVMBuildBitCast(bld->builder, x, bld->int_vec_type, "");
+   x = LLVMBuildBitCast(builder, x, bld->int_vec_type, "");
 
    /* res = x / 2**ipart */
-   res = LLVMBuildAnd(bld->builder, x, mantmask, "");
-   res = LLVMBuildOr(bld->builder, res, one, "");
-   res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+   res = LLVMBuildAnd(builder, x, mantmask, "");
+   res = LLVMBuildOr(builder, res, one, "");
+   res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
 
    return res;
 }
@@ -2374,12 +2437,13 @@ lp_build_log2_approx(struct lp_build_context *bld,
                      LLVMValueRef *p_floor_log2,
                      LLVMValueRef *p_log2)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
 
-   LLVMValueRef expmask = lp_build_const_int_vec(type, 0x7f800000);
-   LLVMValueRef mantmask = lp_build_const_int_vec(type, 0x007fffff);
+   LLVMValueRef expmask = lp_build_const_int_vec(bld->gallivm, type, 0x7f800000);
+   LLVMValueRef mantmask = lp_build_const_int_vec(bld->gallivm, type, 0x007fffff);
    LLVMValueRef one = LLVMConstBitCast(bld->one, int_vec_type);
 
    LLVMValueRef i = NULL;
@@ -2401,35 +2465,35 @@ lp_build_log2_approx(struct lp_build_context *bld,
 
       assert(type.floating && type.width == 32);
 
-      i = LLVMBuildBitCast(bld->builder, x, int_vec_type, "");
+      i = LLVMBuildBitCast(builder, x, int_vec_type, "");
 
       /* exp = (float) exponent(x) */
-      exp = LLVMBuildAnd(bld->builder, i, expmask, "");
+      exp = LLVMBuildAnd(builder, i, expmask, "");
    }
 
    if(p_floor_log2 || p_log2) {
-      logexp = LLVMBuildLShr(bld->builder, exp, lp_build_const_int_vec(type, 23), "");
-      logexp = LLVMBuildSub(bld->builder, logexp, lp_build_const_int_vec(type, 127), "");
-      logexp = LLVMBuildSIToFP(bld->builder, logexp, vec_type, "");
+      logexp = LLVMBuildLShr(builder, exp, lp_build_const_int_vec(bld->gallivm, type, 23), "");
+      logexp = LLVMBuildSub(builder, logexp, lp_build_const_int_vec(bld->gallivm, type, 127), "");
+      logexp = LLVMBuildSIToFP(builder, logexp, vec_type, "");
    }
 
    if(p_log2) {
       /* mant = (float) mantissa(x) */
-      mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
-      mant = LLVMBuildOr(bld->builder, mant, one, "");
-      mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
+      mant = LLVMBuildAnd(builder, i, mantmask, "");
+      mant = LLVMBuildOr(builder, mant, one, "");
+      mant = LLVMBuildBitCast(builder, mant, vec_type, "");
 
       logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
                                     Elements(lp_build_log2_polynomial));
 
       /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
-      logmant = LLVMBuildFMul(bld->builder, logmant, LLVMBuildFSub(bld->builder, mant, bld->one, ""), "");
+      logmant = LLVMBuildFMul(builder, logmant, LLVMBuildFSub(builder, mant, bld->one, ""), "");
 
-      res = LLVMBuildFAdd(bld->builder, logmant, logexp, "");
+      res = LLVMBuildFAdd(builder, logmant, logexp, "");
    }
 
    if(p_exp) {
-      exp = LLVMBuildBitCast(bld->builder, exp, vec_type, "");
+      exp = LLVMBuildBitCast(builder, exp, vec_type, "");
       *p_exp = exp;
    }
 
@@ -2465,6 +2529,7 @@ LLVMValueRef
 lp_build_fast_log2(struct lp_build_context *bld,
                    LLVMValueRef x)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef ipart;
    LLVMValueRef fpart;
 
@@ -2474,13 +2539,13 @@ lp_build_fast_log2(struct lp_build_context *bld,
 
    /* ipart = floor(log2(x)) - 1 */
    ipart = lp_build_extract_exponent(bld, x, -1);
-   ipart = LLVMBuildSIToFP(bld->builder, ipart, bld->vec_type, "");
+   ipart = LLVMBuildSIToFP(builder, ipart, bld->vec_type, "");
 
    /* fpart = x / 2**ipart */
    fpart = lp_build_extract_mantissa(bld, x);
 
    /* ipart + fpart */
-   return LLVMBuildFAdd(bld->builder, ipart, fpart, "");
+   return LLVMBuildFAdd(builder, ipart, fpart, "");
 }
 
 
@@ -2493,7 +2558,8 @@ LLVMValueRef
 lp_build_ilog2(struct lp_build_context *bld,
                LLVMValueRef x)
 {
-   LLVMValueRef sqrt2 = lp_build_const_vec(bld->type, M_SQRT2);
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMValueRef sqrt2 = lp_build_const_vec(bld->gallivm, bld->type, M_SQRT2);
    LLVMValueRef ipart;
 
    assert(bld->type.floating);
@@ -2501,7 +2567,7 @@ lp_build_ilog2(struct lp_build_context *bld,
    assert(lp_check_value(bld->type, x));
 
    /* x * 2^(0.5)   i.e., add 0.5 to the log2(x) */
-   x = LLVMBuildFMul(bld->builder, x, sqrt2, "");
+   x = LLVMBuildFMul(builder, x, sqrt2, "");
 
    /* ipart = floor(log2(x) + 0.5)  */
    ipart = lp_build_extract_exponent(bld, x, 0);
index f2ebd868a8daa280800e13d588b8f6613a2a5cb4..9de5e8e7b51459377ce252f11d4f689bd5751071 100644 (file)
@@ -56,20 +56,21 @@ lp_assert(int condition, const char *msg)
  * \param msg  a string to print if the assertion fails.
  */
 LLVMValueRef
-lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
+lp_build_assert(struct gallivm_state *gallivm,
+                LLVMValueRef condition,
                 const char *msg)
 {
-   LLVMModuleRef module;
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMContextRef context = gallivm->context;
+   LLVMModuleRef module = gallivm->module;
    LLVMTypeRef arg_types[2];
    LLVMValueRef msg_string, assert_func, params[2], r;
 
-   module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(
-                            LLVMGetInsertBlock(builder)));
+   msg_string = lp_build_const_string_variable(module, context,
+                                               msg, strlen(msg) + 1);
 
-   msg_string = lp_build_const_string_variable(module, msg, strlen(msg) + 1);
-
-   arg_types[0] = LLVMInt32Type();
-   arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0);
+   arg_types[0] = LLVMInt32TypeInContext(context);
+   arg_types[1] = LLVMPointerType(LLVMInt8TypeInContext(context), 0);
 
    /* lookup the lp_assert function */
    assert_func = LLVMGetNamedFunction(module, "lp_assert");
@@ -77,12 +78,12 @@ lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
    /* Create the assertion function if not found */
    if (!assert_func) {
       LLVMTypeRef func_type =
-         LLVMFunctionType(LLVMVoidType(), arg_types, 2, 0);
+         LLVMFunctionType(LLVMVoidTypeInContext(context), arg_types, 2, 0);
 
       assert_func = LLVMAddFunction(module, "lp_assert", func_type);
       LLVMSetFunctionCallConv(assert_func, LLVMCCallConv);
       LLVMSetLinkage(assert_func, LLVMExternalLinkage);
-      LLVMAddGlobalMapping(lp_build_engine, assert_func,
+      LLVMAddGlobalMapping(gallivm->engine, assert_func,
                            func_to_pointer((func_pointer)lp_assert));
    }
    assert(assert_func);
index ddd879dc2c6a8b8a5851d7d8b514e4c7266754d3..1d2baab30a21e857c74ac8ce44c2e9b5540e6ddd 100644 (file)
 
 
 #include "lp_bld.h"
+#include "lp_bld_init.h"
 
 
 LLVMValueRef
-lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
+lp_build_assert(struct gallivm_state *gallivm,
+                LLVMValueRef condition,
                 const char *msg);
 
 
index 706479b4d5616c5b9ca1d27628f3c6b755c039b1..a9c57d682f2df649bbeabfb6baeb6fb2652ae4db 100644 (file)
@@ -40,6 +40,7 @@
 LLVMValueRef
 lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -48,14 +49,14 @@ lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 
    /* can't do bitwise ops on floating-point values */
    if (type.floating) {
-      a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, "");
-      b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, "");
+      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
    }
 
-   res = LLVMBuildOr(bld->builder, a, b, "");
+   res = LLVMBuildOr(builder, a, b, "");
 
    if (type.floating) {
-      res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
    }
 
    return res;
@@ -68,6 +69,7 @@ lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 LLVMValueRef
 lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -76,14 +78,14 @@ lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 
    /* can't do bitwise ops on floating-point values */
    if (type.floating) {
-      a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, "");
-      b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, "");
+      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
    }
 
-   res = LLVMBuildAnd(bld->builder, a, b, "");
+   res = LLVMBuildAnd(builder, a, b, "");
 
    if (type.floating) {
-      res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
    }
 
    return res;
@@ -96,6 +98,7 @@ lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 LLVMValueRef
 lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -104,15 +107,15 @@ lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 
    /* can't do bitwise ops on floating-point values */
    if (type.floating) {
-      a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, "");
-      b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, "");
+      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
    }
 
-   res = LLVMBuildNot(bld->builder, b, "");
-   res = LLVMBuildAnd(bld->builder, a, res, "");
+   res = LLVMBuildNot(builder, b, "");
+   res = LLVMBuildAnd(builder, a, res, "");
 
    if (type.floating) {
-      res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
    }
 
    return res;
@@ -125,6 +128,7 @@ lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 LLVMValueRef
 lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -133,7 +137,7 @@ lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
    assert(lp_check_value(type, a));
    assert(lp_check_value(type, b));
 
-   res = LLVMBuildShl(bld->builder, a, b, "");
+   res = LLVMBuildShl(builder, a, b, "");
 
    return res;
 }
@@ -145,6 +149,7 @@ lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 LLVMValueRef
 lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -154,9 +159,9 @@ lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
    assert(lp_check_value(type, b));
 
    if (type.sign) {
-      res = LLVMBuildAShr(bld->builder, a, b, "");
+      res = LLVMBuildAShr(builder, a, b, "");
    } else {
-      res = LLVMBuildLShr(bld->builder, a, b, "");
+      res = LLVMBuildLShr(builder, a, b, "");
    }
 
    return res;
@@ -169,7 +174,7 @@ lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
 LLVMValueRef
 lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
 {
-   LLVMValueRef b = lp_build_const_int_vec(bld->type, imm);
+   LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
    assert(imm <= bld->type.width);
    return lp_build_shl(bld, a, b);
 }
@@ -181,7 +186,7 @@ lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
 LLVMValueRef
 lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
 {
-   LLVMValueRef b = lp_build_const_int_vec(bld->type, imm);
+   LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
    assert(imm <= bld->type.width);
    return lp_build_shr(bld, a, b);
 }
index dd839c0bea56ce5f60bb01974140ef3f74dcef37..6d8b7c26fc8344f37e588dc9d3133e4bce26fb9e 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
 
 
 unsigned
@@ -211,31 +212,31 @@ lp_const_eps(struct lp_type type)
 
 
 LLVMValueRef
-lp_build_undef(struct lp_type type)
+lp_build_undef(struct gallivm_state *gallivm, struct lp_type type)
 {
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
+   LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type);
    return LLVMGetUndef(vec_type);
 }
                
 
 LLVMValueRef
-lp_build_zero(struct lp_type type)
+lp_build_zero(struct gallivm_state *gallivm, struct lp_type type)
 {
    if (type.length == 1) {
       if (type.floating)
-         return LLVMConstReal(LLVMFloatType(), 0.0);
+         return lp_build_const_float(gallivm, 0.0);
       else
-         return LLVMConstInt(LLVMIntType(type.width), 0, 0);
+         return LLVMConstInt(LLVMIntTypeInContext(gallivm->context, type.width), 0, 0);
    }
    else {
-      LLVMTypeRef vec_type = lp_build_vec_type(type);
+      LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type);
       return LLVMConstNull(vec_type);
    }
 }
                
 
 LLVMValueRef
-lp_build_one(struct lp_type type)
+lp_build_one(struct gallivm_state *gallivm, struct lp_type type)
 {
    LLVMTypeRef elem_type;
    LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
@@ -243,7 +244,7 @@ lp_build_one(struct lp_type type)
 
    assert(type.length <= LP_MAX_VECTOR_LENGTH);
 
-   elem_type = lp_build_elem_type(type);
+   elem_type = lp_build_elem_type(gallivm, type);
 
    if(type.floating)
       elems[0] = LLVMConstReal(elem_type, 1.0);
@@ -283,10 +284,11 @@ lp_build_one(struct lp_type type)
  * Build constant-valued element from a scalar value.
  */
 LLVMValueRef
-lp_build_const_elem(struct lp_type type,
+lp_build_const_elem(struct gallivm_state *gallivm,
+                    struct lp_type type,
                     double val)
 {
-   LLVMTypeRef elem_type = lp_build_elem_type(type);
+   LLVMTypeRef elem_type = lp_build_elem_type(gallivm, type);
    LLVMValueRef elem;
 
    if(type.floating) {
@@ -306,15 +308,15 @@ lp_build_const_elem(struct lp_type type,
  * Build constant-valued vector from a scalar value.
  */
 LLVMValueRef
-lp_build_const_vec(struct lp_type type,
+lp_build_const_vec(struct gallivm_state *gallivm, struct lp_type type,
                    double val)
 {
    if (type.length == 1) {
-      return lp_build_const_elem(type, val);
+      return lp_build_const_elem(gallivm, type, val);
    } else {
       LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
       unsigned i;
-      elems[0] = lp_build_const_elem(type, val);
+      elems[0] = lp_build_const_elem(gallivm, type, val);
       for(i = 1; i < type.length; ++i)
          elems[i] = elems[0];
       return LLVMConstVector(elems, type.length);
@@ -323,10 +325,10 @@ lp_build_const_vec(struct lp_type type,
 
 
 LLVMValueRef
-lp_build_const_int_vec(struct lp_type type,
-                          long long val)
+lp_build_const_int_vec(struct gallivm_state *gallivm, struct lp_type type,
+                       long long val)
 {
-   LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+   LLVMTypeRef elem_type = lp_build_int_elem_type(gallivm, type);
    LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
    unsigned i;
 
@@ -343,7 +345,8 @@ lp_build_const_int_vec(struct lp_type type,
 
 
 LLVMValueRef
-lp_build_const_aos(struct lp_type type, 
+lp_build_const_aos(struct gallivm_state *gallivm,
+                   struct lp_type type, 
                    double r, double g, double b, double a, 
                    const unsigned char *swizzle)
 {
@@ -355,7 +358,7 @@ lp_build_const_aos(struct lp_type type,
    assert(type.length % 4 == 0);
    assert(type.length <= LP_MAX_VECTOR_LENGTH);
 
-   elem_type = lp_build_elem_type(type);
+   elem_type = lp_build_elem_type(gallivm, type);
 
    if(swizzle == NULL)
       swizzle = default_swizzle;
@@ -386,10 +389,11 @@ lp_build_const_aos(struct lp_type type,
  * @param mask TGSI_WRITEMASK_xxx
  */
 LLVMValueRef
-lp_build_const_mask_aos(struct lp_type type,
+lp_build_const_mask_aos(struct gallivm_state *gallivm,
+                        struct lp_type type,
                         unsigned mask)
 {
-   LLVMTypeRef elem_type = LLVMIntType(type.width);
+   LLVMTypeRef elem_type = LLVMIntTypeInContext(gallivm->context, type.width);
    LLVMValueRef masks[LP_MAX_VECTOR_LENGTH];
    unsigned i, j;
 
index 6b1fc590c177f8fbfb76186c3a5bb3501b6027d0..c749a7a3150185e2e3829949a557bf2d070fc955 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "pipe/p_compiler.h"
 #include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_init.h"
 
 
 
@@ -73,46 +74,55 @@ lp_const_eps(struct lp_type type);
 
 
 LLVMValueRef
-lp_build_undef(struct lp_type type);
+lp_build_undef(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMValueRef
-lp_build_zero(struct lp_type type);
+lp_build_zero(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMValueRef
-lp_build_one(struct lp_type type);
+lp_build_one(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMValueRef
-lp_build_const_elem(struct lp_type type,
+lp_build_const_elem(struct gallivm_state *gallivm, struct lp_type type,
                     double val);
 
 LLVMValueRef
-lp_build_const_vec(struct lp_type type, double val);
+lp_build_const_vec(struct gallivm_state *gallivm, struct lp_type type,
+                   double val);
 
 
 LLVMValueRef
-lp_build_const_int_vec(struct lp_type type, long long val);
+lp_build_const_int_vec(struct gallivm_state *gallivm,
+                       struct lp_type type, long long val);
 
 
 LLVMValueRef
-lp_build_const_aos(struct lp_type type, 
+lp_build_const_aos(struct gallivm_state *gallivm, struct lp_type type, 
                    double r, double g, double b, double a, 
                    const unsigned char *swizzle);
 
 
 LLVMValueRef
-lp_build_const_mask_aos(struct lp_type type,
+lp_build_const_mask_aos(struct gallivm_state *gallivm,
+                        struct lp_type type,
                         unsigned mask);
 
 
 static INLINE LLVMValueRef
-lp_build_const_int32(int i)
+lp_build_const_int32(struct gallivm_state *gallivm, int i)
 {
-   return LLVMConstInt(LLVMInt32Type(), i, 0);
+   return LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), i, 0);
 }
 
 
+static INLINE LLVMValueRef
+lp_build_const_float(struct gallivm_state *gallivm, float x)
+{
+   return LLVMConstReal(LLVMFloatTypeInContext(gallivm->context), x);
+}
+
 
 #endif /* !LP_BLD_CONST_H */
index 6967dd26225a5dcb2750a190f1f80ccc6015f7de..c43ee8ac6388d3b918cc33181f4c222c4e0561b4 100644 (file)
  * return { i32, i32, i32, i32 } where each value is in [0, 2^dst_width-1].
  */
 LLVMValueRef
-lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
+lp_build_clamped_float_to_unsigned_norm(struct gallivm_state *gallivm,
                                         struct lp_type src_type,
                                         unsigned dst_width,
                                         LLVMValueRef src)
 {
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(src_type);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(gallivm, src_type);
    LLVMValueRef res;
    unsigned mantissa;
 
@@ -122,10 +123,11 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
       scale = (double)mask/ubound;
       bias = (double)(1ULL << (mantissa - dst_width));
 
-      res = LLVMBuildFMul(builder, src, lp_build_const_vec(src_type, scale), "");
-      res = LLVMBuildFAdd(builder, res, lp_build_const_vec(src_type, bias), "");
+      res = LLVMBuildFMul(builder, src, lp_build_const_vec(gallivm, src_type, scale), "");
+      res = LLVMBuildFAdd(builder, res, lp_build_const_vec(gallivm, src_type, bias), "");
       res = LLVMBuildBitCast(builder, res, int_vec_type, "");
-      res = LLVMBuildAnd(builder, res, lp_build_const_int_vec(src_type, mask), "");
+      res = LLVMBuildAnd(builder, res,
+                         lp_build_const_int_vec(gallivm, src_type, mask), "");
    }
    else if (dst_width == (mantissa + 1)) {
       /*
@@ -138,7 +140,8 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
 
       scale = (double)((1ULL << dst_width) - 1);
 
-      res = LLVMBuildFMul(builder, src, lp_build_const_vec(src_type, scale), "");
+      res = LLVMBuildFMul(builder, src,
+                          lp_build_const_vec(gallivm, src_type, scale), "");
       res = LLVMBuildFPToSI(builder, res, int_vec_type, "");
    }
    else {
@@ -166,7 +169,8 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
       LLVMValueRef lshifted;
       LLVMValueRef rshifted;
 
-      res = LLVMBuildFMul(builder, src, lp_build_const_vec(src_type, scale), "");
+      res = LLVMBuildFMul(builder, src,
+                          lp_build_const_vec(gallivm, src_type, scale), "");
       res = LLVMBuildFPToSI(builder, res, int_vec_type, "");
 
       /*
@@ -177,7 +181,8 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
        */
       if (lshift) {
          lshifted = LLVMBuildShl(builder, res,
-                                 lp_build_const_int_vec(src_type, lshift), "");
+                                 lp_build_const_int_vec(gallivm, src_type,
+                                                        lshift), "");
       } else {
          lshifted = res;
       }
@@ -186,7 +191,8 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
        * Align the most significant bit to the right.
        */
       rshifted =  LLVMBuildAShr(builder, res,
-                                lp_build_const_int_vec(src_type, rshift), "");
+                                lp_build_const_int_vec(gallivm, src_type, rshift),
+                                "");
 
       /*
        * Subtract the MSB to the LSB, therefore re-scaling from
@@ -206,13 +212,14 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
  * return {float, float, float, float} with values in range [0, 1].
  */
 LLVMValueRef
-lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
+lp_build_unsigned_norm_to_float(struct gallivm_state *gallivm,
                                 unsigned src_width,
                                 struct lp_type dst_type,
                                 LLVMValueRef src)
 {
-   LLVMTypeRef vec_type = lp_build_vec_type(dst_type);
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(dst_type);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMTypeRef vec_type = lp_build_vec_type(gallivm, dst_type);
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(gallivm, dst_type);
    LLVMValueRef bias_;
    LLVMValueRef res;
    unsigned mantissa;
@@ -230,7 +237,8 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
    if (src_width == 8) {
       scale = 1.0/255.0;
       res = LLVMBuildSIToFP(builder, src, vec_type, "");
-      res = LLVMBuildFMul(builder, res, lp_build_const_vec(dst_type, scale), "");
+      res = LLVMBuildFMul(builder, res,
+                          lp_build_const_vec(gallivm, dst_type, scale), "");
       return res;
    }
 
@@ -247,10 +255,11 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
 
    if(src_width > mantissa) {
       int shift = src_width - mantissa;
-      res = LLVMBuildLShr(builder, res, lp_build_const_int_vec(dst_type, shift), "");
+      res = LLVMBuildLShr(builder, res,
+                          lp_build_const_int_vec(gallivm, dst_type, shift), "");
    }
 
-   bias_ = lp_build_const_vec(dst_type, bias);
+   bias_ = lp_build_const_vec(gallivm, dst_type, bias);
 
    res = LLVMBuildOr(builder,
                      res,
@@ -259,7 +268,7 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
    res = LLVMBuildBitCast(builder, res, vec_type, "");
 
    res = LLVMBuildFSub(builder, res, bias_, "");
-   res = LLVMBuildFMul(builder, res, lp_build_const_vec(dst_type, scale), "");
+   res = LLVMBuildFMul(builder, res, lp_build_const_vec(gallivm, dst_type, scale), "");
 
    return res;
 }
@@ -272,12 +281,13 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
  * to the lp_type union.
  */
 void
-lp_build_conv(LLVMBuilderRef builder,
+lp_build_conv(struct gallivm_state *gallivm,
               struct lp_type src_type,
               struct lp_type dst_type,
               const LLVMValueRef *src, unsigned num_srcs,
               LLVMValueRef *dst, unsigned num_dsts)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type tmp_type;
    LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
    unsigned num_tmps;
@@ -342,12 +352,12 @@ lp_build_conv(LLVMBuilderRef builder,
          int32_type.length /= 4;
          int32_type.sign = 1;
 
-         src_vec_type   = lp_build_vec_type(src_type);
-         dst_vec_type   = lp_build_vec_type(dst_type);
-         int16_vec_type = lp_build_vec_type(int16_type);
-         int32_vec_type = lp_build_vec_type(int32_type);
+         src_vec_type   = lp_build_vec_type(gallivm, src_type);
+         dst_vec_type   = lp_build_vec_type(gallivm, dst_type);
+         int16_vec_type = lp_build_vec_type(gallivm, int16_type);
+         int32_vec_type = lp_build_vec_type(gallivm, int32_type);
 
-         const_255f = lp_build_const_vec(src_type, 255.0f);
+         const_255f = lp_build_const_vec(gallivm, src_type, 255.0f);
 
          a = LLVMBuildFMul(builder, src[0], const_255f, "");
          b = LLVMBuildFMul(builder, src[1], const_255f, "");
@@ -357,14 +367,14 @@ lp_build_conv(LLVMBuilderRef builder,
          {
             struct lp_build_context bld;
 
-            bld.builder = builder;
+            bld.gallivm = gallivm;
             bld.type = src_type;
             bld.vec_type = src_vec_type;
-            bld.int_elem_type = lp_build_elem_type(int32_type);
+            bld.int_elem_type = lp_build_elem_type(gallivm, int32_type);
             bld.int_vec_type = int32_vec_type;
-            bld.undef = lp_build_undef(src_type);
-            bld.zero = lp_build_zero(src_type);
-            bld.one = lp_build_one(src_type);
+            bld.undef = lp_build_undef(gallivm, src_type);
+            bld.zero = lp_build_zero(gallivm, src_type);
+            bld.one = lp_build_one(gallivm, src_type);
 
             src_int0 = lp_build_iround(&bld, a);
             src_int1 = lp_build_iround(&bld, b);
@@ -372,9 +382,9 @@ lp_build_conv(LLVMBuilderRef builder,
             src_int3 = lp_build_iround(&bld, d);
          }
          /* relying on clamping behavior of sse2 intrinsics here */
-         lo = lp_build_pack2(builder, int32_type, int16_type, src_int0, src_int1);
-         hi = lp_build_pack2(builder, int32_type, int16_type, src_int2, src_int3);
-         dst[i] = lp_build_pack2(builder, int16_type, dst_type, lo, hi);
+         lo = lp_build_pack2(gallivm, int32_type, int16_type, src_int0, src_int1);
+         hi = lp_build_pack2(gallivm, int32_type, int16_type, src_int2, src_int3);
+         dst[i] = lp_build_pack2(gallivm, int16_type, dst_type, lo, hi);
       }
       return; 
    }
@@ -391,13 +401,13 @@ lp_build_conv(LLVMBuilderRef builder,
       double dst_max = lp_const_max(dst_type);
       LLVMValueRef thres;
 
-      lp_build_context_init(&bld, builder, tmp_type);
+      lp_build_context_init(&bld, gallivm, tmp_type);
 
       if(src_min < dst_min) {
          if(dst_min == 0.0)
             thres = bld.zero;
          else
-            thres = lp_build_const_vec(src_type, dst_min);
+            thres = lp_build_const_vec(gallivm, src_type, dst_min);
          for(i = 0; i < num_tmps; ++i)
             tmp[i] = lp_build_max(&bld, tmp[i], thres);
       }
@@ -406,7 +416,7 @@ lp_build_conv(LLVMBuilderRef builder,
          if(dst_max == 1.0)
             thres = bld.one;
          else
-            thres = lp_build_const_vec(src_type, dst_max);
+            thres = lp_build_const_vec(gallivm, src_type, dst_max);
          for(i = 0; i < num_tmps; ++i)
             tmp[i] = lp_build_min(&bld, tmp[i], thres);
       }
@@ -422,7 +432,7 @@ lp_build_conv(LLVMBuilderRef builder,
    else if(tmp_type.floating) {
       if(!dst_type.fixed && !dst_type.sign && dst_type.norm) {
          for(i = 0; i < num_tmps; ++i) {
-            tmp[i] = lp_build_clamped_float_to_unsigned_norm(builder,
+            tmp[i] = lp_build_clamped_float_to_unsigned_norm(gallivm,
                                                              tmp_type,
                                                              dst_type.width,
                                                              tmp[i]);
@@ -434,14 +444,14 @@ lp_build_conv(LLVMBuilderRef builder,
          LLVMTypeRef tmp_vec_type;
 
          if (dst_scale != 1.0) {
-            LLVMValueRef scale = lp_build_const_vec(tmp_type, dst_scale);
+            LLVMValueRef scale = lp_build_const_vec(gallivm, tmp_type, dst_scale);
             for(i = 0; i < num_tmps; ++i)
                tmp[i] = LLVMBuildFMul(builder, tmp[i], scale, "");
          }
 
          /* Use an equally sized integer for intermediate computations */
          tmp_type.floating = FALSE;
-         tmp_vec_type = lp_build_vec_type(tmp_type);
+         tmp_vec_type = lp_build_vec_type(gallivm, tmp_type);
          for(i = 0; i < num_tmps; ++i) {
 #if 0
             if(dst_type.sign)
@@ -461,7 +471,8 @@ lp_build_conv(LLVMBuilderRef builder,
 
       /* FIXME: compensate different offsets too */
       if(src_shift > dst_shift) {
-         LLVMValueRef shift = lp_build_const_int_vec(tmp_type, src_shift - dst_shift);
+         LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type,
+                                                     src_shift - dst_shift);
          for(i = 0; i < num_tmps; ++i)
             if(src_type.sign)
                tmp[i] = LLVMBuildAShr(builder, tmp[i], shift, "");
@@ -485,7 +496,7 @@ lp_build_conv(LLVMBuilderRef builder,
       new_type.width  = dst_type.width;
       new_type.length = dst_type.length;
 
-      lp_build_resize(builder, tmp_type, new_type, tmp, num_srcs, tmp, num_dsts);
+      lp_build_resize(gallivm, tmp_type, new_type, tmp, num_srcs, tmp, num_dsts);
 
       tmp_type = new_type;
       num_tmps = num_dsts;
@@ -501,7 +512,7 @@ lp_build_conv(LLVMBuilderRef builder,
    else if(!src_type.floating && dst_type.floating) {
       if(!src_type.fixed && !src_type.sign && src_type.norm) {
          for(i = 0; i < num_tmps; ++i) {
-            tmp[i] = lp_build_unsigned_norm_to_float(builder,
+            tmp[i] = lp_build_unsigned_norm_to_float(gallivm,
                                                      src_type.width,
                                                      dst_type,
                                                      tmp[i]);
@@ -515,7 +526,7 @@ lp_build_conv(LLVMBuilderRef builder,
          /* Use an equally sized integer for intermediate computations */
          tmp_type.floating = TRUE;
          tmp_type.sign = TRUE;
-         tmp_vec_type = lp_build_vec_type(tmp_type);
+         tmp_vec_type = lp_build_vec_type(gallivm, tmp_type);
          for(i = 0; i < num_tmps; ++i) {
 #if 0
             if(dst_type.sign)
@@ -529,7 +540,7 @@ lp_build_conv(LLVMBuilderRef builder,
           }
 
           if (src_scale != 1.0) {
-             LLVMValueRef scale = lp_build_const_vec(tmp_type, 1.0/src_scale);
+             LLVMValueRef scale = lp_build_const_vec(gallivm, tmp_type, 1.0/src_scale);
              for(i = 0; i < num_tmps; ++i)
                 tmp[i] = LLVMBuildFMul(builder, tmp[i], scale, "");
           }
@@ -541,7 +552,7 @@ lp_build_conv(LLVMBuilderRef builder,
 
        /* FIXME: compensate different offsets too */
        if(src_shift < dst_shift) {
-          LLVMValueRef shift = lp_build_const_int_vec(tmp_type, dst_shift - src_shift);
+          LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type, dst_shift - src_shift);
           for(i = 0; i < num_tmps; ++i)
              tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
        }
@@ -565,7 +576,7 @@ lp_build_conv(LLVMBuilderRef builder,
  * This is basically a very trimmed down version of lp_build_conv.
  */
 void
-lp_build_conv_mask(LLVMBuilderRef builder,
+lp_build_conv_mask(struct gallivm_state *gallivm,
                    struct lp_type src_type,
                    struct lp_type dst_type,
                    const LLVMValueRef *src, unsigned num_srcs,
@@ -599,11 +610,11 @@ lp_build_conv_mask(LLVMBuilderRef builder,
 
    if(src_type.width > dst_type.width) {
       assert(num_dsts == 1);
-      dst[0] = lp_build_pack(builder, src_type, dst_type, TRUE, src, num_srcs);
+      dst[0] = lp_build_pack(gallivm, src_type, dst_type, TRUE, src, num_srcs);
    }
    else if(src_type.width < dst_type.width) {
       assert(num_srcs == 1);
-      lp_build_unpack(builder, src_type, dst_type, src[0], dst, num_dsts);
+      lp_build_unpack(gallivm, src_type, dst_type, src[0], dst, num_dsts);
    }
    else {
       assert(num_srcs == num_dsts);
index 628831c3adab720fae2dced62cecb7411128f67b..cec655980faa9532531e346a6ec0e7144480ae90 100644 (file)
@@ -44,27 +44,27 @@ struct lp_type;
 
 
 LLVMValueRef
-lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
+lp_build_clamped_float_to_unsigned_norm(struct gallivm_state *gallivm,
                                         struct lp_type src_type,
                                         unsigned dst_width,
                                         LLVMValueRef src);
 
 LLVMValueRef
-lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
+lp_build_unsigned_norm_to_float(struct gallivm_state *gallivm,
                                 unsigned src_width,
                                 struct lp_type dst_type,
                                 LLVMValueRef src);
 
 
 void
-lp_build_conv(LLVMBuilderRef builder,
+lp_build_conv(struct gallivm_state *gallivm,
               struct lp_type src_type,
               struct lp_type dst_type,
               const LLVMValueRef *srcs, unsigned num_srcs,
               LLVMValueRef *dsts, unsigned num_dsts);
 
 void
-lp_build_conv_mask(LLVMBuilderRef builder,
+lp_build_conv_mask(struct gallivm_state *gallivm,
                    struct lp_type src_type,
                    struct lp_type dst_type,
                    const LLVMValueRef *src, unsigned num_srcs,
index eb11dcd4ef4de25455ca2547af8ba0d031312761..8a58f95b78f34c06b3e8e9b9989695de28fbaaef 100644 (file)
@@ -42,6 +42,7 @@
 #define GALLIVM_DEBUG_NO_OPT        (1 << 3)
 #define GALLIVM_DEBUG_PERF          (1 << 4)
 #define GALLIVM_DEBUG_NO_BRILINEAR  (1 << 5)
+#define GALLIVM_DEBUG_GC            (1 << 6)
 
 
 #ifdef DEBUG
index a2cee199a010c4fcfdf4fcaf81fdad1763400c8b..a9c9c7af10c2d046fe28124b853c40b06af4d047 100644 (file)
@@ -34,6 +34,7 @@
 #include "util/u_debug.h"
 #include "util/u_memory.h"
 
+#include "lp_bld_init.h"
 #include "lp_bld_type.h"
 #include "lp_bld_flow.h"
 
  * be used elsewhere.
  */
 LLVMBasicBlockRef
-lp_build_insert_new_block(LLVMBuilderRef builder, const char *name)
+lp_build_insert_new_block(struct gallivm_state *gallivm, const char *name)
 {
    LLVMBasicBlockRef current_block;
    LLVMBasicBlockRef next_block;
    LLVMBasicBlockRef new_block;
 
    /* get current basic block */
-   current_block = LLVMGetInsertBlock(builder);
+   current_block = LLVMGetInsertBlock(gallivm->builder);
 
    /* check if there's another block after this one */
    next_block = LLVMGetNextBasicBlock(current_block);
    if (next_block) {
       /* insert the new block before the next block */
-      new_block = LLVMInsertBasicBlock(next_block, name);
+      new_block = LLVMInsertBasicBlockInContext(gallivm->context, next_block, name);
    }
    else {
       /* append new block after current block */
       LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
-      new_block = LLVMAppendBasicBlock(function, name);
+      new_block = LLVMAppendBasicBlockInContext(gallivm->context, function, name);
    }
 
    return new_block;
@@ -82,12 +83,11 @@ lp_build_insert_new_block(LLVMBuilderRef builder, const char *name)
  */
 void
 lp_build_flow_skip_begin(struct lp_build_skip_context *skip,
-                         LLVMBuilderRef builder)
+                         struct gallivm_state *gallivm)
 {
-   skip->builder = builder;
-
+   skip->gallivm = gallivm;
    /* create new basic block */
-   skip->block = lp_build_insert_new_block(skip->builder, "skip");
+   skip->block = lp_build_insert_new_block(gallivm, "skip");
 }
 
 
@@ -101,12 +101,12 @@ lp_build_flow_skip_cond_break(struct lp_build_skip_context *skip,
 {
    LLVMBasicBlockRef new_block;
 
-   new_block = lp_build_insert_new_block(skip->builder, "");
+   new_block = lp_build_insert_new_block(skip->gallivm, "");
 
    /* if cond is true, goto skip->block, else goto new_block */
-   LLVMBuildCondBr(skip->builder, cond, skip->block, new_block);
+   LLVMBuildCondBr(skip->gallivm->builder, cond, skip->block, new_block);
 
-   LLVMPositionBuilderAtEnd(skip->builder, new_block);
+   LLVMPositionBuilderAtEnd(skip->gallivm->builder, new_block);
 }
 
 
@@ -114,8 +114,8 @@ void
 lp_build_flow_skip_end(struct lp_build_skip_context *skip)
 {
    /* goto block */
-   LLVMBuildBr(skip->builder, skip->block);
-   LLVMPositionBuilderAtEnd(skip->builder, skip->block);
+   LLVMBuildBr(skip->gallivm->builder, skip->block);
+   LLVMPositionBuilderAtEnd(skip->gallivm->builder, skip->block);
 }
 
 
@@ -125,7 +125,7 @@ lp_build_flow_skip_end(struct lp_build_skip_context *skip)
 void
 lp_build_mask_check(struct lp_build_mask_context *mask)
 {
-   LLVMBuilderRef builder = mask->skip.builder;
+   LLVMBuilderRef builder = mask->skip.gallivm->builder;
    LLVMValueRef value;
    LLVMValueRef cond;
 
@@ -152,27 +152,27 @@ lp_build_mask_check(struct lp_build_mask_context *mask)
  */
 void
 lp_build_mask_begin(struct lp_build_mask_context *mask,
-                    LLVMBuilderRef builder,
+                    struct gallivm_state *gallivm,
                     struct lp_type type,
                     LLVMValueRef value)
 {
    memset(mask, 0, sizeof *mask);
 
-   mask->reg_type = LLVMIntType(type.width * type.length);
-   mask->var = lp_build_alloca(builder,
-                               lp_build_int_vec_type(type),
+   mask->reg_type = LLVMIntTypeInContext(gallivm->context, type.width * type.length);
+   mask->var = lp_build_alloca(gallivm,
+                               lp_build_int_vec_type(gallivm, type),
                                "execution_mask");
 
-   LLVMBuildStore(builder, value, mask->var);
+   LLVMBuildStore(gallivm->builder, value, mask->var);
 
-   lp_build_flow_skip_begin(&mask->skip, builder);
+   lp_build_flow_skip_begin(&mask->skip, gallivm);
 }
 
 
 LLVMValueRef
 lp_build_mask_value(struct lp_build_mask_context *mask)
 {
-   return LLVMBuildLoad(mask->skip.builder, mask->var, "");
+   return LLVMBuildLoad(mask->skip.gallivm->builder, mask->var, "");
 }
 
 
@@ -185,10 +185,10 @@ void
 lp_build_mask_update(struct lp_build_mask_context *mask,
                      LLVMValueRef value)
 {
-   value = LLVMBuildAnd(mask->skip.builder,
+   value = LLVMBuildAnd(mask->skip.gallivm->builder,
                         lp_build_mask_value(mask),
                         value, "");
-   LLVMBuildStore(mask->skip.builder, value, mask->var);
+   LLVMBuildStore(mask->skip.gallivm->builder, value, mask->var);
 }
 
 
@@ -205,13 +205,17 @@ lp_build_mask_end(struct lp_build_mask_context *mask)
 
 
 void
-lp_build_loop_begin(LLVMBuilderRef builder,
-                    LLVMValueRef start,
-                    struct lp_build_loop_state *state)
+lp_build_loop_begin(struct lp_build_loop_state *state,
+                    struct gallivm_state *gallivm,
+                    LLVMValueRef start)
+                    
 {
-   state->block = lp_build_insert_new_block(builder, "loop_begin");
+   LLVMBuilderRef builder = gallivm->builder;
+
+   state->block = lp_build_insert_new_block(gallivm, "loop_begin");
 
-   state->counter_var = lp_build_alloca(builder, LLVMTypeOf(start), "loop_counter");
+   state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter");
+   state->gallivm = gallivm;
 
    LLVMBuildStore(builder, start, state->counter_var);
 
@@ -224,12 +228,12 @@ lp_build_loop_begin(LLVMBuilderRef builder,
 
 
 void
-lp_build_loop_end_cond(LLVMBuilderRef builder,
+lp_build_loop_end_cond(struct lp_build_loop_state *state,
                        LLVMValueRef end,
                        LLVMValueRef step,
-                       LLVMIntPredicate llvm_cond,
-                       struct lp_build_loop_state *state)
+                       LLVMIntPredicate llvm_cond)
 {
+   LLVMBuilderRef builder = state->gallivm->builder;
    LLVMValueRef next;
    LLVMValueRef cond;
    LLVMBasicBlockRef after_block;
@@ -243,7 +247,7 @@ lp_build_loop_end_cond(LLVMBuilderRef builder,
 
    cond = LLVMBuildICmp(builder, llvm_cond, next, end, "");
 
-   after_block = lp_build_insert_new_block(builder, "loop_end");
+   after_block = lp_build_insert_new_block(state->gallivm, "loop_end");
 
    LLVMBuildCondBr(builder, cond, after_block, state->block);
 
@@ -254,12 +258,11 @@ lp_build_loop_end_cond(LLVMBuilderRef builder,
 
 
 void
-lp_build_loop_end(LLVMBuilderRef builder,
+lp_build_loop_end(struct lp_build_loop_state *state,
                   LLVMValueRef end,
-                  LLVMValueRef step,
-                  struct lp_build_loop_state *state)
+                  LLVMValueRef step)
 {
-   lp_build_loop_end_cond(builder, end, step, LLVMIntNE, state);
+   lp_build_loop_end_cond(state, end, step, LLVMIntNE);
 }
 
 
@@ -296,24 +299,27 @@ lp_build_loop_end(LLVMBuilderRef builder,
  */
 void
 lp_build_if(struct lp_build_if_state *ifthen,
-            LLVMBuilderRef builder,
+            struct gallivm_state *gallivm,
             LLVMValueRef condition)
 {
-   LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+   LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
 
    memset(ifthen, 0, sizeof *ifthen);
-   ifthen->builder = builder;
+   ifthen->gallivm = gallivm;
    ifthen->condition = condition;
    ifthen->entry_block = block;
 
    /* create endif/merge basic block for the phi functions */
-   ifthen->merge_block = lp_build_insert_new_block(builder, "endif-block");
+   ifthen->merge_block = lp_build_insert_new_block(gallivm, "endif-block");
 
    /* create/insert true_block before merge_block */
-   ifthen->true_block = LLVMInsertBasicBlock(ifthen->merge_block, "if-true-block");
+   ifthen->true_block =
+      LLVMInsertBasicBlockInContext(gallivm->context,
+                                    ifthen->merge_block,
+                                    "if-true-block");
 
    /* successive code goes into the true block */
-   LLVMPositionBuilderAtEnd(builder, ifthen->true_block);
+   LLVMPositionBuilderAtEnd(gallivm->builder, ifthen->true_block);
 }
 
 
@@ -323,14 +329,19 @@ lp_build_if(struct lp_build_if_state *ifthen,
 void
 lp_build_else(struct lp_build_if_state *ifthen)
 {
+   LLVMBuilderRef builder = ifthen->gallivm->builder;
+
    /* Append an unconditional Br(anch) instruction on the true_block */
-   LLVMBuildBr(ifthen->builder, ifthen->merge_block);
+   LLVMBuildBr(builder, ifthen->merge_block);
 
    /* create/insert false_block before the merge block */
-   ifthen->false_block = LLVMInsertBasicBlock(ifthen->merge_block, "if-false-block");
+   ifthen->false_block =
+      LLVMInsertBasicBlockInContext(ifthen->gallivm->context,
+                                    ifthen->merge_block,
+                                    "if-false-block");
 
    /* successive code goes into the else block */
-   LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->false_block);
+   LLVMPositionBuilderAtEnd(builder, ifthen->false_block);
 }
 
 
@@ -340,28 +351,30 @@ lp_build_else(struct lp_build_if_state *ifthen)
 void
 lp_build_endif(struct lp_build_if_state *ifthen)
 {
+   LLVMBuilderRef builder = ifthen->gallivm->builder;
+
    /* Insert branch to the merge block from current block */
-   LLVMBuildBr(ifthen->builder, ifthen->merge_block);
+   LLVMBuildBr(builder, ifthen->merge_block);
 
    /*
     * Now patch in the various branch instructions.
     */
 
    /* Insert the conditional branch instruction at the end of entry_block */
-   LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->entry_block);
+   LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
    if (ifthen->false_block) {
       /* we have an else clause */
-      LLVMBuildCondBr(ifthen->builder, ifthen->condition,
+      LLVMBuildCondBr(builder, ifthen->condition,
                       ifthen->true_block, ifthen->false_block);
    }
    else {
       /* no else clause */
-      LLVMBuildCondBr(ifthen->builder, ifthen->condition,
+      LLVMBuildCondBr(builder, ifthen->condition,
                       ifthen->true_block, ifthen->merge_block);
    }
 
    /* Resume building code at end of the ifthen->merge_block */
-   LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->merge_block);
+   LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
 }
 
 
@@ -381,15 +394,16 @@ lp_build_endif(struct lp_build_if_state *ifthen)
  * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
  */
 LLVMValueRef
-lp_build_alloca(LLVMBuilderRef builder,
+lp_build_alloca(struct gallivm_state *gallivm,
                 LLVMTypeRef type,
                 const char *name)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
    LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
    LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
    LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
-   LLVMBuilderRef first_builder = LLVMCreateBuilder();
+   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
    LLVMValueRef res;
 
    if (first_instr) {
@@ -422,16 +436,17 @@ lp_build_alloca(LLVMBuilderRef builder,
  * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
  */
 LLVMValueRef
-lp_build_array_alloca(LLVMBuilderRef builder,
+lp_build_array_alloca(struct gallivm_state *gallivm,
                       LLVMTypeRef type,
                       LLVMValueRef count,
                       const char *name)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
    LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
    LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
    LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
-   LLVMBuilderRef first_builder = LLVMCreateBuilder();
+   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
    LLVMValueRef res;
 
    if (first_instr) {
index e729ee6eaac5b1733e59e6461b974cf0885f843b..3cd5a9f42a54bdb14bc6782490e88205b16bdfd5 100644 (file)
@@ -47,7 +47,7 @@ struct lp_type;
  */
 struct lp_build_skip_context
 {
-   LLVMBuilderRef builder;
+   struct gallivm_state *gallivm;
 
    /** Block to skip to */
    LLVMBasicBlockRef block;
@@ -55,7 +55,7 @@ struct lp_build_skip_context
 
 void
 lp_build_flow_skip_begin(struct lp_build_skip_context *ctx,
-                         LLVMBuilderRef builder);
+                         struct gallivm_state *gallivm);
 
 void
 lp_build_flow_skip_cond_break(struct lp_build_skip_context *ctx,
@@ -77,7 +77,7 @@ struct lp_build_mask_context
 
 void
 lp_build_mask_begin(struct lp_build_mask_context *mask,
-                    LLVMBuilderRef builder,
+                    struct gallivm_state *gallivm,
                     struct lp_type type,
                     LLVMValueRef value);
 
@@ -107,31 +107,28 @@ lp_build_mask_end(struct lp_build_mask_context *mask);
  */
 struct lp_build_loop_state
 {
-  LLVMBasicBlockRef block;
-  LLVMValueRef counter_var;
-  LLVMValueRef counter;
+   LLVMBasicBlockRef block;
+   LLVMValueRef counter_var;
+   LLVMValueRef counter;
+   struct gallivm_state *gallivm;
 };
 
 
 void
-lp_build_loop_begin(LLVMBuilderRef builder,
-                    LLVMValueRef start,
-                    struct lp_build_loop_state *state);
-
+lp_build_loop_begin(struct lp_build_loop_state *state,
+                    struct gallivm_state *gallivm,
+                    LLVMValueRef start);
 
 void
-lp_build_loop_end(LLVMBuilderRef builder,
+lp_build_loop_end(struct lp_build_loop_state *state,
                   LLVMValueRef end,
-                  LLVMValueRef step,
-                  struct lp_build_loop_state *state);
+                  LLVMValueRef step);
 
 void
-lp_build_loop_end_cond(LLVMBuilderRef builder,
+lp_build_loop_end_cond(struct lp_build_loop_state *state,
                        LLVMValueRef end,
                        LLVMValueRef step,
-                       LLVMIntPredicate cond,
-                       struct lp_build_loop_state *state);
-
+                       LLVMIntPredicate cond);
 
 
 
@@ -140,7 +137,7 @@ lp_build_loop_end_cond(LLVMBuilderRef builder,
  */
 struct lp_build_if_state
 {
-   LLVMBuilderRef builder;
+   struct gallivm_state *gallivm;
    LLVMValueRef condition;
    LLVMBasicBlockRef entry_block;
    LLVMBasicBlockRef true_block;
@@ -151,7 +148,7 @@ struct lp_build_if_state
 
 void
 lp_build_if(struct lp_build_if_state *ctx,
-            LLVMBuilderRef builder,
+            struct gallivm_state *gallivm,
             LLVMValueRef condition);
 
 void
@@ -161,15 +158,15 @@ void
 lp_build_endif(struct lp_build_if_state *ctx);
 
 LLVMBasicBlockRef
-lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);
+lp_build_insert_new_block(struct gallivm_state *gallivm, const char *name);
 
 LLVMValueRef
-lp_build_alloca(LLVMBuilderRef builder,
+lp_build_alloca(struct gallivm_state *gallivm,
                 LLVMTypeRef type,
                 const char *name);
 
 LLVMValueRef
-lp_build_array_alloca(LLVMBuilderRef builder,
+lp_build_array_alloca(struct gallivm_state *gallivm,
                       LLVMTypeRef type,
                       LLVMValueRef count,
                       const char *name);
index 60e22d727ad456ef33b1117db1ed8057edee4ff3..04142d905b18ffc2ecbe3edbb4edfcd3ea58c7bd 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_init.h"
 
 #include "pipe/p_format.h"
 
@@ -53,12 +54,12 @@ lp_build_format_swizzle_aos(const struct util_format_description *desc,
                             LLVMValueRef unswizzled);
 
 LLVMValueRef
-lp_build_pack_rgba_aos(LLVMBuilderRef builder,
+lp_build_pack_rgba_aos(struct gallivm_state *gallivm,
                        const struct util_format_description *desc,
                        LLVMValueRef rgba);
 
 LLVMValueRef
-lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
+lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
                         const struct util_format_description *format_desc,
                         struct lp_type type,
                         LLVMValueRef base_ptr,
@@ -78,20 +79,20 @@ lp_build_format_swizzle_soa(const struct util_format_description *format_desc,
                             LLVMValueRef swizzled_out[4]);
 
 void
-lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
+lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
                          const struct util_format_description *format_desc,
                          struct lp_type type,
                          LLVMValueRef packed,
                          LLVMValueRef rgba_out[4]);
 
 void
-lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
+lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm,
                           struct lp_type dst_type,
                           LLVMValueRef packed,
                           LLVMValueRef *rgba);
 
 void
-lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
+lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
                         const struct util_format_description *format_desc,
                         struct lp_type type,
                         LLVMValueRef base_ptr,
@@ -106,7 +107,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder,
+lp_build_fetch_subsampled_rgba_aos(struct gallivm_state *gallivm,
                                    const struct util_format_description *format_desc,
                                    unsigned n,
                                    LLVMValueRef base_ptr,
index 6b9189e1da5a06f3a44c5ee199c4606a66e63cd1..75d2e666f09b440f6592fc2dd8f14c0771de65c3 100644 (file)
@@ -145,10 +145,11 @@ format_matches_type(const struct util_format_description *desc,
  * @return RGBA in a float[4] or ubyte[4] or ushort[4] vector.
  */
 static INLINE LLVMValueRef
-lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
+lp_build_unpack_arith_rgba_aos(struct gallivm_state *gallivm,
                                const struct util_format_description *desc,
                                LLVMValueRef packed)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef shifted, casted, scaled, masked;
    LLVMValueRef shifts[4];
    LLVMValueRef masks[4];
@@ -167,21 +168,21 @@ lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
 
    /* Do the intermediate integer computations with 32bit integers since it
     * matches floating point size */
-   assert (LLVMTypeOf(packed) == LLVMInt32Type());
+   assert (LLVMTypeOf(packed) == LLVMInt32TypeInContext(gallivm->context));
 
    /* Broadcast the packed value to all four channels
     * before: packed = BGRA
     * after: packed = {BGRA, BGRA, BGRA, BGRA}
     */
    packed = LLVMBuildInsertElement(builder,
-                                   LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
+                                   LLVMGetUndef(LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4)),
                                    packed,
-                                   LLVMConstNull(LLVMInt32Type()),
+                                   LLVMConstNull(LLVMInt32TypeInContext(gallivm->context)),
                                    "");
    packed = LLVMBuildShuffleVector(builder,
                                    packed,
-                                   LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
-                                   LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
+                                   LLVMGetUndef(LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4)),
+                                   LLVMConstNull(LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4)),
                                    "");
 
    /* Initialize vector constants */
@@ -194,9 +195,9 @@ lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
       unsigned bits = desc->channel[i].size;
 
       if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) {
-         shifts[i] = LLVMGetUndef(LLVMInt32Type());
-         masks[i] = LLVMConstNull(LLVMInt32Type());
-         scales[i] =  LLVMConstNull(LLVMFloatType());
+         shifts[i] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
+         masks[i] = LLVMConstNull(LLVMInt32TypeInContext(gallivm->context));
+         scales[i] =  LLVMConstNull(LLVMFloatTypeInContext(gallivm->context));
       }
       else {
          unsigned long long mask = (1ULL << bits) - 1;
@@ -207,15 +208,15 @@ lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
             needs_uitofp = TRUE;
          }
 
-         shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0);
-         masks[i] = LLVMConstInt(LLVMInt32Type(), mask, 0);
+         shifts[i] = lp_build_const_int32(gallivm, shift);
+         masks[i] = lp_build_const_int32(gallivm, mask);
 
          if (desc->channel[i].normalized) {
-            scales[i] = LLVMConstReal(LLVMFloatType(), 1.0/mask);
+            scales[i] = lp_build_const_float(gallivm, 1.0 / mask);
             normalized = TRUE;
          }
          else
-            scales[i] =  LLVMConstReal(LLVMFloatType(), 1.0);
+            scales[i] =  lp_build_const_float(gallivm, 1.0);
       }
 
       shift += bits;
@@ -230,9 +231,9 @@ lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
 
    if (!needs_uitofp) {
       /* UIToFP can't be expressed in SSE2 */
-      casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");
+      casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4), "");
    } else {
-      casted = LLVMBuildUIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");
+      casted = LLVMBuildUIToFP(builder, masked, LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4), "");
    }
 
    /* At this point 'casted' may be a vector of floats such as
@@ -258,10 +259,11 @@ lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
  * a time is rarely if ever needed.
  */
 LLVMValueRef
-lp_build_pack_rgba_aos(LLVMBuilderRef builder,
+lp_build_pack_rgba_aos(struct gallivm_state *gallivm,
                        const struct util_format_description *desc,
                        LLVMValueRef rgba)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMTypeRef type;
    LLVMValueRef packed = NULL;
    LLVMValueRef swizzles[4];
@@ -276,7 +278,7 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
    assert(desc->block.width == 1);
    assert(desc->block.height == 1);
 
-   type = LLVMIntType(desc->block.bits);
+   type = LLVMIntTypeInContext(gallivm->context, desc->block.bits);
 
    /* Unswizzle the color components into the source vector. */
    for (i = 0; i < 4; ++i) {
@@ -285,13 +287,13 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
             break;
       }
       if (j < 4)
-         swizzles[i] = LLVMConstInt(LLVMInt32Type(), j, 0);
+         swizzles[i] = lp_build_const_int32(gallivm, j);
       else
-         swizzles[i] = LLVMGetUndef(LLVMInt32Type());
+         swizzles[i] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
    }
 
    unswizzled = LLVMBuildShuffleVector(builder, rgba,
-                                       LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4)),
+                                       LLVMGetUndef(LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4)),
                                        LLVMConstVector(swizzles, 4), "");
 
    normalized = FALSE;
@@ -300,8 +302,8 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
       unsigned bits = desc->channel[i].size;
 
       if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) {
-         shifts[i] = LLVMGetUndef(LLVMInt32Type());
-         scales[i] =  LLVMGetUndef(LLVMFloatType());
+         shifts[i] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
+         scales[i] =  LLVMGetUndef(LLVMFloatTypeInContext(gallivm->context));
       }
       else {
          unsigned mask = (1 << bits) - 1;
@@ -309,14 +311,14 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
          assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED);
          assert(bits < 32);
 
-         shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0);
+         shifts[i] = lp_build_const_int32(gallivm, shift);
 
          if (desc->channel[i].normalized) {
-            scales[i] = LLVMConstReal(LLVMFloatType(), mask);
+            scales[i] = lp_build_const_float(gallivm, mask);
             normalized = TRUE;
          }
          else
-            scales[i] =  LLVMConstReal(LLVMFloatType(), 1.0);
+            scales[i] = lp_build_const_float(gallivm, 1.0);
       }
 
       shift += bits;
@@ -327,14 +329,15 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
    else
       scaled = unswizzled;
 
-   casted = LLVMBuildFPToSI(builder, scaled, LLVMVectorType(LLVMInt32Type(), 4), "");
+   casted = LLVMBuildFPToSI(builder, scaled, LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4), "");
 
    shifted = LLVMBuildShl(builder, casted, LLVMConstVector(shifts, 4), "");
    
    /* Bitwise or all components */
    for (i = 0; i < 4; ++i) {
       if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
-         LLVMValueRef component = LLVMBuildExtractElement(builder, shifted, LLVMConstInt(LLVMInt32Type(), i, 0), "");
+         LLVMValueRef component = LLVMBuildExtractElement(builder, shifted,
+                                               lp_build_const_int32(gallivm, i), "");
          if (packed)
             packed = LLVMBuildOr(builder, packed, component, "");
          else
@@ -343,7 +346,7 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
    }
 
    if (!packed)
-      packed = LLVMGetUndef(LLVMInt32Type());
+      packed = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
 
    if (desc->block.bits < 32)
       packed = LLVMBuildTrunc(builder, packed, type, "");
@@ -364,7 +367,7 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
  * \return  a 4 element vector with the pixel's RGBA values.
  */
 LLVMValueRef
-lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
+lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
                         const struct util_format_description *format_desc,
                         struct lp_type type,
                         LLVMValueRef base_ptr,
@@ -372,13 +375,14 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
                         LLVMValueRef i,
                         LLVMValueRef j)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    unsigned num_pixels = type.length / 4;
    struct lp_build_context bld;
 
    assert(type.length <= LP_MAX_VECTOR_LENGTH);
    assert(type.length % 4 == 0);
 
-   lp_build_context_init(&bld, builder, type);
+   lp_build_context_init(&bld, gallivm, type);
 
    /*
     * Trivial case
@@ -397,13 +401,14 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
        * scaling or converting.
        */
 
-      packed = lp_build_gather(builder, type.length/4,
+      packed = lp_build_gather(gallivm, type.length/4,
                                format_desc->block.bits, type.width*4,
                                base_ptr, offset);
 
       assert(format_desc->block.bits <= type.width * type.length);
 
-      packed = LLVMBuildBitCast(builder, packed, lp_build_vec_type(type), "");
+      packed = LLVMBuildBitCast(gallivm->builder, packed,
+                                lp_build_vec_type(gallivm, type), "");
 
       return lp_build_format_swizzle_aos(format_desc, &bld, packed);
    }
@@ -435,11 +440,12 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
       for (k = 0; k < num_pixels; ++k) {
          LLVMValueRef packed;
 
-         packed = lp_build_gather_elem(builder, num_pixels,
+         packed = lp_build_gather_elem(gallivm, num_pixels,
                                        format_desc->block.bits, 32,
                                        base_ptr, offset, k);
 
-         tmps[k] = lp_build_unpack_arith_rgba_aos(builder, format_desc,
+         tmps[k] = lp_build_unpack_arith_rgba_aos(gallivm,
+                                                  format_desc,
                                                   packed);
       }
 
@@ -455,7 +461,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
                       __FUNCTION__, format_desc->short_name);
       }
 
-      lp_build_conv(builder,
+      lp_build_conv(gallivm,
                     lp_float32_vec4_type(),
                     type,
                     tmps, num_pixels, &res, 1);
@@ -476,14 +482,14 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
       tmp_type.length = num_pixels * 4;
       tmp_type.norm = TRUE;
 
-      tmp = lp_build_fetch_subsampled_rgba_aos(builder,
+      tmp = lp_build_fetch_subsampled_rgba_aos(gallivm,
                                                format_desc,
                                                num_pixels,
                                                base_ptr,
                                                offset,
                                                i, j);
 
-      lp_build_conv(builder,
+      lp_build_conv(gallivm,
                     tmp_type, type,
                     &tmp, 1, &tmp, 1);
 
@@ -505,11 +511,11 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
        * or incentive to optimize.
        */
 
-      LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
+      LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
       char name[256];
-      LLVMTypeRef i8t = LLVMInt8Type();
+      LLVMTypeRef i8t = LLVMInt8TypeInContext(gallivm->context);
       LLVMTypeRef pi8t = LLVMPointerType(i8t, 0);
-      LLVMTypeRef i32t = LLVMInt32Type();
+      LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
       LLVMValueRef function;
       LLVMValueRef tmp_ptr;
       LLVMValueRef tmp;
@@ -533,10 +539,10 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
          LLVMTypeRef arg_types[4];
          LLVMTypeRef function_type;
 
-         ret_type = LLVMVoidType();
+         ret_type = LLVMVoidTypeInContext(gallivm->context);
          arg_types[0] = pi8t;
          arg_types[1] = pi8t;
-         arg_types[3] = arg_types[2] = LLVMIntType(sizeof(unsigned) * 8);
+         arg_types[3] = arg_types[2] = LLVMIntTypeInContext(gallivm->context, sizeof(unsigned) * 8);
          function_type = LLVMFunctionType(ret_type, arg_types, Elements(arg_types), 0);
          function = LLVMAddFunction(module, name, function_type);
 
@@ -545,11 +551,11 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
 
          assert(LLVMIsDeclaration(function));
 
-         LLVMAddGlobalMapping(lp_build_engine, function,
+         LLVMAddGlobalMapping(gallivm->engine, function,
                               func_to_pointer((func_pointer)format_desc->fetch_rgba_8unorm));
       }
 
-      tmp_ptr = lp_build_alloca(builder, i32t, "");
+      tmp_ptr = lp_build_alloca(gallivm, i32t, "");
 
       res = LLVMGetUndef(LLVMVectorType(i32t, num_pixels));
 
@@ -559,11 +565,11 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
        */
 
       for (k = 0; k < num_pixels; ++k) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0);
+         LLVMValueRef index = lp_build_const_int32(gallivm, k);
          LLVMValueRef args[4];
 
          args[0] = LLVMBuildBitCast(builder, tmp_ptr, pi8t, "");
-         args[1] = lp_build_gather_elem_ptr(builder, num_pixels,
+         args[1] = lp_build_gather_elem_ptr(gallivm, num_pixels,
                                             base_ptr, offset, k);
 
          if (num_pixels == 1) {
@@ -610,7 +616,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
 
       LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
       char name[256];
-      LLVMTypeRef f32t = LLVMFloatType();
+      LLVMTypeRef f32t = LLVMFloatTypeInContext(gallivm->context);
       LLVMTypeRef f32x4t = LLVMVectorType(f32t, 4);
       LLVMTypeRef pf32t = LLVMPointerType(f32t, 0);
       LLVMValueRef function;
@@ -636,10 +642,10 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
          LLVMTypeRef arg_types[4];
          LLVMTypeRef function_type;
 
-         ret_type = LLVMVoidType();
+         ret_type = LLVMVoidTypeInContext(gallivm->context);
          arg_types[0] = pf32t;
-         arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0);
-         arg_types[3] = arg_types[2] = LLVMIntType(sizeof(unsigned) * 8);
+         arg_types[1] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0);
+         arg_types[3] = arg_types[2] = LLVMIntTypeInContext(gallivm->context, sizeof(unsigned) * 8);
          function_type = LLVMFunctionType(ret_type, arg_types, Elements(arg_types), 0);
          function = LLVMAddFunction(module, name, function_type);
 
@@ -648,11 +654,11 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
 
          assert(LLVMIsDeclaration(function));
 
-         LLVMAddGlobalMapping(lp_build_engine, function,
+         LLVMAddGlobalMapping(gallivm->engine, function,
                               func_to_pointer((func_pointer)format_desc->fetch_rgba_float));
       }
 
-      tmp_ptr = lp_build_alloca(builder, f32x4t, "");
+      tmp_ptr = lp_build_alloca(gallivm, f32x4t, "");
 
       /*
        * Invoke format_desc->fetch_rgba_float() for each pixel and insert the result
@@ -663,7 +669,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
          LLVMValueRef args[4];
 
          args[0] = LLVMBuildBitCast(builder, tmp_ptr, pf32t, "");
-         args[1] = lp_build_gather_elem_ptr(builder, num_pixels,
+         args[1] = lp_build_gather_elem_ptr(gallivm, num_pixels,
                                             base_ptr, offset, k);
 
          if (num_pixels == 1) {
@@ -671,7 +677,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
             args[3] = j;
          }
          else {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm, k);
             args[2] = LLVMBuildExtractElement(builder, i, index, "");
             args[3] = LLVMBuildExtractElement(builder, j, index, "");
          }
@@ -681,7 +687,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
          tmps[k] = LLVMBuildLoad(builder, tmp_ptr, "");
       }
 
-      lp_build_conv(builder,
+      lp_build_conv(gallivm,
                     lp_float32_vec4_type(),
                     type,
                     tmps, num_pixels, &res, 1);
@@ -690,5 +696,5 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
    }
 
    assert(0);
-   return lp_build_undef(type);
+   return lp_build_undef(gallivm, type);
 }
index ce7e54afc76a49be536fe39bdaa0f91dc1ef2792..0a57b3ce794c6a9680829f1208ac0144afafaab8 100644 (file)
@@ -97,12 +97,13 @@ lp_build_format_swizzle_soa(const struct util_format_description *format_desc,
  * \param rgba_out  returns the SoA R,G,B,A vectors
  */
 void
-lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
+lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
                          const struct util_format_description *format_desc,
                          struct lp_type type,
                          LLVMValueRef packed,
                          LLVMValueRef rgba_out[4])
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_build_context bld;
    LLVMValueRef inputs[4];
    unsigned start;
@@ -116,7 +117,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
    assert(type.floating);
    assert(type.width == 32);
 
-   lp_build_context_init(&bld, builder, type);
+   lp_build_context_init(&bld, gallivm, type);
 
    /* Decode the input vector components */
    start = 0;
@@ -129,7 +130,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
       switch(format_desc->channel[chan].type) {
       case UTIL_FORMAT_TYPE_VOID:
-         input = lp_build_undef(type);
+         input = lp_build_undef(gallivm, type);
          break;
 
       case UTIL_FORMAT_TYPE_UNSIGNED:
@@ -138,7 +139,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
           */
 
          if (start) {
-            input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(type, start), "");
+            input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(gallivm, type, start), "");
          }
 
          /*
@@ -147,7 +148,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
          if (stop < format_desc->block.bits) {
             unsigned mask = ((unsigned long long)1 << width) - 1;
-            input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(type, mask), "");
+            input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(gallivm, type, mask), "");
          }
 
          /*
@@ -156,14 +157,15 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
          if (type.floating) {
             if(format_desc->channel[chan].normalized)
-               input = lp_build_unsigned_norm_to_float(builder, width, type, input);
+               input = lp_build_unsigned_norm_to_float(gallivm, width, type, input);
             else
-               input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(type), "");
+               input = LLVMBuildSIToFP(builder, input,
+                                       lp_build_vec_type(gallivm, type), "");
          }
          else {
             /* FIXME */
             assert(0);
-            input = lp_build_undef(type);
+            input = lp_build_undef(gallivm, type);
          }
 
          break;
@@ -175,7 +177,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
          if (stop < type.width) {
             unsigned bits = type.width - stop;
-            LLVMValueRef bits_val = lp_build_const_int_vec(type, bits);
+            LLVMValueRef bits_val = lp_build_const_int_vec(gallivm, type, bits);
             input = LLVMBuildShl(builder, input, bits_val, "");
          }
 
@@ -185,7 +187,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
          if (format_desc->channel[chan].size < type.width) {
             unsigned bits = type.width - format_desc->channel[chan].size;
-            LLVMValueRef bits_val = lp_build_const_int_vec(type, bits);
+            LLVMValueRef bits_val = lp_build_const_int_vec(gallivm, type, bits);
             input = LLVMBuildAShr(builder, input, bits_val, "");
          }
 
@@ -194,17 +196,17 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
           */
 
          if (type.floating) {
-            input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(type), "");
+            input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(gallivm, type), "");
             if (format_desc->channel[chan].normalized) {
                double scale = 1.0 / ((1 << (format_desc->channel[chan].size - 1)) - 1);
-               LLVMValueRef scale_val = lp_build_const_vec(type, scale);
+               LLVMValueRef scale_val = lp_build_const_vec(gallivm, type, scale);
                input = LLVMBuildFMul(builder, input, scale_val, "");
             }
          }
          else {
             /* FIXME */
             assert(0);
-            input = lp_build_undef(type);
+            input = lp_build_undef(gallivm, type);
          }
 
          break;
@@ -214,32 +216,32 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
             assert(start == 0);
             assert(stop == 32);
             assert(type.width == 32);
-            input = LLVMBuildBitCast(builder, input, lp_build_vec_type(type), "");
+            input = LLVMBuildBitCast(builder, input, lp_build_vec_type(gallivm, type), "");
          }
          else {
             /* FIXME */
             assert(0);
-            input = lp_build_undef(type);
+            input = lp_build_undef(gallivm, type);
          }
          break;
 
       case UTIL_FORMAT_TYPE_FIXED:
          if (type.floating) {
             double scale = 1.0 / ((1 << (format_desc->channel[chan].size/2)) - 1);
-            LLVMValueRef scale_val = lp_build_const_vec(type, scale);
-            input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(type), "");
+            LLVMValueRef scale_val = lp_build_const_vec(gallivm, type, scale);
+            input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(gallivm, type), "");
             input = LLVMBuildFMul(builder, input, scale_val, "");
          }
          else {
             /* FIXME */
             assert(0);
-            input = lp_build_undef(type);
+            input = lp_build_undef(gallivm, type);
          }
          break;
 
       default:
          assert(0);
-         input = lp_build_undef(type);
+         input = lp_build_undef(gallivm, type);
          break;
       }
 
@@ -253,16 +255,17 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
 
 void
-lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
+lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm,
                           struct lp_type dst_type,
                           LLVMValueRef packed,
                           LLVMValueRef *rgba)
 {
-   LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef mask = lp_build_const_int_vec(gallivm, dst_type, 0xff);
    unsigned chan;
 
    packed = LLVMBuildBitCast(builder, packed,
-                             lp_build_int_vec_type(dst_type), "");
+                             lp_build_int_vec_type(gallivm, dst_type), "");
 
    /* Decode the input vector components */
    for (chan = 0; chan < 4; ++chan) {
@@ -274,12 +277,12 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
 
       if (start)
          input = LLVMBuildLShr(builder, input,
-                               lp_build_const_int_vec(dst_type, start), "");
+                               lp_build_const_int_vec(gallivm, dst_type, start), "");
 
       if (stop < 32)
          input = LLVMBuildAnd(builder, input, mask, "");
 
-      input = lp_build_unsigned_norm_to_float(builder, 8, dst_type, input);
+      input = lp_build_unsigned_norm_to_float(gallivm, 8, dst_type, input);
 
       rgba[chan] = input;
    }
@@ -303,7 +306,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
  *              be in [0, block_width-1] and j will be in [0, block_height-1].
  */
 void
-lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
+lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
                         const struct util_format_description *format_desc,
                         struct lp_type type,
                         LLVMValueRef base_ptr,
@@ -312,6 +315,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
                         LLVMValueRef j,
                         LLVMValueRef rgba_out[4])
 {
+   LLVMBuilderRef builder = gallivm->builder;
 
    if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
        (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
@@ -334,7 +338,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
        * gather the texels from the texture
        * Ex: packed = {BGRA, BGRA, BGRA, BGRA}.
        */
-      packed = lp_build_gather(builder,
+      packed = lp_build_gather(gallivm,
                                type.length,
                                format_desc->block.bits,
                                type.width,
@@ -343,7 +347,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
       /*
        * convert texels to float rgba
        */
-      lp_build_unpack_rgba_soa(builder,
+      lp_build_unpack_rgba_soa(gallivm,
                                format_desc,
                                type,
                                packed, rgba_out);
@@ -364,10 +368,10 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
       tmp_type.length = type.length * 4;
       tmp_type.norm = TRUE;
 
-      tmp = lp_build_fetch_rgba_aos(builder, format_desc, tmp_type,
+      tmp = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type,
                                     base_ptr, offset, i, j);
 
-      lp_build_rgba8_to_f32_soa(builder,
+      lp_build_rgba8_to_f32_soa(gallivm,
                                 type,
                                 tmp,
                                 rgba_out);
@@ -397,23 +401,24 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
       tmp_type.length = 4;
 
       for (chan = 0; chan < 4; ++chan) {
-         rgba_out[chan] = lp_build_undef(type);
+         rgba_out[chan] = lp_build_undef(gallivm, type);
       }
 
       /* loop over number of pixels */
       for(k = 0; k < type.length; ++k) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0);
+         LLVMValueRef index = lp_build_const_int32(gallivm, k);
          LLVMValueRef offset_elem;
          LLVMValueRef i_elem, j_elem;
          LLVMValueRef tmp;
 
-         offset_elem = LLVMBuildExtractElement(builder, offset, index, "");
+         offset_elem = LLVMBuildExtractElement(builder, offset,
+                                               index, "");
 
          i_elem = LLVMBuildExtractElement(builder, i, index, "");
          j_elem = LLVMBuildExtractElement(builder, j, index, "");
 
          /* Get a single float[4]={R,G,B,A} pixel */
-         tmp = lp_build_fetch_rgba_aos(builder, format_desc, tmp_type,
+         tmp = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type,
                                        base_ptr, offset_elem,
                                        i_elem, j_elem);
 
@@ -422,7 +427,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
           * position = 'index'.
           */
          for (chan = 0; chan < 4; ++chan) {
-            LLVMValueRef chan_val = LLVMConstInt(LLVMInt32Type(), chan, 0),
+            LLVMValueRef chan_val = lp_build_const_int32(gallivm, chan),
             tmp_chan = LLVMBuildExtractElement(builder, tmp, chan_val, "");
             rgba_out[chan] = LLVMBuildInsertElement(builder, rgba_out[chan],
                                                     tmp_chan, index, "");
index 2bce2895551fb04e710141975d089f649230ec35..cdf1956c093ec6f5a6ada5451bc700634a0cf0ae 100644 (file)
@@ -43,6 +43,7 @@
 #include "lp_bld_conv.h"
 #include "lp_bld_gather.h"
 #include "lp_bld_format.h"
+#include "lp_bld_init.h"
 #include "lp_bld_logic.h"
 
 /**
@@ -51,7 +52,7 @@
  * @param i  is a <n x i32> vector with the x pixel coordinate (0 or 1)
  */
 static void
-uyvy_to_yuv_soa(LLVMBuilderRef builder,
+uyvy_to_yuv_soa(struct gallivm_state *gallivm,
                 unsigned n,
                 LLVMValueRef packed,
                 LLVMValueRef i,
@@ -59,6 +60,7 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder,
                 LLVMValueRef *u,
                 LLVMValueRef *v)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type type;
    LLVMValueRef mask;
 
@@ -86,25 +88,25 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder,
       LLVMValueRef sel, tmp, tmp2;
       struct lp_build_context bld32;
 
-      lp_build_context_init(&bld32, builder, type);
+      lp_build_context_init(&bld32, gallivm, type);
 
-      tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 8), "");
-      tmp2 = LLVMBuildLShr(builder, tmp, lp_build_const_int_vec(type, 16), "");
-      sel = lp_build_compare(builder, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(type, 0));
+      tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 8), "");
+      tmp2 = LLVMBuildLShr(builder, tmp, lp_build_const_int_vec(gallivm, type, 16), "");
+      sel = lp_build_compare(gallivm, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(gallivm, type, 0));
       *y = lp_build_select(&bld32, sel, tmp, tmp2);
    } else
 #endif
    {
       LLVMValueRef shift;
-      shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), "");
-      shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(type, 8), "");
+      shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(gallivm, type, 16), "");
+      shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(gallivm, type, 8), "");
       *y = LLVMBuildLShr(builder, packed, shift, "");
    }
 
    *u = packed;
-   *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 16), "");
+   *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 16), "");
 
-   mask = lp_build_const_int_vec(type, 0xff);
+   mask = lp_build_const_int_vec(gallivm, type, 0xff);
 
    *y = LLVMBuildAnd(builder, *y, mask, "y");
    *u = LLVMBuildAnd(builder, *u, mask, "u");
@@ -118,7 +120,7 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder,
  * @param i  is a <n x i32> vector with the x pixel coordinate (0 or 1)
  */
 static void
-yuyv_to_yuv_soa(LLVMBuilderRef builder,
+yuyv_to_yuv_soa(struct gallivm_state *gallivm,
                 unsigned n,
                 LLVMValueRef packed,
                 LLVMValueRef i,
@@ -126,6 +128,7 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder,
                 LLVMValueRef *u,
                 LLVMValueRef *v)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type type;
    LLVMValueRef mask;
 
@@ -153,23 +156,23 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder,
       LLVMValueRef sel, tmp;
       struct lp_build_context bld32;
 
-      lp_build_context_init(&bld32, builder, type);
+      lp_build_context_init(&bld32, gallivm, type);
 
-      tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 16), "");
-      sel = lp_build_compare(builder, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(type, 0));
+      tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 16), "");
+      sel = lp_build_compare(gallivm, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(gallivm, type, 0));
        *y = lp_build_select(&bld32, sel, packed, tmp);
    } else
 #endif
    {
       LLVMValueRef shift;
-      shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), "");
+      shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(gallivm, type, 16), "");
       *y = LLVMBuildLShr(builder, packed, shift, "");
    }
 
-   *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 8), "");
-   *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 24), "");
+   *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 8), "");
+   *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 24), "");
 
-   mask = lp_build_const_int_vec(type, 0xff);
+   mask = lp_build_const_int_vec(gallivm, type, 0xff);
 
    *y = LLVMBuildAnd(builder, *y, mask, "y");
    *u = LLVMBuildAnd(builder, *u, mask, "u");
@@ -178,11 +181,12 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder,
 
 
 static INLINE void
-yuv_to_rgb_soa(LLVMBuilderRef builder,
+yuv_to_rgb_soa(struct gallivm_state *gallivm,
                unsigned n,
                LLVMValueRef y, LLVMValueRef u, LLVMValueRef v,
                LLVMValueRef *r, LLVMValueRef *g, LLVMValueRef *b)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type type;
    struct lp_build_context bld;
 
@@ -203,7 +207,7 @@ yuv_to_rgb_soa(LLVMBuilderRef builder,
    type.width = 32;
    type.length = n;
 
-   lp_build_context_init(&bld, builder, type);
+   lp_build_context_init(&bld, gallivm, type);
 
    assert(lp_check_value(type, y));
    assert(lp_check_value(type, u));
@@ -213,17 +217,17 @@ yuv_to_rgb_soa(LLVMBuilderRef builder,
     * Constants
     */
 
-   c0   = lp_build_const_int_vec(type,   0);
-   c8   = lp_build_const_int_vec(type,   8);
-   c16  = lp_build_const_int_vec(type,  16);
-   c128 = lp_build_const_int_vec(type, 128);
-   c255 = lp_build_const_int_vec(type, 255);
+   c0   = lp_build_const_int_vec(gallivm, type,   0);
+   c8   = lp_build_const_int_vec(gallivm, type,   8);
+   c16  = lp_build_const_int_vec(gallivm, type,  16);
+   c128 = lp_build_const_int_vec(gallivm, type, 128);
+   c255 = lp_build_const_int_vec(gallivm, type, 255);
 
-   cy  = lp_build_const_int_vec(type,  298);
-   cug = lp_build_const_int_vec(type, -100);
-   cub = lp_build_const_int_vec(type,  516);
-   cvr = lp_build_const_int_vec(type,  409);
-   cvg = lp_build_const_int_vec(type, -208);
+   cy  = lp_build_const_int_vec(gallivm, type,  298);
+   cug = lp_build_const_int_vec(gallivm, type, -100);
+   cub = lp_build_const_int_vec(gallivm, type,  516);
+   cvr = lp_build_const_int_vec(gallivm, type,  409);
+   cvg = lp_build_const_int_vec(gallivm, type, -208);
 
    /*
     *  y -= 16;
@@ -276,10 +280,11 @@ yuv_to_rgb_soa(LLVMBuilderRef builder,
 
 
 static LLVMValueRef
-rgb_to_rgba_aos(LLVMBuilderRef builder,
+rgb_to_rgba_aos(struct gallivm_state *gallivm,
                 unsigned n,
                 LLVMValueRef r, LLVMValueRef g, LLVMValueRef b)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type type;
    LLVMValueRef a;
    LLVMValueRef rgba;
@@ -298,9 +303,9 @@ rgb_to_rgba_aos(LLVMBuilderRef builder,
     */
 
    r = r;
-   g = LLVMBuildShl(builder, g, lp_build_const_int_vec(type, 8), "");
-   b = LLVMBuildShl(builder, b, lp_build_const_int_vec(type, 16), "");
-   a = lp_build_const_int_vec(type, 0xff000000);
+   g = LLVMBuildShl(builder, g, lp_build_const_int_vec(gallivm, type, 8), "");
+   b = LLVMBuildShl(builder, b, lp_build_const_int_vec(gallivm, type, 16), "");
+   a = lp_build_const_int_vec(gallivm, type, 0xff000000);
 
    rgba = r;
    rgba = LLVMBuildOr(builder, rgba, g, "");
@@ -308,7 +313,7 @@ rgb_to_rgba_aos(LLVMBuilderRef builder,
    rgba = LLVMBuildOr(builder, rgba, a, "");
 
    rgba = LLVMBuildBitCast(builder, rgba,
-                           LLVMVectorType(LLVMInt8Type(), 4*n), "");
+                           LLVMVectorType(LLVMInt8TypeInContext(gallivm->context), 4*n), "");
 
    return rgba;
 }
@@ -318,7 +323,7 @@ rgb_to_rgba_aos(LLVMBuilderRef builder,
  * Convert from <n x i32> packed UYVY to <4n x i8> RGBA AoS
  */
 static LLVMValueRef
-uyvy_to_rgba_aos(LLVMBuilderRef builder,
+uyvy_to_rgba_aos(struct gallivm_state *gallivm,
                  unsigned n,
                  LLVMValueRef packed,
                  LLVMValueRef i)
@@ -327,9 +332,9 @@ uyvy_to_rgba_aos(LLVMBuilderRef builder,
    LLVMValueRef r, g, b;
    LLVMValueRef rgba;
 
-   uyvy_to_yuv_soa(builder, n, packed, i, &y, &u, &v);
-   yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b);
-   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+   uyvy_to_yuv_soa(gallivm, n, packed, i, &y, &u, &v);
+   yuv_to_rgb_soa(gallivm, n, y, u, v, &r, &g, &b);
+   rgba = rgb_to_rgba_aos(gallivm, n, r, g, b);
 
    return rgba;
 }
@@ -339,7 +344,7 @@ uyvy_to_rgba_aos(LLVMBuilderRef builder,
  * Convert from <n x i32> packed YUYV to <4n x i8> RGBA AoS
  */
 static LLVMValueRef
-yuyv_to_rgba_aos(LLVMBuilderRef builder,
+yuyv_to_rgba_aos(struct gallivm_state *gallivm,
                  unsigned n,
                  LLVMValueRef packed,
                  LLVMValueRef i)
@@ -348,9 +353,9 @@ yuyv_to_rgba_aos(LLVMBuilderRef builder,
    LLVMValueRef r, g, b;
    LLVMValueRef rgba;
 
-   yuyv_to_yuv_soa(builder, n, packed, i, &y, &u, &v);
-   yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b);
-   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+   yuyv_to_yuv_soa(gallivm, n, packed, i, &y, &u, &v);
+   yuv_to_rgb_soa(gallivm, n, y, u, v, &r, &g, &b);
+   rgba = rgb_to_rgba_aos(gallivm, n, r, g, b);
 
    return rgba;
 }
@@ -360,7 +365,7 @@ yuyv_to_rgba_aos(LLVMBuilderRef builder,
  * Convert from <n x i32> packed RG_BG to <4n x i8> RGBA AoS
  */
 static LLVMValueRef
-rgbg_to_rgba_aos(LLVMBuilderRef builder,
+rgbg_to_rgba_aos(struct gallivm_state *gallivm,
                  unsigned n,
                  LLVMValueRef packed,
                  LLVMValueRef i)
@@ -368,8 +373,8 @@ rgbg_to_rgba_aos(LLVMBuilderRef builder,
    LLVMValueRef r, g, b;
    LLVMValueRef rgba;
 
-   uyvy_to_yuv_soa(builder, n, packed, i, &g, &r, &b);
-   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+   uyvy_to_yuv_soa(gallivm, n, packed, i, &g, &r, &b);
+   rgba = rgb_to_rgba_aos(gallivm, n, r, g, b);
 
    return rgba;
 }
@@ -379,7 +384,7 @@ rgbg_to_rgba_aos(LLVMBuilderRef builder,
  * Convert from <n x i32> packed GR_GB to <4n x i8> RGBA AoS
  */
 static LLVMValueRef
-grgb_to_rgba_aos(LLVMBuilderRef builder,
+grgb_to_rgba_aos(struct gallivm_state *gallivm,
                  unsigned n,
                  LLVMValueRef packed,
                  LLVMValueRef i)
@@ -387,8 +392,8 @@ grgb_to_rgba_aos(LLVMBuilderRef builder,
    LLVMValueRef r, g, b;
    LLVMValueRef rgba;
 
-   yuyv_to_yuv_soa(builder, n, packed, i, &g, &r, &b);
-   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+   yuyv_to_yuv_soa(gallivm, n, packed, i, &g, &r, &b);
+   rgba = rgb_to_rgba_aos(gallivm, n, r, g, b);
 
    return rgba;
 }
@@ -401,7 +406,7 @@ grgb_to_rgba_aos(LLVMBuilderRef builder,
  * @return  a <4*n x i8> vector with the pixel RGBA values in AoS
  */
 LLVMValueRef
-lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder,
+lp_build_fetch_subsampled_rgba_aos(struct gallivm_state *gallivm,
                                    const struct util_format_description *format_desc,
                                    unsigned n,
                                    LLVMValueRef base_ptr,
@@ -417,26 +422,26 @@ lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder,
    assert(format_desc->block.width == 2);
    assert(format_desc->block.height == 1);
 
-   packed = lp_build_gather(builder, n, 32, 32, base_ptr, offset);
+   packed = lp_build_gather(gallivm, n, 32, 32, base_ptr, offset);
 
    (void)j;
 
    switch (format_desc->format) {
    case PIPE_FORMAT_UYVY:
-      rgba = uyvy_to_rgba_aos(builder, n, packed, i);
+      rgba = uyvy_to_rgba_aos(gallivm, n, packed, i);
       break;
    case PIPE_FORMAT_YUYV:
-      rgba = yuyv_to_rgba_aos(builder, n, packed, i);
+      rgba = yuyv_to_rgba_aos(gallivm, n, packed, i);
       break;
    case PIPE_FORMAT_R8G8_B8G8_UNORM:
-      rgba = rgbg_to_rgba_aos(builder, n, packed, i);
+      rgba = rgbg_to_rgba_aos(gallivm, n, packed, i);
       break;
    case PIPE_FORMAT_G8R8_G8B8_UNORM:
-      rgba = grgb_to_rgba_aos(builder, n, packed, i);
+      rgba = grgb_to_rgba_aos(gallivm, n, packed, i);
       break;
    default:
       assert(0);
-      rgba =  LLVMGetUndef(LLVMVectorType(LLVMInt8Type(), 4*n));
+      rgba =  LLVMGetUndef(LLVMVectorType(LLVMInt8TypeInContext(gallivm->context), 4*n));
       break;
    }
 
index d60472e06567385f324a70a73f4d0616f8af7488..0dc81b1abbedcb35077527a9c47ac296374fbd0b 100644 (file)
@@ -31,6 +31,7 @@
 #include "lp_bld_const.h"
 #include "lp_bld_format.h"
 #include "lp_bld_gather.h"
+#include "lp_bld_init.h"
 
 
 /**
@@ -39,7 +40,7 @@
  * @sa lp_build_gather()
  */
 LLVMValueRef
-lp_build_gather_elem_ptr(LLVMBuilderRef builder,
+lp_build_gather_elem_ptr(struct gallivm_state *gallivm,
                          unsigned length,
                          LLVMValueRef base_ptr,
                          LLVMValueRef offsets,
@@ -48,17 +49,17 @@ lp_build_gather_elem_ptr(LLVMBuilderRef builder,
    LLVMValueRef offset;
    LLVMValueRef ptr;
 
-   assert(LLVMTypeOf(base_ptr) == LLVMPointerType(LLVMInt8Type(), 0));
+   assert(LLVMTypeOf(base_ptr) == LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0));
 
    if (length == 1) {
       assert(i == 0);
       offset = offsets;
    } else {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      offset = LLVMBuildExtractElement(builder, offsets, index, "");
+      LLVMValueRef index = lp_build_const_int32(gallivm, i);
+      offset = LLVMBuildExtractElement(gallivm->builder, offsets, index, "");
    }
 
-   ptr = LLVMBuildGEP(builder, base_ptr, &offset, 1, "");
+   ptr = LLVMBuildGEP(gallivm->builder, base_ptr, &offset, 1, "");
 
    return ptr;
 }
@@ -70,7 +71,7 @@ lp_build_gather_elem_ptr(LLVMBuilderRef builder,
  * @sa lp_build_gather()
  */
 LLVMValueRef
-lp_build_gather_elem(LLVMBuilderRef builder,
+lp_build_gather_elem(struct gallivm_state *gallivm,
                      unsigned length,
                      unsigned src_width,
                      unsigned dst_width,
@@ -78,23 +79,23 @@ lp_build_gather_elem(LLVMBuilderRef builder,
                      LLVMValueRef offsets,
                      unsigned i)
 {
-   LLVMTypeRef src_type = LLVMIntType(src_width);
+   LLVMTypeRef src_type = LLVMIntTypeInContext(gallivm->context, src_width);
    LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
-   LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
+   LLVMTypeRef dst_elem_type = LLVMIntTypeInContext(gallivm->context, dst_width);
    LLVMValueRef ptr;
    LLVMValueRef res;
 
-   assert(LLVMTypeOf(base_ptr) == LLVMPointerType(LLVMInt8Type(), 0));
+   assert(LLVMTypeOf(base_ptr) == LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0));
 
-   ptr = lp_build_gather_elem_ptr(builder, length, base_ptr, offsets, i);
-   ptr = LLVMBuildBitCast(builder, ptr, src_ptr_type, "");
-   res = LLVMBuildLoad(builder, ptr, "");
+   ptr = lp_build_gather_elem_ptr(gallivm, length, base_ptr, offsets, i);
+   ptr = LLVMBuildBitCast(gallivm->builder, ptr, src_ptr_type, "");
+   res = LLVMBuildLoad(gallivm->builder, ptr, "");
 
    assert(src_width <= dst_width);
    if (src_width > dst_width)
-      res = LLVMBuildTrunc(builder, res, dst_elem_type, "");
+      res = LLVMBuildTrunc(gallivm->builder, res, dst_elem_type, "");
    if (src_width < dst_width)
-      res = LLVMBuildZExt(builder, res, dst_elem_type, "");
+      res = LLVMBuildZExt(gallivm->builder, res, dst_elem_type, "");
 
    return res;
 }
@@ -112,7 +113,7 @@ lp_build_gather_elem(LLVMBuilderRef builder,
  * @param offsets vector with offsets
  */
 LLVMValueRef
-lp_build_gather(LLVMBuilderRef builder,
+lp_build_gather(struct gallivm_state *gallivm,
                 unsigned length,
                 unsigned src_width,
                 unsigned dst_width,
@@ -123,24 +124,24 @@ lp_build_gather(LLVMBuilderRef builder,
 
    if (length == 1) {
       /* Scalar */
-      return lp_build_gather_elem(builder, length,
+      return lp_build_gather_elem(gallivm, length,
                                   src_width, dst_width,
                                   base_ptr, offsets, 0);
    } else {
       /* Vector */
 
-      LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
+      LLVMTypeRef dst_elem_type = LLVMIntTypeInContext(gallivm->context, dst_width);
       LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
       unsigned i;
 
       res = LLVMGetUndef(dst_vec_type);
       for (i = 0; i < length; ++i) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+         LLVMValueRef index = lp_build_const_int32(gallivm, i);
          LLVMValueRef elem;
-         elem = lp_build_gather_elem(builder, length,
+         elem = lp_build_gather_elem(gallivm, length,
                                      src_width, dst_width,
                                      base_ptr, offsets, i);
-         res = LLVMBuildInsertElement(builder, res, elem, index, "");
+         res = LLVMBuildInsertElement(gallivm->builder, res, elem, index, "");
       }
    }
 
index 131af8ea07ec1bae4a40616b79f8ad7b74cc3fb1..5b0413173027a68c86b0975cf7ad700cc8257a92 100644 (file)
 
 
 LLVMValueRef
-lp_build_gather_elem_ptr(LLVMBuilderRef builder,
+lp_build_gather_elem_ptr(struct gallivm_state *gallivm,
                          unsigned length,
                          LLVMValueRef base_ptr,
                          LLVMValueRef offsets,
                          unsigned i);
 
 LLVMValueRef
-lp_build_gather_elem(LLVMBuilderRef builder,
+lp_build_gather_elem(struct gallivm_state *gallivm,
                      unsigned length,
                      unsigned src_width,
                      unsigned dst_width,
@@ -50,7 +50,7 @@ lp_build_gather_elem(LLVMBuilderRef builder,
                      unsigned i);
 
 LLVMValueRef
-lp_build_gather(LLVMBuilderRef builder,
+lp_build_gather(struct gallivm_state *gallivm,
                 unsigned length,
                 unsigned src_width,
                 unsigned dst_width,
index 0b9a6f745fb648365991495275f568c8c34c07e7..efe8d38b8f069af68d7cca48e4502981196cd053 100644 (file)
@@ -29,6 +29,7 @@
 #include "pipe/p_compiler.h"
 #include "util/u_cpu_detect.h"
 #include "util/u_debug.h"
+#include "util/u_memory.h"
 #include "lp_bld_debug.h"
 #include "lp_bld_init.h"
 
@@ -45,6 +46,7 @@ static const struct debug_named_value lp_bld_debug_flags[] = {
    { "nopt",   GALLIVM_DEBUG_NO_OPT, NULL },
    { "perf",   GALLIVM_DEBUG_PERF, NULL },
    { "no_brilinear", GALLIVM_DEBUG_NO_BRILINEAR, NULL },
+   { "gc",     GALLIVM_DEBUG_GC, NULL },
    DEBUG_NAMED_VALUE_END
 };
 
@@ -52,11 +54,7 @@ DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags,
 #endif
 
 
-LLVMModuleRef lp_build_module = NULL;
-LLVMExecutionEngineRef lp_build_engine = NULL;
-LLVMModuleProviderRef lp_build_provider = NULL;
-LLVMTargetDataRef lp_build_target = NULL;
-LLVMPassManagerRef lp_build_pass = NULL;
+static boolean gallivm_initialized = FALSE;
 
 
 /*
@@ -82,6 +80,19 @@ enum LLVM_CodeGenOpt_Level {
 };
 
 
+/**
+ * LLVM 2.6 permits only one ExecutionEngine to be created.  This is it.
+ */
+static LLVMExecutionEngineRef GlobalEngine = NULL;
+
+/**
+ * Same gallivm state shared by all contexts.
+ */
+static struct gallivm_state *GlobalGallivm = NULL;
+
+
+
+
 extern void
 lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE);
 
@@ -89,26 +100,148 @@ extern void
 lp_set_target_options(void);
 
 
-void
-lp_build_init(void)
+
+/**
+ * Create the LLVM (optimization) pass manager and install
+ * relevant optimization passes.
+ * \return  TRUE for success, FALSE for failure
+ */
+static boolean
+create_pass_manager(struct gallivm_state *gallivm)
 {
-#ifdef DEBUG
-   gallivm_debug = debug_get_option_gallivm_debug();
+   assert(!gallivm->passmgr);
+
+   gallivm->passmgr = LLVMCreateFunctionPassManager(gallivm->provider);
+   if (!gallivm->passmgr)
+      return FALSE;
+
+   LLVMAddTargetData(gallivm->target, gallivm->passmgr);
+
+   if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
+      /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+       * but there are more on SVN.
+       * TODO: Add more passes.
+       */
+      LLVMAddCFGSimplificationPass(gallivm->passmgr);
+
+      if (HAVE_LLVM >= 0x207 && sizeof(void*) == 4) {
+         /* For LLVM >= 2.7 and 32-bit build, use this order of passes to
+          * avoid generating bad code.
+          * Test with piglit glsl-vs-sqrt-zero test.
+          */
+         LLVMAddConstantPropagationPass(gallivm->passmgr);
+         LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
+      }
+      else {
+         LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
+         LLVMAddConstantPropagationPass(gallivm->passmgr);
+      }
+
+      if (util_cpu_caps.has_sse4_1) {
+         /* FIXME: There is a bug in this pass, whereby the combination
+          * of fptosi and sitofp (necessary for trunc/floor/ceil/round
+          * implementation) somehow becomes invalid code.
+          */
+         LLVMAddInstructionCombiningPass(gallivm->passmgr);
+      }
+      LLVMAddGVNPass(gallivm->passmgr);
+   }
+   else {
+      /* We need at least this pass to prevent the backends to fail in
+       * unexpected ways.
+       */
+      LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
+   }
+
+   return TRUE;
+}
+
+
+/**
+ * Free gallivm object's LLVM allocations, but not the gallivm object itself.
+ */
+static void
+free_gallivm_state(struct gallivm_state *gallivm)
+{
+#if HAVE_LLVM >= 0x207 /* XXX or 0x208? */
+   /* This leads to crashes w/ some versions of LLVM */
+   LLVMModuleRef mod;
+   char *error;
+
+   if (gallivm->engine && gallivm->provider)
+      LLVMRemoveModuleProvider(gallivm->engine, gallivm->provider,
+                               &mod, &error);
 #endif
 
-   lp_set_target_options();
+#if 0
+   /* XXX this seems to crash with all versions of LLVM */
+   if (gallivm->provider)
+      LLVMDisposeModuleProvider(gallivm->provider);
+#endif
 
-   LLVMInitializeNativeTarget();
+   if (gallivm->passmgr)
+      LLVMDisposePassManager(gallivm->passmgr);
 
-   LLVMLinkInJIT();
+#if HAVE_LLVM >= 0x207
+   if (gallivm->module)
+      LLVMDisposeModule(gallivm->module);
+#endif
+
+#if 0
+   /* Don't free the exec engine, it's a global/singleton */
+   if (gallivm->engine)
+      LLVMDisposeExecutionEngine(gallivm->engine);
+#endif
+
+#if 0
+   /* Don't free the TargetData, it's owned by the exec engine */
+   LLVMDisposeTargetData(gallivm->target);
+#endif
+
+   if (gallivm->context)
+      LLVMContextDispose(gallivm->context);
 
-   if (!lp_build_module)
-      lp_build_module = LLVMModuleCreateWithName("gallivm");
+   if (gallivm->builder)
+      LLVMDisposeBuilder(gallivm->builder);
+
+   gallivm->engine = NULL;
+   gallivm->target = NULL;
+   gallivm->module = NULL;
+   gallivm->provider = NULL;
+   gallivm->passmgr = NULL;
+   gallivm->context = NULL;
+   gallivm->builder = NULL;
+}
 
-   if (!lp_build_provider)
-      lp_build_provider = LLVMCreateModuleProviderForExistingModule(lp_build_module);
 
-   if (!lp_build_engine) {
+/**
+ * Allocate gallivm LLVM objects.
+ * \return  TRUE for success, FALSE for failure
+ */
+static boolean
+init_gallivm_state(struct gallivm_state *gallivm)
+{
+   assert(gallivm_initialized);
+   assert(!gallivm->context);
+   assert(!gallivm->module);
+   assert(!gallivm->provider);
+
+   gallivm->context = LLVMContextCreate();
+   if (!gallivm->context)
+      goto fail;
+
+   gallivm->module = LLVMModuleCreateWithNameInContext("gallivm",
+                                                       gallivm->context);
+   if (!gallivm->module)
+      goto fail;
+
+   gallivm->provider =
+      LLVMCreateModuleProviderForExistingModule(gallivm->module);
+   if (!gallivm->provider)
+      goto fail;
+
+   if (!GlobalEngine) {
+      /* We can only create one LLVMExecutionEngine (w/ LLVM 2.6 anyway) */
       enum LLVM_CodeGenOpt_Level optlevel;
       char *error = NULL;
 
@@ -119,43 +252,152 @@ lp_build_init(void)
          optlevel = Default;
       }
 
-      if (LLVMCreateJITCompiler(&lp_build_engine, lp_build_provider,
-                                (unsigned)optlevel, &error)) {
+      if (LLVMCreateJITCompiler(&GlobalEngine, gallivm->provider,
+                                (unsigned) optlevel, &error)) {
          _debug_printf("%s\n", error);
          LLVMDisposeMessage(error);
-         assert(0);
+         goto fail;
       }
 
 #if defined(DEBUG) || defined(PROFILE)
-      lp_register_oprofile_jit_event_listener(lp_build_engine);
+      lp_register_oprofile_jit_event_listener(GlobalEngine);
 #endif
    }
 
-   if (!lp_build_target)
-      lp_build_target = LLVMGetExecutionEngineTargetData(lp_build_engine);
-
-   if (!lp_build_pass) {
-      lp_build_pass = LLVMCreateFunctionPassManager(lp_build_provider);
-      LLVMAddTargetData(lp_build_target, lp_build_pass);
-
-      if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
-         /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-          * but there are more on SVN. */
-         /* TODO: Add more passes */
-         LLVMAddCFGSimplificationPass(lp_build_pass);
-         LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
-         LLVMAddConstantPropagationPass(lp_build_pass);
-         LLVMAddInstructionCombiningPass(lp_build_pass);
-         LLVMAddGVNPass(lp_build_pass);
-      } else {
-         /* We need at least this pass to prevent the backends to fail in
-          * unexpected ways.
-          */
-         LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
+   gallivm->engine = GlobalEngine;
+
+   LLVMAddModuleProvider(gallivm->engine, gallivm->provider);//new
+
+   gallivm->target = LLVMGetExecutionEngineTargetData(gallivm->engine);
+   if (!gallivm->target)
+      goto fail;
+
+   if (!create_pass_manager(gallivm))
+      goto fail;
+
+   gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
+   if (!gallivm->builder)
+      goto fail;
+
+   return TRUE;
+
+fail:
+   free_gallivm_state(gallivm);
+   return FALSE;
+}
+
+
+struct callback
+{
+   garbage_collect_callback_func func;
+   void *cb_data;
+};
+
+
+#define MAX_CALLBACKS 32
+static struct callback Callbacks[MAX_CALLBACKS];
+static unsigned NumCallbacks = 0;
+
+
+/**
+ * Register a function with gallivm which will be called when we
+ * do garbage collection.
+ */
+void
+gallivm_register_garbage_collector_callback(garbage_collect_callback_func func,
+                                            void *cb_data)
+{
+   unsigned i;
+
+   for (i = 0; i < NumCallbacks; i++) {
+      if (Callbacks[i].func == func && Callbacks[i].cb_data == cb_data) {
+         /* already in list: no-op */
+         return;
+      }
+   }
+
+   assert(NumCallbacks < MAX_CALLBACKS);
+   if (NumCallbacks < MAX_CALLBACKS) {
+      Callbacks[NumCallbacks].func = func;
+      Callbacks[NumCallbacks].cb_data = cb_data;
+      NumCallbacks++;
+   }
+}
+
+
+/**
+ * Remove a callback.
+ */
+void
+gallivm_remove_garbage_collector_callback(garbage_collect_callback_func func,
+                                          void *cb_data)
+{
+   unsigned i;
+
+   for (i = 0; i < NumCallbacks; i++) {
+      if (Callbacks[i].func == func && Callbacks[i].cb_data == cb_data) {
+         /* found, now remove it */
+         NumCallbacks--;
+         for ( ; i < NumCallbacks; i++) {
+            Callbacks[i] = Callbacks[i + 1];
+         }
+         return;
       }
    }
+}
+
+
+/**
+ * Call the callback functions (which are typically in the
+ * draw module and llvmpipe driver.
+ */
+static void
+call_garbage_collector_callbacks(void)
+{
+   unsigned i;
+
+   for (i = 0; i < NumCallbacks; i++) {
+      Callbacks[i].func(Callbacks[i].cb_data);
+   }
+}
+
+
+
+/**
+ * Other gallium components using gallivm should call this periodically
+ * to let us do garbage collection (or at least try to free memory
+ * accumulated by the LLVM libraries).
+ */
+void
+gallivm_garbage_collect(struct gallivm_state *gallivm)
+{
+   if (gallivm->context) {
+      if (gallivm_debug & GALLIVM_DEBUG_GC)
+         debug_printf("***** Doing LLVM garbage collection\n");
+
+      call_garbage_collector_callbacks();
+      free_gallivm_state(gallivm);
+      init_gallivm_state(gallivm);
+   }
+}
+
+
+void
+lp_build_init(void)
+{
+#ifdef DEBUG
+   gallivm_debug = debug_get_option_gallivm_debug();
+#endif
+
+   lp_set_target_options();
+
+   LLVMInitializeNativeTarget();
+
+   LLVMLinkInJIT();
 
    util_cpu_detect();
+   gallivm_initialized = TRUE;
 
 #if 0
    /* For simulating less capable machines */
@@ -166,6 +408,39 @@ lp_build_init(void)
 }
 
 
+
+/**
+ * Create a new gallivm_state object.
+ * Note that we return a singleton.
+ */
+struct gallivm_state *
+gallivm_create(void)
+{
+   if (!GlobalGallivm) {
+      GlobalGallivm = CALLOC_STRUCT(gallivm_state);
+      if (GlobalGallivm) {
+         if (!init_gallivm_state(GlobalGallivm)) {
+            FREE(GlobalGallivm);
+            GlobalGallivm = NULL;
+         }
+      }
+   }
+   return GlobalGallivm;
+}
+
+
+/**
+ * Destroy a gallivm_state object.
+ */
+void
+gallivm_destroy(struct gallivm_state *gallivm)
+{
+   /* No-op: don't destroy the singleton */
+   (void) gallivm;
+}
+
+
+
 /* 
  * Hack to allow the linking of release LLVM static libraries on a debug build.
  *
index 0b4b1ca7d11d1d94f7bc07342cbd27dee8ad5198..f68bf75a8515df54506f97430b8ff914c84bacb1 100644 (file)
 #define LP_BLD_INIT_H
 
 
+#include "pipe/p_compiler.h"
 #include "lp_bld.h"
 #include <llvm-c/ExecutionEngine.h>
 
 
-extern LLVMModuleRef lp_build_module;
-extern LLVMExecutionEngineRef lp_build_engine;
-extern LLVMModuleProviderRef lp_build_provider;
-extern LLVMTargetDataRef lp_build_target;
-extern LLVMPassManagerRef lp_build_pass;
+struct gallivm_state
+{
+   LLVMModuleRef module;
+   LLVMExecutionEngineRef engine;
+   LLVMModuleProviderRef provider;
+   LLVMTargetDataRef target;
+   LLVMPassManagerRef passmgr;
+   LLVMContextRef context;
+   LLVMBuilderRef builder;
+};
 
 
 void
 lp_build_init(void);
 
+
 extern void
 lp_func_delete_body(LLVMValueRef func);
 
 
+void
+gallivm_garbage_collect(struct gallivm_state *gallivm);
+
+
+typedef void (*garbage_collect_callback_func)(void *cb_data);
+
+void
+gallivm_register_garbage_collector_callback(garbage_collect_callback_func func,
+                                            void *cb_data);
+
+void
+gallivm_remove_garbage_collector_callback(garbage_collect_callback_func func,
+                                          void *cb_data);
+
+
+struct gallivm_state *
+gallivm_create(void);
+
+void
+gallivm_destroy(struct gallivm_state *gallivm);
+
+
 extern LLVMValueRef
 lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
                        const char *Name);
index 9895749d5686978930db5537b2cf0e7be64b0d38..518a01fdb9f1b7ecec1196ab3e3f7d648d6b1785 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "util/u_debug.h"
 
+#include "lp_bld_const.h"
 #include "lp_bld_intr.h"
 
 
@@ -136,12 +137,13 @@ lp_build_intrinsic_binary(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_intrinsic_map(LLVMBuilderRef builder,
+lp_build_intrinsic_map(struct gallivm_state *gallivm,
                        const char *name,
                        LLVMTypeRef ret_type,
                        LLVMValueRef *args,
                        unsigned num_args)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type);
    unsigned n = LLVMGetVectorSize(ret_type);
    unsigned i, j;
@@ -151,7 +153,7 @@ lp_build_intrinsic_map(LLVMBuilderRef builder,
 
    res = LLVMGetUndef(ret_type);
    for(i = 0; i < n; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef index = lp_build_const_int32(gallivm, i);
       LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS];
       LLVMValueRef res_elem;
       for(j = 0; j < num_args; ++j)
@@ -165,17 +167,17 @@ lp_build_intrinsic_map(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_intrinsic_map_unary(LLVMBuilderRef builder,
+lp_build_intrinsic_map_unary(struct gallivm_state *gallivm,
                              const char *name,
                              LLVMTypeRef ret_type,
                              LLVMValueRef a)
 {
-   return lp_build_intrinsic_map(builder, name, ret_type, &a, 1);
+   return lp_build_intrinsic_map(gallivm, name, ret_type, &a, 1);
 }
 
 
 LLVMValueRef
-lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
+lp_build_intrinsic_map_binary(struct gallivm_state *gallivm,
                               const char *name,
                               LLVMTypeRef ret_type,
                               LLVMValueRef a,
@@ -186,7 +188,7 @@ lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
    args[0] = a;
    args[1] = b;
 
-   return lp_build_intrinsic_map(builder, name, ret_type, args, 2);
+   return lp_build_intrinsic_map(gallivm, name, ret_type, args, 2);
 }
 
 
index 977f7673228a0ba262cbbfb17c5b6bf0cadaeda8..b73dd700362b0f66a77e7535c82246058dfc6f48 100644 (file)
@@ -38,6 +38,7 @@
 
 
 #include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_init.h"
 
 
 /**
@@ -77,7 +78,7 @@ lp_build_intrinsic_binary(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_intrinsic_map(LLVMBuilderRef builder,
+lp_build_intrinsic_map(struct gallivm_state *gallivm,
                        const char *name,
                        LLVMTypeRef ret_type,
                        LLVMValueRef *args,
@@ -85,14 +86,14 @@ lp_build_intrinsic_map(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_intrinsic_map_unary(LLVMBuilderRef builder,
+lp_build_intrinsic_map_unary(struct gallivm_state *gallivm,
                              const char *name,
                              LLVMTypeRef ret_type,
                              LLVMValueRef a);
 
 
 LLVMValueRef
-lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
+lp_build_intrinsic_map_binary(struct gallivm_state *gallivm,
                               const char *name,
                               LLVMTypeRef ret_type,
                               LLVMValueRef a,
index 026b60ac36ef28b872896c9ab8fc80d1e730990d..f7e6fbaff1a2aaad405167986db40fb0bcd1610a 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
 #include "lp_bld_intr.h"
 #include "lp_bld_debug.h"
 #include "lp_bld_logic.h"
  * The result values will be 0 for false or ~0 for true.
  */
 LLVMValueRef
-lp_build_compare(LLVMBuilderRef builder,
+lp_build_compare(struct gallivm_state *gallivm,
                  const struct lp_type type,
                  unsigned func,
                  LLVMValueRef a,
                  LLVMValueRef b)
 {
-   LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(gallivm, type);
    LLVMValueRef zeros = LLVMConstNull(int_vec_type);
    LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
    LLVMValueRef cond;
@@ -115,7 +117,7 @@ lp_build_compare(LLVMBuilderRef builder,
    if(type.width * type.length == 128) {
       if(type.floating && util_cpu_caps.has_sse) {
          /* float[4] comparison */
-         LLVMTypeRef vec_type = lp_build_vec_type(type);
+         LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type);
          LLVMValueRef args[3];
          unsigned cc;
          boolean swap;
@@ -144,7 +146,7 @@ lp_build_compare(LLVMBuilderRef builder,
             break;
          default:
             assert(0);
-            return lp_build_undef(type);
+            return lp_build_undef(gallivm, type);
          }
 
          if(swap) {
@@ -156,7 +158,7 @@ lp_build_compare(LLVMBuilderRef builder,
             args[1] = b;
          }
 
-         args[2] = LLVMConstInt(LLVMInt8Type(), cc, 0);
+         args[2] = LLVMConstInt(LLVMInt8TypeInContext(gallivm->context), cc, 0);
          res = lp_build_intrinsic(builder,
                                   "llvm.x86.sse.cmp.ps",
                                   vec_type,
@@ -185,7 +187,7 @@ lp_build_compare(LLVMBuilderRef builder,
          const char *pcmpgt;
          LLVMValueRef args[2];
          LLVMValueRef res;
-         LLVMTypeRef vec_type = lp_build_vec_type(type);
+         LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type);
 
          switch (type.width) {
          case 8:
@@ -202,14 +204,14 @@ lp_build_compare(LLVMBuilderRef builder,
             break;
          default:
             assert(0);
-            return lp_build_undef(type);
+            return lp_build_undef(gallivm, type);
          }
 
          /* There are no unsigned comparison instructions. So flip the sign bit
           * so that the results match.
           */
          if (table[func].gt && !type.sign) {
-            LLVMValueRef msb = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
+            LLVMValueRef msb = lp_build_const_int_vec(gallivm, type, (unsigned long long)1 << (type.width - 1));
             a = LLVMBuildXor(builder, a, msb, "");
             b = LLVMBuildXor(builder, b, msb, "");
          }
@@ -270,7 +272,7 @@ lp_build_compare(LLVMBuilderRef builder,
          break;
       default:
          assert(0);
-         return lp_build_undef(type);
+         return lp_build_undef(gallivm, type);
       }
 
 #if HAVE_LLVM >= 0x0207
@@ -289,7 +291,7 @@ lp_build_compare(LLVMBuilderRef builder,
          debug_printf("%s: warning: using slow element-wise float"
                       " vector comparison\n", __FUNCTION__);
          for (i = 0; i < type.length; ++i) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm, i);
             cond = LLVMBuildFCmp(builder, op,
                                  LLVMBuildExtractElement(builder, a, index, ""),
                                  LLVMBuildExtractElement(builder, b, index, ""),
@@ -326,7 +328,7 @@ lp_build_compare(LLVMBuilderRef builder,
          break;
       default:
          assert(0);
-         return lp_build_undef(type);
+         return lp_build_undef(gallivm, type);
       }
 
 #if HAVE_LLVM >= 0x0207
@@ -348,7 +350,7 @@ lp_build_compare(LLVMBuilderRef builder,
          }
 
          for(i = 0; i < type.length; ++i) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm, i);
             cond = LLVMBuildICmp(builder, op,
                                  LLVMBuildExtractElement(builder, a, index, ""),
                                  LLVMBuildExtractElement(builder, b, index, ""),
@@ -379,7 +381,7 @@ lp_build_cmp(struct lp_build_context *bld,
              LLVMValueRef a,
              LLVMValueRef b)
 {
-   return lp_build_compare(bld->builder, bld->type, func, a, b);
+   return lp_build_compare(bld->gallivm, bld->type, func, a, b);
 }
 
 
@@ -392,6 +394,7 @@ lp_build_select_bitwise(struct lp_build_context *bld,
                         LLVMValueRef a,
                         LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -403,25 +406,25 @@ lp_build_select_bitwise(struct lp_build_context *bld,
    }
 
    if(type.floating) {
-      LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
-      a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
-      b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
+      a = LLVMBuildBitCast(builder, a, int_vec_type, "");
+      b = LLVMBuildBitCast(builder, b, int_vec_type, "");
    }
 
-   a = LLVMBuildAnd(bld->builder, a, mask, "");
+   a = LLVMBuildAnd(builder, a, mask, "");
 
    /* This often gets translated to PANDN, but sometimes the NOT is
     * pre-computed and stored in another constant. The best strategy depends
     * on available registers, so it is not a big deal -- hopefully LLVM does
     * the right decision attending the rest of the program.
     */
-   b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
+   b = LLVMBuildAnd(builder, b, LLVMBuildNot(builder, mask, ""), "");
 
-   res = LLVMBuildOr(bld->builder, a, b, "");
+   res = LLVMBuildOr(builder, a, b, "");
 
    if(type.floating) {
-      LLVMTypeRef vec_type = lp_build_vec_type(type);
-      res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+      res = LLVMBuildBitCast(builder, res, vec_type, "");
    }
 
    return res;
@@ -440,6 +443,8 @@ lp_build_select(struct lp_build_context *bld,
                 LLVMValueRef a,
                 LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMContextRef lc = bld->gallivm->context;
    struct lp_type type = bld->type;
    LLVMValueRef res;
 
@@ -450,8 +455,8 @@ lp_build_select(struct lp_build_context *bld,
       return a;
 
    if (type.length == 1) {
-      mask = LLVMBuildTrunc(bld->builder, mask, LLVMInt1Type(), "");
-      res = LLVMBuildSelect(bld->builder, mask, a, b, "");
+      mask = LLVMBuildTrunc(builder, mask, LLVMInt1TypeInContext(lc), "");
+      res = LLVMBuildSelect(builder, mask, a, b, "");
    }
    else if (util_cpu_caps.has_sse4_1 &&
             type.width * type.length == 128 &&
@@ -465,34 +470,34 @@ lp_build_select(struct lp_build_context *bld,
       if (type.floating &&
           type.width == 64) {
          intrinsic = "llvm.x86.sse41.blendvpd";
-         arg_type = LLVMVectorType(LLVMDoubleType(), 2);
+         arg_type = LLVMVectorType(LLVMDoubleTypeInContext(lc), 2);
       } else if (type.floating &&
                  type.width == 32) {
          intrinsic = "llvm.x86.sse41.blendvps";
-         arg_type = LLVMVectorType(LLVMFloatType(), 4);
+         arg_type = LLVMVectorType(LLVMFloatTypeInContext(lc), 4);
       } else {
          intrinsic = "llvm.x86.sse41.pblendvb";
-         arg_type = LLVMVectorType(LLVMInt8Type(), 16);
+         arg_type = LLVMVectorType(LLVMInt8TypeInContext(lc), 16);
       }
 
       if (arg_type != bld->int_vec_type) {
-         mask = LLVMBuildBitCast(bld->builder, mask, arg_type, "");
+         mask = LLVMBuildBitCast(builder, mask, arg_type, "");
       }
 
       if (arg_type != bld->vec_type) {
-         a = LLVMBuildBitCast(bld->builder, a, arg_type, "");
-         b = LLVMBuildBitCast(bld->builder, b, arg_type, "");
+         a = LLVMBuildBitCast(builder, a, arg_type, "");
+         b = LLVMBuildBitCast(builder, b, arg_type, "");
       }
 
       args[0] = b;
       args[1] = a;
       args[2] = mask;
 
-      res = lp_build_intrinsic(bld->builder, intrinsic,
+      res = lp_build_intrinsic(builder, intrinsic,
                                arg_type, args, Elements(args));
 
       if (arg_type != bld->vec_type) {
-         res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+         res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
       }
    }
    else {
@@ -514,6 +519,7 @@ lp_build_select_aos(struct lp_build_context *bld,
                     LLVMValueRef a,
                     LLVMValueRef b)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    const unsigned n = type.length;
    unsigned i, j;
@@ -544,7 +550,7 @@ lp_build_select_aos(struct lp_build_context *bld,
       /*
        * Shuffle.
        */
-      LLVMTypeRef elem_type = LLVMInt32Type();
+      LLVMTypeRef elem_type = LLVMInt32TypeInContext(bld->gallivm->context);
       LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
 
       for(j = 0; j < n; j += 4)
@@ -553,7 +559,7 @@ lp_build_select_aos(struct lp_build_context *bld,
                                            (mask & (1 << i) ? 0 : n) + j + i,
                                            0);
 
-      return LLVMBuildShuffleVector(bld->builder, a, b, LLVMConstVector(shuffles, n), "");
+      return LLVMBuildShuffleVector(builder, a, b, LLVMConstVector(shuffles, n), "");
    }
    else {
 #if 0
@@ -567,9 +573,9 @@ lp_build_select_aos(struct lp_build_context *bld,
             cond_vec[j + i] = LLVMConstInt(elem_type,
                                            mask & (1 << i) ? 1 : 0, 0);
 
-      return LLVMBuildSelect(bld->builder, LLVMConstVector(cond_vec, n), a, b, "");
+      return LLVMBuildSelect(builder, LLVMConstVector(cond_vec, n), a, b, "");
 #else
-      LLVMValueRef mask_vec = lp_build_const_mask_aos(type, mask);
+      LLVMValueRef mask_vec = lp_build_const_mask_aos(bld->gallivm, type, mask);
       return lp_build_select(bld, mask_vec, a, b);
 #endif
    }
index 141fb92058a8d8ef6c568122671b656f0d05ef24..ef33a65368242a74d6bf793587ac119900020d30 100644 (file)
@@ -47,7 +47,7 @@ struct lp_build_context;
 
 
 LLVMValueRef
-lp_build_compare(LLVMBuilderRef builder,
+lp_build_compare(struct gallivm_state *gallivm,
                  const struct lp_type type,
                  unsigned func,
                  LLVMValueRef a,
index f7eb7148ab8332866c84c2982b8d12cda18c523d..fde6bb594f17d64864cf970256caadafee3576ce 100644 (file)
@@ -72,6 +72,7 @@
 
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
 #include "lp_bld_intr.h"
 #include "lp_bld_arit.h"
 #include "lp_bld_pack.h"
@@ -81,7 +82,8 @@
  * Build shuffle vectors that match PUNPCKLxx and PUNPCKHxx instructions.
  */
 static LLVMValueRef
-lp_build_const_unpack_shuffle(unsigned n, unsigned lo_hi)
+lp_build_const_unpack_shuffle(struct gallivm_state *gallivm,
+                              unsigned n, unsigned lo_hi)
 {
    LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
    unsigned i, j;
@@ -92,8 +94,8 @@ lp_build_const_unpack_shuffle(unsigned n, unsigned lo_hi)
    /* TODO: cache results in a static table */
 
    for(i = 0, j = lo_hi*n/2; i < n; i += 2, ++j) {
-      elems[i + 0] = LLVMConstInt(LLVMInt32Type(), 0 + j, 0);
-      elems[i + 1] = LLVMConstInt(LLVMInt32Type(), n + j, 0);
+      elems[i + 0] = lp_build_const_int32(gallivm, 0 + j);
+      elems[i + 1] = lp_build_const_int32(gallivm, n + j);
    }
 
    return LLVMConstVector(elems, n);
@@ -104,7 +106,7 @@ lp_build_const_unpack_shuffle(unsigned n, unsigned lo_hi)
  * Build shuffle vectors that match PACKxx instructions.
  */
 static LLVMValueRef
-lp_build_const_pack_shuffle(unsigned n)
+lp_build_const_pack_shuffle(struct gallivm_state *gallivm, unsigned n)
 {
    LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
    unsigned i;
@@ -112,7 +114,7 @@ lp_build_const_pack_shuffle(unsigned n)
    assert(n <= LP_MAX_VECTOR_LENGTH);
 
    for(i = 0; i < n; ++i)
-      elems[i] = LLVMConstInt(LLVMInt32Type(), 2*i, 0);
+      elems[i] = lp_build_const_int32(gallivm, 2*i);
 
    return LLVMConstVector(elems, n);
 }
@@ -124,7 +126,7 @@ lp_build_const_pack_shuffle(unsigned n)
  * Matches the PUNPCKLxx and PUNPCKHxx SSE instructions.
  */
 LLVMValueRef
-lp_build_interleave2(LLVMBuilderRef builder,
+lp_build_interleave2(struct gallivm_state *gallivm,
                      struct lp_type type,
                      LLVMValueRef a,
                      LLVMValueRef b,
@@ -132,9 +134,9 @@ lp_build_interleave2(LLVMBuilderRef builder,
 {
    LLVMValueRef shuffle;
 
-   shuffle = lp_build_const_unpack_shuffle(type.length, lo_hi);
+   shuffle = lp_build_const_unpack_shuffle(gallivm, type.length, lo_hi);
 
-   return LLVMBuildShuffleVector(builder, a, b, shuffle, "");
+   return LLVMBuildShuffleVector(gallivm->builder, a, b, shuffle, "");
 }
 
 
@@ -145,13 +147,14 @@ lp_build_interleave2(LLVMBuilderRef builder,
  * values themselves.
  */
 void
-lp_build_unpack2(LLVMBuilderRef builder,
+lp_build_unpack2(struct gallivm_state *gallivm,
                  struct lp_type src_type,
                  struct lp_type dst_type,
                  LLVMValueRef src,
                  LLVMValueRef *dst_lo,
                  LLVMValueRef *dst_hi)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef msb;
    LLVMTypeRef dst_vec_type;
 
@@ -162,24 +165,24 @@ lp_build_unpack2(LLVMBuilderRef builder,
 
    if(dst_type.sign && src_type.sign) {
       /* Replicate the sign bit in the most significant bits */
-      msb = LLVMBuildAShr(builder, src, lp_build_const_int_vec(src_type, src_type.width - 1), "");
+      msb = LLVMBuildAShr(builder, src, lp_build_const_int_vec(gallivm, src_type, src_type.width - 1), "");
    }
    else
       /* Most significant bits always zero */
-      msb = lp_build_zero(src_type);
+      msb = lp_build_zero(gallivm, src_type);
 
    /* Interleave bits */
 #ifdef PIPE_ARCH_LITTLE_ENDIAN
-      *dst_lo = lp_build_interleave2(builder, src_type, src, msb, 0);
-      *dst_hi = lp_build_interleave2(builder, src_type, src, msb, 1);
+   *dst_lo = lp_build_interleave2(gallivm, src_type, src, msb, 0);
+   *dst_hi = lp_build_interleave2(gallivm, src_type, src, msb, 1);
 #else
-      *dst_lo = lp_build_interleave2(builder, src_type, msb, src, 0);
-      *dst_hi = lp_build_interleave2(builder, src_type, msb, src, 1);
+   *dst_lo = lp_build_interleave2(gallivm, src_type, msb, src, 0);
+   *dst_hi = lp_build_interleave2(gallivm, src_type, msb, src, 1);
 #endif
 
    /* Cast the result into the new type (twice as wide) */
 
-   dst_vec_type = lp_build_vec_type(dst_type);
+   dst_vec_type = lp_build_vec_type(gallivm, dst_type);
 
    *dst_lo = LLVMBuildBitCast(builder, *dst_lo, dst_vec_type, "");
    *dst_hi = LLVMBuildBitCast(builder, *dst_hi, dst_vec_type, "");
@@ -193,7 +196,7 @@ lp_build_unpack2(LLVMBuilderRef builder,
  * values themselves.
  */
 void
-lp_build_unpack(LLVMBuilderRef builder,
+lp_build_unpack(struct gallivm_state *gallivm,
                 struct lp_type src_type,
                 struct lp_type dst_type,
                 LLVMValueRef src,
@@ -218,7 +221,7 @@ lp_build_unpack(LLVMBuilderRef builder,
       tmp_type.length /= 2;
 
       for(i = num_tmps; i--; ) {
-         lp_build_unpack2(builder, src_type, tmp_type, dst[i], &dst[2*i + 0], &dst[2*i + 1]);
+         lp_build_unpack2(gallivm, src_type, tmp_type, dst[i], &dst[2*i + 0], &dst[2*i + 1]);
       }
 
       src_type = tmp_type;
@@ -247,16 +250,17 @@ lp_build_unpack(LLVMBuilderRef builder,
  * lp_build_packs2 instead.
  */
 LLVMValueRef
-lp_build_pack2(LLVMBuilderRef builder,
+lp_build_pack2(struct gallivm_state *gallivm,
                struct lp_type src_type,
                struct lp_type dst_type,
                LLVMValueRef lo,
                LLVMValueRef hi)
 {
+   LLVMBuilderRef builder = gallivm->builder;
 #if HAVE_LLVM < 0x0207
-   LLVMTypeRef src_vec_type = lp_build_vec_type(src_type);
+   LLVMTypeRef src_vec_type = lp_build_vec_type(gallivm, src_type);
 #endif
-   LLVMTypeRef dst_vec_type = lp_build_vec_type(dst_type);
+   LLVMTypeRef dst_vec_type = lp_build_vec_type(gallivm, dst_type);
    LLVMValueRef shuffle;
    LLVMValueRef res = NULL;
 
@@ -318,7 +322,7 @@ lp_build_pack2(LLVMBuilderRef builder,
    lo = LLVMBuildBitCast(builder, lo, dst_vec_type, "");
    hi = LLVMBuildBitCast(builder, hi, dst_vec_type, "");
 
-   shuffle = lp_build_const_pack_shuffle(dst_type.length);
+   shuffle = lp_build_const_pack_shuffle(gallivm, dst_type.length);
 
    res = LLVMBuildShuffleVector(builder, lo, hi, shuffle, "");
 
@@ -334,7 +338,7 @@ lp_build_pack2(LLVMBuilderRef builder,
  * destination type.
  */
 LLVMValueRef
-lp_build_packs2(LLVMBuilderRef builder,
+lp_build_packs2(struct gallivm_state *gallivm,
                 struct lp_type src_type,
                 struct lp_type dst_type,
                 LLVMValueRef lo,
@@ -360,14 +364,14 @@ lp_build_packs2(LLVMBuilderRef builder,
    if(clamp) {
       struct lp_build_context bld;
       unsigned dst_bits = dst_type.sign ? dst_type.width - 1 : dst_type.width;
-      LLVMValueRef dst_max = lp_build_const_int_vec(src_type, ((unsigned long long)1 << dst_bits) - 1);
-      lp_build_context_init(&bld, builder, src_type);
+      LLVMValueRef dst_max = lp_build_const_int_vec(gallivm, src_type, ((unsigned long long)1 << dst_bits) - 1);
+      lp_build_context_init(&bld, gallivm, src_type);
       lo = lp_build_min(&bld, lo, dst_max);
       hi = lp_build_min(&bld, hi, dst_max);
       /* FIXME: What about lower bound? */
    }
 
-   return lp_build_pack2(builder, src_type, dst_type, lo, hi);
+   return lp_build_pack2(gallivm, src_type, dst_type, lo, hi);
 }
 
 
@@ -377,13 +381,13 @@ lp_build_packs2(LLVMBuilderRef builder,
  * TODO: Handle saturation consistently.
  */
 LLVMValueRef
-lp_build_pack(LLVMBuilderRef builder,
+lp_build_pack(struct gallivm_state *gallivm,
               struct lp_type src_type,
               struct lp_type dst_type,
               boolean clamped,
               const LLVMValueRef *src, unsigned num_srcs)
 {
-   LLVMValueRef (*pack2)(LLVMBuilderRef builder,
+   LLVMValueRef (*pack2)(struct gallivm_state *gallivm,
                          struct lp_type src_type,
                          struct lp_type dst_type,
                          LLVMValueRef lo,
@@ -419,7 +423,8 @@ lp_build_pack(LLVMBuilderRef builder,
       num_srcs /= 2;
 
       for(i = 0; i < num_srcs; ++i)
-         tmp[i] = pack2(builder, src_type, tmp_type, tmp[2*i + 0], tmp[2*i + 1]);
+         tmp[i] = pack2(gallivm, src_type, tmp_type,
+                        tmp[2*i + 0], tmp[2*i + 1]);
 
       src_type = tmp_type;
    }
@@ -437,12 +442,13 @@ lp_build_pack(LLVMBuilderRef builder,
  * intrinsics that do saturation.
  */
 void
-lp_build_resize(LLVMBuilderRef builder,
+lp_build_resize(struct gallivm_state *gallivm,
                 struct lp_type src_type,
                 struct lp_type dst_type,
                 const LLVMValueRef *src, unsigned num_srcs,
                 LLVMValueRef *dst, unsigned num_dsts)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
    unsigned i;
 
@@ -482,7 +488,7 @@ lp_build_resize(LLVMBuilderRef builder,
          * Register width remains constant -- use vector packing intrinsics
          */
 
-         tmp[0] = lp_build_pack(builder, src_type, dst_type, TRUE, src, num_srcs);
+         tmp[0] = lp_build_pack(gallivm, src_type, dst_type, TRUE, src, num_srcs);
       }
       else {
          /*
@@ -490,11 +496,11 @@ lp_build_resize(LLVMBuilderRef builder,
           */
 
          assert(src_type.length == dst_type.length);
-         tmp[0] = lp_build_undef(dst_type);
+         tmp[0] = lp_build_undef(gallivm, dst_type);
          for (i = 0; i < dst_type.length; ++i) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm, i);
             LLVMValueRef val = LLVMBuildExtractElement(builder, src[0], index, "");
-            val = LLVMBuildTrunc(builder, val, lp_build_elem_type(dst_type), "");
+            val = LLVMBuildTrunc(builder, val, lp_build_elem_type(gallivm, dst_type), "");
             tmp[0] = LLVMBuildInsertElement(builder, tmp[0], val, index, "");
          }
       }
@@ -510,7 +516,7 @@ lp_build_resize(LLVMBuilderRef builder,
          /*
           * Register width remains constant -- use vector unpack intrinsics
           */
-         lp_build_unpack(builder, src_type, dst_type, src[0], tmp, num_dsts);
+         lp_build_unpack(gallivm, src_type, dst_type, src[0], tmp, num_dsts);
       }
       else {
          /*
@@ -518,15 +524,15 @@ lp_build_resize(LLVMBuilderRef builder,
           */
 
          assert(src_type.length == dst_type.length);
-         tmp[0] = lp_build_undef(dst_type);
+         tmp[0] = lp_build_undef(gallivm, dst_type);
          for (i = 0; i < dst_type.length; ++i) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm, i);
             LLVMValueRef val = LLVMBuildExtractElement(builder, src[0], index, "");
 
             if (src_type.sign && dst_type.sign) {
-               val = LLVMBuildSExt(builder, val, lp_build_elem_type(dst_type), "");
+               val = LLVMBuildSExt(builder, val, lp_build_elem_type(gallivm, dst_type), "");
             } else {
-               val = LLVMBuildZExt(builder, val, lp_build_elem_type(dst_type), "");
+               val = LLVMBuildZExt(builder, val, lp_build_elem_type(gallivm, dst_type), "");
             }
             tmp[0] = LLVMBuildInsertElement(builder, tmp[0], val, index, "");
          }
index e947b90d1642a2e3a880eb6d0c67d4886b701dee..d58da4f01b365f93ac47945dbbe7f7800bfd4baf 100644 (file)
@@ -46,7 +46,7 @@ struct lp_type;
 
 
 LLVMValueRef
-lp_build_interleave2(LLVMBuilderRef builder,
+lp_build_interleave2(struct gallivm_state *gallivm,
                      struct lp_type type,
                      LLVMValueRef a,
                      LLVMValueRef b,
@@ -54,7 +54,7 @@ lp_build_interleave2(LLVMBuilderRef builder,
 
 
 void
-lp_build_unpack2(LLVMBuilderRef builder,
+lp_build_unpack2(struct gallivm_state *gallivm,
                  struct lp_type src_type,
                  struct lp_type dst_type,
                  LLVMValueRef src,
@@ -63,7 +63,7 @@ lp_build_unpack2(LLVMBuilderRef builder,
 
 
 void
-lp_build_unpack(LLVMBuilderRef builder,
+lp_build_unpack(struct gallivm_state *gallivm,
                 struct lp_type src_type,
                 struct lp_type dst_type,
                 LLVMValueRef src,
@@ -71,7 +71,7 @@ lp_build_unpack(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_packs2(LLVMBuilderRef builder,
+lp_build_packs2(struct gallivm_state *gallivm,
                 struct lp_type src_type,
                 struct lp_type dst_type,
                 LLVMValueRef lo,
@@ -79,7 +79,7 @@ lp_build_packs2(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_pack2(LLVMBuilderRef builder,
+lp_build_pack2(struct gallivm_state *gallivm,
                struct lp_type src_type,
                struct lp_type dst_type,
                LLVMValueRef lo,
@@ -87,7 +87,7 @@ lp_build_pack2(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_pack(LLVMBuilderRef builder,
+lp_build_pack(struct gallivm_state *gallivm,
               struct lp_type src_type,
               struct lp_type dst_type,
               boolean clamped,
@@ -95,7 +95,7 @@ lp_build_pack(LLVMBuilderRef builder,
 
 
 void
-lp_build_resize(LLVMBuilderRef builder,
+lp_build_resize(struct gallivm_state *gallivm,
                 struct lp_type src_type,
                 struct lp_type dst_type,
                 const LLVMValueRef *src, unsigned num_srcs,
index f418e96aff4e0b7f169393eeda95c2ad1965f5f7..60cc6094f5a362f72defe1b18e96c6bd92a5d39f 100644 (file)
@@ -31,6 +31,8 @@
 #include "util/u_memory.h"
 #include "util/u_string.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
+#include "lp_bld_const.h"
 #include "lp_bld_printf.h"
 
 
@@ -65,12 +67,14 @@ lp_get_printf_arg_count(const char *fmt)
 }
 
 LLVMValueRef 
-lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len)
+lp_build_const_string_variable(LLVMModuleRef module,
+                               LLVMContextRef context,
+                               const char *str, int len)
 {
-   LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), len + 1), "");
+   LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8TypeInContext(context), len + 1), "");
    LLVMSetGlobalConstant(string, TRUE);
    LLVMSetLinkage(string, LLVMInternalLinkage);
-   LLVMSetInitializer(string, LLVMConstString(str, len + 1, TRUE));
+   LLVMSetInitializer(string, LLVMConstStringInContext(context, str, len + 1, TRUE));
    return string;
 }
  
@@ -83,15 +87,18 @@ lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len)
  * LLVMValueRef.
  */
 LLVMValueRef
-lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...)
+lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...)
 {
    va_list arglist;
    int i = 0;
    int argcount = lp_get_printf_arg_count(fmt);
-   LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMContextRef context = gallivm->context;
+   LLVMModuleRef module = gallivm->module;
    LLVMValueRef params[50];
-   LLVMValueRef fmtarg = lp_build_const_string_variable(module, fmt, strlen(fmt) + 1);
-   LLVMValueRef int0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   LLVMValueRef fmtarg = lp_build_const_string_variable(module, context,
+                                                        fmt, strlen(fmt) + 1);
+   LLVMValueRef int0 = lp_build_const_int32(gallivm, 0);
    LLVMValueRef index[2];
    LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf");
 
@@ -100,7 +107,7 @@ lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...)
    index[0] = index[1] = int0;
 
    if (!func_printf) {
-      LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntType(32), NULL, 0, 1);
+      LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntTypeInContext(context, 32), NULL, 0, 1);
       func_printf = LLVMAddFunction(module, "printf", printf_type);
    }
 
@@ -113,7 +120,7 @@ lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...)
       /* printf wants doubles, so lets convert so that
        * we can actually print them */
       if (LLVMGetTypeKind(type) == LLVMFloatTypeKind)
-         val = LLVMBuildFPExt(builder, val, LLVMDoubleType(), "");
+         val = LLVMBuildFPExt(builder, val, LLVMDoubleTypeInContext(context), "");
       params[i] = val;
    }
    va_end(arglist);
@@ -127,16 +134,18 @@ lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...)
  * Print a float[4] vector.
  */
 LLVMValueRef
-lp_build_print_vec4(LLVMBuilderRef builder, const char *msg, LLVMValueRef vec)
+lp_build_print_vec4(struct gallivm_state *gallivm,
+                    const char *msg, LLVMValueRef vec)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    char format[1000];
    LLVMValueRef x, y, z, w;
 
-   x = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(0), "");
-   y = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(1), "");
-   z = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(2), "");
-   w = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(3), "");
+   x = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 0), "");
+   y = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 1), "");
+   z = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 2), "");
+   w = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 3), "");
 
    util_snprintf(format, sizeof(format), "%s %%f %%f %%f %%f\n", msg);
-   return lp_build_printf(builder, format, x, y, z, w);
+   return lp_build_printf(gallivm, format, x, y, z, w);
 }
index b6222c62ebede70151018b407c97d66dca0cbf0d..f6bb8348699e9c4231d61df3fc66fe27643c86ed 100644 (file)
 
 #include "pipe/p_compiler.h"
 #include "lp_bld.h"
+#include "lp_bld_init.h"
 
-LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len);
-LLVMValueRef lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...);
+
+LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module,
+                                            LLVMContextRef context,
+                                            const char *str, int len);
+
+LLVMValueRef lp_build_printf(struct gallivm_state *gallivm,
+                             const char *fmt, ...);
 
 LLVMValueRef
-lp_build_print_vec4(LLVMBuilderRef builder, const char *msg, LLVMValueRef vec);
+lp_build_print_vec4(struct gallivm_state *gallivm,
+                    const char *msg, LLVMValueRef vec);
 
 
 #endif
index c18c8b47100dc52bc8597dec07205b43024796fe..b0a5bc0267ff2a75dac13d95d4de8dfe9d7e2eea 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "lp_bld_type.h"
 #include "lp_bld_arit.h"
+#include "lp_bld_const.h"
 #include "lp_bld_swizzle.h"
 #include "lp_bld_quad.h"
 
@@ -81,15 +82,15 @@ LLVMValueRef
 lp_build_scalar_ddx(struct lp_build_context *bld,
                     LLVMValueRef a)
 {
-   LLVMTypeRef i32t = LLVMInt32Type();
-   LLVMValueRef idx_left  = LLVMConstInt(i32t, LP_BLD_QUAD_TOP_LEFT, 0);
-   LLVMValueRef idx_right = LLVMConstInt(i32t, LP_BLD_QUAD_TOP_RIGHT, 0);
-   LLVMValueRef a_left  = LLVMBuildExtractElement(bld->builder, a, idx_left, "left");
-   LLVMValueRef a_right = LLVMBuildExtractElement(bld->builder, a, idx_right, "right");
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMValueRef idx_left  = lp_build_const_int32(bld->gallivm, LP_BLD_QUAD_TOP_LEFT);
+   LLVMValueRef idx_right = lp_build_const_int32(bld->gallivm, LP_BLD_QUAD_TOP_RIGHT);
+   LLVMValueRef a_left  = LLVMBuildExtractElement(builder, a, idx_left, "left");
+   LLVMValueRef a_right = LLVMBuildExtractElement(builder, a, idx_right, "right");
    if (bld->type.floating)
-      return LLVMBuildFSub(bld->builder, a_right, a_left, "ddx");
+      return LLVMBuildFSub(builder, a_right, a_left, "ddx");
    else
-      return LLVMBuildSub(bld->builder, a_right, a_left, "ddx");
+      return LLVMBuildSub(builder, a_right, a_left, "ddx");
 }
 
 
@@ -97,13 +98,13 @@ LLVMValueRef
 lp_build_scalar_ddy(struct lp_build_context *bld,
                     LLVMValueRef a)
 {
-   LLVMTypeRef i32t = LLVMInt32Type();
-   LLVMValueRef idx_top    = LLVMConstInt(i32t, LP_BLD_QUAD_TOP_LEFT, 0);
-   LLVMValueRef idx_bottom = LLVMConstInt(i32t, LP_BLD_QUAD_BOTTOM_LEFT, 0);
-   LLVMValueRef a_top    = LLVMBuildExtractElement(bld->builder, a, idx_top, "top");
-   LLVMValueRef a_bottom = LLVMBuildExtractElement(bld->builder, a, idx_bottom, "bottom");
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMValueRef idx_top    = lp_build_const_int32(bld->gallivm, LP_BLD_QUAD_TOP_LEFT);
+   LLVMValueRef idx_bottom = lp_build_const_int32(bld->gallivm, LP_BLD_QUAD_BOTTOM_LEFT);
+   LLVMValueRef a_top    = LLVMBuildExtractElement(builder, a, idx_top, "top");
+   LLVMValueRef a_bottom = LLVMBuildExtractElement(builder, a, idx_bottom, "bottom");
    if (bld->type.floating)
-      return LLVMBuildFSub(bld->builder, a_bottom, a_top, "ddy");
+      return LLVMBuildFSub(builder, a_bottom, a_top, "ddy");
    else
-      return LLVMBuildSub(bld->builder, a_bottom, a_top, "ddy");
+      return LLVMBuildSub(builder, a_bottom, a_top, "ddy");
 }
index 844d1d935b59c0a19a8157208b1ad57bebaa5d6e..8ad34598a92d94d25fa6975f051dd57d78c61393 100644 (file)
@@ -134,7 +134,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
    state->min_img_filter    = sampler->min_img_filter;
    state->mag_img_filter    = sampler->mag_img_filter;
 
-   if (view->last_level && sampler->max_lod > 0.0f) {
+   if (view->u.tex.last_level && sampler->max_lod > 0.0f) {
       state->min_mip_filter = sampler->min_mip_filter;
    } else {
       state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
@@ -155,7 +155,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
             state->apply_min_lod = 1;
          }
 
-         if (sampler->max_lod < (float)view->last_level) {
+         if (sampler->max_lod < (float)view->u.tex.last_level) {
             state->apply_max_lod = 1;
          }
       }
@@ -190,7 +190,8 @@ lp_build_rho(struct lp_build_sample_context *bld,
    struct lp_build_context *float_size_bld = &bld->float_size_bld;
    struct lp_build_context *float_bld = &bld->float_bld;
    const unsigned dims = bld->dims;
-   LLVMTypeRef i32t = LLVMInt32Type();
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(bld->gallivm->context);
    LLVMValueRef index0 = LLVMConstInt(i32t, 0, 0);
    LLVMValueRef index1 = LLVMConstInt(i32t, 1, 0);
    LLVMValueRef index2 = LLVMConstInt(i32t, 2, 0);
@@ -211,21 +212,21 @@ lp_build_rho(struct lp_build_sample_context *bld,
       rho_x = float_size_bld->undef;
       rho_y = float_size_bld->undef;
 
-      rho_x = LLVMBuildInsertElement(bld->builder, rho_x, dsdx, index0, "");
-      rho_y = LLVMBuildInsertElement(bld->builder, rho_y, dsdy, index0, "");
+      rho_x = LLVMBuildInsertElement(builder, rho_x, dsdx, index0, "");
+      rho_y = LLVMBuildInsertElement(builder, rho_y, dsdy, index0, "");
 
       dtdx = ddx[1];
       dtdy = ddy[1];
 
-      rho_x = LLVMBuildInsertElement(bld->builder, rho_x, dtdx, index1, "");
-      rho_y = LLVMBuildInsertElement(bld->builder, rho_y, dtdy, index1, "");
+      rho_x = LLVMBuildInsertElement(builder, rho_x, dtdx, index1, "");
+      rho_y = LLVMBuildInsertElement(builder, rho_y, dtdy, index1, "");
 
       if (dims >= 3) {
          drdx = ddx[2];
          drdy = ddy[2];
 
-         rho_x = LLVMBuildInsertElement(bld->builder, rho_x, drdx, index2, "");
-         rho_y = LLVMBuildInsertElement(bld->builder, rho_y, drdy, index2, "");
+         rho_x = LLVMBuildInsertElement(builder, rho_x, drdx, index2, "");
+         rho_y = LLVMBuildInsertElement(builder, rho_y, drdy, index2, "");
       }
    }
 
@@ -245,13 +246,13 @@ lp_build_rho(struct lp_build_sample_context *bld,
       if (dims >= 2) {
          LLVMValueRef rho_s, rho_t, rho_r;
 
-         rho_s = LLVMBuildExtractElement(bld->builder, rho_vec, index0, "");
-         rho_t = LLVMBuildExtractElement(bld->builder, rho_vec, index1, "");
+         rho_s = LLVMBuildExtractElement(builder, rho_vec, index0, "");
+         rho_t = LLVMBuildExtractElement(builder, rho_vec, index1, "");
 
          rho = lp_build_max(float_bld, rho_s, rho_t);
 
          if (dims >= 3) {
-            rho_r = LLVMBuildExtractElement(bld->builder, rho_vec, index0, "");
+            rho_r = LLVMBuildExtractElement(builder, rho_vec, index0, "");
             rho = lp_build_max(float_bld, rho, rho_r);
          }
       }
@@ -304,19 +305,19 @@ lp_build_brilinear_lod(struct lp_build_context *bld,
    double post_offset = 1 - factor;
 
    if (0) {
-      lp_build_printf(bld->builder, "lod = %f\n", lod);
+      lp_build_printf(bld->gallivm, "lod = %f\n", lod);
    }
 
    lod = lp_build_add(bld, lod,
-                      lp_build_const_vec(bld->type, pre_offset));
+                      lp_build_const_vec(bld->gallivm, bld->type, pre_offset));
 
    lp_build_ifloor_fract(bld, lod, out_lod_ipart, &lod_fpart);
 
    lod_fpart = lp_build_mul(bld, lod_fpart,
-                            lp_build_const_vec(bld->type, factor));
+                            lp_build_const_vec(bld->gallivm, bld->type, factor));
 
    lod_fpart = lp_build_add(bld, lod_fpart,
-                            lp_build_const_vec(bld->type, post_offset));
+                            lp_build_const_vec(bld->gallivm, bld->type, post_offset));
 
    /*
     * It's not necessary to clamp lod_fpart since:
@@ -327,8 +328,8 @@ lp_build_brilinear_lod(struct lp_build_context *bld,
    *out_lod_fpart = lod_fpart;
 
    if (0) {
-      lp_build_printf(bld->builder, "lod_ipart = %i\n", *out_lod_ipart);
-      lp_build_printf(bld->builder, "lod_fpart = %f\n\n", *out_lod_fpart);
+      lp_build_printf(bld->gallivm, "lod_ipart = %i\n", *out_lod_ipart);
+      lp_build_printf(bld->gallivm, "lod_fpart = %f\n\n", *out_lod_fpart);
    }
 }
 
@@ -363,7 +364,7 @@ lp_build_brilinear_rho(struct lp_build_context *bld,
     * part will not need any post adjustments.
     */
    rho = lp_build_mul(bld, rho,
-                      lp_build_const_vec(bld->type, pre_factor));
+                      lp_build_const_vec(bld->gallivm, bld->type, pre_factor));
 
    /* ipart = ifloor(log2(rho)) */
    lod_ipart = lp_build_extract_exponent(bld, rho, 0);
@@ -372,10 +373,10 @@ lp_build_brilinear_rho(struct lp_build_context *bld,
    lod_fpart = lp_build_extract_mantissa(bld, rho);
 
    lod_fpart = lp_build_mul(bld, lod_fpart,
-                            lp_build_const_vec(bld->type, factor));
+                            lp_build_const_vec(bld->gallivm, bld->type, factor));
 
    lod_fpart = lp_build_add(bld, lod_fpart,
-                            lp_build_const_vec(bld->type, post_offset));
+                            lp_build_const_vec(bld->gallivm, bld->type, post_offset));
 
    /*
     * Like lp_build_brilinear_lod, it's not necessary to clamp lod_fpart since:
@@ -413,6 +414,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
                       LLVMValueRef *out_lod_fpart)
 
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_build_context *float_bld = &bld->float_bld;
    LLVMValueRef lod;
 
@@ -424,17 +426,17 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
        * This is hit during mipmap generation.
        */
       LLVMValueRef min_lod =
-         bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
+         bld->dynamic_state->min_lod(bld->dynamic_state, bld->gallivm, unit);
 
       lod = min_lod;
    }
    else {
       LLVMValueRef sampler_lod_bias =
-         bld->dynamic_state->lod_bias(bld->dynamic_state, bld->builder, unit);
-      LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+         bld->dynamic_state->lod_bias(bld->dynamic_state, bld->gallivm, unit);
+      LLVMValueRef index0 = lp_build_const_int32(bld->gallivm, 0);
 
       if (explicit_lod) {
-         lod = LLVMBuildExtractElement(bld->builder, explicit_lod,
+         lod = LLVMBuildExtractElement(builder, explicit_lod,
                                        index0, "");
       }
       else {
@@ -479,27 +481,27 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
 
          /* add shader lod bias */
          if (lod_bias) {
-            lod_bias = LLVMBuildExtractElement(bld->builder, lod_bias,
+            lod_bias = LLVMBuildExtractElement(builder, lod_bias,
                                                index0, "");
-            lod = LLVMBuildFAdd(bld->builder, lod, lod_bias, "shader_lod_bias");
+            lod = LLVMBuildFAdd(builder, lod, lod_bias, "shader_lod_bias");
          }
       }
 
       /* add sampler lod bias */
       if (bld->static_state->lod_bias_non_zero)
-         lod = LLVMBuildFAdd(bld->builder, lod, sampler_lod_bias, "sampler_lod_bias");
+         lod = LLVMBuildFAdd(builder, lod, sampler_lod_bias, "sampler_lod_bias");
 
 
       /* clamp lod */
       if (bld->static_state->apply_max_lod) {
          LLVMValueRef max_lod =
-            bld->dynamic_state->max_lod(bld->dynamic_state, bld->builder, unit);
+            bld->dynamic_state->max_lod(bld->dynamic_state, bld->gallivm, unit);
 
          lod = lp_build_min(float_bld, lod, max_lod);
       }
       if (bld->static_state->apply_min_lod) {
          LLVMValueRef min_lod =
-            bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
+            bld->dynamic_state->min_lod(bld->dynamic_state, bld->gallivm, unit);
 
          lod = lp_build_max(float_bld, lod, min_lod);
       }
@@ -542,10 +544,10 @@ lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
    struct lp_build_context *int_bld = &bld->int_bld;
    LLVMValueRef last_level, level;
 
-   LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   LLVMValueRef zero = lp_build_const_int32(bld->gallivm, 0);
 
    last_level = bld->dynamic_state->last_level(bld->dynamic_state,
-                                               bld->builder, unit);
+                                               bld->gallivm, unit);
 
    /* convert float lod to integer */
    level = lod_ipart;
@@ -568,7 +570,7 @@ lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
                            LLVMValueRef *level0_out,
                            LLVMValueRef *level1_out)
 {
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_build_context *int_bld = &bld->int_bld;
    struct lp_build_context *float_bld = &bld->float_bld;
    LLVMValueRef last_level;
@@ -579,7 +581,7 @@ lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
    *level1_out = lp_build_add(int_bld, lod_ipart, int_bld->one);
 
    last_level = bld->dynamic_state->last_level(bld->dynamic_state,
-                                               bld->builder, unit);
+                                               bld->gallivm, unit);
 
    /*
     * Clamp both lod_ipart and lod_ipart + 1 to [0, last_level], with the
@@ -630,11 +632,13 @@ LLVMValueRef
 lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
                           LLVMValueRef level)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef indexes[2], data_ptr;
-   indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+
+   indexes[0] = lp_build_const_int32(bld->gallivm, 0);
    indexes[1] = level;
-   data_ptr = LLVMBuildGEP(bld->builder, bld->data_array, indexes, 2, "");
-   data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+   data_ptr = LLVMBuildGEP(builder, bld->data_array, indexes, 2, "");
+   data_ptr = LLVMBuildLoad(builder, data_ptr, "");
    return data_ptr;
 }
 
@@ -643,7 +647,7 @@ LLVMValueRef
 lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
                                 int level)
 {
-   LLVMValueRef lvl = LLVMConstInt(LLVMInt32Type(), level, 0);
+   LLVMValueRef lvl = lp_build_const_int32(bld->gallivm, level);
    return lp_build_get_mipmap_level(bld, lvl);
 }
 
@@ -657,6 +661,7 @@ lp_build_minify(struct lp_build_context *bld,
                 LLVMValueRef base_size,
                 LLVMValueRef level)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    assert(lp_check_value(bld->type, base_size));
    assert(lp_check_value(bld->type, level));
 
@@ -666,7 +671,7 @@ lp_build_minify(struct lp_build_context *bld,
    }
    else {
       LLVMValueRef size =
-         LLVMBuildLShr(bld->builder, base_size, level, "minify");
+         LLVMBuildLShr(builder, base_size, level, "minify");
       assert(bld->type.sign);
       size = lp_build_max(bld, size, bld->one);
       return size;
@@ -682,11 +687,12 @@ static LLVMValueRef
 lp_build_get_level_stride_vec(struct lp_build_sample_context *bld,
                               LLVMValueRef stride_array, LLVMValueRef level)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef indexes[2], stride;
-   indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indexes[0] = lp_build_const_int32(bld->gallivm, 0);
    indexes[1] = level;
-   stride = LLVMBuildGEP(bld->builder, stride_array, indexes, 2, "");
-   stride = LLVMBuildLoad(bld->builder, stride, "");
+   stride = LLVMBuildGEP(builder, stride_array, indexes, 2, "");
+   stride = LLVMBuildLoad(builder, stride, "");
    stride = lp_build_broadcast_scalar(&bld->int_coord_bld, stride);
    return stride;
 }
@@ -747,21 +753,21 @@ lp_build_extract_image_sizes(struct lp_build_sample_context *bld,
                              LLVMValueRef *out_depth)
 {
    const unsigned dims = bld->dims;
-   LLVMTypeRef i32t = LLVMInt32Type();
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(bld->gallivm->context);
 
-   *out_width = lp_build_extract_broadcast(bld->builder,
+   *out_width = lp_build_extract_broadcast(bld->gallivm,
                                            size_type,
                                            coord_type,
                                            size,
                                            LLVMConstInt(i32t, 0, 0));
    if (dims >= 2) {
-      *out_height = lp_build_extract_broadcast(bld->builder,
+      *out_height = lp_build_extract_broadcast(bld->gallivm,
                                                size_type,
                                                coord_type,
                                                size,
                                                LLVMConstInt(i32t, 1, 0));
       if (dims == 3) {
-         *out_depth = lp_build_extract_broadcast(bld->builder,
+         *out_depth = lp_build_extract_broadcast(bld->gallivm,
                                                  size_type,
                                                  coord_type,
                                                  size,
@@ -812,7 +818,7 @@ static LLVMValueRef
 lp_build_cube_ima(struct lp_build_context *coord_bld, LLVMValueRef coord)
 {
    /* ima = -0.5 / abs(coord); */
-   LLVMValueRef negHalf = lp_build_const_vec(coord_bld->type, -0.5);
+   LLVMValueRef negHalf = lp_build_const_vec(coord_bld->gallivm, coord_bld->type, -0.5);
    LLVMValueRef absCoord = lp_build_abs(coord_bld, coord);
    LLVMValueRef ima = lp_build_div(coord_bld, negHalf, absCoord);
    return ima;
@@ -831,7 +837,7 @@ lp_build_cube_coord(struct lp_build_context *coord_bld,
                     LLVMValueRef coord, LLVMValueRef ima)
 {
    /* return negate(coord) * ima * sign + 0.5; */
-   LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
+   LLVMValueRef half = lp_build_const_vec(coord_bld->gallivm, coord_bld->type, 0.5);
    LLVMValueRef res;
 
    assert(negate_coord == +1 || negate_coord == -1);
@@ -859,12 +865,14 @@ lp_build_cube_face(struct lp_build_sample_context *bld,
                    LLVMValueRef major_coord,
                    unsigned pos_face, unsigned neg_face)
 {
-   LLVMValueRef cmp = LLVMBuildFCmp(bld->builder, LLVMRealUGE,
+   struct gallivm_state *gallivm = bld->gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef cmp = LLVMBuildFCmp(builder, LLVMRealUGE,
                                     major_coord,
                                     bld->float_bld.zero, "");
-   LLVMValueRef pos = LLVMConstInt(LLVMInt32Type(), pos_face, 0);
-   LLVMValueRef neg = LLVMConstInt(LLVMInt32Type(), neg_face, 0);
-   LLVMValueRef res = LLVMBuildSelect(bld->builder, cmp, pos, neg, "");
+   LLVMValueRef pos = lp_build_const_int32(gallivm, pos_face);
+   LLVMValueRef neg = lp_build_const_int32(gallivm, neg_face);
+   LLVMValueRef res = LLVMBuildSelect(builder, cmp, pos, neg, "");
    return res;
 }
 
@@ -884,9 +892,10 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
 {
    struct lp_build_context *float_bld = &bld->float_bld;
    struct lp_build_context *coord_bld = &bld->coord_bld;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef rx, ry, rz;
    LLVMValueRef arx, ary, arz;
-   LLVMValueRef c25 = LLVMConstReal(LLVMFloatType(), 0.25);
+   LLVMValueRef c25 = lp_build_const_float(bld->gallivm, 0.25);
    LLVMValueRef arx_ge_ary, arx_ge_arz;
    LLVMValueRef ary_ge_arx, ary_ge_arz;
    LLVMValueRef arx_ge_ary_arz, ary_ge_arx_arz;
@@ -911,17 +920,17 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
    /*
     * Compare sign/magnitude of rx,ry,rz to determine face
     */
-   arx_ge_ary = LLVMBuildFCmp(bld->builder, LLVMRealUGE, arx, ary, "");
-   arx_ge_arz = LLVMBuildFCmp(bld->builder, LLVMRealUGE, arx, arz, "");
-   ary_ge_arx = LLVMBuildFCmp(bld->builder, LLVMRealUGE, ary, arx, "");
-   ary_ge_arz = LLVMBuildFCmp(bld->builder, LLVMRealUGE, ary, arz, "");
+   arx_ge_ary = LLVMBuildFCmp(builder, LLVMRealUGE, arx, ary, "");
+   arx_ge_arz = LLVMBuildFCmp(builder, LLVMRealUGE, arx, arz, "");
+   ary_ge_arx = LLVMBuildFCmp(builder, LLVMRealUGE, ary, arx, "");
+   ary_ge_arz = LLVMBuildFCmp(builder, LLVMRealUGE, ary, arz, "");
 
-   arx_ge_ary_arz = LLVMBuildAnd(bld->builder, arx_ge_ary, arx_ge_arz, "");
-   ary_ge_arx_arz = LLVMBuildAnd(bld->builder, ary_ge_arx, ary_ge_arz, "");
+   arx_ge_ary_arz = LLVMBuildAnd(builder, arx_ge_ary, arx_ge_arz, "");
+   ary_ge_arx_arz = LLVMBuildAnd(builder, ary_ge_arx, ary_ge_arz, "");
 
-   rx_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, rx, float_bld->zero, "");
-   ry_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, ry, float_bld->zero, "");
-   rz_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, rz, float_bld->zero, "");
+   rx_pos = LLVMBuildFCmp(builder, LLVMRealUGE, rx, float_bld->zero, "");
+   ry_pos = LLVMBuildFCmp(builder, LLVMRealUGE, ry, float_bld->zero, "");
+   rz_pos = LLVMBuildFCmp(builder, LLVMRealUGE, rz, float_bld->zero, "");
 
    {
       struct lp_build_if_state if_ctx;
@@ -929,11 +938,11 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
       LLVMValueRef face_t_var;
       LLVMValueRef face_var;
 
-      face_s_var = lp_build_alloca(bld->builder, bld->coord_bld.vec_type, "face_s_var");
-      face_t_var = lp_build_alloca(bld->builder, bld->coord_bld.vec_type, "face_t_var");
-      face_var = lp_build_alloca(bld->builder, bld->int_bld.vec_type, "face_var");
+      face_s_var = lp_build_alloca(bld->gallivm, bld->coord_bld.vec_type, "face_s_var");
+      face_t_var = lp_build_alloca(bld->gallivm, bld->coord_bld.vec_type, "face_t_var");
+      face_var = lp_build_alloca(bld->gallivm, bld->int_bld.vec_type, "face_var");
 
-      lp_build_if(&if_ctx, bld->builder, arx_ge_ary_arz);
+      lp_build_if(&if_ctx, bld->gallivm, arx_ge_ary_arz);
       {
          /* +/- X face */
          LLVMValueRef sign = lp_build_sgn(float_bld, rx);
@@ -943,17 +952,17 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
          *face = lp_build_cube_face(bld, rx,
                                     PIPE_TEX_FACE_POS_X,
                                     PIPE_TEX_FACE_NEG_X);
-         LLVMBuildStore(bld->builder, *face_s, face_s_var);
-         LLVMBuildStore(bld->builder, *face_t, face_t_var);
-         LLVMBuildStore(bld->builder, *face, face_var);
+         LLVMBuildStore(builder, *face_s, face_s_var);
+         LLVMBuildStore(builder, *face_t, face_t_var);
+         LLVMBuildStore(builder, *face, face_var);
       }
       lp_build_else(&if_ctx);
       {
          struct lp_build_if_state if_ctx2;
 
-         ary_ge_arx_arz = LLVMBuildAnd(bld->builder, ary_ge_arx, ary_ge_arz, "");
+         ary_ge_arx_arz = LLVMBuildAnd(builder, ary_ge_arx, ary_ge_arz, "");
 
-         lp_build_if(&if_ctx2, bld->builder, ary_ge_arx_arz);
+         lp_build_if(&if_ctx2, bld->gallivm, ary_ge_arx_arz);
          {
             /* +/- Y face */
             LLVMValueRef sign = lp_build_sgn(float_bld, ry);
@@ -963,9 +972,9 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
             *face = lp_build_cube_face(bld, ry,
                                        PIPE_TEX_FACE_POS_Y,
                                        PIPE_TEX_FACE_NEG_Y);
-            LLVMBuildStore(bld->builder, *face_s, face_s_var);
-            LLVMBuildStore(bld->builder, *face_t, face_t_var);
-            LLVMBuildStore(bld->builder, *face, face_var);
+            LLVMBuildStore(builder, *face_s, face_s_var);
+            LLVMBuildStore(builder, *face_t, face_t_var);
+            LLVMBuildStore(builder, *face, face_var);
          }
          lp_build_else(&if_ctx2);
          {
@@ -977,18 +986,18 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
             *face = lp_build_cube_face(bld, rz,
                                        PIPE_TEX_FACE_POS_Z,
                                        PIPE_TEX_FACE_NEG_Z);
-            LLVMBuildStore(bld->builder, *face_s, face_s_var);
-            LLVMBuildStore(bld->builder, *face_t, face_t_var);
-            LLVMBuildStore(bld->builder, *face, face_var);
+            LLVMBuildStore(builder, *face_s, face_s_var);
+            LLVMBuildStore(builder, *face_t, face_t_var);
+            LLVMBuildStore(builder, *face, face_var);
          }
          lp_build_endif(&if_ctx2);
       }
 
       lp_build_endif(&if_ctx);
 
-      *face_s = LLVMBuildLoad(bld->builder, face_s_var, "face_s");
-      *face_t = LLVMBuildLoad(bld->builder, face_t_var, "face_t");
-      *face   = LLVMBuildLoad(bld->builder, face_var, "face");
+      *face_s = LLVMBuildLoad(builder, face_s_var, "face_s");
+      *face_t = LLVMBuildLoad(builder, face_t_var, "face_t");
+      *face   = LLVMBuildLoad(builder, face_var, "face");
    }
 }
 
@@ -1011,6 +1020,7 @@ lp_build_sample_partial_offset(struct lp_build_context *bld,
                                LLVMValueRef *out_offset,
                                LLVMValueRef *out_subcoord)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef offset;
    LLVMValueRef subcoord;
 
@@ -1028,14 +1038,14 @@ lp_build_sample_partial_offset(struct lp_build_context *bld,
        */
 #if 0
       LLVMValueRef block_width = lp_build_const_int_vec(bld->type, block_length);
-      subcoord = LLVMBuildURem(bld->builder, coord, block_width, "");
-      coord    = LLVMBuildUDiv(bld->builder, coord, block_width, "");
+      subcoord = LLVMBuildURem(builder, coord, block_width, "");
+      coord    = LLVMBuildUDiv(builder, coord, block_width, "");
 #else
       unsigned logbase2 = util_unsigned_logbase2(block_length);
-      LLVMValueRef block_shift = lp_build_const_int_vec(bld->type, logbase2);
-      LLVMValueRef block_mask = lp_build_const_int_vec(bld->type, block_length - 1);
-      subcoord = LLVMBuildAnd(bld->builder, coord, block_mask, "");
-      coord = LLVMBuildLShr(bld->builder, coord, block_shift, "");
+      LLVMValueRef block_shift = lp_build_const_int_vec(bld->gallivm, bld->type, logbase2);
+      LLVMValueRef block_mask = lp_build_const_int_vec(bld->gallivm, bld->type, block_length - 1);
+      subcoord = LLVMBuildAnd(builder, coord, block_mask, "");
+      coord = LLVMBuildLShr(builder, coord, block_shift, "");
 #endif
    }
 
@@ -1071,7 +1081,8 @@ lp_build_sample_offset(struct lp_build_context *bld,
    LLVMValueRef x_stride;
    LLVMValueRef offset;
 
-   x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8);
+   x_stride = lp_build_const_vec(bld->gallivm, bld->type,
+                                 format_desc->block.bits/8);
 
    lp_build_sample_partial_offset(bld,
                                   format_desc->block.width,
index ffed27cee8302ee0b4902c434709fe102320e8b8..8c9d5df4e43aa9281002977747378a0bfe487f05 100644 (file)
@@ -105,64 +105,64 @@ struct lp_sampler_dynamic_state
    /** Obtain the base texture width (returns int32) */
    LLVMValueRef
    (*width)( const struct lp_sampler_dynamic_state *state,
-             LLVMBuilderRef builder,
+             struct gallivm_state *gallivm,
              unsigned unit);
 
    /** Obtain the base texture height (returns int32) */
    LLVMValueRef
    (*height)( const struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder,
+              struct gallivm_state *gallivm,
               unsigned unit);
 
    /** Obtain the base texture depth (returns int32) */
    LLVMValueRef
    (*depth)( const struct lp_sampler_dynamic_state *state,
-             LLVMBuilderRef builder,
+             struct gallivm_state *gallivm,
              unsigned unit);
 
    /** Obtain the number of mipmap levels minus one (returns int32) */
    LLVMValueRef
    (*last_level)( const struct lp_sampler_dynamic_state *state,
-                  LLVMBuilderRef builder,
+                  struct gallivm_state *gallivm,
                   unsigned unit);
 
    /** Obtain stride in bytes between image rows/blocks (returns int32) */
    LLVMValueRef
    (*row_stride)( const struct lp_sampler_dynamic_state *state,
-                  LLVMBuilderRef builder,
+                  struct gallivm_state *gallivm,
                   unsigned unit);
 
    /** Obtain stride in bytes between image slices (returns int32) */
    LLVMValueRef
    (*img_stride)( const struct lp_sampler_dynamic_state *state,
-                  LLVMBuilderRef builder,
+                  struct gallivm_state *gallivm,
                   unsigned unit);
 
    /** Obtain pointer to array of pointers to mimpap levels */
    LLVMValueRef
    (*data_ptr)( const struct lp_sampler_dynamic_state *state,
-                LLVMBuilderRef builder,
+                struct gallivm_state *gallivm,
                 unsigned unit);
 
    /** Obtain texture min lod (returns float) */
    LLVMValueRef
    (*min_lod)(const struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder, unsigned unit);
+              struct gallivm_state *gallivm, unsigned unit);
 
    /** Obtain texture max lod (returns float) */
    LLVMValueRef
    (*max_lod)(const struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder, unsigned unit);
+              struct gallivm_state *gallivm, unsigned unit);
 
    /** Obtain texture lod bias (returns float) */
    LLVMValueRef
    (*lod_bias)(const struct lp_sampler_dynamic_state *state,
-               LLVMBuilderRef builder, unsigned unit);
+               struct gallivm_state *gallivm, unsigned unit);
 
    /** Obtain texture border color (returns ptr to float[4]) */
    LLVMValueRef
    (*border_color)(const struct lp_sampler_dynamic_state *state,
-                   LLVMBuilderRef builder, unsigned unit);
+                   struct gallivm_state *gallivm, unsigned unit);
 };
 
 
@@ -171,7 +171,7 @@ struct lp_sampler_dynamic_state
  */
 struct lp_build_sample_context
 {
-   LLVMBuilderRef builder;
+   struct gallivm_state *gallivm;
 
    const struct lp_sampler_static_state *static_state;
 
@@ -385,7 +385,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
 
 
 void
-lp_build_sample_soa(LLVMBuilderRef builder,
+lp_build_sample_soa(struct gallivm_state *gallivm,
                     const struct lp_sampler_static_state *static_state,
                     struct lp_sampler_dynamic_state *dynamic_state,
                     struct lp_type fp_type,
@@ -399,7 +399,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
                     LLVMValueRef texel_out[4]);
 
 void
-lp_build_sample_nop(struct lp_type type,
+lp_build_sample_nop(struct gallivm_state *gallivm, struct lp_type type,
                     LLVMValueRef texel_out[4]);
 
 
index d6831a580b3c8c6cc17e55bcfc19e3ebbb3fbebd..991f6fa5ef7bdf45a6fa43761545fefaf4ef0909 100644 (file)
@@ -52,6 +52,7 @@
 #include "lp_bld_flow.h"
 #include "lp_bld_gather.h"
 #include "lp_bld_format.h"
+#include "lp_bld_init.h"
 #include "lp_bld_sample.h"
 #include "lp_bld_sample_aos.h"
 #include "lp_bld_quad.h"
@@ -82,6 +83,7 @@ lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld,
                                  LLVMValueRef *out_i)
 {
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef length_minus_one;
 
    length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
@@ -89,12 +91,12 @@ lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld,
    switch(wrap_mode) {
    case PIPE_TEX_WRAP_REPEAT:
       if(is_pot)
-         coord = LLVMBuildAnd(bld->builder, coord, length_minus_one, "");
+         coord = LLVMBuildAnd(builder, coord, length_minus_one, "");
       else {
          /* Add a bias to the texcoord to handle negative coords */
          LLVMValueRef bias = lp_build_mul_imm(int_coord_bld, length, 1024);
-         coord = LLVMBuildAdd(bld->builder, coord, bias, "");
-         coord = LLVMBuildURem(bld->builder, coord, length, "");
+         coord = LLVMBuildAdd(builder, coord, bias, "");
+         coord = LLVMBuildURem(builder, coord, length, "");
       }
       break;
 
@@ -147,6 +149,7 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
                                 LLVMValueRef *i1)
 {
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef length_minus_one;
    LLVMValueRef lmask, umask, mask;
 
@@ -195,39 +198,39 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
    switch(wrap_mode) {
    case PIPE_TEX_WRAP_REPEAT:
       if (is_pot) {
-         coord0 = LLVMBuildAnd(bld->builder, coord0, length_minus_one, "");
+         coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
       }
       else {
          /* Add a bias to the texcoord to handle negative coords */
          LLVMValueRef bias = lp_build_mul_imm(int_coord_bld, length, 1024);
-         coord0 = LLVMBuildAdd(bld->builder, coord0, bias, "");
-         coord0 = LLVMBuildURem(bld->builder, coord0, length, "");
+         coord0 = LLVMBuildAdd(builder, coord0, bias, "");
+         coord0 = LLVMBuildURem(builder, coord0, length, "");
       }
 
-      mask = lp_build_compare(bld->builder, int_coord_bld->type,
+      mask = lp_build_compare(bld->gallivm, int_coord_bld->type,
                               PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
 
       *offset0 = lp_build_mul(int_coord_bld, coord0, stride);
-      *offset1 = LLVMBuildAnd(bld->builder,
+      *offset1 = LLVMBuildAnd(builder,
                               lp_build_add(int_coord_bld, *offset0, stride),
                               mask, "");
       break;
 
    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      lmask = lp_build_compare(int_coord_bld->builder, int_coord_bld->type,
+      lmask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
                                PIPE_FUNC_GEQUAL, coord0, int_coord_bld->zero);
-      umask = lp_build_compare(int_coord_bld->builder, int_coord_bld->type,
+      umask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
                                PIPE_FUNC_LESS, coord0, length_minus_one);
 
       coord0 = lp_build_select(int_coord_bld, lmask, coord0, int_coord_bld->zero);
       coord0 = lp_build_select(int_coord_bld, umask, coord0, length_minus_one);
 
-      mask = LLVMBuildAnd(bld->builder, lmask, umask, "");
+      mask = LLVMBuildAnd(builder, lmask, umask, "");
 
       *offset0 = lp_build_mul(int_coord_bld, coord0, stride);
       *offset1 = lp_build_add(int_coord_bld,
                               *offset0,
-                              LLVMBuildAnd(bld->builder, stride, mask, ""));
+                              LLVMBuildAnd(builder, stride, mask, ""));
       break;
 
    case PIPE_TEX_WRAP_CLAMP:
@@ -263,7 +266,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
                               LLVMValueRef *colors_hi)
 {
    const unsigned dims = bld->dims;
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_build_context i32, h16, u8n;
    LLVMTypeRef i32_vec_type, h16_vec_type, u8n_vec_type;
    LLVMValueRef i32_c8;
@@ -273,13 +276,13 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
    LLVMValueRef x_offset, offset;
    LLVMValueRef x_subcoord, y_subcoord, z_subcoord;
 
-   lp_build_context_init(&i32, builder, lp_type_int_vec(32));
-   lp_build_context_init(&h16, builder, lp_type_ufixed(16));
-   lp_build_context_init(&u8n, builder, lp_type_unorm(8));
+   lp_build_context_init(&i32, bld->gallivm, lp_type_int_vec(32));
+   lp_build_context_init(&h16, bld->gallivm, lp_type_ufixed(16));
+   lp_build_context_init(&u8n, bld->gallivm, lp_type_unorm(8));
 
-   i32_vec_type = lp_build_vec_type(i32.type);
-   h16_vec_type = lp_build_vec_type(h16.type);
-   u8n_vec_type = lp_build_vec_type(u8n.type);
+   i32_vec_type = lp_build_vec_type(bld->gallivm, i32.type);
+   h16_vec_type = lp_build_vec_type(bld->gallivm, h16.type);
+   u8n_vec_type = lp_build_vec_type(bld->gallivm, u8n.type);
 
    lp_build_extract_image_sizes(bld,
                                 bld->int_size_type,
@@ -317,7 +320,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
       r = LLVMBuildFPToSI(builder, r, i32_vec_type, "");
 
    /* compute floor (shift right 8) */
-   i32_c8 = lp_build_const_int_vec(i32.type, 8);
+   i32_c8 = lp_build_const_int_vec(bld->gallivm, i32.type, 8);
    s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
    if (dims >= 2)
       t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
@@ -325,7 +328,8 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
       r_ipart = LLVMBuildAShr(builder, r, i32_c8, "");
 
    /* get pixel, row, image strides */
-   x_stride = lp_build_const_vec(bld->int_coord_bld.type,
+   x_stride = lp_build_const_vec(bld->gallivm,
+                                 bld->int_coord_bld.type,
                                  bld->format_desc->block.bits/8);
 
    /* Do texcoord wrapping, compute texel offset */
@@ -387,7 +391,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
           * Given the format is a rgba8, just read the pixels as is,
           * without any swizzling. Swizzling will be done later.
           */
-         rgba8 = lp_build_gather(bld->builder,
+         rgba8 = lp_build_gather(bld->gallivm,
                                  bld->texel_type.length,
                                  bld->format_desc->block.bits,
                                  bld->texel_type.width,
@@ -396,7 +400,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
          rgba8 = LLVMBuildBitCast(builder, rgba8, u8n_vec_type, "");
       }
       else {
-         rgba8 = lp_build_fetch_rgba_aos(bld->builder,
+         rgba8 = lp_build_fetch_rgba_aos(bld->gallivm,
                                          bld->format_desc,
                                          u8n.type,
                                          data_ptr, offset,
@@ -405,7 +409,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
       }
 
       /* Expand one 4*rgba8 to two 2*rgba16 */
-      lp_build_unpack2(builder, u8n.type, h16.type,
+      lp_build_unpack2(bld->gallivm, u8n.type, h16.type,
                        rgba8,
                        colors_lo, colors_hi);
    }
@@ -429,7 +433,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
                              LLVMValueRef *colors_hi)
 {
    const unsigned dims = bld->dims;
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_build_context i32, h16, u8n;
    LLVMTypeRef i32_vec_type, h16_vec_type, u8n_vec_type;
    LLVMValueRef i32_c8, i32_c128, i32_c255;
@@ -450,13 +454,13 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
    unsigned i, j, k;
    unsigned numj, numk;
 
-   lp_build_context_init(&i32, builder, lp_type_int_vec(32));
-   lp_build_context_init(&h16, builder, lp_type_ufixed(16));
-   lp_build_context_init(&u8n, builder, lp_type_unorm(8));
+   lp_build_context_init(&i32, bld->gallivm, lp_type_int_vec(32));
+   lp_build_context_init(&h16, bld->gallivm, lp_type_ufixed(16));
+   lp_build_context_init(&u8n, bld->gallivm, lp_type_unorm(8));
 
-   i32_vec_type = lp_build_vec_type(i32.type);
-   h16_vec_type = lp_build_vec_type(h16.type);
-   u8n_vec_type = lp_build_vec_type(u8n.type);
+   i32_vec_type = lp_build_vec_type(bld->gallivm, i32.type);
+   h16_vec_type = lp_build_vec_type(bld->gallivm, h16.type);
+   u8n_vec_type = lp_build_vec_type(bld->gallivm, u8n.type);
 
    lp_build_extract_image_sizes(bld,
                                 bld->int_size_type,
@@ -494,7 +498,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
       r = LLVMBuildFPToSI(builder, r, i32_vec_type, "");
 
    /* subtract 0.5 (add -128) */
-   i32_c128 = lp_build_const_int_vec(i32.type, -128);
+   i32_c128 = lp_build_const_int_vec(bld->gallivm, i32.type, -128);
    s = LLVMBuildAdd(builder, s, i32_c128, "");
    if (dims >= 2) {
       t = LLVMBuildAdd(builder, t, i32_c128, "");
@@ -504,7 +508,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
    }
 
    /* compute floor (shift right 8) */
-   i32_c8 = lp_build_const_int_vec(i32.type, 8);
+   i32_c8 = lp_build_const_int_vec(bld->gallivm, i32.type, 8);
    s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
    if (dims >= 2)
       t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
@@ -512,7 +516,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
       r_ipart = LLVMBuildAShr(builder, r, i32_c8, "");
 
    /* compute fractional part (AND with 0xff) */
-   i32_c255 = lp_build_const_int_vec(i32.type, 255);
+   i32_c255 = lp_build_const_int_vec(bld->gallivm, i32.type, 255);
    s_fpart = LLVMBuildAnd(builder, s, i32_c255, "");
    if (dims >= 2)
       t_fpart = LLVMBuildAnd(builder, t, i32_c255, "");
@@ -520,7 +524,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
       r_fpart = LLVMBuildAnd(builder, r, i32_c255, "");
 
    /* get pixel, row and image strides */
-   x_stride = lp_build_const_vec(bld->int_coord_bld.type,
+   x_stride = lp_build_const_vec(bld->gallivm, bld->int_coord_bld.type,
                                  bld->format_desc->block.bits/8);
    y_stride = row_stride_vec;
    z_stride = img_stride_vec;
@@ -612,7 +616,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
       r_fpart = LLVMBuildBitCast(builder, r_fpart, h16_vec_type, "");
 
    {
-      LLVMTypeRef elem_type = LLVMInt32Type();
+      LLVMTypeRef elem_type = LLVMInt32TypeInContext(bld->gallivm->context);
       LLVMValueRef shuffles_lo[LP_MAX_VECTOR_LENGTH];
       LLVMValueRef shuffles_hi[LP_MAX_VECTOR_LENGTH];
       LLVMValueRef shuffle_lo;
@@ -685,7 +689,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
                 * Given the format is a rgba8, just read the pixels as is,
                 * without any swizzling. Swizzling will be done later.
                 */
-               rgba8 = lp_build_gather(bld->builder,
+               rgba8 = lp_build_gather(bld->gallivm,
                                        bld->texel_type.length,
                                        bld->format_desc->block.bits,
                                        bld->texel_type.width,
@@ -694,7 +698,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
                rgba8 = LLVMBuildBitCast(builder, rgba8, u8n_vec_type, "");
             }
             else {
-               rgba8 = lp_build_fetch_rgba_aos(bld->builder,
+               rgba8 = lp_build_fetch_rgba_aos(bld->gallivm,
                                                bld->format_desc,
                                                u8n.type,
                                                data_ptr, offset[k][j][i],
@@ -703,7 +707,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
             }
 
             /* Expand one 4*rgba8 to two 2*rgba16 */
-            lp_build_unpack2(builder, u8n.type, h16.type,
+            lp_build_unpack2(bld->gallivm, u8n.type, h16.type,
                              rgba8,
                              &neighbors_lo[k][j][i], &neighbors_hi[k][j][i]);
          }
@@ -790,7 +794,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
                        LLVMValueRef colors_lo_var,
                        LLVMValueRef colors_hi_var)
 {
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef size0;
    LLVMValueRef size1;
    LLVMValueRef row_stride0_vec;
@@ -802,7 +806,6 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
    LLVMValueRef colors0_lo, colors0_hi;
    LLVMValueRef colors1_lo, colors1_hi;
 
-
    /* sample the first mipmap level */
    lp_build_mipmap_level_sizes(bld, ilevel0,
                                &size0,
@@ -829,8 +832,8 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
    LLVMBuildStore(builder, colors0_hi, colors_hi_var);
 
    if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
-      LLVMValueRef h16_scale = LLVMConstReal(LLVMFloatType(), 256.0);
-      LLVMTypeRef i32_type = LLVMIntType(32);
+      LLVMValueRef h16_scale = lp_build_const_float(bld->gallivm, 256.0);
+      LLVMTypeRef i32_type = LLVMIntTypeInContext(bld->gallivm->context, 32);
       struct lp_build_if_state if_ctx;
       LLVMValueRef need_lerp;
 
@@ -842,11 +845,11 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
                                 lod_fpart, LLVMConstNull(i32_type),
                                 "need_lerp");
 
-      lp_build_if(&if_ctx, builder, need_lerp);
+      lp_build_if(&if_ctx, bld->gallivm, need_lerp);
       {
          struct lp_build_context h16_bld;
 
-         lp_build_context_init(&h16_bld, builder, lp_type_ufixed(16));
+         lp_build_context_init(&h16_bld, bld->gallivm, lp_type_ufixed(16));
 
          /* sample the second mipmap level */
          lp_build_mipmap_level_sizes(bld, ilevel1,
@@ -885,7 +888,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
             int i;
             assert(h16_bld.type.length <= Elements(shuffles));
             for (i = 0; i < h16_bld.type.length; i++)
-               shuffles[i] = lp_build_const_int32(2 * (i & 1));
+               shuffles[i] = lp_build_const_int32(bld->gallivm, 2 * (i & 1));
             shuffle = LLVMConstVector(shuffles, h16_bld.type.length);
             lod_fpart = LLVMBuildShuffleVector(builder,
                                                lod_fpart, lod_fpart,
@@ -925,7 +928,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
                     LLVMValueRef texel_out[4])
 {
    struct lp_build_context *int_bld = &bld->int_bld;
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const unsigned mip_filter = bld->static_state->min_mip_filter;
    const unsigned min_filter = bld->static_state->min_img_filter;
    const unsigned mag_filter = bld->static_state->mag_img_filter;
@@ -936,8 +939,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
    LLVMValueRef unswizzled[4];
    LLVMValueRef face_ddx[4], face_ddy[4];
    struct lp_build_context h16_bld;
-   LLVMTypeRef i32t = LLVMInt32Type();
-   LLVMValueRef i32t_zero = LLVMConstInt(i32t, 0, 0);
+   LLVMValueRef i32t_zero = lp_build_const_int32(bld->gallivm, 0);
 
    /* we only support the common/simple wrap modes at this time */
    assert(lp_is_simple_wrap_mode(bld->static_state->wrap_s));
@@ -948,7 +950,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
 
 
    /* make 16-bit fixed-pt builder context */
-   lp_build_context_init(&h16_bld, builder, lp_type_ufixed(16));
+   lp_build_context_init(&h16_bld, bld->gallivm, lp_type_ufixed(16));
 
    /* cube face selection, compute pre-face coords, etc. */
    if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
@@ -1026,8 +1028,8 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
     * Get/interpolate texture colors.
     */
 
-   packed_lo = lp_build_alloca(builder, h16_bld.vec_type, "packed_lo");
-   packed_hi = lp_build_alloca(builder, h16_bld.vec_type, "packed_hi");
+   packed_lo = lp_build_alloca(bld->gallivm, h16_bld.vec_type, "packed_lo");
+   packed_hi = lp_build_alloca(bld->gallivm, h16_bld.vec_type, "packed_hi");
 
    if (min_filter == mag_filter) {
       /* no need to distinquish between minification and magnification */
@@ -1048,7 +1050,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
       minify = LLVMBuildICmp(builder, LLVMIntSGE,
                              lod_ipart, int_bld->zero, "");
 
-      lp_build_if(&if_ctx, builder, minify);
+      lp_build_if(&if_ctx, bld->gallivm, minify);
       {
          /* Use the minification filter */
          lp_build_sample_mipmap(bld,
@@ -1073,7 +1075,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
     * combine the values stored in 'packed_lo' and 'packed_hi' variables
     * into 'packed'
     */
-   packed = lp_build_pack2(builder,
+   packed = lp_build_pack2(bld->gallivm,
                            h16_bld.type, lp_type_unorm(8),
                            LLVMBuildLoad(builder, packed_lo, ""),
                            LLVMBuildLoad(builder, packed_hi, ""));
@@ -1081,7 +1083,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
    /*
     * Convert to SoA and swizzle.
     */
-   lp_build_rgba8_to_f32_soa(builder,
+   lp_build_rgba8_to_f32_soa(bld->gallivm,
                              bld->texel_type,
                              packed, unswizzled);
 
index 53cc0c5f34541c7c897a7e4509247ef1283fff72..cf46e2be83269fb98307a49ed4af5084f122fb60 100644 (file)
@@ -84,6 +84,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
    const struct lp_sampler_static_state *static_state = bld->static_state;
    const unsigned dims = bld->dims;
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef offset;
    LLVMValueRef i, j;
    LLVMValueRef use_border = NULL;
@@ -95,7 +96,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       LLVMValueRef b1, b2;
       b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, x, int_coord_bld->zero);
       b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, x, width);
-      use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
+      use_border = LLVMBuildOr(builder, b1, b2, "b1_or_b2");
    }
 
    if (dims >= 2 &&
@@ -106,11 +107,11 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, y, int_coord_bld->zero);
       b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, y, height);
       if (use_border) {
-         use_border = LLVMBuildOr(bld->builder, use_border, b1, "ub_or_b1");
-         use_border = LLVMBuildOr(bld->builder, use_border, b2, "ub_or_b2");
+         use_border = LLVMBuildOr(builder, use_border, b1, "ub_or_b1");
+         use_border = LLVMBuildOr(builder, use_border, b2, "ub_or_b2");
       }
       else {
-         use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
+         use_border = LLVMBuildOr(builder, b1, b2, "b1_or_b2");
       }
    }
 
@@ -122,11 +123,11 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, z, int_coord_bld->zero);
       b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, z, depth);
       if (use_border) {
-         use_border = LLVMBuildOr(bld->builder, use_border, b1, "ub_or_b1");
-         use_border = LLVMBuildOr(bld->builder, use_border, b2, "ub_or_b2");
+         use_border = LLVMBuildOr(builder, use_border, b1, "ub_or_b1");
+         use_border = LLVMBuildOr(builder, use_border, b2, "ub_or_b2");
       }
       else {
-         use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
+         use_border = LLVMBuildOr(builder, b1, b2, "b1_or_b2");
       }
    }
 
@@ -148,7 +149,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       offset = lp_build_andnot(&bld->int_coord_bld, offset, use_border);
    }
 
-   lp_build_fetch_rgba_soa(bld->builder,
+   lp_build_fetch_rgba_soa(bld->gallivm,
                            bld->format_desc,
                            bld->texel_type,
                            data_ptr, offset,
@@ -174,12 +175,12 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       /* select texel color or border color depending on use_border */
       LLVMValueRef border_color_ptr = 
          bld->dynamic_state->border_color(bld->dynamic_state,
-                                          bld->builder, unit);
+                                          bld->gallivm, unit);
       int chan;
       for (chan = 0; chan < 4; chan++) {
          LLVMValueRef border_chan =
-            lp_build_array_get(bld->builder, border_color_ptr,
-                               lp_build_const_int32(chan));
+            lp_build_array_get(bld->gallivm, border_color_ptr,
+                               lp_build_const_int32(bld->gallivm, chan));
          LLVMValueRef border_chan_vec =
             lp_build_broadcast_scalar(&bld->float_vec_bld, border_chan);
          texel_out[chan] = lp_build_select(&bld->texel_bld, use_border,
@@ -205,7 +206,7 @@ lp_build_coord_mirror(struct lp_build_sample_context *bld,
    lp_build_ifloor_fract(coord_bld, coord, &flr, &fract);
 
    /* isOdd = flr & 1 */
-   isOdd = LLVMBuildAnd(bld->builder, flr, int_coord_bld->one, "");
+   isOdd = LLVMBuildAnd(bld->gallivm->builder, flr, int_coord_bld->one, "");
 
    /* make coord positive or negative depending on isOdd */
    coord = lp_build_set_sign(coord_bld, fract, isOdd);
@@ -239,7 +240,8 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
 {
    struct lp_build_context *coord_bld = &bld->coord_bld;
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
-   LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
+   LLVMBuilderRef builder = bld->gallivm->builder;
+   LLVMValueRef half = lp_build_const_vec(bld->gallivm, coord_bld->type, 0.5);
    LLVMValueRef length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
    LLVMValueRef coord0, coord1, weight;
 
@@ -253,18 +255,18 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
       /* repeat wrap */
       if (is_pot) {
          coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
-         coord0 = LLVMBuildAnd(bld->builder, coord0, length_minus_one, "");
-         coord1 = LLVMBuildAnd(bld->builder, coord1, length_minus_one, "");
+         coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
+         coord1 = LLVMBuildAnd(builder, coord1, length_minus_one, "");
       }
       else {
          /* Add a bias to the texcoord to handle negative coords */
          LLVMValueRef bias = lp_build_mul_imm(int_coord_bld, length, 1024);
          LLVMValueRef mask;
-         coord0 = LLVMBuildAdd(bld->builder, coord0, bias, "");
-         coord0 = LLVMBuildURem(bld->builder, coord0, length, "");
-         mask = lp_build_compare(bld->builder, int_coord_bld->type,
+         coord0 = LLVMBuildAdd(builder, coord0, bias, "");
+         coord0 = LLVMBuildURem(builder, coord0, length, "");
+         mask = lp_build_compare(bld->gallivm, int_coord_bld->type,
                                  PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
-         coord1 = LLVMBuildAnd(bld->builder,
+         coord1 = LLVMBuildAnd(builder,
                               lp_build_add(int_coord_bld, coord0, int_coord_bld->one),
                               mask, "");
       }
@@ -318,7 +320,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
          }
          /* was: clamp to [-0.5, length + 0.5], then sub 0.5 */
          coord = lp_build_sub(coord_bld, coord, half);
-         min = lp_build_const_vec(coord_bld->type, -1.0F);
+         min = lp_build_const_vec(bld->gallivm, coord_bld->type, -1.0F);
          coord = lp_build_clamp(coord_bld, coord, min, length_f);
          /* convert to int, compute lerp weight */
          lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
@@ -437,6 +439,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
 {
    struct lp_build_context *coord_bld = &bld->coord_bld;
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
    LLVMValueRef icoord;
    
@@ -445,12 +448,12 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
       coord = lp_build_mul(coord_bld, coord, length_f);
       icoord = lp_build_ifloor(coord_bld, coord);
       if (is_pot)
-         icoord = LLVMBuildAnd(bld->builder, icoord, length_minus_one, "");
+         icoord = LLVMBuildAnd(builder, icoord, length_minus_one, "");
       else {
          /* Add a bias to the texcoord to handle negative coords */
          LLVMValueRef bias = lp_build_mul_imm(int_coord_bld, length, 1024);
-         icoord = LLVMBuildAdd(bld->builder, icoord, bias, "");
-         icoord = LLVMBuildURem(bld->builder, icoord, length, "");
+         icoord = LLVMBuildAdd(builder, icoord, bias, "");
+         icoord = LLVMBuildURem(builder, icoord, length, "");
       }
       break;
 
@@ -830,7 +833,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
                        LLVMValueRef lod_fpart,
                        LLVMValueRef *colors_out)
 {
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef size0;
    LLVMValueRef size1;
    LLVMValueRef row_stride0_vec;
@@ -878,7 +881,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
                                 bld->float_bld.zero,
                                 "need_lerp");
 
-      lp_build_if(&if_ctx, builder, need_lerp);
+      lp_build_if(&if_ctx, bld->gallivm, need_lerp);
       {
          /* sample the second mipmap level */
          lp_build_mipmap_level_sizes(bld, ilevel1,
@@ -934,7 +937,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
                         LLVMValueRef *colors_out)
 {
    struct lp_build_context *int_bld = &bld->int_bld;
-   LLVMBuilderRef builder = bld->builder;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const unsigned mip_filter = bld->static_state->min_mip_filter;
    const unsigned min_filter = bld->static_state->min_img_filter;
    const unsigned mag_filter = bld->static_state->mag_img_filter;
@@ -942,8 +945,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
    LLVMValueRef ilevel0, ilevel1 = NULL;
    LLVMValueRef face_ddx[4], face_ddy[4];
    LLVMValueRef texels[4];
-   LLVMTypeRef i32t = LLVMInt32Type();
-   LLVMValueRef i32t_zero = LLVMConstInt(i32t, 0, 0);
+   LLVMValueRef i32t_zero = lp_build_const_int32(bld->gallivm, 0);
    unsigned chan;
 
    /*
@@ -1030,7 +1032,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
     */
 
    for (chan = 0; chan < 4; ++chan) {
-     texels[chan] = lp_build_alloca(builder, bld->texel_bld.vec_type, "");
+     texels[chan] = lp_build_alloca(bld->gallivm, bld->texel_bld.vec_type, "");
      lp_build_name(texels[chan], "sampler%u_texel_%c_var", unit, "xyzw"[chan]);
    }
 
@@ -1053,7 +1055,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
       minify = LLVMBuildICmp(builder, LLVMIntSGE,
                              lod_ipart, int_bld->zero, "");
 
-      lp_build_if(&if_ctx, builder, minify);
+      lp_build_if(&if_ctx, bld->gallivm, minify);
       {
          /* Use the minification filter */
          lp_build_sample_mipmap(bld, unit,
@@ -1092,6 +1094,7 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
                         LLVMValueRef texel[4])
 {
    struct lp_build_context *texel_bld = &bld->texel_bld;
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef res;
    const unsigned chan = 0;
 
@@ -1100,11 +1103,10 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
 
    /* debug code */
    if (0) {
-      LLVMValueRef indx = lp_build_const_int32(0);
-      LLVMValueRef coord = LLVMBuildExtractElement(bld->builder, p, indx, "");
-      LLVMValueRef tex = LLVMBuildExtractElement(bld->builder,
-                                                 texel[chan], indx, "");
-      lp_build_printf(bld->builder, "shadow compare coord %f to texture %f\n",
+      LLVMValueRef indx = lp_build_const_int32(bld->gallivm, 0);
+      LLVMValueRef coord = LLVMBuildExtractElement(builder, p, indx, "");
+      LLVMValueRef tex = LLVMBuildExtractElement(builder, texel[chan], indx, "");
+      lp_build_printf(bld->gallivm, "shadow compare coord %f to texture %f\n",
                       coord, tex);
    }
 
@@ -1126,10 +1128,10 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
  * For debugging.
  */
 void
-lp_build_sample_nop(struct lp_type type,
+lp_build_sample_nop(struct gallivm_state *gallivm, struct lp_type type,
                     LLVMValueRef texel_out[4])
 {
-   LLVMValueRef one = lp_build_one(type);
+   LLVMValueRef one = lp_build_one(gallivm, type);
    unsigned chan;
 
    for (chan = 0; chan < 4; chan++) {
@@ -1147,7 +1149,7 @@ lp_build_sample_nop(struct lp_type type,
  * \param ddy  partial derivatives of (s,t,r,q) with respect to y
  */
 void
-lp_build_sample_soa(LLVMBuilderRef builder,
+lp_build_sample_soa(struct gallivm_state *gallivm,
                     const struct lp_sampler_static_state *static_state,
                     struct lp_sampler_dynamic_state *dynamic_state,
                     struct lp_type type,
@@ -1162,8 +1164,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
 {
    unsigned dims = texture_dims(static_state->target);
    struct lp_build_sample_context bld;
-   LLVMTypeRef i32t = LLVMInt32Type();
-
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef s;
    LLVMValueRef t;
    LLVMValueRef r;
@@ -1178,7 +1180,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
 
    /* Setup our build context */
    memset(&bld, 0, sizeof bld);
-   bld.builder = builder;
+   bld.gallivm = gallivm;
    bld.static_state = static_state;
    bld.dynamic_state = dynamic_state;
    bld.format_desc = util_format_description(static_state->format);
@@ -1195,22 +1197,22 @@ lp_build_sample_soa(LLVMBuilderRef builder,
 
    float_vec_type = lp_type_float_vec(32);
 
-   lp_build_context_init(&bld.float_bld, builder, bld.float_type);
-   lp_build_context_init(&bld.float_vec_bld, builder, float_vec_type);
-   lp_build_context_init(&bld.int_bld, builder, bld.int_type);
-   lp_build_context_init(&bld.coord_bld, builder, bld.coord_type);
-   lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type);
-   lp_build_context_init(&bld.int_size_bld, builder, bld.int_size_type);
-   lp_build_context_init(&bld.float_size_bld, builder, bld.float_size_type);
-   lp_build_context_init(&bld.texel_bld, builder, bld.texel_type);
+   lp_build_context_init(&bld.float_bld, gallivm, bld.float_type);
+   lp_build_context_init(&bld.float_vec_bld, gallivm, float_vec_type);
+   lp_build_context_init(&bld.int_bld, gallivm, bld.int_type);
+   lp_build_context_init(&bld.coord_bld, gallivm, bld.coord_type);
+   lp_build_context_init(&bld.int_coord_bld, gallivm, bld.int_coord_type);
+   lp_build_context_init(&bld.int_size_bld, gallivm, bld.int_size_type);
+   lp_build_context_init(&bld.float_size_bld, gallivm, bld.float_size_type);
+   lp_build_context_init(&bld.texel_bld, gallivm, bld.texel_type);
 
    /* Get the dynamic state */
-   bld.width = dynamic_state->width(dynamic_state, builder, unit);
-   bld.height = dynamic_state->height(dynamic_state, builder, unit);
-   bld.depth = dynamic_state->depth(dynamic_state, builder, unit);
-   bld.row_stride_array = dynamic_state->row_stride(dynamic_state, builder, unit);
-   bld.img_stride_array = dynamic_state->img_stride(dynamic_state, builder, unit);
-   bld.data_array = dynamic_state->data_ptr(dynamic_state, builder, unit);
+   bld.width = dynamic_state->width(dynamic_state, gallivm, unit);
+   bld.height = dynamic_state->height(dynamic_state, gallivm, unit);
+   bld.depth = dynamic_state->depth(dynamic_state, gallivm, unit);
+   bld.row_stride_array = dynamic_state->row_stride(dynamic_state, gallivm, unit);
+   bld.img_stride_array = dynamic_state->img_stride(dynamic_state, gallivm, unit);
+   bld.data_array = dynamic_state->data_ptr(dynamic_state, gallivm, unit);
    /* Note that data_array is an array[level] of pointers to texture images */
 
    s = coords[0];
@@ -1236,7 +1238,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
 
    if (0) {
       /* For debug: no-op texture sampling */
-      lp_build_sample_nop(bld.texel_type, texel_out);
+      lp_build_sample_nop(gallivm, bld.texel_type, texel_out);
    }
    else if (util_format_fits_8unorm(bld.format_desc) &&
             lp_is_simple_wrap_mode(static_state->wrap_s) &&
index 4693c2de6f9c0bb0f604b995683c5ea3f7562a31..0dc2f24d10a2eb0695ede785e6a77de495f21450 100644 (file)
 #include "util/u_debug.h"
 #include "util/u_memory.h"
 
+#include "lp_bld_const.h"
 #include "lp_bld_debug.h"
 #include "lp_bld_struct.h"
 
 
 LLVMValueRef
-lp_build_struct_get_ptr(LLVMBuilderRef builder,
+lp_build_struct_get_ptr(struct gallivm_state *gallivm,
                         LLVMValueRef ptr,
                         unsigned member,
                         const char *name)
@@ -51,16 +52,16 @@ lp_build_struct_get_ptr(LLVMBuilderRef builder,
    LLVMValueRef member_ptr;
    assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
    assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMStructTypeKind);
-   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   indices[1] = LLVMConstInt(LLVMInt32Type(), member, 0);
-   member_ptr = LLVMBuildGEP(builder, ptr, indices, Elements(indices), "");
+   indices[0] = lp_build_const_int32(gallivm, 0);
+   indices[1] = lp_build_const_int32(gallivm, member);
+   member_ptr = LLVMBuildGEP(gallivm->builder, ptr, indices, Elements(indices), "");
    lp_build_name(member_ptr, "%s.%s_ptr", LLVMGetValueName(ptr), name);
    return member_ptr;
 }
 
 
 LLVMValueRef
-lp_build_struct_get(LLVMBuilderRef builder,
+lp_build_struct_get(struct gallivm_state *gallivm,
                     LLVMValueRef ptr,
                     unsigned member,
                     const char *name)
@@ -69,15 +70,15 @@ lp_build_struct_get(LLVMBuilderRef builder,
    LLVMValueRef res;
    assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
    assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMStructTypeKind);
-   member_ptr = lp_build_struct_get_ptr(builder, ptr, member, name);
-   res = LLVMBuildLoad(builder, member_ptr, "");
+   member_ptr = lp_build_struct_get_ptr(gallivm, ptr, member, name);
+   res = LLVMBuildLoad(gallivm->builder, member_ptr, "");
    lp_build_name(res, "%s.%s", LLVMGetValueName(ptr), name);
    return res;
 }
 
 
 LLVMValueRef
-lp_build_array_get_ptr(LLVMBuilderRef builder,
+lp_build_array_get_ptr(struct gallivm_state *gallivm,
                        LLVMValueRef ptr,
                        LLVMValueRef index)
 {
@@ -85,9 +86,9 @@ lp_build_array_get_ptr(LLVMBuilderRef builder,
    LLVMValueRef element_ptr;
    assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
    assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind);
-   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indices[0] = lp_build_const_int32(gallivm, 0);
    indices[1] = index;
-   element_ptr = LLVMBuildGEP(builder, ptr, indices, Elements(indices), "");
+   element_ptr = LLVMBuildGEP(gallivm->builder, ptr, indices, Elements(indices), "");
 #ifdef DEBUG
    lp_build_name(element_ptr, "&%s[%s]",
                  LLVMGetValueName(ptr), LLVMGetValueName(index));
@@ -97,7 +98,7 @@ lp_build_array_get_ptr(LLVMBuilderRef builder,
 
 
 LLVMValueRef
-lp_build_array_get(LLVMBuilderRef builder,
+lp_build_array_get(struct gallivm_state *gallivm,
                    LLVMValueRef ptr,
                    LLVMValueRef index)
 {
@@ -105,8 +106,8 @@ lp_build_array_get(LLVMBuilderRef builder,
    LLVMValueRef res;
    assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
    assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind);
-   element_ptr = lp_build_array_get_ptr(builder, ptr, index);
-   res = LLVMBuildLoad(builder, element_ptr, "");
+   element_ptr = lp_build_array_get_ptr(gallivm, ptr, index);
+   res = LLVMBuildLoad(gallivm->builder, element_ptr, "");
 #ifdef DEBUG
    lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index));
 #endif
@@ -115,7 +116,7 @@ lp_build_array_get(LLVMBuilderRef builder,
 
 
 void
-lp_build_array_set(LLVMBuilderRef builder,
+lp_build_array_set(struct gallivm_state *gallivm,
                    LLVMValueRef ptr,
                    LLVMValueRef index,
                    LLVMValueRef value)
@@ -123,8 +124,8 @@ lp_build_array_set(LLVMBuilderRef builder,
    LLVMValueRef element_ptr;
    assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
    assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind);
-   element_ptr = lp_build_array_get_ptr(builder, ptr, index);
-   LLVMBuildStore(builder, value, element_ptr);
+   element_ptr = lp_build_array_get_ptr(gallivm, ptr, index);
+   LLVMBuildStore(gallivm->builder, value, element_ptr);
 }
 
 
index eb87a8eee9ee40a24fbf74d1c2f695be4f669eeb..11605c685f09d5b50b5a77879014ee72dc2f837f 100644 (file)
@@ -38,7 +38,7 @@
 
 
 #include "gallivm/lp_bld.h"
-#include <llvm-c/Target.h>
+#include "gallivm/lp_bld_init.h"
 
 #include "util/u_debug.h"
 #include "util/u_memory.h"
@@ -57,7 +57,7 @@
  * Get value pointer to a structure member.
  */
 LLVMValueRef
-lp_build_struct_get_ptr(LLVMBuilderRef builder,
+lp_build_struct_get_ptr(struct gallivm_state *gallivm,
                         LLVMValueRef ptr,
                         unsigned member,
                         const char *name);
@@ -66,7 +66,7 @@ lp_build_struct_get_ptr(LLVMBuilderRef builder,
  * Get the value of a structure member.
  */
 LLVMValueRef
-lp_build_struct_get(LLVMBuilderRef builder,
+lp_build_struct_get(struct gallivm_state *gallivm,
                     LLVMValueRef ptr,
                     unsigned member,
                     const char *name);
@@ -75,7 +75,7 @@ lp_build_struct_get(LLVMBuilderRef builder,
  * Get value pointer to an array element.
  */
 LLVMValueRef
-lp_build_array_get_ptr(LLVMBuilderRef builder,
+lp_build_array_get_ptr(struct gallivm_state *gallivm,
                        LLVMValueRef ptr,
                        LLVMValueRef index);
 
@@ -83,7 +83,7 @@ lp_build_array_get_ptr(LLVMBuilderRef builder,
  * Get the value of an array element.
  */
 LLVMValueRef
-lp_build_array_get(LLVMBuilderRef builder,
+lp_build_array_get(struct gallivm_state *gallivm,
                    LLVMValueRef ptr,
                    LLVMValueRef index);
 
@@ -91,7 +91,7 @@ lp_build_array_get(LLVMBuilderRef builder,
  * Set the value of an array element.
  */
 void
-lp_build_array_set(LLVMBuilderRef builder,
+lp_build_array_set(struct gallivm_state *gallivm,
                    LLVMValueRef ptr,
                    LLVMValueRef index,
                    LLVMValueRef value);
index 4685a90e41818a0e7be2f8caa3554a175f8099ef..71693603c12a9c873448e8d1c1ef34efc15a94a3 100644 (file)
 
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_swizzle.h"
 
 
 LLVMValueRef
-lp_build_broadcast(LLVMBuilderRef builder,
+lp_build_broadcast(struct gallivm_state *gallivm,
                    LLVMTypeRef vec_type,
                    LLVMValueRef scalar)
 {
@@ -52,8 +53,8 @@ lp_build_broadcast(LLVMBuilderRef builder,
 
    res = LLVMGetUndef(vec_type);
    for(i = 0; i < n; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      res = LLVMBuildInsertElement(builder, res, scalar, index, "");
+      LLVMValueRef index = lp_build_const_int32(gallivm, i);
+      res = LLVMBuildInsertElement(gallivm->builder, res, scalar, index, "");
    }
 
    return res;
@@ -67,6 +68,7 @@ LLVMValueRef
 lp_build_broadcast_scalar(struct lp_build_context *bld,
                           LLVMValueRef scalar)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
 
    assert(lp_check_elem_type(type, LLVMTypeOf(scalar)));
@@ -82,17 +84,17 @@ lp_build_broadcast_scalar(struct lp_build_context *bld,
       struct lp_type i32_vec_type = lp_type_int_vec(32);
       i32_vec_type.length = type.length;
 
-      res = LLVMBuildInsertElement(bld->builder, bld->undef, scalar,
-                                   LLVMConstInt(LLVMInt32Type(), 0, 0), "");
-      res = LLVMBuildShuffleVector(bld->builder, res, bld->undef,
-                                   lp_build_const_int_vec(i32_vec_type, 0), "");
+      res = LLVMBuildInsertElement(builder, bld->undef, scalar,
+                                   lp_build_const_int32(bld->gallivm, 0), "");
+      res = LLVMBuildShuffleVector(builder, res, bld->undef,
+                                   lp_build_const_int_vec(bld->gallivm, i32_vec_type, 0), "");
 #else
       /* XXX: The above path provokes a bug in LLVM 2.6 */
       unsigned i;
       res = bld->undef;
       for(i = 0; i < type.length; ++i) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-         res = LLVMBuildInsertElement(bld->builder, res, scalar, index, "");
+         LLVMValueRef index = lp_build_const_int32(bld->gallivm, i);
+         res = LLVMBuildInsertElement(builder, res, scalar, index, "");
       }
 #endif
       return res;
@@ -104,13 +106,13 @@ lp_build_broadcast_scalar(struct lp_build_context *bld,
  * Combined extract and broadcast (or a mere shuffle when the two types match)
  */
 LLVMValueRef
-lp_build_extract_broadcast(LLVMBuilderRef builder,
+lp_build_extract_broadcast(struct gallivm_state *gallivm,
                            struct lp_type src_type,
                            struct lp_type dst_type,
                            LLVMValueRef vector,
                            LLVMValueRef index)
 {
-   LLVMTypeRef i32t = LLVMInt32Type();
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
    LLVMValueRef res;
 
    assert(src_type.floating == dst_type.floating);
@@ -132,8 +134,8 @@ lp_build_extract_broadcast(LLVMBuilderRef builder,
           * Broadcast scalar -> vector.
           */
 
-         res = lp_build_broadcast(builder,
-                                  lp_build_vec_type(dst_type),
+         res = lp_build_broadcast(gallivm,
+                                  lp_build_vec_type(gallivm, dst_type),
                                   vector);
       }
    }
@@ -144,16 +146,16 @@ lp_build_extract_broadcast(LLVMBuilderRef builder,
           */
 
          LLVMValueRef shuffle;
-         shuffle = lp_build_broadcast(builder,
+         shuffle = lp_build_broadcast(gallivm,
                                       LLVMVectorType(i32t, dst_type.length),
                                       index);
-         res = LLVMBuildShuffleVector(builder, vector,
-                                      LLVMGetUndef(lp_build_vec_type(dst_type)),
+         res = LLVMBuildShuffleVector(gallivm->builder, vector,
+                                      LLVMGetUndef(lp_build_vec_type(gallivm, dst_type)),
                                       shuffle, "");
       }
       else {
          LLVMValueRef scalar;
-         scalar = LLVMBuildExtractElement(builder, vector, index, "");
+         scalar = LLVMBuildExtractElement(gallivm->builder, vector, index, "");
          if (dst_type.length == 1) {
             /*
              * Trivial extract scalar from vector.
@@ -166,8 +168,8 @@ lp_build_extract_broadcast(LLVMBuilderRef builder,
              * General case of different sized vectors.
              */
 
-            res = lp_build_broadcast(builder,
-                                     lp_build_vec_type(dst_type),
+            res = lp_build_broadcast(gallivm,
+                                     lp_build_vec_type(gallivm, dst_type),
                                      vector);
          }
       }
@@ -185,6 +187,7 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
                             LLVMValueRef a,
                             unsigned channel)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    const unsigned n = type.length;
    unsigned i, j;
@@ -199,14 +202,14 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
       /*
        * Shuffle.
        */
-      LLVMTypeRef elem_type = LLVMInt32Type();
+      LLVMTypeRef elem_type = LLVMInt32TypeInContext(bld->gallivm->context);
       LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
 
       for(j = 0; j < n; j += 4)
          for(i = 0; i < 4; ++i)
             shuffles[j + i] = LLVMConstInt(elem_type, j + channel, 0);
 
-      return LLVMBuildShuffleVector(bld->builder, a, bld->undef, LLVMConstVector(shuffles, n), "");
+      return LLVMBuildShuffleVector(builder, a, bld->undef, LLVMConstVector(shuffles, n), "");
    }
    else {
       /*
@@ -226,8 +229,9 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
       };
       unsigned i;
 
-      a = LLVMBuildAnd(bld->builder, a,
-                       lp_build_const_mask_aos(type, 1 << channel), "");
+      a = LLVMBuildAnd(builder, a,
+                       lp_build_const_mask_aos(bld->gallivm,
+                                               type, 1 << channel), "");
 
       /*
        * Build a type where each element is an integer that cover the four
@@ -239,7 +243,7 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
       type4.width *= 4;
       type4.length /= 4;
 
-      a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(type4), "");
+      a = LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type4), "");
 
       for(i = 0; i < 2; ++i) {
          LLVMValueRef tmp = NULL;
@@ -250,16 +254,16 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
 #endif
 
          if(shift > 0)
-            tmp = LLVMBuildLShr(bld->builder, a, lp_build_const_int_vec(type4, shift*type.width), "");
+            tmp = LLVMBuildLShr(builder, a, lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
          if(shift < 0)
-            tmp = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type4, -shift*type.width), "");
+            tmp = LLVMBuildShl(builder, a, lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
 
          assert(tmp);
          if(tmp)
-            a = LLVMBuildOr(bld->builder, a, tmp, "");
+            a = LLVMBuildOr(builder, a, tmp, "");
       }
 
-      return LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(type), "");
+      return LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type), "");
    }
 }
 
@@ -269,6 +273,7 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
                      LLVMValueRef a,
                      const unsigned char swizzles[4])
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const struct lp_type type = bld->type;
    const unsigned n = type.length;
    unsigned i, j;
@@ -303,8 +308,8 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
       /*
        * Shuffle.
        */
-      LLVMValueRef undef = LLVMGetUndef(lp_build_elem_type(type));
-      LLVMTypeRef i32t = LLVMInt32Type();
+      LLVMValueRef undef = LLVMGetUndef(lp_build_elem_type(bld->gallivm, type));
+      LLVMTypeRef i32t = LLVMInt32TypeInContext(bld->gallivm->context);
       LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
       LLVMValueRef aux[LP_MAX_VECTOR_LENGTH];
 
@@ -326,13 +331,13 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
             case PIPE_SWIZZLE_ZERO:
                shuffle = type.length + 0;
                if (!aux[0]) {
-                  aux[0] = lp_build_const_elem(type, 0.0);
+                  aux[0] = lp_build_const_elem(bld->gallivm, type, 0.0);
                }
                break;
             case PIPE_SWIZZLE_ONE:
                shuffle = type.length + 1;
                if (!aux[1]) {
-                  aux[1] = lp_build_const_elem(type, 1.0);
+                  aux[1] = lp_build_const_elem(bld->gallivm, type, 1.0);
                }
                break;
             }
@@ -346,7 +351,7 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
          }
       }
 
-      return LLVMBuildShuffleVector(bld->builder, a,
+      return LLVMBuildShuffleVector(builder, a,
                                     LLVMConstVector(aux, n),
                                     LLVMConstVector(shuffles, n), "");
    } else {
@@ -387,8 +392,8 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
       type4.width *= 4;
       type4.length /= 4;
 
-      a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(type4), "");
-      res = LLVMBuildBitCast(bld->builder, res, lp_build_vec_type(type4), "");
+      a = LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type4), "");
+      res = LLVMBuildBitCast(builder, res, lp_build_vec_type(bld->gallivm, type4), "");
 
       /*
        * Mask and shift the channels, trying to group as many channels in the
@@ -414,23 +419,24 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
             if (0)
                debug_printf("shift = %i, mask = 0x%08llx\n", shift, mask);
 
-            masked = LLVMBuildAnd(bld->builder, a,
-                                  lp_build_const_int_vec(type4, mask), "");
+            masked = LLVMBuildAnd(builder, a,
+                                  lp_build_const_int_vec(bld->gallivm, type4, mask), "");
             if (shift > 0) {
-               shifted = LLVMBuildShl(bld->builder, masked,
-                                      lp_build_const_int_vec(type4, shift*type.width), "");
+               shifted = LLVMBuildShl(builder, masked,
+                                      lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
             } else if (shift < 0) {
-               shifted = LLVMBuildLShr(bld->builder, masked,
-                                       lp_build_const_int_vec(type4, -shift*type.width), "");
+               shifted = LLVMBuildLShr(builder, masked,
+                                       lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
             } else {
                shifted = masked;
             }
 
-            res = LLVMBuildOr(bld->builder, res, shifted, "");
+            res = LLVMBuildOr(builder, res, shifted, "");
          }
       }
 
-      return LLVMBuildBitCast(bld->builder, res, lp_build_vec_type(type), "");
+      return LLVMBuildBitCast(builder, res,
+                              lp_build_vec_type(bld->gallivm, type), "");
    }
 }
 
index fdea8442aef38eeb9cc28ee2791fcd3864e34b50..c366a65103ef5ebb85b25538a27957d9dc0870fa 100644 (file)
@@ -45,7 +45,7 @@ struct lp_build_context;
 
 
 LLVMValueRef
-lp_build_broadcast(LLVMBuilderRef builder,
+lp_build_broadcast(struct gallivm_state *gallivm,
                    LLVMTypeRef vec_type,
                    LLVMValueRef scalar);
 
@@ -56,7 +56,7 @@ lp_build_broadcast_scalar(struct lp_build_context *bld,
 
 
 LLVMValueRef
-lp_build_extract_broadcast(LLVMBuilderRef builder,
+lp_build_extract_broadcast(struct gallivm_state *gallivm,
                            struct lp_type src_type,
                            struct lp_type dst_type,
                            LLVMValueRef vector,
index a4d3b750c3cfa36f8d75d781024e287297ea7dc5..40186befb9fda3e5687ede835152e7862844ef22 100644 (file)
@@ -46,6 +46,7 @@ struct tgsi_shader_info;
 struct lp_type;
 struct lp_build_context;
 struct lp_build_mask_context;
+struct gallivm_state;
 
 
 enum lp_build_tex_modifier {
@@ -141,7 +142,7 @@ struct lp_build_sampler_soa
 
    void
    (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler,
-                        LLVMBuilderRef builder,
+                        struct gallivm_state *gallivm,
                         struct lp_type type,
                         unsigned unit,
                         unsigned num_coords,
@@ -174,7 +175,7 @@ lp_build_tgsi_info(const struct tgsi_token *tokens,
 
 
 void
-lp_build_tgsi_soa(LLVMBuilderRef builder,
+lp_build_tgsi_soa(struct gallivm_state *gallivm,
                   const struct tgsi_token *tokens,
                   struct lp_type type,
                   struct lp_build_mask_context *mask,
@@ -187,7 +188,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
 
 
 void
-lp_build_tgsi_aos(LLVMBuilderRef builder,
+lp_build_tgsi_aos(struct gallivm_state *gallivm,
                   const struct tgsi_token *tokens,
                   struct lp_type type,
                   const unsigned char swizzles[4],
index c3c082b2b95334d6d6ebd4d61a083c61ffe9c7c9..a021efd69ff8b15c1c45ccac55b577b2c4b32767 100644 (file)
@@ -151,6 +151,7 @@ emit_fetch(
    const struct tgsi_full_instruction *inst,
    unsigned src_op)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    struct lp_type type = bld->base.type;
    const struct tgsi_full_src_register *reg = &inst->Src[src_op];
    LLVMValueRef res;
@@ -175,14 +176,12 @@ emit_fetch(
          LLVMValueRef scalar;
          LLVMValueRef swizzle;
 
-         index = LLVMConstInt(LLVMInt32Type(),
-                              reg->Register.Index*4 + chan,
-                              0);
+         index = lp_build_const_int32(bld->base.gallivm, reg->Register.Index * 4 + chan);
 
-         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
+         scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr,
                                    &index, 1, "");
 
-         scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+         scalar = LLVMBuildLoad(builder, scalar_ptr, "");
 
          lp_build_name(scalar, "const[%u].%c", reg->Register.Index, "xyzw"[chan]);
 
@@ -190,9 +189,9 @@ emit_fetch(
           * NOTE: constants array is always assumed to be RGBA
           */
 
-         swizzle = LLVMConstInt(LLVMInt32Type(), chan, 0);
+         swizzle = lp_build_const_int32(bld->base.gallivm, chan);
 
-         res = LLVMBuildInsertElement(bld->base.builder, res, scalar, swizzle, "");
+         res = LLVMBuildInsertElement(builder, res, scalar, swizzle, "");
       }
 
       /*
@@ -206,14 +205,14 @@ emit_fetch(
          unsigned i;
 
          for (chan = 0; chan < 4; ++chan) {
-            shuffles[chan] = LLVMConstInt(LLVMInt32Type(), chan, 0);
+            shuffles[chan] = lp_build_const_int32(bld->base.gallivm, chan);
          }
 
          for (i = 4; i < type.length; ++i) {
             shuffles[i] = shuffles[i % 4];
          }
 
-         res = LLVMBuildShuffleVector(bld->base.builder,
+         res = LLVMBuildShuffleVector(builder,
                                       res, bld->base.undef,
                                       LLVMConstVector(shuffles, type.length),
                                       "");
@@ -234,7 +233,7 @@ emit_fetch(
       {
          LLVMValueRef temp_ptr;
          temp_ptr = bld->temps[reg->Register.Index];
-         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
+         res = LLVMBuildLoad(builder, temp_ptr, "");
          if (!res)
             return bld->base.undef;
       }
@@ -281,6 +280,7 @@ emit_store(
    unsigned index,
    LLVMValueRef value)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    const struct tgsi_full_dst_register *reg = &inst->Dst[index];
    LLVMValueRef mask = NULL;
    LLVMValueRef ptr;
@@ -299,7 +299,7 @@ emit_store(
       break;
 
    case TGSI_SAT_MINUS_PLUS_ONE:
-      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
+      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.gallivm, bld->base.type, -1.0));
       value = lp_build_min(&bld->base, value, bld->base.one);
       break;
 
@@ -344,20 +344,20 @@ emit_store(
 
       assert(inst->Predicate.Index < LP_MAX_TGSI_PREDS);
 
-      pred = LLVMBuildLoad(bld->base.builder,
+      pred = LLVMBuildLoad(builder,
                            bld->preds[inst->Predicate.Index], "");
 
       /*
        * Convert the value to an integer mask.
        */
-      pred = lp_build_compare(bld->base.builder,
+      pred = lp_build_compare(bld->base.gallivm,
                                bld->base.type,
                                PIPE_FUNC_NOTEQUAL,
                                pred,
                                bld->base.zero);
 
       if (inst->Predicate.Negate) {
-         pred = LLVMBuildNot(bld->base.builder, pred, "");
+         pred = LLVMBuildNot(builder, pred, "");
       }
 
       pred = swizzle_aos(bld, pred,
@@ -367,7 +367,7 @@ emit_store(
                          inst->Predicate.SwizzleW);
 
       if (mask) {
-         mask = LLVMBuildAnd(bld->base.builder, mask, pred, "");
+         mask = LLVMBuildAnd(builder, mask, pred, "");
       } else {
          mask = pred;
       }
@@ -380,10 +380,11 @@ emit_store(
    if (reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) {
       LLVMValueRef writemask;
 
-      writemask = lp_build_const_mask_aos(bld->base.type, reg->Register.WriteMask);
+      writemask = lp_build_const_mask_aos(bld->base.gallivm, bld->base.type,
+                                          reg->Register.WriteMask);
 
       if (mask) {
-         mask = LLVMBuildAnd(bld->base.builder, mask, writemask, "");
+         mask = LLVMBuildAnd(builder, mask, writemask, "");
       } else {
          mask = writemask;
       }
@@ -392,12 +393,12 @@ emit_store(
    if (mask) {
       LLVMValueRef orig_value;
 
-      orig_value = LLVMBuildLoad(bld->base.builder, ptr, "");
+      orig_value = LLVMBuildLoad(builder, ptr, "");
       value = lp_build_select(&bld->base,
                               mask, value, orig_value);
    }
 
-   LLVMBuildStore(bld->base.builder, value, ptr);
+   LLVMBuildStore(builder, value, ptr);
 }
 
 
@@ -454,7 +455,8 @@ emit_declaration(
    struct lp_build_tgsi_aos_context *bld,
    const struct tgsi_full_declaration *decl)
 {
-   LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type);
+   struct gallivm_state *gallivm = bld->base.gallivm;
+   LLVMTypeRef vec_type = lp_build_vec_type(bld->base.gallivm, bld->base.type);
 
    unsigned first = decl->Range.First;
    unsigned last = decl->Range.Last;
@@ -465,31 +467,26 @@ emit_declaration(
       case TGSI_FILE_TEMPORARY:
          assert(idx < LP_MAX_TGSI_TEMPS);
          if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
-            LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
-                                                   last + 1, 0);
-            bld->temps_array = lp_build_array_alloca(bld->base.builder,
+            LLVMValueRef array_size = lp_build_const_int32(gallivm, last + 1);
+            bld->temps_array = lp_build_array_alloca(bld->base.gallivm,
                                                      vec_type, array_size, "");
          } else {
-            bld->temps[idx] = lp_build_alloca(bld->base.builder,
-                                              vec_type, "");
+            bld->temps[idx] = lp_build_alloca(gallivm, vec_type, "");
          }
          break;
 
       case TGSI_FILE_OUTPUT:
-         bld->outputs[idx] = lp_build_alloca(bld->base.builder,
-                                             vec_type, "");
+         bld->outputs[idx] = lp_build_alloca(gallivm, vec_type, "");
          break;
 
       case TGSI_FILE_ADDRESS:
          assert(idx < LP_MAX_TGSI_ADDRS);
-         bld->addr[idx] = lp_build_alloca(bld->base.builder,
-                                          vec_type, "");
+         bld->addr[idx] = lp_build_alloca(gallivm, vec_type, "");
          break;
 
       case TGSI_FILE_PREDICATE:
          assert(idx < LP_MAX_TGSI_PREDS);
-         bld->preds[idx] = lp_build_alloca(bld->base.builder,
-                                           vec_type, "");
+         bld->preds[idx] = lp_build_alloca(gallivm, vec_type, "");
          break;
 
       default:
@@ -644,7 +641,7 @@ emit_instruction(
       src0 = emit_fetch(bld, inst, 0);
       src1 = emit_fetch(bld, inst, 1);
       src2 = emit_fetch(bld, inst, 2);
-      tmp1 = lp_build_const_vec(bld->base.type, 0.5);
+      tmp1 = lp_build_const_vec(bld->base.gallivm, bld->base.type, 0.5);
       tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, src2, tmp1);
       dst0 = lp_build_select(&bld->base, tmp0, src0, src1);
       break;
@@ -1039,7 +1036,7 @@ emit_instruction(
 
 
 void
-lp_build_tgsi_aos(LLVMBuilderRef builder,
+lp_build_tgsi_aos(struct gallivm_state *gallivm,
                   const struct tgsi_token *tokens,
                   struct lp_type type,
                   const unsigned char swizzles[4],
@@ -1058,8 +1055,8 @@ lp_build_tgsi_aos(LLVMBuilderRef builder,
 
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
-   lp_build_context_init(&bld.base, builder, type);
-   lp_build_context_init(&bld.int_bld, builder, lp_int_type(type));
+   lp_build_context_init(&bld.base, gallivm, type);
+   lp_build_context_init(&bld.int_bld, gallivm, lp_int_type(type));
 
    for (chan = 0; chan < 4; ++chan) {
       bld.swizzles[chan] = swizzles[chan];
@@ -1131,7 +1128,7 @@ lp_build_tgsi_aos(LLVMBuilderRef builder,
                imm[swizzle] = parse.FullToken.FullImmediate.u[chan].Float;
             }
             bld.immediates[num_immediates] =
-                     lp_build_const_aos(type,
+                     lp_build_const_aos(gallivm, type,
                                         imm[0], imm[1], imm[2], imm[3],
                                         NULL);
             num_immediates++;
@@ -1156,7 +1153,7 @@ lp_build_tgsi_aos(LLVMBuilderRef builder,
    }
 
    if (0) {
-      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+      LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
       LLVMValueRef function = LLVMGetBasicBlockParent(block);
       debug_printf("11111111111111111111111111111 \n");
       tgsi_dump(tokens, 0);
@@ -1167,7 +1164,7 @@ lp_build_tgsi_aos(LLVMBuilderRef builder,
 
    if (0) {
       LLVMModuleRef module = LLVMGetGlobalParent(
-         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
+         LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
       LLVMDumpModule(module);
    }
 
index 7f0f058c2225d75dd53fca86bec148f486f690e6..1b5a8a5903b7d7a11df900bcd59bbec39ca7a9ae 100644 (file)
@@ -51,6 +51,7 @@
 #include "lp_bld_arit.h"
 #include "lp_bld_bitarit.h"
 #include "lp_bld_gather.h"
+#include "lp_bld_init.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_swizzle.h"
 #include "lp_bld_flow.h"
@@ -175,22 +176,24 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context
    mask->loop_stack_size = 0;
    mask->call_stack_size = 0;
 
-   mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
+   mask->int_vec_type = lp_build_int_vec_type(bld->gallivm, mask->bld->type);
    mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
          LLVMConstAllOnes(mask->int_vec_type);
 }
 
 static void lp_exec_mask_update(struct lp_exec_mask *mask)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
    if (mask->loop_stack_size) {
       /*for loops we need to update the entire mask at runtime */
       LLVMValueRef tmp;
       assert(mask->break_mask);
-      tmp = LLVMBuildAnd(mask->bld->builder,
+      tmp = LLVMBuildAnd(builder,
                          mask->cont_mask,
                          mask->break_mask,
                          "maskcb");
-      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+      mask->exec_mask = LLVMBuildAnd(builder,
                                      mask->cond_mask,
                                      tmp,
                                      "maskfull");
@@ -198,7 +201,7 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask)
       mask->exec_mask = mask->cond_mask;
 
    if (mask->call_stack_size) {
-      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+      mask->exec_mask = LLVMBuildAnd(builder,
                                      mask->exec_mask,
                                      mask->ret_mask,
                                      "callmask");
@@ -212,13 +215,15 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask)
 static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
                                    LLVMValueRef val)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
    assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
    if (mask->cond_stack_size == 0) {
       assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
    }
    mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
    assert(LLVMTypeOf(val) == mask->int_vec_type);
-   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
+   mask->cond_mask = LLVMBuildAnd(builder,
                                   mask->cond_mask,
                                   val,
                                   "");
@@ -227,6 +232,7 @@ static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
 
 static void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
    LLVMValueRef prev_mask;
    LLVMValueRef inv_mask;
 
@@ -236,9 +242,9 @@ static void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
       assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
    }
 
-   inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, "");
+   inv_mask = LLVMBuildNot(builder, mask->cond_mask, "");
 
-   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
+   mask->cond_mask = LLVMBuildAnd(builder,
                                   inv_mask,
                                   prev_mask, "");
    lp_exec_mask_update(mask);
@@ -253,6 +259,8 @@ static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
 
 static void lp_exec_bgnloop(struct lp_exec_mask *mask)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
    if (mask->loop_stack_size == 0) {
       assert(mask->loop_block == NULL);
       assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
@@ -268,25 +276,26 @@ static void lp_exec_bgnloop(struct lp_exec_mask *mask)
    mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
    ++mask->loop_stack_size;
 
-   mask->break_var = lp_build_alloca(mask->bld->builder, mask->int_vec_type, "");
-   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
+   mask->break_var = lp_build_alloca(mask->bld->gallivm, mask->int_vec_type, "");
+   LLVMBuildStore(builder, mask->break_mask, mask->break_var);
 
-   mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
-   LLVMBuildBr(mask->bld->builder, mask->loop_block);
-   LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
+   mask->loop_block = lp_build_insert_new_block(mask->bld->gallivm, "bgnloop");
+   LLVMBuildBr(builder, mask->loop_block);
+   LLVMPositionBuilderAtEnd(builder, mask->loop_block);
 
-   mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, "");
+   mask->break_mask = LLVMBuildLoad(builder, mask->break_var, "");
 
    lp_exec_mask_update(mask);
 }
 
 static void lp_exec_break(struct lp_exec_mask *mask)
 {
-   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
+   LLVMValueRef exec_mask = LLVMBuildNot(builder,
                                          mask->exec_mask,
                                          "break");
 
-   mask->break_mask = LLVMBuildAnd(mask->bld->builder,
+   mask->break_mask = LLVMBuildAnd(builder,
                                    mask->break_mask,
                                    exec_mask, "break_full");
 
@@ -295,11 +304,12 @@ static void lp_exec_break(struct lp_exec_mask *mask)
 
 static void lp_exec_continue(struct lp_exec_mask *mask)
 {
-   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
+   LLVMValueRef exec_mask = LLVMBuildNot(builder,
                                          mask->exec_mask,
                                          "");
 
-   mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
+   mask->cont_mask = LLVMBuildAnd(builder,
                                   mask->cont_mask,
                                   exec_mask, "");
 
@@ -307,11 +317,14 @@ static void lp_exec_continue(struct lp_exec_mask *mask)
 }
 
 
-static void lp_exec_endloop(struct lp_exec_mask *mask)
+static void lp_exec_endloop(struct gallivm_state *gallivm,
+                            struct lp_exec_mask *mask)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
    LLVMBasicBlockRef endloop;
-   LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
-                                      mask->bld->type.length);
+   LLVMTypeRef reg_type = LLVMIntTypeInContext(gallivm->context,
+                                               mask->bld->type.width *
+                                               mask->bld->type.length);
    LLVMValueRef i1cond;
 
    assert(mask->break_mask);
@@ -327,21 +340,21 @@ static void lp_exec_endloop(struct lp_exec_mask *mask)
     * Unlike the continue mask, the break_mask must be preserved across loop
     * iterations
     */
-   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
+   LLVMBuildStore(builder, mask->break_mask, mask->break_var);
 
    /* i1cond = (mask == 0) */
    i1cond = LLVMBuildICmp(
-      mask->bld->builder,
+      builder,
       LLVMIntNE,
-      LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""),
+      LLVMBuildBitCast(builder, mask->exec_mask, reg_type, ""),
       LLVMConstNull(reg_type), "");
 
-   endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
+   endloop = lp_build_insert_new_block(mask->bld->gallivm, "endloop");
 
-   LLVMBuildCondBr(mask->bld->builder,
+   LLVMBuildCondBr(builder,
                    i1cond, mask->loop_block, endloop);
 
-   LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
+   LLVMPositionBuilderAtEnd(builder, endloop);
 
    assert(mask->loop_stack_size);
    --mask->loop_stack_size;
@@ -363,10 +376,12 @@ static void lp_exec_mask_store(struct lp_exec_mask *mask,
                                LLVMValueRef val,
                                LLVMValueRef dst)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
    /* Mix the predicate and execution mask */
    if (mask->has_mask) {
       if (pred) {
-         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
+         pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
       } else {
          pred = mask->exec_mask;
       }
@@ -375,14 +390,14 @@ static void lp_exec_mask_store(struct lp_exec_mask *mask,
    if (pred) {
       LLVMValueRef real_val, dst_val;
 
-      dst_val = LLVMBuildLoad(mask->bld->builder, dst, "");
+      dst_val = LLVMBuildLoad(builder, dst, "");
       real_val = lp_build_select(mask->bld,
                                  pred,
                                  val, dst_val);
 
-      LLVMBuildStore(mask->bld->builder, real_val, dst);
+      LLVMBuildStore(builder, real_val, dst);
    } else
-      LLVMBuildStore(mask->bld->builder, val, dst);
+      LLVMBuildStore(builder, val, dst);
 }
 
 static void lp_exec_mask_call(struct lp_exec_mask *mask,
@@ -398,6 +413,7 @@ static void lp_exec_mask_call(struct lp_exec_mask *mask,
 
 static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
 {
+   LLVMBuilderRef builder = mask->bld->gallivm->builder;
    LLVMValueRef exec_mask;
 
    if (mask->call_stack_size == 0) {
@@ -405,11 +421,11 @@ static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
       *pc = -1;
       return;
    }
-   exec_mask = LLVMBuildNot(mask->bld->builder,
+   exec_mask = LLVMBuildNot(builder,
                             mask->exec_mask,
                             "ret");
 
-   mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
+   mask->ret_mask = LLVMBuildAnd(builder,
                                  mask->ret_mask,
                                  exec_mask, "ret_full");
 
@@ -441,10 +457,11 @@ get_temp_ptr(struct lp_build_tgsi_soa_context *bld,
              unsigned index,
              unsigned chan)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    assert(chan < 4);
    if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
-      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
-      return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
+      LLVMValueRef lindex = lp_build_const_int32(bld->base.gallivm, index * 4 + chan);
+      return LLVMBuildGEP(builder, bld->temps_array, &lindex, 1, "");
    }
    else {
       return bld->temps[index][chan];
@@ -462,10 +479,12 @@ get_output_ptr(struct lp_build_tgsi_soa_context *bld,
                unsigned index,
                unsigned chan)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    assert(chan < 4);
    if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
-      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
-      return LLVMBuildGEP(bld->base.builder, bld->outputs_array, &lindex, 1, "");
+      LLVMValueRef lindex = lp_build_const_int32(bld->base.gallivm,
+                                                 index * 4 + chan);
+      return LLVMBuildGEP(builder, bld->outputs_array, &lindex, 1, "");
    }
    else {
       return bld->outputs[index][chan];
@@ -482,6 +501,7 @@ build_gather(struct lp_build_tgsi_soa_context *bld,
              LLVMValueRef base_ptr,
              LLVMValueRef indexes)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    LLVMValueRef res = bld->base.undef;
    unsigned i;
 
@@ -489,14 +509,14 @@ build_gather(struct lp_build_tgsi_soa_context *bld,
     * Loop over elements of index_vec, load scalar value, insert it into 'res'.
     */
    for (i = 0; i < bld->base.type.length; i++) {
-      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
-      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
+      LLVMValueRef ii = lp_build_const_int32(bld->base.gallivm, i);
+      LLVMValueRef index = LLVMBuildExtractElement(builder,
                                                    indexes, ii, "");
-      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
+      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr,
                                              &index, 1, "gather_ptr");
-      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+      LLVMValueRef scalar = LLVMBuildLoad(builder, scalar_ptr, "");
 
-      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
+      res = LLVMBuildInsertElement(builder, res, scalar, ii, "");
    }
 
    return res;
@@ -514,13 +534,14 @@ emit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
                   struct lp_exec_mask *mask,
                   LLVMValueRef pred)
 {
-   LLVMBuilderRef builder = bld->base.builder;
+   struct gallivm_state *gallivm = bld->base.gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
    unsigned i;
 
    /* Mix the predicate and execution mask */
    if (mask->has_mask) {
       if (pred) {
-         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
+         pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
       }
       else {
          pred = mask->exec_mask;
@@ -531,7 +552,7 @@ emit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
     * Loop over elements of index_vec, store scalar value.
     */
    for (i = 0; i < bld->base.type.length; i++) {
-      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef ii = lp_build_const_int32(gallivm, i);
       LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, "");
       LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr");
       LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val");
@@ -539,7 +560,7 @@ emit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
          LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL;
 
       if (0)
-         lp_build_printf(builder, "scatter %d: val %f at %d %p\n",
+         lp_build_printf(gallivm, "scatter %d: val %f at %d %p\n",
                          ii, val, index, scalar_ptr);
 
       if (scalar_pred) {
@@ -566,6 +587,7 @@ get_indirect_index(struct lp_build_tgsi_soa_context *bld,
                    unsigned reg_file, unsigned reg_index,
                    const struct tgsi_src_register *indirect_reg)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    struct lp_build_context *uint_bld = &bld->uint_bld;
    /* always use X component of address register */
    unsigned swizzle = indirect_reg->SwizzleX;
@@ -576,21 +598,22 @@ get_indirect_index(struct lp_build_tgsi_soa_context *bld,
 
    assert(bld->indirect_files & (1 << reg_file));
 
-   base = lp_build_const_int_vec(uint_bld->type, reg_index);
+   base = lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, reg_index);
 
    assert(swizzle < 4);
-   rel = LLVMBuildLoad(bld->base.builder,
+   rel = LLVMBuildLoad(builder,
                         bld->addr[indirect_reg->Index][swizzle],
                         "load addr reg");
 
    /* for indexing we want integers */
-   rel = LLVMBuildFPToSI(bld->base.builder,
+   rel = LLVMBuildFPToSI(builder,
                          rel,
                          uint_bld->vec_type, "");
 
    index = lp_build_add(uint_bld, base, rel);
 
-   max_index = lp_build_const_int_vec(uint_bld->type,
+   max_index = lp_build_const_int_vec(bld->base.gallivm,
+                                      uint_bld->type,
                                       bld->info->file_max[reg_file]);
 
    assert(!uint_bld->type.sign);
@@ -610,6 +633,8 @@ emit_fetch(
    unsigned src_op,
    const unsigned chan_index )
 {
+   struct gallivm_state *gallivm = bld->base.gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_build_context *uint_bld = &bld->uint_bld;
    const struct tgsi_full_src_register *reg = &inst->Src[src_op];
    const unsigned swizzle =
@@ -635,7 +660,7 @@ emit_fetch(
    case TGSI_FILE_CONSTANT:
       if (reg->Register.Indirect) {
          LLVMValueRef swizzle_vec =
-            lp_build_const_int_vec(uint_bld->type, swizzle);
+            lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, swizzle);
          LLVMValueRef index_vec;  /* index into the const buffer */
 
          /* index_vec = indirect_index * 4 + swizzle */
@@ -649,11 +674,11 @@ emit_fetch(
          LLVMValueRef index;  /* index into the const buffer */
          LLVMValueRef scalar, scalar_ptr;
 
-         index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
+         index = lp_build_const_int32(gallivm, reg->Register.Index*4 + swizzle);
 
-         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
+         scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr,
                                    &index, 1, "");
-         scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+         scalar = LLVMBuildLoad(builder, scalar_ptr, "");
 
          res = lp_build_broadcast_scalar(&bld->base, scalar);
       }
@@ -667,9 +692,9 @@ emit_fetch(
    case TGSI_FILE_INPUT:
       if (reg->Register.Indirect) {
          LLVMValueRef swizzle_vec =
-            lp_build_const_int_vec(uint_bld->type, swizzle);
+            lp_build_const_int_vec(gallivm, uint_bld->type, swizzle);
          LLVMValueRef length_vec =
-            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
+            lp_build_const_int_vec(gallivm, uint_bld->type, bld->base.type.length);
          LLVMValueRef index_vec;  /* index into the const buffer */
          LLVMValueRef inputs_array;
          LLVMTypeRef float4_ptr_type;
@@ -680,18 +705,19 @@ emit_fetch(
          index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
 
          /* cast inputs_array pointer to float* */
-         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
-         inputs_array = LLVMBuildBitCast(uint_bld->builder, bld->inputs_array,
-                                        float4_ptr_type, "");
+         float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
+         inputs_array = LLVMBuildBitCast(builder, bld->inputs_array,
+                                         float4_ptr_type, "");
 
          /* Gather values from the temporary register array */
          res = build_gather(bld, inputs_array, index_vec);
       } else {
          if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) {
-            LLVMValueRef lindex = lp_build_const_int32(reg->Register.Index * 4 + swizzle);
-            LLVMValueRef input_ptr =  LLVMBuildGEP(bld->base.builder,
+            LLVMValueRef lindex = lp_build_const_int32(gallivm,
+                                           reg->Register.Index * 4 + swizzle);
+            LLVMValueRef input_ptr =  LLVMBuildGEP(builder,
                                                    bld->inputs_array, &lindex, 1, "");
-            res = LLVMBuildLoad(bld->base.builder, input_ptr, "");
+            res = LLVMBuildLoad(builder, input_ptr, "");
          }
          else {
             res = bld->inputs[reg->Register.Index][swizzle];
@@ -703,9 +729,10 @@ emit_fetch(
    case TGSI_FILE_TEMPORARY:
       if (reg->Register.Indirect) {
          LLVMValueRef swizzle_vec =
-            lp_build_const_int_vec(uint_bld->type, swizzle);
+            lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, swizzle);
          LLVMValueRef length_vec =
-            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
+            lp_build_const_int_vec(bld->base.gallivm, uint_bld->type,
+                                   bld->base.type.length);
          LLVMValueRef index_vec;  /* index into the const buffer */
          LLVMValueRef temps_array;
          LLVMTypeRef float4_ptr_type;
@@ -716,8 +743,8 @@ emit_fetch(
          index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
 
          /* cast temps_array pointer to float* */
-         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
-         temps_array = LLVMBuildBitCast(uint_bld->builder, bld->temps_array,
+         float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(bld->base.gallivm->context), 0);
+         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
                                         float4_ptr_type, "");
 
          /* Gather values from the temporary register array */
@@ -726,7 +753,7 @@ emit_fetch(
       else {
          LLVMValueRef temp_ptr;
          temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
-         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
+         res = LLVMBuildLoad(builder, temp_ptr, "");
          if (!res)
             return bld->base.undef;
       }
@@ -796,6 +823,7 @@ emit_fetch_predicate(
    const struct tgsi_full_instruction *inst,
    LLVMValueRef *pred)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    unsigned index;
    unsigned char swizzles[4];
    LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
@@ -825,7 +853,7 @@ emit_fetch_predicate(
        * in the swizzles
        */
       if (!unswizzled[swizzle]) {
-         value = LLVMBuildLoad(bld->base.builder,
+         value = LLVMBuildLoad(builder,
                                bld->preds[index][swizzle], "");
 
          /*
@@ -835,13 +863,13 @@ emit_fetch_predicate(
           * is needlessly causing two comparisons due to storing the intermediate
           * result as float vector instead of an integer mask vector.
           */
-         value = lp_build_compare(bld->base.builder,
+         value = lp_build_compare(bld->base.gallivm,
                                   bld->base.type,
                                   PIPE_FUNC_NOTEQUAL,
                                   value,
                                   bld->base.zero);
          if (inst->Predicate.Negate) {
-            value = LLVMBuildNot(bld->base.builder, value, "");
+            value = LLVMBuildNot(builder, value, "");
          }
 
          unswizzled[swizzle] = value;
@@ -866,6 +894,8 @@ emit_store(
    LLVMValueRef pred,
    LLVMValueRef value)
 {
+   struct gallivm_state *gallivm = bld->base.gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
    const struct tgsi_full_dst_register *reg = &inst->Dst[index];
    struct lp_build_context *uint_bld = &bld->uint_bld;
    LLVMValueRef indirect_index = NULL;
@@ -880,7 +910,7 @@ emit_store(
       break;
 
    case TGSI_SAT_MINUS_PLUS_ONE:
-      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
+      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.gallivm, bld->base.type, -1.0));
       value = lp_build_min(&bld->base, value, bld->base.one);
       break;
 
@@ -900,11 +930,10 @@ emit_store(
    switch( reg->Register.File ) {
    case TGSI_FILE_OUTPUT:
       if (reg->Register.Indirect) {
-         LLVMBuilderRef builder = bld->base.builder;
          LLVMValueRef chan_vec =
-            lp_build_const_int_vec(uint_bld->type, chan_index);
+            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
          LLVMValueRef length_vec =
-            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
+            lp_build_const_int_vec(gallivm, uint_bld->type, bld->base.type.length);
          LLVMValueRef index_vec;  /* indexes into the temp registers */
          LLVMValueRef outputs_array;
          LLVMValueRef pixel_offsets;
@@ -914,7 +943,7 @@ emit_store(
          /* build pixel offset vector: {0, 1, 2, 3, ...} */
          pixel_offsets = uint_bld->undef;
          for (i = 0; i < bld->base.type.length; i++) {
-            LLVMValueRef ii = lp_build_const_int32(i);
+            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
             pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
                                                    ii, ii, "");
          }
@@ -925,7 +954,8 @@ emit_store(
          index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
          index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
 
-         float_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
+         float_ptr_type =
+            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
          outputs_array = LLVMBuildBitCast(builder, bld->outputs_array,
                                           float_ptr_type, "");
 
@@ -942,11 +972,11 @@ emit_store(
 
    case TGSI_FILE_TEMPORARY:
       if (reg->Register.Indirect) {
-         LLVMBuilderRef builder = bld->base.builder;
          LLVMValueRef chan_vec =
-            lp_build_const_int_vec(uint_bld->type, chan_index);
+            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
          LLVMValueRef length_vec =
-            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
+            lp_build_const_int_vec(gallivm, uint_bld->type,
+                                   bld->base.type.length);
          LLVMValueRef index_vec;  /* indexes into the temp registers */
          LLVMValueRef temps_array;
          LLVMValueRef pixel_offsets;
@@ -956,7 +986,7 @@ emit_store(
          /* build pixel offset vector: {0, 1, 2, 3, ...} */
          pixel_offsets = uint_bld->undef; 
          for (i = 0; i < bld->base.type.length; i++) {
-            LLVMValueRef ii = lp_build_const_int32(i);
+            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
             pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
                                                    ii, ii, "");
          }
@@ -967,7 +997,8 @@ emit_store(
          index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
          index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
 
-         float_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
+         float_ptr_type =
+            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
          temps_array = LLVMBuildBitCast(builder, bld->temps_array,
                                         float_ptr_type, "");
 
@@ -984,7 +1015,7 @@ emit_store(
 
    case TGSI_FILE_ADDRESS:
       lp_exec_mask_store(&bld->exec_mask, pred, value,
-                         bld->addr[reg->Indirect.Index][chan_index]);
+                         bld->addr[reg->Register.Index][chan_index]);
       break;
 
    case TGSI_FILE_PREDICATE:
@@ -1008,6 +1039,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
           enum lp_build_tex_modifier modifier,
           LLVMValueRef *texel)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    unsigned unit;
    LLVMValueRef lod_bias, explicit_lod;
    LLVMValueRef oow = NULL;
@@ -1073,13 +1105,12 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
    }
 
    if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
-      LLVMTypeRef i32t = LLVMInt32Type();
-      LLVMValueRef index0 = LLVMConstInt(i32t, 0, 0);
+      LLVMValueRef index0 = lp_build_const_int32(bld->base.gallivm, 0);
       for (i = 0; i < num_coords; i++) {
          LLVMValueRef src1 = emit_fetch( bld, inst, 1, i );
          LLVMValueRef src2 = emit_fetch( bld, inst, 2, i );
-         ddx[i] = LLVMBuildExtractElement(bld->base.builder, src1, index0, "");
-         ddy[i] = LLVMBuildExtractElement(bld->base.builder, src2, index0, "");
+         ddx[i] = LLVMBuildExtractElement(builder, src1, index0, "");
+         ddy[i] = LLVMBuildExtractElement(builder, src2, index0, "");
       }
       unit = inst->Src[3].Register.Index;
    }  else {
@@ -1095,7 +1126,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
    }
 
    bld->sampler->emit_fetch_texel(bld->sampler,
-                                  bld->base.builder,
+                                  bld->base.gallivm,
                                   bld->base.type,
                                   unit, num_coords, coords,
                                   ddx, ddy,
@@ -1150,6 +1181,7 @@ emit_kil(
    const struct tgsi_full_instruction *inst,
    int pc)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    const struct tgsi_full_src_register *reg = &inst->Src[0];
    LLVMValueRef terms[NUM_CHANNELS];
    LLVMValueRef mask;
@@ -1181,7 +1213,7 @@ emit_kil(
          chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
 
          if(mask)
-            mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
+            mask = LLVMBuildAnd(builder, mask, chan_mask, "");
          else
             mask = chan_mask;
       }
@@ -1207,13 +1239,14 @@ emit_kilp(struct lp_build_tgsi_soa_context *bld,
           const struct tgsi_full_instruction *inst,
          int pc)
 {
+   LLVMBuilderRef builder = bld->base.gallivm->builder;
    LLVMValueRef mask;
 
    /* For those channels which are "alive", disable fragment shader
     * execution.
     */
    if (bld->exec_mask.has_mask) {
-      mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp");
+      mask = LLVMBuildNot(builder, bld->exec_mask.exec_mask, "kilp");
    }
    else {
       LLVMValueRef zero = LLVMConstNull(bld->base.int_vec_type);
@@ -1234,38 +1267,39 @@ emit_kilp(struct lp_build_tgsi_soa_context *bld,
 static void
 emit_dump_temps(struct lp_build_tgsi_soa_context *bld)
 {
-   LLVMBuilderRef builder = bld->base.builder;
+   struct gallivm_state *gallivm = bld->base.gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef temp_ptr;
-   LLVMValueRef i0 = lp_build_const_int32(0);
-   LLVMValueRef i1 = lp_build_const_int32(1);
-   LLVMValueRef i2 = lp_build_const_int32(2);
-   LLVMValueRef i3 = lp_build_const_int32(3);
+   LLVMValueRef i0 = lp_build_const_int32(gallivm, 0);
+   LLVMValueRef i1 = lp_build_const_int32(gallivm, 1);
+   LLVMValueRef i2 = lp_build_const_int32(gallivm, 2);
+   LLVMValueRef i3 = lp_build_const_int32(gallivm, 3);
    int index;
    int n = bld->info->file_max[TGSI_FILE_TEMPORARY];
 
    for (index = 0; index < n; index++) {
-      LLVMValueRef idx = lp_build_const_int32(index);
+      LLVMValueRef idx = lp_build_const_int32(gallivm, index);
       LLVMValueRef v[4][4], res;
       int chan;
 
-      lp_build_printf(builder, "TEMP[%d]:\n", idx);
+      lp_build_printf(gallivm, "TEMP[%d]:\n", idx);
 
       for (chan = 0; chan < 4; chan++) {
          temp_ptr = get_temp_ptr(bld, index, chan);
-         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
+         res = LLVMBuildLoad(builder, temp_ptr, "");
          v[chan][0] = LLVMBuildExtractElement(builder, res, i0, "");
          v[chan][1] = LLVMBuildExtractElement(builder, res, i1, "");
          v[chan][2] = LLVMBuildExtractElement(builder, res, i2, "");
          v[chan][3] = LLVMBuildExtractElement(builder, res, i3, "");
       }
 
-      lp_build_printf(builder, "  X: %f %f %f %f\n",
+      lp_build_printf(gallivm, "  X: %f %f %f %f\n",
                       v[0][0], v[0][1], v[0][2], v[0][3]);
-      lp_build_printf(builder, "  Y: %f %f %f %f\n",
+      lp_build_printf(gallivm, "  Y: %f %f %f %f\n",
                       v[1][0], v[1][1], v[1][2], v[1][3]);
-      lp_build_printf(builder, "  Z: %f %f %f %f\n",
+      lp_build_printf(gallivm, "  Z: %f %f %f %f\n",
                       v[2][0], v[2][1], v[2][2], v[2][3]);
-      lp_build_printf(builder, "  W: %f %f %f %f\n",
+      lp_build_printf(gallivm, "  W: %f %f %f %f\n",
                       v[3][0], v[3][1], v[3][2], v[3][3]);
    }
 }
@@ -1277,6 +1311,7 @@ emit_declaration(
    struct lp_build_tgsi_soa_context *bld,
    const struct tgsi_full_declaration *decl)
 {
+   struct gallivm_state *gallivm = bld->base.gallivm;
    LLVMTypeRef vec_type = bld->base.vec_type;
    const unsigned first = decl->Range.First;
    const unsigned last = decl->Range.Last;
@@ -1289,15 +1324,14 @@ emit_declaration(
          assert(idx < LP_MAX_TGSI_TEMPS);
          if (!(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY))) {
             for (i = 0; i < NUM_CHANNELS; i++)
-               bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
-                                                    vec_type, "temp");
+               bld->temps[idx][i] = lp_build_alloca(gallivm, vec_type, "temp");
          }
          break;
 
       case TGSI_FILE_OUTPUT:
          if (!(bld->indirect_files & (1 << TGSI_FILE_OUTPUT))) {
             for (i = 0; i < NUM_CHANNELS; i++)
-               bld->outputs[idx][i] = lp_build_alloca(bld->base.builder,
+               bld->outputs[idx][i] = lp_build_alloca(gallivm,
                                                       vec_type, "output");
          }
          break;
@@ -1305,15 +1339,14 @@ emit_declaration(
       case TGSI_FILE_ADDRESS:
          assert(idx < LP_MAX_TGSI_ADDRS);
          for (i = 0; i < NUM_CHANNELS; i++)
-            bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
-                                                vec_type, "addr");
+            bld->addr[idx][i] = lp_build_alloca(gallivm, vec_type, "addr");
          break;
 
       case TGSI_FILE_PREDICATE:
          assert(idx < LP_MAX_TGSI_PREDS);
          for (i = 0; i < NUM_CHANNELS; i++)
-            bld->preds[idx][i] = lp_build_alloca(bld->base.builder,
-                                                 vec_type, "predicate");
+            bld->preds[idx][i] = lp_build_alloca(gallivm, vec_type,
+                                                 "predicate");
          break;
 
       default:
@@ -1639,7 +1672,7 @@ emit_instruction(
          src0 = emit_fetch( bld, inst, 0, chan_index );
          src1 = emit_fetch( bld, inst, 1, chan_index );
          src2 = emit_fetch( bld, inst, 2, chan_index );
-         tmp1 = lp_build_const_vec(bld->base.type, 0.5);
+         tmp1 = lp_build_const_vec(bld->base.gallivm, bld->base.type, 0.5);
          tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
          dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
       }
@@ -2151,7 +2184,7 @@ emit_instruction(
       break;
 
    case TGSI_OPCODE_ENDLOOP:
-      lp_exec_endloop(&bld->exec_mask);
+      lp_exec_endloop(bld->base.gallivm, &bld->exec_mask);
       break;
 
    case TGSI_OPCODE_ENDSUB:
@@ -2284,7 +2317,7 @@ emit_instruction(
 
 
 void
-lp_build_tgsi_soa(LLVMBuilderRef builder,
+lp_build_tgsi_soa(struct gallivm_state *gallivm,
                   const struct tgsi_token *tokens,
                   struct lp_type type,
                   struct lp_build_mask_context *mask,
@@ -2312,9 +2345,9 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
 
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
-   lp_build_context_init(&bld.base, builder, type);
-   lp_build_context_init(&bld.uint_bld, builder, lp_uint_type(type));
-   lp_build_context_init(&bld.elem_bld, builder, lp_elem_type(type));
+   lp_build_context_init(&bld.base, gallivm, type);
+   lp_build_context_init(&bld.uint_bld, gallivm, lp_uint_type(type));
+   lp_build_context_init(&bld.elem_bld, gallivm, lp_elem_type(type));
    bld.mask = mask;
    bld.pos = pos;
    bld.inputs = inputs;
@@ -2334,17 +2367,19 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    lp_exec_mask_init(&bld.exec_mask, &bld.base);
 
    if (bld.indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
-      LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
-                                             info->file_max[TGSI_FILE_TEMPORARY]*4 + 4, 0);
-      bld.temps_array = lp_build_array_alloca(bld.base.builder,
+      LLVMValueRef array_size =
+         lp_build_const_int32(gallivm,
+                              info->file_max[TGSI_FILE_TEMPORARY] * 4 + 4);
+      bld.temps_array = lp_build_array_alloca(gallivm,
                                               bld.base.vec_type, array_size,
                                               "temp_array");
    }
 
    if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) {
-      LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
-                                             info->file_max[TGSI_FILE_OUTPUT]*4 + 4, 0);
-      bld.outputs_array = lp_build_array_alloca(bld.base.builder,
+      LLVMValueRef array_size =
+         lp_build_const_int32(gallivm,
+                              info->file_max[TGSI_FILE_OUTPUT] * 4 + 4);
+      bld.outputs_array = lp_build_array_alloca(gallivm,
                                                 bld.base.vec_type, array_size,
                                                 "output_array");
    }
@@ -2354,9 +2389,9 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    if (bld.indirect_files & (1 << TGSI_FILE_INPUT)) {
       unsigned index, chan;
       LLVMTypeRef vec_type = bld.base.vec_type;
-      LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
-                                             info->file_max[TGSI_FILE_INPUT]*4 + 4, 0);
-      bld.inputs_array = lp_build_array_alloca(bld.base.builder,
+      LLVMValueRef array_size =
+         lp_build_const_int32(gallivm, info->file_max[TGSI_FILE_INPUT]*4 + 4);
+      bld.inputs_array = lp_build_array_alloca(gallivm,
                                                vec_type, array_size,
                                                "input_array");
 
@@ -2364,13 +2399,14 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
 
       for (index = 0; index < info->num_inputs; ++index) {
          for (chan = 0; chan < NUM_CHANNELS; ++chan) {
-            LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
+            LLVMValueRef lindex =
+               lp_build_const_int32(gallivm, index * 4 + chan);
             LLVMValueRef input_ptr =
-               LLVMBuildGEP(bld.base.builder, bld.inputs_array,
+               LLVMBuildGEP(gallivm->builder, bld.inputs_array,
                             &lindex, 1, "");
             LLVMValueRef value = bld.inputs[index][chan];
             if (value)
-               LLVMBuildStore(bld.base.builder, value, input_ptr);
+               LLVMBuildStore(gallivm->builder, value, input_ptr);
          }
       }
    }
@@ -2420,7 +2456,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
             assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
             for( i = 0; i < size; ++i )
                bld.immediates[num_immediates][i] =
-                  lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
+                  lp_build_const_vec(gallivm, type, parse.FullToken.FullImmediate.u[i].Float);
             for( i = size; i < 4; ++i )
                bld.immediates[num_immediates][i] = bld.base.undef;
             num_immediates++;
@@ -2457,7 +2493,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    }
 
    if (0) {
-      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+      LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
       LLVMValueRef function = LLVMGetBasicBlockParent(block);
       debug_printf("11111111111111111111111111111 \n");
       tgsi_dump(tokens, 0);
@@ -2468,7 +2504,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
 
    if (0) {
       LLVMModuleRef module = LLVMGetGlobalParent(
-         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
+         LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
       LLVMDumpModule(module);
 
    }
index 5205c7ada91ae284ce86a8ba7e58f81b7ab21529..c5cf6d4a6c4f85480287f7750304996b3e18fbf4 100644 (file)
 
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
+#include "lp_bld_init.h"
 
 
 LLVMTypeRef
-lp_build_elem_type(struct lp_type type)
+lp_build_elem_type(struct gallivm_state *gallivm, struct lp_type type)
 {
    if (type.floating) {
       switch(type.width) {
       case 32:
-         return LLVMFloatType();
+         return LLVMFloatTypeInContext(gallivm->context);
          break;
       case 64:
-         return LLVMDoubleType();
+         return LLVMDoubleTypeInContext(gallivm->context);
          break;
       default:
          assert(0);
-         return LLVMFloatType();
+         return LLVMFloatTypeInContext(gallivm->context);
       }
    }
    else {
-      return LLVMIntType(type.width);
+      return LLVMIntTypeInContext(gallivm->context, type.width);
    }
 }
 
 
 LLVMTypeRef
-lp_build_vec_type(struct lp_type type)
+lp_build_vec_type(struct gallivm_state *gallivm,struct lp_type type)
 {
-   LLVMTypeRef elem_type = lp_build_elem_type(type);
+   LLVMTypeRef elem_type = lp_build_elem_type(gallivm, type);
    if (type.length == 1)
       return elem_type;
    else
@@ -149,16 +150,16 @@ lp_check_value(struct lp_type type, LLVMValueRef val)
 
 
 LLVMTypeRef
-lp_build_int_elem_type(struct lp_type type)
+lp_build_int_elem_type(struct gallivm_state *gallivm, struct lp_type type)
 {
-   return LLVMIntType(type.width);
+   return LLVMIntTypeInContext(gallivm->context, type.width);
 }
 
 
 LLVMTypeRef
-lp_build_int_vec_type(struct lp_type type)
+lp_build_int_vec_type(struct gallivm_state *gallivm, struct lp_type type)
 {
-   LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+   LLVMTypeRef elem_type = lp_build_int_elem_type(gallivm, type);
    if (type.length == 1)
       return elem_type;
    else
@@ -170,7 +171,7 @@ lp_build_int_vec_type(struct lp_type type)
  * Build int32[4] vector type
  */
 LLVMTypeRef
-lp_build_int32_vec4_type(void)
+lp_build_int32_vec4_type(struct gallivm_state *gallivm)
 {
    struct lp_type t;
    LLVMTypeRef type;
@@ -182,7 +183,7 @@ lp_build_int32_vec4_type(void)
    t.width = 32;       /* 32-bit int */
    t.length = 4;       /* 4 elements per vector */
 
-   type = lp_build_int_elem_type(t);
+   type = lp_build_int_elem_type(gallivm, t);
    return LLVMVectorType(type, t.length);
 }
 
@@ -383,15 +384,15 @@ lp_dump_llvmtype(LLVMTypeRef t)
 
 void
 lp_build_context_init(struct lp_build_context *bld,
-                      LLVMBuilderRef builder,
+                      struct gallivm_state *gallivm,
                       struct lp_type type)
 {
-   bld->builder = builder;
+   bld->gallivm = gallivm;
    bld->type = type;
 
-   bld->int_elem_type = lp_build_int_elem_type(type);
+   bld->int_elem_type = lp_build_int_elem_type(gallivm, type);
    if (type.floating)
-      bld->elem_type = lp_build_elem_type(type);
+      bld->elem_type = lp_build_elem_type(gallivm, type);
    else
       bld->elem_type = bld->int_elem_type;
 
@@ -406,5 +407,5 @@ lp_build_context_init(struct lp_build_context *bld,
 
    bld->undef = LLVMGetUndef(bld->vec_type);
    bld->zero = LLVMConstNull(bld->vec_type);
-   bld->one = lp_build_one(type);
+   bld->one = lp_build_one(gallivm, type);
 }
index a135d0df847d9885a024aea355ec8474c36ba0bc..5007e83ac5f28a1a0739a653170a3fd813cc390b 100644 (file)
@@ -120,7 +120,7 @@ struct lp_type {
  */
 struct lp_build_context
 {
-   LLVMBuilderRef builder;
+   struct gallivm_state *gallivm;
 
    /**
     * This not only describes the input/output LLVM types, but also whether
@@ -285,11 +285,11 @@ lp_type_ufixed(unsigned width)
 
 
 LLVMTypeRef
-lp_build_elem_type(struct lp_type type);
+lp_build_elem_type(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMTypeRef
-lp_build_vec_type(struct lp_type type);
+lp_build_vec_type(struct gallivm_state *gallivm, struct lp_type type);
 
 
 boolean
@@ -305,15 +305,15 @@ lp_check_value(struct lp_type type, LLVMValueRef val);
 
 
 LLVMTypeRef
-lp_build_int_elem_type(struct lp_type type);
+lp_build_int_elem_type(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMTypeRef
-lp_build_int_vec_type(struct lp_type type);
+lp_build_int_vec_type(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMTypeRef
-lp_build_int32_vec4_type(void);
+lp_build_int32_vec4_type(struct gallivm_state *gallivm);
 
 
 static INLINE struct lp_type
@@ -394,7 +394,7 @@ lp_dump_llvmtype(LLVMTypeRef t);
 
 void
 lp_build_context_init(struct lp_build_context *bld,
-                      LLVMBuilderRef builder,
+                      struct gallivm_state *gallivm,
                       struct lp_type type);
 
 
index 7b0777860138c7ec9f7ece665b9b69670049d497..b5ebbfbfaabaa9b65fdf43fb21c103d9c53af90f 100644 (file)
@@ -388,6 +388,8 @@ tgsi_exec_get_shader_param(enum pipe_shader_cap param)
    case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
    case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
       return 1;
+   case PIPE_SHADER_CAP_SUBROUTINES:
+      return 1;
    default:
       return 0;
    }
index dfb142b9e1cc92b8074b99b1fc36a5ff18c29ca6..c11f7d383db7e62b2c2fb301e6fd6815113fdb40 100644 (file)
@@ -291,7 +291,7 @@ regions_overlap(int srcX0, int srcY0,
 void
 util_blit_pixels_writemask(struct blit_state *ctx,
                            struct pipe_resource *src_tex,
-                           struct pipe_subresource srcsub,
+                           unsigned src_level,
                            int srcX0, int srcY0,
                            int srcX1, int srcY1,
                            int srcZ0,
@@ -316,13 +316,12 @@ util_blit_pixels_writemask(struct blit_state *ctx,
    assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
           filter == PIPE_TEX_MIPFILTER_LINEAR);
 
-   assert(srcsub.level <= src_tex->last_level);
+   assert(src_level <= src_tex->last_level);
 
    /* do the regions overlap? */
    overlap = src_tex == dst->texture &&
-             dst->face == srcsub.face &&
-             dst->level == srcsub.level &&
-             dst->zslice == srcZ0 &&
+             dst->u.tex.level == src_level &&
+             dst->u.tex.first_layer == srcZ0 &&
       regions_overlap(srcX0, srcY0, srcX1, srcY1,
                       dstX0, dstY0, dstX1, dstY1);
 
@@ -339,16 +338,19 @@ util_blit_pixels_writemask(struct blit_state *ctx,
        (dstX1 - dstX0) == (srcX1 - srcX0) &&
        (dstY1 - dstY0) == (srcY1 - srcY0) &&
        !overlap) {
-      struct pipe_subresource subdst;
-      subdst.face = dst->face;
-      subdst.level = dst->level;
+      struct pipe_box src_box;
+      src_box.x = srcX0;
+      src_box.y = srcY0;
+      src_box.z = srcZ0;
+      src_box.width = srcW;
+      src_box.height = srcH;
+      src_box.depth = 1;
       pipe->resource_copy_region(pipe,
-                                 dst->texture, subdst,
-                                 dstX0, dstY0, dst->zslice,/* dest */
-                                 src_tex, srcsub,
-                                 srcX0, srcY0, srcZ0,/* src */
-                                 srcW, srcH);       /* size */
-      return;
+                                 dst->texture, dst->u.tex.level,
+                                 dstX0, dstY0, dst->u.tex.first_layer,/* dest */
+                                 src_tex, src_level,
+                                 &src_box);
+       return;
    }
 
    /* Create a temporary texture when src and dest alias or when src
@@ -359,16 +361,16 @@ util_blit_pixels_writemask(struct blit_state *ctx,
     * This can still be improved upon.
     */
    if ((src_tex == dst->texture &&
-       dst->face == srcsub.face &&
-       dst->level == srcsub.level &&
-       dst->zslice == srcZ0) ||
+       dst->u.tex.level == src_level &&
+       dst->u.tex.first_layer == srcZ0) ||
        (src_tex->target != PIPE_TEXTURE_2D &&
+       src_tex->target != PIPE_TEXTURE_2D &&
        src_tex->target != PIPE_TEXTURE_RECT))
    {
       struct pipe_resource texTemp;
       struct pipe_resource *tex;
       struct pipe_sampler_view sv_templ;
-      struct pipe_subresource texsub;
+      struct pipe_box src_box;
       const int srcLeft = MIN2(srcX0, srcX1);
       const int srcTop = MIN2(srcY0, srcY1);
 
@@ -394,19 +396,23 @@ util_blit_pixels_writemask(struct blit_state *ctx,
       texTemp.width0 = srcW;
       texTemp.height0 = srcH;
       texTemp.depth0 = 1;
+      texTemp.array_size = 1;
       texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
 
       tex = screen->resource_create(screen, &texTemp);
       if (!tex)
          return;
 
-      texsub.face = 0;
-      texsub.level = 0;
+      src_box.x = srcLeft;
+      src_box.y = srcTop;
+      src_box.z = srcZ0;
+      src_box.width = srcW;
+      src_box.height = srcH;
+      src_box.depth = 1;
       /* load temp texture */
       pipe->resource_copy_region(pipe,
-                                 tex, texsub, 0, 0, 0,  /* dest */
-                                 src_tex, srcsub, srcLeft, srcTop, srcZ0, /* src */
-                                 srcW, srcH);     /* size */
+                                 tex, 0, 0, 0, 0,  /* dest */
+                                 src_tex, src_level, &src_box);
 
       normalized = tex->target != PIPE_TEXTURE_RECT;
       if(normalized) {
@@ -433,7 +439,6 @@ util_blit_pixels_writemask(struct blit_state *ctx,
    }
    else {
       u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);
-      sv_templ.first_level = sv_templ.last_level = srcsub.level;
       sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
 
       if (!sampler_view) {
@@ -447,10 +452,10 @@ util_blit_pixels_writemask(struct blit_state *ctx,
       normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT;
       if(normalized)
       {
-         s0 /= (float)(u_minify(sampler_view->texture->width0, srcsub.level));
-         s1 /= (float)(u_minify(sampler_view->texture->width0, srcsub.level));
-         t0 /= (float)(u_minify(sampler_view->texture->height0, srcsub.level));
-         t1 /= (float)(u_minify(sampler_view->texture->height0, srcsub.level));
+         s0 /= (float)(u_minify(sampler_view->texture->width0, src_level));
+         s1 /= (float)(u_minify(sampler_view->texture->width0, src_level));
+         t0 /= (float)(u_minify(sampler_view->texture->height0, src_level));
+         t1 /= (float)(u_minify(sampler_view->texture->height0, src_level));
       }
    }
 
@@ -489,9 +494,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
    ctx->sampler.normalized_coords = normalized;
    ctx->sampler.min_img_filter = filter;
    ctx->sampler.mag_img_filter = filter;
-   /* we've limited this already with the sampler view but you never know... */
-   ctx->sampler.min_lod = srcsub.level;
-   ctx->sampler.max_lod = srcsub.level;
+   ctx->sampler.min_lod = src_level;
+   ctx->sampler.max_lod = src_level;
    cso_single_sampler(ctx->cso, 0, &ctx->sampler);
    cso_single_sampler_done(ctx->cso);
 
@@ -575,7 +579,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
 void
 util_blit_pixels(struct blit_state *ctx,
                  struct pipe_resource *src_tex,
-                 struct pipe_subresource srcsub,
+                 unsigned src_level,
                  int srcX0, int srcY0,
                  int srcX1, int srcY1,
                  int srcZ,
@@ -585,7 +589,7 @@ util_blit_pixels(struct blit_state *ctx,
                  float z, uint filter )
 {
    util_blit_pixels_writemask( ctx, src_tex,
-                               srcsub,
+                               src_level,
                                srcX0, srcY0,
                                srcX1, srcY1,
                                srcZ,
@@ -662,6 +666,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_save_rasterizer(ctx->cso);
    cso_save_samplers(ctx->cso);
    cso_save_fragment_sampler_views(ctx->cso);
+   cso_save_viewport(ctx->cso);
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
@@ -729,6 +734,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_restore_rasterizer(ctx->cso);
    cso_restore_samplers(ctx->cso);
    cso_restore_fragment_sampler_views(ctx->cso);
+   cso_restore_viewport(ctx->cso);
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
index b8a0dfce13f443b5c4634f9d256897cf86053698..3009e25eca3d4107e40d0b94b80769c70a637e52 100644 (file)
@@ -42,7 +42,6 @@ struct cso_context;
 struct pipe_context;
 struct pipe_resource;
 struct pipe_sampler_view;
-struct pipe_subresource;
 struct pipe_surface;
 
 
@@ -55,7 +54,7 @@ util_destroy_blit(struct blit_state *ctx);
 extern void
 util_blit_pixels(struct blit_state *ctx,
                  struct pipe_resource *src_tex,
-                 struct pipe_subresource srcsub,
+                 unsigned src_level,
                  int srcX0, int srcY0,
                  int srcX1, int srcY1,
                  int srcZ0,
@@ -67,7 +66,7 @@ util_blit_pixels(struct blit_state *ctx,
 void
 util_blit_pixels_writemask(struct blit_state *ctx,
                            struct pipe_resource *src_tex,
-                           struct pipe_subresource srcsub,
+                           unsigned src_level,
                            int srcX0, int srcY0,
                            int srcX1, int srcY1,
                            int srcZ0,
index a163f93cb826fec91a99f1eb43c7a7c9756e33d6..4c986e3565cd66d47879ceb7ee4b6c24041604a6 100644 (file)
@@ -63,8 +63,7 @@ struct blitter_context_priv
 
    /* Constant state objects. */
    /* Vertex shaders. */
-   void *vs_col; /**< Vertex shader which passes {pos, color} to the output */
-   void *vs_tex; /**< Vertex shader which passes {pos, texcoord} to the output.*/
+   void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
 
    /* Fragment shaders. */
    /* The shader at index i outputs color to color buffers 0,1,...,i-1. */
@@ -211,20 +210,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
 
    /* fragment shaders are created on-demand */
 
-   /* vertex shaders */
-   {
-      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
-                                      TGSI_SEMANTIC_COLOR };
-      const uint semantic_indices[] = { 0, 0 };
-      ctx->vs_col =
-         util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
-                                             semantic_indices);
-   }
+   /* vertex shader */
    {
       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
                                       TGSI_SEMANTIC_GENERIC };
       const uint semantic_indices[] = { 0, 0 };
-      ctx->vs_tex =
+      ctx->vs =
          util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
                                              semantic_indices);
    }
@@ -257,8 +248,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_flush_depth_stencil);
 
    pipe->delete_rasterizer_state(pipe, ctx->rs_state);
-   pipe->delete_vs_state(pipe, ctx->vs_col);
-   pipe->delete_vs_state(pipe, ctx->vs_tex);
+   pipe->delete_vs_state(pipe, ctx->vs);
    pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
 
    for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
@@ -419,17 +409,17 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
 }
 
 static void get_texcoords(struct pipe_resource *src,
-                                     struct pipe_subresource subsrc,
-                                     unsigned x1, unsigned y1,
-                                     unsigned x2, unsigned y2,
-                                     boolean normalized, float out[4])
+                          unsigned level,
+                          unsigned x1, unsigned y1,
+                          unsigned x2, unsigned y2,
+                          boolean normalized, float out[4])
 {
    if(normalized)
    {
-      out[0] = x1 / (float)u_minify(src->width0,  subsrc.level);
-      out[1] = y1 / (float)u_minify(src->height0, subsrc.level);
-      out[2] = x2 / (float)u_minify(src->width0,  subsrc.level);
-      out[3] = y2 / (float)u_minify(src->height0, subsrc.level);
+      out[0] = x1 / (float)u_minify(src->width0,  level);
+      out[1] = y1 / (float)u_minify(src->height0, level);
+      out[2] = x2 / (float)u_minify(src->width0,  level);
+      out[3] = y2 / (float)u_minify(src->height0, level);
    }
    else
    {
@@ -458,14 +448,14 @@ static void set_texcoords_in_vertices(const float coord[4],
 
 static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
                                      struct pipe_resource *src,
-                                     struct pipe_subresource subsrc,
+                                     unsigned level,
                                      unsigned x1, unsigned y1,
                                      unsigned x2, unsigned y2)
 {
    unsigned i;
    float coord[4];
 
-   get_texcoords(src, subsrc, x1, y1, x2, y2, TRUE, coord);
+   get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
    set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
 
    for (i = 0; i < 4; i++) {
@@ -476,15 +466,15 @@ static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
 
 static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
                                      struct pipe_resource *src,
-                                     struct pipe_subresource subsrc,
+                                     unsigned level,
                                      unsigned zslice,
                                      unsigned x1, unsigned y1,
                                      unsigned x2, unsigned y2)
 {
    int i;
-   float r = zslice / (float)u_minify(src->depth0, subsrc.level);
+   float r = zslice / (float)u_minify(src->depth0, level);
 
-   blitter_set_texcoords_2d(ctx, src, subsrc, x1, y1, x2, y2);
+   blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2);
 
    for (i = 0; i < 4; i++)
       ctx->vertices[i][1][2] = r; /*r*/
@@ -492,7 +482,7 @@ static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
 
 static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
                                        struct pipe_resource *src,
-                                       struct pipe_subresource subsrc,
+                                       unsigned level, unsigned face,
                                        unsigned x1, unsigned y1,
                                        unsigned x2, unsigned y2)
 {
@@ -500,10 +490,10 @@ static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
    float coord[4];
    float st[4][2];
 
-   get_texcoords(src, subsrc, x1, y1, x2, y2, TRUE, coord);
+   get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
    set_texcoords_in_vertices(coord, &st[0][0], 2);
 
-   util_map_texcoords2d_onto_cubemap(subsrc.face,
+   util_map_texcoords2d_onto_cubemap(face,
                                      /* pointer, stride in floats */
                                      &st[0][0], 2,
                                      &ctx->vertices[0][1][0], 8);
@@ -522,10 +512,13 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
 static void blitter_draw_quad(struct blitter_context_priv *ctx)
 {
    struct pipe_context *pipe = ctx->base.pipe;
+   struct pipe_box box;
 
    /* write vertices and draw them */
-   pipe_buffer_write(pipe, ctx->vbuf,
-                     0, sizeof(ctx->vertices), ctx->vertices);
+   u_box_1d(0, sizeof(ctx->vertices), &box);
+   pipe->transfer_inline_write(pipe, ctx->vbuf, 0,
+                               PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+                               &box, ctx->vertices, sizeof(ctx->vertices), 0);
 
    util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
                            4,  /* verts */
@@ -566,7 +559,9 @@ void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
 
    if (!ctx->fs_col[num_cbufs])
       ctx->fs_col[num_cbufs] =
-         util_make_fragment_clonecolor_shader(pipe, num_cbufs);
+         util_make_fragment_cloneinput_shader(pipe, num_cbufs,
+                                              TGSI_SEMANTIC_GENERIC,
+                                              TGSI_INTERPOLATE_LINEAR);
 
    return ctx->fs_col[num_cbufs];
 }
@@ -697,7 +692,7 @@ void util_blitter_clear(struct blitter_context *blitter,
    pipe->bind_rasterizer_state(pipe, ctx->rs_state);
    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
    pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
-   pipe->bind_vs_state(pipe, ctx->vs_col);
+   pipe->bind_vs_state(pipe, ctx->vs);
 
    blitter_set_dst_dimensions(ctx, width, height);
    blitter->draw_rectangle(blitter, 0, 0, width, height, depth,
@@ -714,21 +709,22 @@ boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
 
 void util_blitter_copy_region(struct blitter_context *blitter,
                               struct pipe_resource *dst,
-                              struct pipe_subresource subdst,
+                              unsigned dstlevel,
                               unsigned dstx, unsigned dsty, unsigned dstz,
                               struct pipe_resource *src,
-                              struct pipe_subresource subsrc,
-                              unsigned srcx, unsigned srcy, unsigned srcz,
-                              unsigned width, unsigned height,
+                              unsigned srclevel,
+                              const struct pipe_box *srcbox,
                               boolean ignore_stencil)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
    struct pipe_context *pipe = ctx->base.pipe;
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *dstsurf;
+   struct pipe_surface *dstsurf, surf_templ;
    struct pipe_framebuffer_state fb_state;
    struct pipe_sampler_view viewTempl, *view;
    unsigned bind;
+   unsigned width = srcbox->width;
+   unsigned height = srcbox->height;
    boolean is_stencil, is_depth;
    boolean normalized;
 
@@ -739,12 +735,15 @@ void util_blitter_copy_region(struct blitter_context *blitter,
 
    /* Sanity checks. */
    if (dst == src) {
-      assert(!is_overlap(srcx, srcx + width, srcy, srcy + height,
+      assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
                          dstx, dstx + width, dsty, dsty + height));
    } else {
-      assert(dst->format == src->format);
+      assert(util_is_format_compatible(util_format_description(dst->format),
+                                       util_format_description(src->format)));
    }
    assert(src->target < PIPE_MAX_TEXTURE_TYPES);
+   /* XXX should handle 3d regions */
+   assert(srcbox->depth == 1);
 
    /* Is this a ZS format? */
    is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
@@ -762,15 +761,18 @@ void util_blitter_copy_region(struct blitter_context *blitter,
                                     dst->nr_samples, bind, 0) ||
        !screen->is_format_supported(screen, src->format, src->target,
                                     src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
-      util_resource_copy_region(pipe, dst, subdst, dstx, dsty, dstz,
-                                src, subsrc, srcx, srcy, srcz, width, height);
+      util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
+                                src, srclevel, srcbox);
       return;
    }
 
-   /* Get surfaces. */
-   dstsurf = screen->get_tex_surface(screen, dst,
-                                     subdst.face, subdst.level, dstz,
-                                     bind);
+   /* Get surface. */
+   memset(&surf_templ, 0, sizeof(surf_templ));
+   u_surface_default_template(&surf_templ, dst, bind);
+   surf_templ.u.tex.level = dstlevel;
+   surf_templ.u.tex.first_layer = dstz;
+   surf_templ.u.tex.last_layer = dstz;
+   dstsurf = pipe->create_surface(pipe, dst, &surf_templ);
 
    /* Check whether the states are properly saved. */
    blitter_check_saved_CSOs(ctx);
@@ -810,9 +812,9 @@ void util_blitter_copy_region(struct blitter_context *blitter,
 
    /* Set rasterizer state, shaders, and textures. */
    pipe->bind_rasterizer_state(pipe, ctx->rs_state);
-   pipe->bind_vs_state(pipe, ctx->vs_tex);
+   pipe->bind_vs_state(pipe, ctx->vs);
    pipe->bind_fragment_sampler_states(pipe, 1,
-                                      blitter_get_sampler_state(ctx, subsrc.level, normalized));
+                                      blitter_get_sampler_state(ctx, srclevel, normalized));
    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
    pipe->set_fragment_sampler_views(pipe, 1, &view);
    pipe->set_framebuffer_state(pipe, &fb_state);
@@ -827,8 +829,8 @@ void util_blitter_copy_region(struct blitter_context *blitter,
          {
             /* Set texture coordinates. */
             float coord[4];
-            get_texcoords(src, subsrc, srcx, srcy,
-                                     srcx+width, srcy+height, normalized, coord);
+            get_texcoords(src, srclevel, srcbox->x, srcbox->y,
+                          srcbox->x+width, srcbox->y+height, normalized, coord);
 
             /* Draw. */
             blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
@@ -841,11 +843,13 @@ void util_blitter_copy_region(struct blitter_context *blitter,
       case PIPE_TEXTURE_CUBE:
          /* Set texture coordinates. */
          if (src->target == PIPE_TEXTURE_3D)
-            blitter_set_texcoords_3d(ctx, src, subsrc, srcz,
-                                     srcx, srcy, srcx+width, srcy+height);
+            blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z,
+                                     srcbox->x, srcbox->y,
+                                     srcbox->x + width, srcbox->y + height);
          else
-            blitter_set_texcoords_cube(ctx, src, subsrc,
-                                       srcx, srcy, srcx+width, srcy+height);
+            blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z,
+                                       srcbox->x, srcbox->y,
+                                       srcbox->x + width, srcbox->y + height);
 
          /* Draw. */
          blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
@@ -887,7 +891,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
    pipe->bind_rasterizer_state(pipe, ctx->rs_state);
    pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
-   pipe->bind_vs_state(pipe, ctx->vs_col);
+   pipe->bind_vs_state(pipe, ctx->vs);
    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
 
    /* set a framebuffer state */
@@ -947,7 +951,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
 
    pipe->bind_rasterizer_state(pipe, ctx->rs_state);
    pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
-   pipe->bind_vs_state(pipe, ctx->vs_col);
+   pipe->bind_vs_state(pipe, ctx->vs);
    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
 
    /* set a framebuffer state */
@@ -988,7 +992,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
 
    pipe->bind_rasterizer_state(pipe, ctx->rs_state);
    pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
-   pipe->bind_vs_state(pipe, ctx->vs_col);
+   pipe->bind_vs_state(pipe, ctx->vs);
    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
 
    /* set a framebuffer state */
index f9f96f25c77e28cc1b2455173bb5f2a562b7d50a..c5660cf2d00a6cb37cd51a8221328e13ab205874 100644 (file)
@@ -164,12 +164,11 @@ void util_blitter_clear(struct blitter_context *blitter,
  */
 void util_blitter_copy_region(struct blitter_context *blitter,
                               struct pipe_resource *dst,
-                              struct pipe_subresource subdst,
+                              unsigned dstlevel,
                               unsigned dstx, unsigned dsty, unsigned dstz,
                               struct pipe_resource *src,
-                              struct pipe_subresource subsrc,
-                              unsigned srcx, unsigned srcy, unsigned srcz,
-                              unsigned width, unsigned height,
+                              unsigned srclevel,
+                              const struct pipe_box *srcbox,
                               boolean ignore_stencil);
 
 /**
index e9c71743fc89e62a723b8e5b112e4f88885cf66f..0b28d0f12c3530cde20aaa3bdc09d0a8af81e51b 100644 (file)
@@ -60,7 +60,6 @@ void u_box_2d_zslice( unsigned x,
    box->depth = 1;
 }
 
-
 static INLINE
 void u_box_3d( unsigned x,
               unsigned y,
@@ -78,15 +77,4 @@ void u_box_3d( unsigned x,
    box->depth = d;
 }
 
-
-static INLINE
-struct pipe_subresource u_subresource( unsigned face,
-                                      unsigned level )
-{
-   struct pipe_subresource subresource;
-   subresource.face = face;
-   subresource.level = level;
-   return subresource;
-}
-
 #endif
index 504e6d2a18ff1aa05346dc30af3ad4b3f42349e5..2ad2f95b13e9b3fd106828127e66e61677077928 100644 (file)
@@ -40,7 +40,8 @@
 #include "util/u_string.h" 
 #include "util/u_math.h" 
 #include "util/u_tile.h" 
-#include "util/u_prim.h" 
+#include "util/u_prim.h"
+#include "util/u_surface.h"
 
 #include <limits.h> /* CHAR_BIT */
 
@@ -453,9 +454,10 @@ void debug_dump_image(const char *prefix,
 #endif
 }
 
+/* FIXME: dump resources, not surfaces... */
 void debug_dump_surface(struct pipe_context *pipe,
-                       const char *prefix,
-                        struct pipe_surface *surface)     
+                        const char *prefix,
+                        struct pipe_surface *surface)
 {
    struct pipe_resource *texture;
    struct pipe_transfer *transfer;
@@ -472,23 +474,23 @@ void debug_dump_surface(struct pipe_context *pipe,
     */
    texture = surface->texture;
 
-   transfer = pipe_get_transfer(pipe, texture, surface->face,
-                                    surface->level, surface->zslice,
-                                    PIPE_TRANSFER_READ, 0, 0, surface->width,
-                                    surface->height);
-   
+   transfer = pipe_get_transfer(pipe, texture, surface->u.tex.level,
+                                surface->u.tex.first_layer,
+                                PIPE_TRANSFER_READ,
+                                0, 0, surface->width, surface->height);
+
    data = pipe->transfer_map(pipe, transfer);
    if(!data)
       goto error;
-   
-   debug_dump_image(prefix, 
+
+   debug_dump_image(prefix,
                     texture->format,
-                    util_format_get_blocksize(texture->format), 
+                    util_format_get_blocksize(texture->format),
                     util_format_get_nblocksx(texture->format, surface->width),
                     util_format_get_nblocksy(texture->format, surface->height),
                     transfer->stride,
                     data);
-   
+
    pipe->transfer_unmap(pipe, transfer);
 error:
    pipe->transfer_destroy(pipe, transfer);
@@ -499,20 +501,18 @@ void debug_dump_texture(struct pipe_context *pipe,
                         const char *prefix,
                         struct pipe_resource *texture)
 {
-   struct pipe_surface *surface;
-   struct pipe_screen *screen;
+   struct pipe_surface *surface, surf_tmpl;
 
    if (!texture)
       return;
 
-   screen = texture->screen;
-
-   /* XXX for now, just dump image for face=0, level=0 */
-   surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
-                                     PIPE_BIND_SAMPLER_VIEW);
+   /* XXX for now, just dump image for layer=0, level=0 */
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, texture, 0 /* no bind flag - not a surface */);
+   surface = pipe->create_surface(pipe, texture, &surf_tmpl);
    if (surface) {
       debug_dump_surface(pipe, prefix, surface);
-      screen->tex_surface_destroy(surface);
+      pipe->surface_destroy(pipe, surface);
    }
 }
 
@@ -550,17 +550,16 @@ struct bmp_rgb_quad {
 
 void
 debug_dump_surface_bmp(struct pipe_context *pipe,
-                      const char *filename,
+                       const char *filename,
                        struct pipe_surface *surface)
 {
 #ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
    struct pipe_transfer *transfer;
    struct pipe_resource *texture = surface->texture;
 
-   transfer = pipe_get_transfer(pipe, texture, surface->face,
-                               surface->level, surface->zslice,
-                               PIPE_TRANSFER_READ, 0, 0, surface->width,
-                               surface->height);
+   transfer = pipe_get_transfer(pipe, texture, surface->u.tex.level,
+                                surface->u.tex.first_layer, PIPE_TRANSFER_READ,
+                                0, 0, surface->width, surface->height);
 
    debug_dump_transfer_bmp(pipe, filename, transfer);
 
index 1c90ff31069838443064ea0b94080a45c011a205..7ed8ee608a80577b93fd7b55ee57f9b0d492a0ab 100644 (file)
@@ -69,7 +69,7 @@ debug_describe_surface(char* buf, const struct pipe_surface *ptr)
 {
    char res[128];
    debug_describe_resource(res, ptr->texture);
-   util_sprintf(buf, "pipe_surface<%s,%u,%u,%u>", res, ptr->face, ptr->level, ptr->zslice);
+   util_sprintf(buf, "pipe_surface<%s,%u,%u,%u>", res, ptr->u.tex.level, ptr->u.tex.first_layer, ptr->u.tex.last_layer);
 }
 
 void
index 528a1c394befa0bf1dbb810f1c184cd968d9a5d7..24e039fd226aa2d5f3e6f5331808a9dc2a6f2a18 100644 (file)
@@ -48,7 +48,10 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
    if(!nr_frames)
       return;
 
-#if defined(PIPE_CC_GCC)
+#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
+   __asm__ __volatile__("mov (%%ebp),%0": "=r" (frame_pointer));
+   frame_pointer = (const void **)frame_pointer[0];
+#elif defined(PIPE_CC_GCC)
    frame_pointer = ((const void **)__builtin_frame_address(1));
 #elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
    __asm {
index 332952af88b85c4036a0f7866e3c93cb70775138..44d437747a1841c48c7dfefc46c594cb5405535a 100644 (file)
@@ -40,7 +40,7 @@
 #include "u_debug_symbol.h"
 #include "u_hash_table.h"
 
-#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) && defined(PIPE_ARCH_X86)
+#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
    
 #include <windows.h>
 #include <stddef.h>
@@ -165,7 +165,7 @@ debug_symbol_name_glibc(const void *addr, char* buf, unsigned size)
 void
 debug_symbol_name(const void *addr, char* buf, unsigned size)
 {
-#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) && defined(PIPE_ARCH_X86)
+#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
    debug_symbol_name_imagehlp(addr, buf, size);
    if(buf[0])
       return;
index 7e1be45ad5a6c4cf11301dfdc25b45b6777fc019..40539f0b0ea699d1d5ef919e78dbea43cf82ec7a 100644 (file)
@@ -24,5 +24,9 @@
 #define U_NEW_VERTEX_BUFFER         0x10000
 #define U_NEW_QUERY                 0x20000
 #define U_NEW_DEPTH_STENCIL         0x40000
+#define U_NEW_GS                    0x80000
+#define U_NEW_GS_CONSTANTS          0x100000
+#define U_NEW_GS_SAMPLER_VIEW       0x200000
+#define U_NEW_GS_SAMPLER_STATES     0x400000
 
 #endif
index fd1bbe5ffdf3d48c935872924c44f639b3b47247..f3618d9be74b080cad2209e44c8adf4d76ff4b33 100644 (file)
@@ -77,7 +77,7 @@ util_dirty_surfaces_use_levels_for_sampling(struct pipe_context *pipe, struct ut
       struct util_dirty_surface *ds = LIST_ENTRY(struct util_dirty_surface, p, dirty_list);
       next = p->next;
 
-      if(ds->base.level >= first && ds->base.level <= last)
+      if(ds->base.u.tex.level >= first && ds->base.u.tex.level <= last)
         flush(pipe, &ds->base);
    }
 }
@@ -86,7 +86,8 @@ static INLINE void
 util_dirty_surfaces_use_for_sampling_with(struct pipe_context *pipe, struct util_dirty_surfaces *dss, struct pipe_sampler_view *psv, struct pipe_sampler_state *pss, util_dirty_surface_flush_t flush)
 {
    if(!LIST_IS_EMPTY(&dss->dirty_list))
-      util_dirty_surfaces_use_levels_for_sampling(pipe, dss, (unsigned)pss->min_lod + psv->first_level, MIN2((unsigned)ceilf(pss->max_lod) + psv->first_level, psv->last_level), flush);
+      util_dirty_surfaces_use_levels_for_sampling(pipe, dss, (unsigned)pss->min_lod + psv->u.tex.first_level,
+                                                 MIN2((unsigned)ceilf(pss->max_lod) + psv->u.tex.first_level, psv->u.tex.last_level), flush);
 }
 
 static INLINE void
index cda5b8ba512881b06ea84535be8a2c590826f7fd..b471d59eebf35295fd6fe39c65e7abc38c709d67 100644 (file)
@@ -279,6 +279,10 @@ util_dump_template(struct os_stream *stream, const struct pipe_resource *templat
    util_dump_uint(stream, templat->depth0);
    util_dump_member_end(stream);
 
+   util_dump_member_begin(stream, "array_size");
+   util_dump_uint(stream, templat->array_size);
+   util_dump_member_end(stream);
+
    util_dump_member(stream, uint, templat, last_level);
    util_dump_member(stream, uint, templat, usage);
    util_dump_member(stream, uint, templat, bind);
@@ -633,14 +637,12 @@ util_dump_surface(struct os_stream *stream, const struct pipe_surface *state)
    util_dump_member(stream, uint, state, width);
    util_dump_member(stream, uint, state, height);
 
-   util_dump_member(stream, uint, state, layout);
-   util_dump_member(stream, uint, state, offset);
    util_dump_member(stream, uint, state, usage);
 
    util_dump_member(stream, ptr, state, texture);
-   util_dump_member(stream, uint, state, face);
-   util_dump_member(stream, uint, state, level);
-   util_dump_member(stream, uint, state, zslice);
+   util_dump_member(stream, uint, state, u.tex.level);
+   util_dump_member(stream, uint, state, u.tex.first_layer);
+   util_dump_member(stream, uint, state, u.tex.last_layer);
 
    util_dump_struct_end(stream);
 }
@@ -660,7 +662,7 @@ util_dump_transfer(struct os_stream *stream, const struct pipe_transfer *state)
    /*util_dump_member(stream, uint, state, box);*/
 
    util_dump_member(stream, uint, state, stride);
-   util_dump_member(stream, uint, state, slice_stride);
+   util_dump_member(stream, uint, state, layer_stride);
 
    /*util_dump_member(stream, ptr, state, data);*/
 
index 6a931a95819cdd690b074870212dab49986cbf55..d22ae8b375b8f828984f33391b52cb3c072831b5 100644 (file)
@@ -48,6 +48,8 @@
 #include "util/u_simple_shaders.h"
 #include "util/u_math.h"
 #include "util/u_texture.h"
+#include "util/u_half.h"
+#include "util/u_surface.h"
 
 #include "cso_cache/cso_context.h"
 
@@ -65,7 +67,7 @@ struct gen_mipmap_state
    struct pipe_vertex_element velem[2];
 
    void *vs;
-   void *fs2d, *fsCube;
+   void *fs1d, *fs2d, *fs3d, *fsCube;
 
    struct pipe_resource *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -89,24 +91,7 @@ enum dtype
 };
 
 
-typedef ushort half_float;
-
-
-static half_float
-float_to_half(float f)
-{
-   /* XXX fix this */
-   return 0;
-}
-
-static float
-half_to_float(half_float h)
-{
-   /* XXX fix this */
-   return 0.0f;
-}
-
-
+typedef uint16_t half_float;
 
 
 /**
@@ -145,7 +130,7 @@ half_to_float(half_float h)
                                 rowC[j][e], rowC[k][e], \
                                 rowD[j][e], rowD[k][e]); \
    } while(0)
-   
+
 #define FILTER_F_3D(e) \
    do { \
       dst[i][e] = (rowA[j][e] + rowA[k][e] \
@@ -156,15 +141,15 @@ half_to_float(half_float h)
 
 #define FILTER_HF_3D(e) \
    do { \
-      const float aj = half_to_float(rowA[j][e]); \
-      const float ak = half_to_float(rowA[k][e]); \
-      const float bj = half_to_float(rowB[j][e]); \
-      const float bk = half_to_float(rowB[k][e]); \
-      const float cj = half_to_float(rowC[j][e]); \
-      const float ck = half_to_float(rowC[k][e]); \
-      const float dj = half_to_float(rowD[j][e]); \
-      const float dk = half_to_float(rowD[k][e]); \
-      dst[i][e] = float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \
+      const float aj = util_half_to_float(rowA[j][e]); \
+      const float ak = util_half_to_float(rowA[k][e]); \
+      const float bj = util_half_to_float(rowB[j][e]); \
+      const float bk = util_half_to_float(rowB[k][e]); \
+      const float cj = util_half_to_float(rowC[j][e]); \
+      const float ck = util_half_to_float(rowC[k][e]); \
+      const float dj = util_half_to_float(rowD[j][e]); \
+      const float dk = util_half_to_float(rowD[k][e]); \
+      dst[i][e] = util_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \
                                       * 0.125F); \
    } while(0)
 /*@}*/
@@ -343,8 +328,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth,
       }
    }
 
-#if 0
-   else if (datatype == HALF_DTYPE_FLOAT && comps == 4) {
+   else if (datatype == DTYPE_HALF_FLOAT && comps == 4) {
       uint i, j, k, comp;
       const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA;
       const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB;
@@ -353,11 +337,11 @@ do_row(enum dtype datatype, uint comps, int srcWidth,
            i++, j += colStride, k += colStride) {
          for (comp = 0; comp < 4; comp++) {
             float aj, ak, bj, bk;
-            aj = half_to_float(rowA[j][comp]);
-            ak = half_to_float(rowA[k][comp]);
-            bj = half_to_float(rowB[j][comp]);
-            bk = half_to_float(rowB[k][comp]);
-            dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
+            aj = util_half_to_float(rowA[j][comp]);
+            ak = util_half_to_float(rowA[k][comp]);
+            bj = util_half_to_float(rowB[j][comp]);
+            bk = util_half_to_float(rowB[k][comp]);
+            dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
          }
       }
    }
@@ -370,11 +354,11 @@ do_row(enum dtype datatype, uint comps, int srcWidth,
            i++, j += colStride, k += colStride) {
          for (comp = 0; comp < 3; comp++) {
             float aj, ak, bj, bk;
-            aj = half_to_float(rowA[j][comp]);
-            ak = half_to_float(rowA[k][comp]);
-            bj = half_to_float(rowB[j][comp]);
-            bk = half_to_float(rowB[k][comp]);
-            dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
+            aj = util_half_to_float(rowA[j][comp]);
+            ak = util_half_to_float(rowA[k][comp]);
+            bj = util_half_to_float(rowB[j][comp]);
+            bk = util_half_to_float(rowB[k][comp]);
+            dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
          }
       }
    }
@@ -387,11 +371,11 @@ do_row(enum dtype datatype, uint comps, int srcWidth,
            i++, j += colStride, k += colStride) {
          for (comp = 0; comp < 2; comp++) {
             float aj, ak, bj, bk;
-            aj = half_to_float(rowA[j][comp]);
-            ak = half_to_float(rowA[k][comp]);
-            bj = half_to_float(rowB[j][comp]);
-            bk = half_to_float(rowB[k][comp]);
-            dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
+            aj = util_half_to_float(rowA[j][comp]);
+            ak = util_half_to_float(rowA[k][comp]);
+            bj = util_half_to_float(rowB[j][comp]);
+            bk = util_half_to_float(rowB[k][comp]);
+            dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
          }
       }
    }
@@ -403,14 +387,13 @@ do_row(enum dtype datatype, uint comps, int srcWidth,
       for (i = j = 0, k = k0; i < (uint) dstWidth;
            i++, j += colStride, k += colStride) {
          float aj, ak, bj, bk;
-         aj = half_to_float(rowA[j]);
-         ak = half_to_float(rowA[k]);
-         bj = half_to_float(rowB[j]);
-         bk = half_to_float(rowB[k]);
-         dst[i] = float_to_half((aj + ak + bj + bk) * 0.25F);
+         aj = util_half_to_float(rowA[j]);
+         ak = util_half_to_float(rowA[k]);
+         bj = util_half_to_float(rowB[j]);
+         bk = util_half_to_float(rowB[k]);
+         dst[i] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
       }
    }
-#endif
 
    else if (datatype == DTYPE_UINT && comps == 1) {
       uint i, j, k;
@@ -1036,32 +1019,34 @@ reduce_2d(enum pipe_format pformat,
 static void
 reduce_3d(enum pipe_format pformat,
           int srcWidth, int srcHeight, int srcDepth,
-          int srcRowStride, const ubyte *srcPtr,
+          int srcRowStride, int srcImageStride, const ubyte *srcPtr,
           int dstWidth, int dstHeight, int dstDepth,
-          int dstRowStride, ubyte *dstPtr)
+          int dstRowStride, int dstImageStride, ubyte *dstPtr)
 {
    const int bpt = util_format_get_blocksize(pformat);
-   const int border = 0;
    int img, row;
-   int bytesPerSrcImage, bytesPerDstImage;
-   int bytesPerSrcRow, bytesPerDstRow;
    int srcImageOffset, srcRowOffset;
    enum dtype datatype;
    uint comps;
 
    format_to_type_comps(pformat, &datatype, &comps);
 
-   bytesPerSrcImage = srcWidth * srcHeight * bpt;
-   bytesPerDstImage = dstWidth * dstHeight * bpt;
+   /* XXX I think we should rather assert those strides */
+   if (!srcImageStride)
+      srcImageStride = srcWidth * srcHeight * bpt;
+   if (!dstImageStride)
+      dstImageStride = dstWidth * dstHeight * bpt;
 
-   bytesPerSrcRow = srcWidth * bpt;
-   bytesPerDstRow = dstWidth * bpt;
+   if (!srcRowStride)
+      srcRowStride = srcWidth * bpt;
+   if (!dstRowStride)
+      dstRowStride = dstWidth * bpt;
 
    /* Offset between adjacent src images to be averaged together */
-   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
+   srcImageOffset = (srcDepth == dstDepth) ? 0 : srcImageStride;
 
    /* Offset between adjacent src rows to be averaged together */
-   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
+   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcRowStride;
 
    /*
     * Need to average together up to 8 src pixels for each dest pixel.
@@ -1077,16 +1062,13 @@ reduce_3d(enum pipe_format pformat,
    */
 
    for (img = 0; img < dstDepth; img++) {
-      /* first source image pointer, skipping border */
+      /* first source image pointer */
       const ubyte *imgSrcA = srcPtr
-         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
-         + img * (bytesPerSrcImage + srcImageOffset);
-      /* second source image pointer, skipping border */
+         + img * (srcImageStride + srcImageOffset);
+      /* second source image pointer */
       const ubyte *imgSrcB = imgSrcA + srcImageOffset;
-      /* address of the dest image, skipping border */
-      ubyte *imgDst = dstPtr
-         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
-         + img * bytesPerDstImage;
+      /* address of the dest image */
+      ubyte *imgDst = dstPtr + img * dstImageStride;
 
       /* setup the four source row pointers and the dest row pointer */
       const ubyte *srcImgARowA = imgSrcA;
@@ -1102,11 +1084,11 @@ reduce_3d(enum pipe_format pformat,
                    dstWidth, dstImgRow);
 
          /* advance to next rows */
-         srcImgARowA += bytesPerSrcRow + srcRowOffset;
-         srcImgARowB += bytesPerSrcRow + srcRowOffset;
-         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
-         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
-         dstImgRow += bytesPerDstRow;
+         srcImgARowA += srcRowStride + srcRowOffset;
+         srcImgARowB += srcRowStride + srcRowOffset;
+         srcImgBRowA += srcRowStride + srcRowOffset;
+         srcImgBRowB += srcRowStride + srcRowOffset;
+         dstImgRow += dstImageStride;
       }
    }
 }
@@ -1117,25 +1099,24 @@ reduce_3d(enum pipe_format pformat,
 static void
 make_1d_mipmap(struct gen_mipmap_state *ctx,
                struct pipe_resource *pt,
-               uint face, uint baseLevel, uint lastLevel)
+               uint layer, uint baseLevel, uint lastLevel)
 {
    struct pipe_context *pipe = ctx->pipe;
-   const uint zslice = 0;
    uint dstLevel;
 
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
       struct pipe_transfer *srcTrans, *dstTrans;
       void *srcMap, *dstMap;
-      
-      srcTrans = pipe_get_transfer(pipe, pt, face, srcLevel, zslice,
-                                          PIPE_TRANSFER_READ, 0, 0,
-                                          u_minify(pt->width0, srcLevel),
-                                          u_minify(pt->height0, srcLevel));
-      dstTrans = pipe_get_transfer(pipe, pt, face, dstLevel, zslice,
-                                          PIPE_TRANSFER_WRITE, 0, 0,
-                                          u_minify(pt->width0, dstLevel),
-                                          u_minify(pt->height0, dstLevel));
+
+      srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
+                                   PIPE_TRANSFER_READ, 0, 0,
+                                   u_minify(pt->width0, srcLevel),
+                                   u_minify(pt->height0, srcLevel));
+      dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
+                                   PIPE_TRANSFER_WRITE, 0, 0,
+                                   u_minify(pt->width0, dstLevel),
+                                   u_minify(pt->height0, dstLevel));
 
       srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
       dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
@@ -1156,12 +1137,11 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
 static void
 make_2d_mipmap(struct gen_mipmap_state *ctx,
                struct pipe_resource *pt,
-               uint face, uint baseLevel, uint lastLevel)
+               uint layer, uint baseLevel, uint lastLevel)
 {
    struct pipe_context *pipe = ctx->pipe;
-   const uint zslice = 0;
    uint dstLevel;
-   
+
    assert(util_format_get_blockwidth(pt->format) == 1);
    assert(util_format_get_blockheight(pt->format) == 1);
 
@@ -1169,15 +1149,15 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
       const uint srcLevel = dstLevel - 1;
       struct pipe_transfer *srcTrans, *dstTrans;
       ubyte *srcMap, *dstMap;
-      
-      srcTrans = pipe_get_transfer(pipe, pt, face, srcLevel, zslice,
-                                  PIPE_TRANSFER_READ, 0, 0,
-                                  u_minify(pt->width0, srcLevel),
-                                  u_minify(pt->height0, srcLevel));
-      dstTrans = pipe_get_transfer(pipe, pt, face, dstLevel, zslice,
-                                  PIPE_TRANSFER_WRITE, 0, 0,
-                                  u_minify(pt->width0, dstLevel),
-                                  u_minify(pt->height0, dstLevel));
+
+      srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
+                                   PIPE_TRANSFER_READ, 0, 0,
+                                   u_minify(pt->width0, srcLevel),
+                                   u_minify(pt->height0, srcLevel));
+      dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
+                                   PIPE_TRANSFER_WRITE, 0, 0,
+                                   u_minify(pt->width0, dstLevel),
+                                   u_minify(pt->height0, dstLevel));
 
       srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
       dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
@@ -1197,41 +1177,49 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
 }
 
 
+/* XXX looks a bit more like it could work now but need to test */
 static void
 make_3d_mipmap(struct gen_mipmap_state *ctx,
                struct pipe_resource *pt,
                uint face, uint baseLevel, uint lastLevel)
 {
-#if 0
    struct pipe_context *pipe = ctx->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   uint dstLevel, zslice = 0;
+   uint dstLevel;
+   struct pipe_box src_box, dst_box;
 
    assert(util_format_get_blockwidth(pt->format) == 1);
    assert(util_format_get_blockheight(pt->format) == 1);
 
+   src_box.x = src_box.y = src_box.z = 0;
+   dst_box.x = dst_box.y = dst_box.z = 0;
+
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
       struct pipe_transfer *srcTrans, *dstTrans;
       ubyte *srcMap, *dstMap;
-      
-      srcTrans = pipe->get_transfer(pipe, pt, face, srcLevel, zslice,
-                                          PIPE_TRANSFER_READ, 0, 0,
-                                          u_minify(pt->width0, srcLevel),
-                                          u_minify(pt->height0, srcLevel));
-      dstTrans = pipe->get_transfer(pipe, pt, face, dstLevel, zslice,
-                                          PIPE_TRANSFER_WRITE, 0, 0,
-                                          u_minify(pt->width0, dstLevel),
-                                          u_minify(pt->height0, dstLevel));
+      struct pipe_box src_box, dst_box;
+      src_box.width = u_minify(pt->width0, srcLevel);
+      src_box.height = u_minify(pt->height0, srcLevel);
+      src_box.depth = u_minify(pt->depth0, srcLevel);
+      dst_box.width = u_minify(pt->width0, dstLevel);
+      dst_box.height = u_minify(pt->height0, dstLevel);
+      dst_box.depth = u_minify(pt->depth0, dstLevel);
+
+      srcTrans = pipe->get_transfer(pipe, pt, srcLevel,
+                                    PIPE_TRANSFER_READ,
+                                    &src_box);
+      dstTrans = pipe->get_transfer(pipe, pt, dstLevel,
+                                    PIPE_TRANSFER_WRITE,
+                                    &dst_box);
 
       srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
       dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
 
       reduce_3d(pt->format,
-                srcTrans->width, srcTrans->height,
-                srcTrans->stride, srcMap,
-                dstTrans->width, dstTrans->height,
-                dstTrans->stride, dstMap);
+                srcTrans->box.width, srcTrans->box.height, srcTrans->box.depth,
+                srcTrans->stride, srcTrans->layer_stride, srcMap,
+                dstTrans->box.width, dstTrans->box.height, dstTrans->box.depth,
+                dstTrans->stride, dstTrans->layer_stride, dstMap);
 
       pipe->transfer_unmap(pipe, srcTrans);
       pipe->transfer_unmap(pipe, dstTrans);
@@ -1239,28 +1227,25 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
       pipe->transfer_destroy(pipe, srcTrans);
       pipe->transfer_destroy(pipe, dstTrans);
    }
-#else
-   (void) reduce_3d;
-#endif
 }
 
 
 static void
 fallback_gen_mipmap(struct gen_mipmap_state *ctx,
                     struct pipe_resource *pt,
-                    uint face, uint baseLevel, uint lastLevel)
+                    uint layer, uint baseLevel, uint lastLevel)
 {
    switch (pt->target) {
    case PIPE_TEXTURE_1D:
-      make_1d_mipmap(ctx, pt, face, baseLevel, lastLevel);
+      make_1d_mipmap(ctx, pt, layer, baseLevel, lastLevel);
       break;
    case PIPE_TEXTURE_2D:
    case PIPE_TEXTURE_RECT:
    case PIPE_TEXTURE_CUBE:
-      make_2d_mipmap(ctx, pt, face, baseLevel, lastLevel);
+      make_2d_mipmap(ctx, pt, layer, baseLevel, lastLevel);
       break;
    case PIPE_TEXTURE_3D:
-      make_3d_mipmap(ctx, pt, face, baseLevel, lastLevel);
+      make_3d_mipmap(ctx, pt, layer, baseLevel, lastLevel);
       break;
    default:
       assert(0);
@@ -1328,8 +1313,12 @@ util_create_gen_mipmap(struct pipe_context *pipe,
    }
 
    /* fragment shader */
+   ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D,
+                                             TGSI_INTERPOLATE_LINEAR);
    ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
                                              TGSI_INTERPOLATE_LINEAR);
+   ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D,
+                                               TGSI_INTERPOLATE_LINEAR);
    ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
                                                TGSI_INTERPOLATE_LINEAR);
 
@@ -1371,7 +1360,7 @@ get_next_slot(struct gen_mipmap_state *ctx)
 static unsigned
 set_vertex_data(struct gen_mipmap_state *ctx,
                 enum pipe_texture_target tex_target,
-                uint face)
+                uint layer, float r)
 {
    unsigned offset;
 
@@ -1397,26 +1386,26 @@ set_vertex_data(struct gen_mipmap_state *ctx,
          {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
       };
 
-      util_map_texcoords2d_onto_cubemap(face, &st[0][0], 2,
+      util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2,
                                         &ctx->vertices[0][1][0], 8);
    }
    else {
-      /* 1D/2D */
+      /* 1D/2D/3D */
       ctx->vertices[0][1][0] = 0.0f; /*s*/
       ctx->vertices[0][1][1] = 0.0f; /*t*/
-      ctx->vertices[0][1][2] = 0.0f; /*r*/
+      ctx->vertices[0][1][2] = r;    /*r*/
 
       ctx->vertices[1][1][0] = 1.0f;
       ctx->vertices[1][1][1] = 0.0f;
-      ctx->vertices[1][1][2] = 0.0f;
+      ctx->vertices[1][1][2] = r;
 
       ctx->vertices[2][1][0] = 1.0f;
       ctx->vertices[2][1][1] = 1.0f;
-      ctx->vertices[2][1][2] = 0.0f;
+      ctx->vertices[2][1][2] = r;
 
       ctx->vertices[3][1][0] = 0.0f;
       ctx->vertices[3][1][1] = 1.0f;
-      ctx->vertices[3][1][2] = 0.0f;
+      ctx->vertices[3][1][2] = r;
    }
 
    offset = get_next_slot( ctx );
@@ -1437,9 +1426,11 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
 
-   pipe->delete_vs_state(pipe, ctx->vs);
-   pipe->delete_fs_state(pipe, ctx->fs2d);
    pipe->delete_fs_state(pipe, ctx->fsCube);
+   pipe->delete_fs_state(pipe, ctx->fs3d);
+   pipe->delete_fs_state(pipe, ctx->fs2d);
+   pipe->delete_fs_state(pipe, ctx->fs1d);
+   pipe->delete_vs_state(pipe, ctx->vs);
 
    pipe_resource_reference(&ctx->vbuf, NULL);
 
@@ -1478,9 +1469,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    struct pipe_screen *screen = pipe->screen;
    struct pipe_framebuffer_state fb;
    struct pipe_resource *pt = psv->texture;
-   void *fs = (pt->target == PIPE_TEXTURE_CUBE) ? ctx->fsCube : ctx->fs2d;
+   void *fs;
    uint dstLevel;
-   uint zslice = 0;
    uint offset;
 
    /* The texture object should have room for the levels which we're
@@ -1494,8 +1484,28 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    assert(filter == PIPE_TEX_FILTER_LINEAR ||
           filter == PIPE_TEX_FILTER_NEAREST);
 
+   switch (pt->target) {
+   case PIPE_TEXTURE_1D:
+      fs = ctx->fs1d;
+      break;
+   case PIPE_TEXTURE_2D:
+      fs = ctx->fs2d;
+      break;
+   case PIPE_TEXTURE_3D:
+      fs = ctx->fs3d;
+      break;
+   case PIPE_TEXTURE_CUBE:
+      fs = ctx->fsCube;
+      break;
+   case PIPE_TEXTURE_1D_ARRAY:
+   case PIPE_TEXTURE_2D_ARRAY:
+   default:
+      assert(0);
+      fs = ctx->fs2d;
+   }
+
    /* check if we can render in the texture's format */
-   if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D,
+   if (!screen->is_format_supported(screen, psv->format, pt->target,
                                     pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) {
       fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
       return;
@@ -1539,60 +1549,85 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
       struct pipe_viewport_state vp;
-
-      struct pipe_surface *surf = 
-         screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
-                                 PIPE_BIND_RENDER_TARGET);
-
-      /*
-       * Setup framebuffer / dest surface
-       */
-      fb.cbufs[0] = surf;
-      fb.width = u_minify(pt->width0, dstLevel);
-      fb.height = u_minify(pt->height0, dstLevel);
-      cso_set_framebuffer(ctx->cso, &fb);
-
-      /* viewport */
-      vp.scale[0] = 0.5f * fb.width;
-      vp.scale[1] = 0.5f * fb.height;
-      vp.scale[2] = 1.0f;
-      vp.scale[3] = 1.0f;
-      vp.translate[0] = 0.5f * fb.width;
-      vp.translate[1] = 0.5f * fb.height;
-      vp.translate[2] = 0.0f;
-      vp.translate[3] = 0.0f;
-      cso_set_viewport(ctx->cso, &vp);
-
-      /*
-       * Setup sampler state
-       * Note: we should only have to set the min/max LOD clamps to ensure
-       * we grab texels from the right mipmap level.  But some hardware
-       * has trouble with min clamping so we also set the lod_bias to
-       * try to work around that.
-       */
-      ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
-      ctx->sampler.lod_bias = (float) srcLevel;
-      cso_single_sampler(ctx->cso, 0, &ctx->sampler);
-      cso_single_sampler_done(ctx->cso);
-
-      cso_set_fragment_sampler_views(ctx->cso, 1, &psv);
-
-      /* quad coords in clip coords */
-      offset = set_vertex_data(ctx,
-                               pt->target,
-                               face);
-
-      util_draw_vertex_buffer(ctx->pipe, 
-                              ctx->vbuf,
-                              offset,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
-
-      pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
-      /* need to signal that the texture has changed _after_ rendering to it */
-      pipe_surface_reference( &surf, NULL );
+      unsigned nr_layers, layer, i;
+      float rcoord = 0.0f;
+
+      if (pt->target == PIPE_TEXTURE_3D)
+         nr_layers = u_minify(pt->depth0, dstLevel);
+      else
+         nr_layers = 1;
+
+      for (i = 0; i < nr_layers; i++) {
+         struct pipe_surface *surf, surf_templ;
+         if (pt->target == PIPE_TEXTURE_3D) {
+            /* in theory with geom shaders and driver with full layer support
+               could do that in one go. */
+            layer = i;
+            offset = 1.0f / (float)(nr_layers * 2);
+            /* XXX hmm really? */
+            rcoord = (float)layer / (float)nr_layers + 1.0f / (float)(nr_layers * 2);
+         }
+         else
+            layer = face;
+
+         memset(&surf_templ, 0, sizeof(surf_templ));
+         u_surface_default_template(&surf_templ, pt, PIPE_BIND_RENDER_TARGET);
+         surf_templ.u.tex.level = dstLevel;
+         surf_templ.u.tex.first_layer = layer;
+         surf_templ.u.tex.last_layer = layer;
+         surf = pipe->create_surface(pipe, pt, &surf_templ);
+
+         /*
+          * Setup framebuffer / dest surface
+          */
+         fb.cbufs[0] = surf;
+         fb.width = u_minify(pt->width0, dstLevel);
+         fb.height = u_minify(pt->height0, dstLevel);
+         cso_set_framebuffer(ctx->cso, &fb);
+
+         /* viewport */
+         vp.scale[0] = 0.5f * fb.width;
+         vp.scale[1] = 0.5f * fb.height;
+         vp.scale[2] = 1.0f;
+         vp.scale[3] = 1.0f;
+         vp.translate[0] = 0.5f * fb.width;
+         vp.translate[1] = 0.5f * fb.height;
+         vp.translate[2] = 0.0f;
+         vp.translate[3] = 0.0f;
+         cso_set_viewport(ctx->cso, &vp);
+
+         /*
+          * Setup sampler state
+          * Note: we should only have to set the min/max LOD clamps to ensure
+          * we grab texels from the right mipmap level.  But some hardware
+          * has trouble with min clamping so we also set the lod_bias to
+          * try to work around that.
+          */
+         ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
+         ctx->sampler.lod_bias = (float) srcLevel;
+         cso_single_sampler(ctx->cso, 0, &ctx->sampler);
+         cso_single_sampler_done(ctx->cso);
+
+         cso_set_fragment_sampler_views(ctx->cso, 1, &psv);
+
+         /* quad coords in clip coords */
+         offset = set_vertex_data(ctx,
+                                  pt->target,
+                                  face,
+                                  rcoord);
+
+         util_draw_vertex_buffer(ctx->pipe, 
+                                 ctx->vbuf,
+                                 offset,
+                                 PIPE_PRIM_TRIANGLE_FAN,
+                                 4,  /* verts */
+                                 2); /* attribs/vert */
+
+         pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+         /* need to signal that the texture has changed _after_ rendering to it */
+         pipe_surface_reference( &surf, NULL );
+      }
    }
 
    /* restore state we changed */
index a7502b9982b082add8a550e36b61ff50bc5e835a..a10b6a4aba9e8caaf794adb7f05934c34dd76f3d 100644 (file)
@@ -60,7 +60,7 @@ util_gen_mipmap_flush( struct gen_mipmap_state *ctx );
 extern void
 util_gen_mipmap(struct gen_mipmap_state *ctx,
                 struct pipe_sampler_view *psv,
-                uint face, uint baseLevel, uint lastLevel, uint filter);
+                uint layer, uint baseLevel, uint lastLevel, uint filter);
 
 
 #ifdef __cplusplus
index 6ed39561fbe941aa56f238b4932c8fac262e4cf6..e55aafe90f02fbfe64e97dde56b71d891a9b6866 100644 (file)
@@ -109,7 +109,7 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
 
    if (pipe_reference_described(&(*ptr)->reference, &surf->reference, 
                                 (debug_reference_descriptor)debug_describe_surface))
-      old_surf->texture->screen->tex_surface_destroy(old_surf);
+      old_surf->context->surface_destroy(old_surf->context, old_surf);
    *ptr = surf;
 }
 
@@ -136,26 +136,28 @@ pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_
 }
 
 static INLINE void
-pipe_surface_reset(struct pipe_surface* ps, struct pipe_resource *pt,
-               unsigned face, unsigned level, unsigned zslice, unsigned flags)
+pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps,
+                   struct pipe_resource *pt, unsigned level, unsigned layer,
+                   unsigned flags)
 {
    pipe_resource_reference(&ps->texture, pt);
    ps->format = pt->format;
    ps->width = u_minify(pt->width0, level);
    ps->height = u_minify(pt->height0, level);
    ps->usage = flags;
-   ps->face = face;
-   ps->level = level;
-   ps->zslice = zslice;
+   ps->u.tex.level = level;
+   ps->u.tex.first_layer = ps->u.tex.last_layer = layer;
+   ps->context = ctx;
 }
 
 static INLINE void
-pipe_surface_init(struct pipe_surface* ps, struct pipe_resource *pt,
-                unsigned face, unsigned level, unsigned zslice, unsigned flags)
+pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
+                  struct pipe_resource *pt, unsigned level, unsigned layer,
+                  unsigned flags)
 {
    ps->texture = 0;
    pipe_reference_init(&ps->reference, 1);
-   pipe_surface_reset(ps, pt, face, level, zslice, flags);
+   pipe_surface_reset(ctx, ps, pt, level, layer, flags);
 }
 
 /*
@@ -177,6 +179,7 @@ pipe_buffer_create( struct pipe_screen *screen,
    buffer.width0 = size;
    buffer.height0 = 1;
    buffer.depth0 = 1;
+   buffer.array_size = 1;
    return screen->resource_create(screen, &buffer);
 }
 
@@ -202,15 +205,15 @@ pipe_buffer_map_range(struct pipe_context *pipe,
    assert(offset < buffer->width0);
    assert(offset + length <= buffer->width0);
    assert(length);
-   
+
    u_box_1d(offset, length, &box);
 
    *transfer = pipe->get_transfer( pipe,
-                                  buffer,
-                                  u_subresource(0, 0),
-                                  usage,
-                                  &box);
-   
+                                   buffer,
+                                   0,
+                                   usage,
+                                   &box);
+
    if (*transfer == NULL)
       return NULL;
 
@@ -231,7 +234,7 @@ static INLINE void *
 pipe_buffer_map(struct pipe_context *pipe,
                 struct pipe_resource *buffer,
                 unsigned usage,
-               struct pipe_transfer **transfer)
+                struct pipe_transfer **transfer)
 {
    return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer);
 }
@@ -240,7 +243,7 @@ pipe_buffer_map(struct pipe_context *pipe,
 static INLINE void
 pipe_buffer_unmap(struct pipe_context *pipe,
                   struct pipe_resource *buf,
-                 struct pipe_transfer *transfer)
+                  struct pipe_transfer *transfer)
 {
    if (transfer) {
       pipe->transfer_unmap(pipe, transfer);
@@ -250,7 +253,7 @@ pipe_buffer_unmap(struct pipe_context *pipe,
 
 static INLINE void
 pipe_buffer_flush_mapped_range(struct pipe_context *pipe,
-                              struct pipe_transfer *transfer,
+                               struct pipe_transfer *transfer,
                                unsigned offset,
                                unsigned length)
 {
@@ -266,7 +269,7 @@ pipe_buffer_flush_mapped_range(struct pipe_context *pipe,
     * mapped range.
     */
    transfer_offset = offset - transfer->box.x;
-   
+
    u_box_1d(transfer_offset, length, &box);
 
    pipe->transfer_flush_region(pipe, transfer, &box);
@@ -276,7 +279,7 @@ static INLINE void
 pipe_buffer_write(struct pipe_context *pipe,
                   struct pipe_resource *buf,
                   unsigned offset,
-                 unsigned size,
+                  unsigned size,
                   const void *data)
 {
    struct pipe_box box;
@@ -284,13 +287,13 @@ pipe_buffer_write(struct pipe_context *pipe,
    u_box_1d(offset, size, &box);
 
    pipe->transfer_inline_write( pipe,
-                               buf,
-                               u_subresource(0,0),
-                               PIPE_TRANSFER_WRITE,
-                               &box,
-                               data,
-                               size,
-                               0);
+                                buf,
+                                0,
+                                PIPE_TRANSFER_WRITE,
+                                &box,
+                                data,
+                                size,
+                                0);
 }
 
 /**
@@ -309,21 +312,21 @@ pipe_buffer_write_nooverlap(struct pipe_context *pipe,
 
    u_box_1d(offset, size, &box);
 
-   pipe->transfer_inline_write(pipe, 
-                              buf,
-                              u_subresource(0,0),
-                              (PIPE_TRANSFER_WRITE |
-                               PIPE_TRANSFER_NOOVERWRITE),
-                              &box,
-                              data,
-                              0, 0);
+   pipe->transfer_inline_write(pipe,
+                               buf,
+                               0,
+                               (PIPE_TRANSFER_WRITE |
+                                PIPE_TRANSFER_NOOVERWRITE),
+                               &box,
+                               data,
+                               0, 0);
 }
 
 static INLINE void
 pipe_buffer_read(struct pipe_context *pipe,
                  struct pipe_resource *buf,
                  unsigned offset,
-                unsigned size,
+                 unsigned size,
                  void *data)
 {
    struct pipe_transfer *src_transfer;
@@ -343,20 +346,19 @@ pipe_buffer_read(struct pipe_context *pipe,
 
 static INLINE struct pipe_transfer *
 pipe_get_transfer( struct pipe_context *context,
-                      struct pipe_resource *resource,
-                      unsigned face, unsigned level,
-                      unsigned zslice,
-                      enum pipe_transfer_usage usage,
-                      unsigned x, unsigned y,
-                      unsigned w, unsigned h)
+                   struct pipe_resource *resource,
+                   unsigned level, unsigned layer,
+                   enum pipe_transfer_usage usage,
+                   unsigned x, unsigned y,
+                   unsigned w, unsigned h)
 {
    struct pipe_box box;
-   u_box_2d_zslice( x, y, zslice, w, h, &box );
+   u_box_2d_zslice( x, y, layer, w, h, &box );
    return context->get_transfer( context,
-                                resource,
-                                u_subresource(face, level),
-                                usage,
-                                &box );
+                                 resource,
+                                 level,
+                                 usage,
+                                 &box );
 }
 
 static INLINE void *
@@ -376,7 +378,7 @@ pipe_transfer_unmap( struct pipe_context *context,
 
 static INLINE void
 pipe_transfer_destroy( struct pipe_context *context, 
-                      struct pipe_transfer *transfer )
+                       struct pipe_transfer *transfer )
 {
    context->transfer_destroy(context, transfer);
 }
diff --git a/src/gallium/auxiliary/util/u_mempool.c b/src/gallium/auxiliary/util/u_mempool.c
deleted file mode 100644 (file)
index 1f336b3..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2010 Marek Olšák <maraeo@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "util/u_mempool.h"
-
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "util/u_simple_list.h"
-
-#include <stdio.h>
-
-#define UTIL_MEMPOOL_MAGIC 0xcafe4321
-
-/* The block is either allocated memory or free space. */
-struct util_mempool_block {
-   /* The header. */
-   /* The first next free block. */
-   struct util_mempool_block *next_free;
-
-   intptr_t magic;
-
-   /* Memory after the last member is dedicated to the block itself.
-    * The allocated size is always larger than this structure. */
-};
-
-static struct util_mempool_block *
-util_mempool_get_block(struct util_mempool *pool,
-                       struct util_mempool_page *page, unsigned index)
-{
-   return (struct util_mempool_block*)
-          ((uint8_t*)page + sizeof(struct util_mempool_page) +
-           (pool->block_size * index));
-}
-
-static void util_mempool_add_new_page(struct util_mempool *pool)
-{
-   struct util_mempool_page *page;
-   struct util_mempool_block *block;
-   int i;
-
-   page = MALLOC(pool->page_size);
-   insert_at_tail(&pool->list, page);
-
-   /* Mark all blocks as free. */
-   for (i = 0; i < pool->num_blocks-1; i++) {
-      block = util_mempool_get_block(pool, page, i);
-      block->next_free = util_mempool_get_block(pool, page, i+1);
-      block->magic = UTIL_MEMPOOL_MAGIC;
-   }
-
-   block = util_mempool_get_block(pool, page, pool->num_blocks-1);
-   block->next_free = pool->first_free;
-   block->magic = UTIL_MEMPOOL_MAGIC;
-   pool->first_free = util_mempool_get_block(pool, page, 0);
-   pool->num_pages++;
-
-#if 0
-   fprintf(stderr, "New page! Num of pages: %i\n", pool->num_pages);
-#endif
-}
-
-static void *util_mempool_malloc_st(struct util_mempool *pool)
-{
-   struct util_mempool_block *block;
-
-   if (!pool->first_free)
-      util_mempool_add_new_page(pool);
-
-   block = pool->first_free;
-   assert(block->magic == UTIL_MEMPOOL_MAGIC);
-   pool->first_free = block->next_free;
-
-   return (uint8_t*)block + sizeof(struct util_mempool_block);
-}
-
-static void util_mempool_free_st(struct util_mempool *pool, void *ptr)
-{
-   struct util_mempool_block *block =
-         (struct util_mempool_block*)
-         ((uint8_t*)ptr - sizeof(struct util_mempool_block));
-
-   assert(block->magic == UTIL_MEMPOOL_MAGIC);
-   block->next_free = pool->first_free;
-   pool->first_free = block;
-}
-
-static void *util_mempool_malloc_mt(struct util_mempool *pool)
-{
-   void *mem;
-
-   pipe_mutex_lock(pool->mutex);
-   mem = util_mempool_malloc_st(pool);
-   pipe_mutex_unlock(pool->mutex);
-   return mem;
-}
-
-static void util_mempool_free_mt(struct util_mempool *pool, void *ptr)
-{
-   pipe_mutex_lock(pool->mutex);
-   util_mempool_free_st(pool, ptr);
-   pipe_mutex_unlock(pool->mutex);
-}
-
-void util_mempool_set_thread_safety(struct util_mempool *pool,
-                                    enum util_mempool_threading threading)
-{
-   pool->threading = threading;
-
-   if (threading) {
-      pool->malloc = util_mempool_malloc_mt;
-      pool->free = util_mempool_free_mt;
-   } else {
-      pool->malloc = util_mempool_malloc_st;
-      pool->free = util_mempool_free_st;
-   }
-}
-
-void util_mempool_create(struct util_mempool *pool,
-                         unsigned item_size,
-                         unsigned num_blocks,
-                         enum util_mempool_threading threading)
-{
-   item_size = align(item_size, sizeof(intptr_t));
-
-   pool->num_pages = 0;
-   pool->num_blocks = num_blocks;
-   pool->block_size = sizeof(struct util_mempool_block) + item_size;
-   pool->block_size = align(pool->block_size, sizeof(intptr_t));
-   pool->page_size = sizeof(struct util_mempool_page) +
-                     num_blocks * pool->block_size;
-   pool->first_free = NULL;
-
-   make_empty_list(&pool->list);
-
-   pipe_mutex_init(pool->mutex);
-
-   util_mempool_set_thread_safety(pool, threading);
-}
-
-void util_mempool_destroy(struct util_mempool *pool)
-{
-   struct util_mempool_page *page, *temp;
-
-   foreach_s(page, temp, &pool->list) {
-      remove_from_list(page);
-      FREE(page);
-   }
-
-   pipe_mutex_destroy(pool->mutex);
-}
diff --git a/src/gallium/auxiliary/util/u_mempool.h b/src/gallium/auxiliary/util/u_mempool.h
deleted file mode 100644 (file)
index a5b5d6a..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2010 Marek Olšák <maraeo@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-/**
- * @file
- * Simple memory pool for equally sized memory allocations.
- * util_mempool_malloc and util_mempool_free are in O(1).
- *
- * Good for allocations which have very low lifetime and are allocated
- * and freed very often. Use a profiler first!
- *
- * Candidates: get_transfer, user_buffer_create
- *
- * @author Marek Olšák
- */
-
-#ifndef U_MEMPOOL_H
-#define U_MEMPOOL_H
-
-#include "os/os_thread.h"
-
-enum util_mempool_threading {
-   UTIL_MEMPOOL_SINGLETHREADED = FALSE,
-   UTIL_MEMPOOL_MULTITHREADED = TRUE
-};
-
-/* The page is an array of blocks (allocations). */
-struct util_mempool_page {
-   /* The header (linked-list pointers). */
-   struct util_mempool_page *prev, *next;
-
-   /* Memory after the last member is dedicated to the page itself.
-    * The allocated size is always larger than this structure. */
-};
-
-struct util_mempool {
-   /* Public members. */
-   void *(*malloc)(struct util_mempool *pool);
-   void (*free)(struct util_mempool *pool, void *ptr);
-
-   /* Private members. */
-   struct util_mempool_block *first_free;
-
-   struct util_mempool_page list;
-
-   unsigned block_size;
-   unsigned page_size;
-   unsigned num_blocks;
-   unsigned num_pages;
-   enum util_mempool_threading threading;
-
-   pipe_mutex mutex;
-};
-
-void util_mempool_create(struct util_mempool *pool,
-                         unsigned item_size,
-                         unsigned num_blocks,
-                         enum util_mempool_threading threading);
-
-void util_mempool_destroy(struct util_mempool *pool);
-
-void util_mempool_set_thread_safety(struct util_mempool *pool,
-                                    enum util_mempool_threading threading);
-
-#define util_mempool_malloc(pool)    (pool)->malloc(pool)
-#define util_mempool_free(pool, ptr) (pool)->free(pool, ptr)
-
-#endif
index 9e6474b83de6f7a121204f86e995a9d1e00ccb76..443c9f8067ef53643bfe28c8f557aa4bc99d4428 100644 (file)
@@ -10,85 +10,85 @@ u_resource( struct pipe_resource *res )
 }
 
 boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
-                         struct pipe_resource *resource,
-                         struct winsys_handle *handle)
+                                   struct pipe_resource *resource,
+                                   struct winsys_handle *handle)
 {
    struct u_resource *ur = u_resource(resource);
    return ur->vtbl->resource_get_handle(screen, resource, handle);
 }
 
 void u_resource_destroy_vtbl(struct pipe_screen *screen,
-                   struct pipe_resource *resource)
+                             struct pipe_resource *resource)
 {
    struct u_resource *ur = u_resource(resource);
    ur->vtbl->resource_destroy(screen, resource);
 }
 
 unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
-                                       struct pipe_resource *resource,
-                                       unsigned face, unsigned level)
+                                        struct pipe_resource *resource,
+                                        unsigned level, int layer)
 {
    struct u_resource *ur = u_resource(resource);
-   return ur->vtbl->is_resource_referenced(pipe, resource, face, level);
+   return ur->vtbl->is_resource_referenced(pipe, resource, level, layer);
 }
 
 struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
-                                         struct pipe_resource *resource,
-                                         struct pipe_subresource sr,
-                                         enum pipe_transfer_usage usage,
-                                         const struct pipe_box *box)
+                                          struct pipe_resource *resource,
+                                          unsigned level,
+                                          enum pipe_transfer_usage usage,
+                                          const struct pipe_box *box)
 {
    struct u_resource *ur = u_resource(resource);
-   return ur->vtbl->get_transfer(context, resource, sr, usage, box);
+   return ur->vtbl->get_transfer(context, resource, level, usage, box);
 }
 
 void u_transfer_destroy_vtbl(struct pipe_context *pipe,
-                            struct pipe_transfer *transfer)
+                             struct pipe_transfer *transfer)
 {
    struct u_resource *ur = u_resource(transfer->resource);
    ur->vtbl->transfer_destroy(pipe, transfer);
 }
 
 void *u_transfer_map_vtbl( struct pipe_context *pipe,
-                          struct pipe_transfer *transfer )
+                           struct pipe_transfer *transfer )
 {
    struct u_resource *ur = u_resource(transfer->resource);
    return ur->vtbl->transfer_map(pipe, transfer);
 }
 
 void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
-                                  struct pipe_transfer *transfer,
-                                  const struct pipe_box *box)
+                                   struct pipe_transfer *transfer,
+                                   const struct pipe_box *box)
 {
    struct u_resource *ur = u_resource(transfer->resource);
    ur->vtbl->transfer_flush_region(pipe, transfer, box);
 }
 
 void u_transfer_unmap_vtbl( struct pipe_context *pipe,
-                           struct pipe_transfer *transfer )
+                            struct pipe_transfer *transfer )
 {
    struct u_resource *ur = u_resource(transfer->resource);
    ur->vtbl->transfer_unmap(pipe, transfer);
 }
 
 void u_transfer_inline_write_vtbl( struct pipe_context *pipe,
-                                  struct pipe_resource *resource,
-                                  struct pipe_subresource sr,
-                                  unsigned usage,
-                                  const struct pipe_box *box,
-                                  const void *data,
-                                  unsigned stride,
-                                  unsigned slice_stride)
+                                   struct pipe_resource *resource,
+                                   unsigned level,
+                                   unsigned usage,
+                                   const struct pipe_box *box,
+                                   const void *data,
+                                   unsigned stride,
+                                   unsigned layer_stride)
 {
    struct u_resource *ur = u_resource(resource);
-   ur->vtbl->transfer_inline_write(pipe, 
-                                  resource,
-                                  sr,
-                                  usage,
-                                  box,
-                                  data,
-                                  stride,
-                                  slice_stride);
+   ur->vtbl->transfer_inline_write(pipe,
+                                   resource,
+                                   level,
+                                   usage,
+                                   box,
+                                   data,
+                                   stride,
+                                   layer_stride);
 }
 
 
index e77f562ea222a2cec01a2f38636d14acad873b3d..bb26099b7e15febdb349ac1223abe3d62b3b5c90 100644 (file)
@@ -40,8 +40,11 @@ default_template(struct pipe_sampler_view *view,
     */
 
    view->format = format;
-   view->first_level = 0;
-   view->last_level = texture->last_level;
+   view->u.tex.first_level = 0;
+   view->u.tex.last_level = texture->last_level;
+   view->u.tex.first_layer = 0;
+   view->u.tex.last_layer = texture->target == PIPE_TEXTURE_3D ?
+                               texture->depth0 - 1 : texture->array_size - 1;
    view->swizzle_r = PIPE_SWIZZLE_RED;
    view->swizzle_g = PIPE_SWIZZLE_GREEN;
    view->swizzle_b = PIPE_SWIZZLE_BLUE;
index b52232f025c2e779b1ac094a28f5b0700c0fdc50..7139aaabc565b5d686c4c85ca0efff2516d46993 100644 (file)
@@ -57,7 +57,8 @@ struct pipe_winsys
     * displayed, eg copy fake frontbuffer.
     */
    void (*flush_frontbuffer)( struct pipe_winsys *ws,
-                              struct pipe_surface *surf,
+                              struct pipe_resource *resource,
+                              unsigned level, unsigned layer,
                               void *context_private );
 
 
index 58ef68377fcea467509125842e854c72cdf205ef..b0f2dd8aa29e8173c9620140c180fa2f6c5a4238 100644 (file)
@@ -204,7 +204,8 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
 void *
 util_make_fragment_passthrough_shader(struct pipe_context *pipe)
 {
-   return util_make_fragment_clonecolor_shader(pipe, 1);
+   return util_make_fragment_cloneinput_shader(pipe, 1, TGSI_SEMANTIC_COLOR,
+                                               TGSI_INTERPOLATE_PERSPECTIVE);
 }
 
 
@@ -212,7 +213,9 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe)
  * Make a fragment shader that copies the input color to N output colors.
  */
 void *
-util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs)
+util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
+                                     int input_semantic,
+                                     int input_interpolate)
 {
    struct ureg_program *ureg;
    struct ureg_src src;
@@ -225,8 +228,8 @@ util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs)
    if (ureg == NULL)
       return NULL;
 
-   src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0, 
-                             TGSI_INTERPOLATE_PERSPECTIVE );
+   src = ureg_DECL_fs_input( ureg, input_semantic, 0,
+                             input_interpolate );
 
    for (i = 0; i < num_cbufs; i++)
       dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
index 4aa34bc47575289450e83ef12b9c94fe22536730..1bfec183e3471579adb3c4b85822efbf6da77fd0 100644 (file)
@@ -71,7 +71,9 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe);
 
 
 extern void *
-util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs);
+util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
+                                     int input_semantic,
+                                     int input_interpolate);
 
 #ifdef __cplusplus
 }
diff --git a/src/gallium/auxiliary/util/u_slab.c b/src/gallium/auxiliary/util/u_slab.c
new file mode 100644 (file)
index 0000000..21bf2d7
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "util/u_slab.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+
+#include <stdio.h>
+
+#define UTIL_SLAB_MAGIC 0xcafe4321
+
+/* The block is either allocated memory or free space. */
+struct util_slab_block {
+   /* The header. */
+   /* The first next free block. */
+   struct util_slab_block *next_free;
+
+   intptr_t magic;
+
+   /* Memory after the last member is dedicated to the block itself.
+    * The allocated size is always larger than this structure. */
+};
+
+static struct util_slab_block *
+util_slab_get_block(struct util_slab_mempool *pool,
+                    struct util_slab_page *page, unsigned index)
+{
+   return (struct util_slab_block*)
+          ((uint8_t*)page + sizeof(struct util_slab_page) +
+           (pool->block_size * index));
+}
+
+static void util_slab_add_new_page(struct util_slab_mempool *pool)
+{
+   struct util_slab_page *page;
+   struct util_slab_block *block;
+   int i;
+
+   page = MALLOC(pool->page_size);
+   insert_at_tail(&pool->list, page);
+
+   /* Mark all blocks as free. */
+   for (i = 0; i < pool->num_blocks-1; i++) {
+      block = util_slab_get_block(pool, page, i);
+      block->next_free = util_slab_get_block(pool, page, i+1);
+      block->magic = UTIL_SLAB_MAGIC;
+   }
+
+   block = util_slab_get_block(pool, page, pool->num_blocks-1);
+   block->next_free = pool->first_free;
+   block->magic = UTIL_SLAB_MAGIC;
+   pool->first_free = util_slab_get_block(pool, page, 0);
+   pool->num_pages++;
+
+#if 0
+   fprintf(stderr, "New page! Num of pages: %i\n", pool->num_pages);
+#endif
+}
+
+static void *util_slab_alloc_st(struct util_slab_mempool *pool)
+{
+   struct util_slab_block *block;
+
+   if (!pool->first_free)
+      util_slab_add_new_page(pool);
+
+   block = pool->first_free;
+   assert(block->magic == UTIL_SLAB_MAGIC);
+   pool->first_free = block->next_free;
+
+   return (uint8_t*)block + sizeof(struct util_slab_block);
+}
+
+static void util_slab_free_st(struct util_slab_mempool *pool, void *ptr)
+{
+   struct util_slab_block *block =
+         (struct util_slab_block*)
+         ((uint8_t*)ptr - sizeof(struct util_slab_block));
+
+   assert(block->magic == UTIL_SLAB_MAGIC);
+   block->next_free = pool->first_free;
+   pool->first_free = block;
+}
+
+static void *util_slab_alloc_mt(struct util_slab_mempool *pool)
+{
+   void *mem;
+
+   pipe_mutex_lock(pool->mutex);
+   mem = util_slab_alloc_st(pool);
+   pipe_mutex_unlock(pool->mutex);
+   return mem;
+}
+
+static void util_slab_free_mt(struct util_slab_mempool *pool, void *ptr)
+{
+   pipe_mutex_lock(pool->mutex);
+   util_slab_free_st(pool, ptr);
+   pipe_mutex_unlock(pool->mutex);
+}
+
+void util_slab_set_thread_safety(struct util_slab_mempool *pool,
+                                    enum util_slab_threading threading)
+{
+   pool->threading = threading;
+
+   if (threading) {
+      pool->alloc = util_slab_alloc_mt;
+      pool->free = util_slab_free_mt;
+   } else {
+      pool->alloc = util_slab_alloc_st;
+      pool->free = util_slab_free_st;
+   }
+}
+
+void util_slab_create(struct util_slab_mempool *pool,
+                      unsigned item_size,
+                      unsigned num_blocks,
+                      enum util_slab_threading threading)
+{
+   item_size = align(item_size, sizeof(intptr_t));
+
+   pool->num_pages = 0;
+   pool->num_blocks = num_blocks;
+   pool->block_size = sizeof(struct util_slab_block) + item_size;
+   pool->block_size = align(pool->block_size, sizeof(intptr_t));
+   pool->page_size = sizeof(struct util_slab_page) +
+                     num_blocks * pool->block_size;
+   pool->first_free = NULL;
+
+   make_empty_list(&pool->list);
+
+   pipe_mutex_init(pool->mutex);
+
+   util_slab_set_thread_safety(pool, threading);
+}
+
+void util_slab_destroy(struct util_slab_mempool *pool)
+{
+   struct util_slab_page *page, *temp;
+
+   foreach_s(page, temp, &pool->list) {
+      remove_from_list(page);
+      FREE(page);
+   }
+
+   pipe_mutex_destroy(pool->mutex);
+}
diff --git a/src/gallium/auxiliary/util/u_slab.h b/src/gallium/auxiliary/util/u_slab.h
new file mode 100644 (file)
index 0000000..6b9718d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+/**
+ * @file
+ * Simple slab allocator for equally sized memory allocations.
+ * util_slab_alloc and util_slab_free have time complexity in O(1).
+ *
+ * Good for allocations which have very low lifetime and are allocated
+ * and freed very often. Use a profiler first to know if it's worth using it!
+ *
+ * Candidates: get_transfer, user_buffer_create
+ *
+ * @author Marek Olšák
+ */
+
+#ifndef U_SLAB_H
+#define U_SLAB_H
+
+#include "os/os_thread.h"
+
+enum util_slab_threading {
+   UTIL_SLAB_SINGLETHREADED = FALSE,
+   UTIL_SLAB_MULTITHREADED = TRUE
+};
+
+/* The page is an array of blocks (allocations). */
+struct util_slab_page {
+   /* The header (linked-list pointers). */
+   struct util_slab_page *prev, *next;
+
+   /* Memory after the last member is dedicated to the page itself.
+    * The allocated size is always larger than this structure. */
+};
+
+struct util_slab_mempool {
+   /* Public members. */
+   void *(*alloc)(struct util_slab_mempool *pool);
+   void (*free)(struct util_slab_mempool *pool, void *ptr);
+
+   /* Private members. */
+   struct util_slab_block *first_free;
+
+   struct util_slab_page list;
+
+   unsigned block_size;
+   unsigned page_size;
+   unsigned num_blocks;
+   unsigned num_pages;
+   enum util_slab_threading threading;
+
+   pipe_mutex mutex;
+};
+
+void util_slab_create(struct util_slab_mempool *pool,
+                      unsigned item_size,
+                      unsigned num_blocks,
+                      enum util_slab_threading threading);
+
+void util_slab_destroy(struct util_slab_mempool *pool);
+
+void util_slab_set_thread_safety(struct util_slab_mempool *pool,
+                                 enum util_slab_threading threading);
+
+#define util_slab_alloc(pool)     (pool)->alloc(pool)
+#define util_slab_free(pool, ptr) (pool)->free(pool, ptr)
+
+#endif
index c5d68f8df8674aac26cbe8adc90194fa5438aae7..b6bf241a22a2d8ad96d4af04093bf065b11db14b 100644 (file)
@@ -41,6 +41,7 @@ util_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigne
    template->width0 = width;
    template->height0 = height;
    template->depth0 = depth;
+   template->array_size = 1;
    template->last_level = 0;
    template->nr_samples = pt->nr_samples;
    template->bind = 0;
@@ -51,7 +52,7 @@ util_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigne
 struct util_staging_transfer *
 util_staging_transfer_init(struct pipe_context *pipe,
            struct pipe_resource *pt,
-           struct pipe_subresource sr,
+           unsigned level,
            unsigned usage,
            const struct pipe_box *box,
            bool direct, struct util_staging_transfer *tx)
@@ -61,7 +62,7 @@ util_staging_transfer_init(struct pipe_context *pipe,
    struct pipe_resource staging_resource_template;
 
    pipe_resource_reference(&tx->base.resource, pt);
-   tx->base.sr = sr;
+   tx->base.level = level;
    tx->base.usage = usage;
    tx->base.box = *box;
 
@@ -82,12 +83,20 @@ util_staging_transfer_init(struct pipe_context *pipe,
 
    if (usage & PIPE_TRANSFER_READ)
    {
-      struct pipe_subresource dstsr;
+      /* XXX this looks wrong dst is always the same but looping over src z? */
       unsigned zi;
-      dstsr.face = 0;
-      dstsr.level = 0;
-      for(zi = 0; zi < box->depth; ++zi)
-         pipe->resource_copy_region(pipe, tx->staging_resource, dstsr, 0, 0, 0, tx->base.resource, sr, box->x, box->y, box->z + zi, box->width, box->height);
+      struct pipe_box sbox;
+      sbox.x = box->x;
+      sbox.y = box->y;
+      sbox.z = box->z;
+      sbox.width = box->width;
+      sbox.height = box->height;
+      sbox.depth = 1;
+      for(zi = 0; zi < box->depth; ++zi) {
+         sbox.z = sbox.z + zi;
+         pipe->resource_copy_region(pipe, tx->staging_resource, 0, 0, 0, 0,
+                                    tx->base.resource, level, &sbox);
+      }
    }
 
    return tx;
@@ -101,12 +110,18 @@ util_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *p
    if (tx->staging_resource != tx->base.resource)
    {
       if(tx->base.usage & PIPE_TRANSFER_WRITE) {
-         struct pipe_subresource srcsr;
+         /* XXX this looks wrong src is always the same but looping over dst z? */
          unsigned zi;
-         srcsr.face = 0;
-         srcsr.level = 0;
+         struct pipe_box sbox;
+         sbox.x = 0;
+         sbox.y = 0;
+         sbox.z = 0;
+         sbox.width = tx->base.box.width;
+         sbox.height = tx->base.box.height;
+         sbox.depth = 1;
          for(zi = 0; zi < tx->base.box.depth; ++zi)
-            pipe->resource_copy_region(pipe, tx->base.resource, tx->base.sr, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi, tx->staging_resource, srcsr, 0, 0, 0, tx->base.box.width, tx->base.box.height);
+            pipe->resource_copy_region(pipe, tx->base.resource, tx->base.level, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi,
+                                       tx->staging_resource, 0, &sbox);
       }
 
       pipe_resource_reference(&tx->staging_resource, NULL);
index 1aab78cc88173fd47a0eb339e657be972bab73b1..49839d254396d1c6740fe75dec492f0d36d4d0f7 100644 (file)
@@ -52,7 +52,7 @@ struct util_staging_transfer {
 struct util_staging_transfer *
 util_staging_transfer_init(struct pipe_context *pipe,
            struct pipe_resource *pt,
-           struct pipe_subresource sr,
+           unsigned level,
            unsigned usage,
            const struct pipe_box *box,
            bool direct, struct util_staging_transfer *tx);
index f78b6838a72e53ca5907c13d4e0f5c279565fc33..4eddd3f519e8d430c5abdb52788162ed59d14375 100644 (file)
 #include "util/u_surface.h"
 #include "util/u_pack_color.h"
 
+void
+u_surface_default_template(struct pipe_surface *view,
+                           const struct pipe_resource *texture,
+                           unsigned bind)
+{
+   view->format = texture->format;
+   view->u.tex.level = 0;
+   view->u.tex.first_layer = 0;
+   view->u.tex.last_layer = 0;
+   /* XXX should filter out all non-rt/ds bind flags ? */
+   view->usage = bind;
+}
 
 /**
  * Helper to quickly create an RGBA rendering surface of a certain size.
@@ -50,9 +62,9 @@
  * \return TRUE for success, FALSE if failure
  */
 boolean
-util_create_rgba_surface(struct pipe_screen *screen,
+util_create_rgba_surface(struct pipe_context *pipe,
                          uint width, uint height,
-                        uint bind,
+                         uint bind,
                          struct pipe_resource **textureOut,
                          struct pipe_surface **surfaceOut)
 {
@@ -65,6 +77,8 @@ util_create_rgba_surface(struct pipe_screen *screen,
    const uint target = PIPE_TEXTURE_2D;
    enum pipe_format format = PIPE_FORMAT_NONE;
    struct pipe_resource templ;
+   struct pipe_surface surf_templ;
+   struct pipe_screen *screen = pipe->screen;
    uint i;
 
    /* Choose surface format */
@@ -86,17 +100,20 @@ util_create_rgba_surface(struct pipe_screen *screen,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.bind = bind;
 
    *textureOut = screen->resource_create(screen, &templ);
    if (!*textureOut)
       return FALSE;
 
+   /* create surface */
+   memset(&surf_templ, 0, sizeof(surf_templ));
+   u_surface_default_template(&surf_templ, *textureOut, bind);
    /* create surface / view into texture */
-   *surfaceOut = screen->get_tex_surface(screen, 
-                                        *textureOut,
-                                        0, 0, 0,
-                                        bind);
+   *surfaceOut = pipe->create_surface(pipe,
+                                      *textureOut,
+                                      &surf_templ);
    if (!*surfaceOut) {
       pipe_resource_reference(textureOut, NULL);
       return FALSE;
@@ -126,17 +143,18 @@ util_destroy_rgba_surface(struct pipe_resource *texture,
 void
 util_resource_copy_region(struct pipe_context *pipe,
                           struct pipe_resource *dst,
-                          struct pipe_subresource subdst,
+                          unsigned dst_level,
                           unsigned dst_x, unsigned dst_y, unsigned dst_z,
                           struct pipe_resource *src,
-                          struct pipe_subresource subsrc,
-                          unsigned src_x, unsigned src_y, unsigned src_z,
-                          unsigned w, unsigned h)
+                          unsigned src_level,
+                          const struct pipe_box *src_box)
 {
    struct pipe_transfer *src_trans, *dst_trans;
    void *dst_map;
    const void *src_map;
    enum pipe_format src_format, dst_format;
+   unsigned w = src_box->width;
+   unsigned h = src_box->height;
 
    assert(src && dst);
    if (!src || !dst)
@@ -146,20 +164,18 @@ util_resource_copy_region(struct pipe_context *pipe,
    dst_format = dst->format;
 
    src_trans = pipe_get_transfer(pipe,
-                                src,
-                                subsrc.face,
-                                subsrc.level,
-                                src_z,
-                                PIPE_TRANSFER_READ,
-                                src_x, src_y, w, h);
+                                 src,
+                                 src_level,
+                                 src_box->z,
+                                 PIPE_TRANSFER_READ,
+                                 src_box->x, src_box->y, w, h);
 
    dst_trans = pipe_get_transfer(pipe,
-                                dst,
-                                subdst.face,
-                                subdst.level,
-                                src_z,
-                                PIPE_TRANSFER_WRITE,
-                                dst_x, dst_y, w, h);
+                                 dst,
+                                 dst_level,
+                                 dst_z,
+                                 PIPE_TRANSFER_WRITE,
+                                 dst_x, dst_y, w, h);
 
    assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
    assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
@@ -216,14 +232,13 @@ util_clear_render_target(struct pipe_context *pipe,
    assert(dst->texture);
    if (!dst->texture)
       return;
-
+   /* XXX: should handle multiple layers */
    dst_trans = pipe_get_transfer(pipe,
-                                dst->texture,
-                                dst->face,
-                                dst->level,
-                                dst->zslice,
-                                PIPE_TRANSFER_WRITE,
-                                dstx, dsty, width, height);
+                                 dst->texture,
+                                 dst->u.tex.level,
+                                 dst->u.tex.first_layer,
+                                 PIPE_TRANSFER_WRITE,
+                                 dstx, dsty, width, height);
 
    dst_map = pipe->transfer_map(pipe, dst_trans);
 
@@ -271,9 +286,8 @@ util_clear_depth_stencil(struct pipe_context *pipe,
       return;
    dst_trans = pipe_get_transfer(pipe,
                                  dst->texture,
-                                 dst->face,
-                                 dst->level,
-                                 dst->zslice,
+                                 dst->u.tex.level,
+                                 dst->u.tex.first_layer,
                                  (need_rmw ? PIPE_TRANSFER_READ_WRITE :
                                      PIPE_TRANSFER_WRITE),
                                  dstx, dsty, width, height);
index 6cd12af3a8b21a26545a13f4c037a12360959191..6a7cc82b0550710fc1dede3b7c686587b9d7b202 100644 (file)
 #include "pipe/p_state.h"
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern void
+u_surface_default_template(struct pipe_surface *view,
+                           const struct pipe_resource *texture,
+                           unsigned bind);
+
 extern boolean
-util_create_rgba_surface(struct pipe_screen *screen,
+util_create_rgba_surface(struct pipe_context *ctx,
                          uint width, uint height, uint bind,
                          struct pipe_resource **textureOut,
                          struct pipe_surface **surfaceOut);
@@ -49,12 +59,11 @@ util_destroy_rgba_surface(struct pipe_resource *texture,
 extern void
 util_resource_copy_region(struct pipe_context *pipe,
                           struct pipe_resource *dst,
-                          struct pipe_subresource subdst,
+                          unsigned dst_level,
                           unsigned dst_x, unsigned dst_y, unsigned dst_z,
                           struct pipe_resource *src,
-                          struct pipe_subresource subsrc,
-                          unsigned src_x, unsigned src_y, unsigned src_z,
-                          unsigned w, unsigned h);
+                          unsigned src_level,
+                          const struct pipe_box *src_box);
 
 extern void
 util_clear_render_target(struct pipe_context *pipe,
@@ -73,4 +82,9 @@ util_clear_depth_stencil(struct pipe_context *pipe,
                          unsigned width, unsigned height);
 
 
+#ifdef __cplusplus
+}
+#endif
+
+
 #endif /* U_SURFACE_H */
index 404e12199525681076c521076753d1bd2d117a12..b0cfec2a8260867d2f278e78a9b95d24f71e62e6 100644 (file)
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
 
-struct pipe_surface *
-util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags)
+boolean
+util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
+                     struct pipe_context *ctx, struct pipe_resource *pt,
+                     unsigned level, unsigned layer, unsigned flags,
+                     struct pipe_surface **res)
 {
    struct pipe_surface *ps;
 
@@ -39,7 +42,7 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, str
       if(!us->u.hash)
          us->u.hash = cso_hash_create();
 
-      ps = cso_hash_iter_data(cso_hash_find(us->u.hash, ((zslice + face) << 8) | level));
+      ps = cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level));
    }
    else
    {
@@ -48,25 +51,29 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, str
       ps = us->u.array[level];
    }
 
-   if(ps)
+   if(ps && ps->context == ctx)
    {
       p_atomic_inc(&ps->reference.count);
-      return ps;
+      *res = ps;
+      return FALSE;
    }
 
    ps = (struct pipe_surface *)CALLOC(1, surface_struct_size);
    if(!ps)
-      return NULL;
+   {
+      *res = NULL;
+      return FALSE;
+   }
 
-   pipe_surface_init(ps, pt, face, level, zslice, flags);
-   ps->offset = ~0;
+   pipe_surface_init(ctx, ps, pt, level, layer, flags);
 
    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
-      cso_hash_insert(us->u.hash, ((zslice + face) << 8) | level, ps);
+      cso_hash_insert(us->u.hash, (layer << 8) | level, ps);
    else
       us->u.array[level] = ps;
 
-   return ps;
+   *res = ps;
+   return TRUE;
 }
 
 void
@@ -75,10 +82,10 @@ util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps)
    struct pipe_resource *pt = ps->texture;
    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
    {    /* or 2D array */
-      cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, ((ps->zslice + ps->face) << 8) | ps->level));
+      cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, (ps->u.tex.first_layer << 8) | ps->u.tex.level));
    }
    else
-      us->u.array[ps->level] = 0;
+      us->u.array[ps->u.tex.level] = 0;
 }
 
 void
index 17d8a5d3a5b6fc3e9908ae9b3a0be8ac5f7d38cf..9581feda7c814f00e46477040f8c49f1eb2924ee 100644 (file)
@@ -42,33 +42,42 @@ struct util_surfaces
    } u;
 };
 
-struct pipe_surface *util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags);
+/* Return value indicates if the pipe surface result is new */
+boolean
+util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
+                     struct pipe_context *ctx, struct pipe_resource *pt,
+                     unsigned level, unsigned layer, unsigned flags,
+                     struct pipe_surface **res);
 
 /* fast inline path for the very common case */
-static INLINE struct pipe_surface *
-util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags)
+static INLINE boolean
+util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size,
+                  struct pipe_context *ctx, struct pipe_resource *pt,
+                  unsigned level, unsigned layer, unsigned flags,
+                  struct pipe_surface **res)
 {
    if(likely((pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT) && us->u.array))
    {
       struct pipe_surface *ps = us->u.array[level];
-      if(ps)
+      if(ps && ps->context == ctx)
       {
         p_atomic_inc(&ps->reference.count);
-        return ps;
+        *res = ps;
+        return FALSE;
       }
    }
 
-   return util_surfaces_do_get(us, surface_struct_size, pscreen, pt, face, level, zslice, flags);
+   return util_surfaces_do_get(us, surface_struct_size, ctx, pt, level, layer, flags, res);
 }
 
 static INLINE struct pipe_surface *
-util_surfaces_peek(struct util_surfaces *us, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice)
+util_surfaces_peek(struct util_surfaces *us, struct pipe_resource *pt, unsigned level, unsigned layer)
 {
    if(!us->u.pv)
       return 0;
 
    if(unlikely(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE))
-      return cso_hash_iter_data(cso_hash_find(us->u.hash, ((zslice + face) << 8) | level));
+      return cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level));
    else
       return us->u.array[level];
 }
@@ -80,7 +89,7 @@ util_surfaces_detach(struct util_surfaces *us, struct pipe_surface *ps)
 {
    if(likely(ps->texture->target == PIPE_TEXTURE_2D || ps->texture->target == PIPE_TEXTURE_RECT))
    {
-      us->u.array[ps->level] = 0;
+      us->u.array[ps->u.tex.level] = 0;
       return;
    }
 
index 69f6fab9504e62870031a27095a37da55db87a67..e2828cfd99e8ef54330f777dadc199b9335b9884 100644 (file)
@@ -8,22 +8,24 @@
  * pointer.  XXX: strides??
  */
 void u_default_transfer_inline_write( struct pipe_context *pipe,
-                                     struct pipe_resource *resource,
-                                     struct pipe_subresource sr,
-                                     unsigned usage,
-                                     const struct pipe_box *box,
-                                     const void *data,
-                                     unsigned stride,
-                                     unsigned slice_stride)
+                                      struct pipe_resource *resource,
+                                      unsigned level,
+                                      unsigned usage,
+                                      const struct pipe_box *box,
+                                      const void *data,
+                                      unsigned stride,
+                                      unsigned layer_stride)
 {
    struct pipe_transfer *transfer = NULL;
    uint8_t *map = NULL;
-
-   transfer = pipe->get_transfer(pipe, 
-                                resource,
-                                sr,
-                                usage,
-                                box );
+   const uint8_t *src_data = data;
+   unsigned i;
+
+   transfer = pipe->get_transfer(pipe,
+                                 resource,
+                                 level,
+                                 usage,
+                                 box );
    if (transfer == NULL)
       goto out;
 
@@ -31,17 +33,19 @@ void u_default_transfer_inline_write( struct pipe_context *pipe,
    if (map == NULL)
       goto out;
 
-   assert(box->depth == 1);    /* XXX: fix me */
-   
-   util_copy_rect(map,
-                 resource->format,
-                 transfer->stride, /* bytes */
-                 0, 0,
-                 box->width,
-                 box->height,
-                 data,
-                 stride,       /* bytes */
-                 0, 0);
+   for (i = 0; i < box->depth; i++) {
+      util_copy_rect(map,
+                     resource->format,
+                     transfer->stride, /* bytes */
+                     0, 0,
+                     box->width,
+                     box->height,
+                     src_data,
+                     stride,       /* bytes */
+                     0, 0);
+      map += transfer->layer_stride;
+      src_data += layer_stride;
+   }
 
 out:
    if (map)
@@ -53,8 +57,8 @@ out:
 
 
 boolean u_default_resource_get_handle(struct pipe_screen *screen,
-                                     struct pipe_resource *resource,
-                                     struct winsys_handle *handle)
+                                      struct pipe_resource *resource,
+                                      struct winsys_handle *handle)
 {
    return FALSE;
 }
@@ -62,32 +66,32 @@ boolean u_default_resource_get_handle(struct pipe_screen *screen,
 
 
 void u_default_transfer_flush_region( struct pipe_context *pipe,
-                                     struct pipe_transfer *transfer,
-                                     const struct pipe_box *box)
+                                      struct pipe_transfer *transfer,
+                                      const struct pipe_box *box)
 {
    /* This is a no-op implementation, nothing to do.
     */
 }
 
 unsigned u_default_is_resource_referenced( struct pipe_context *pipe,
-                                          struct pipe_resource *resource,
-                                       unsigned face, unsigned level)
+                                           struct pipe_resource *resource,
+                                           unsigned level, int layer)
 {
    return 0;
 }
 
 struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
-                                             struct pipe_resource *resource,
-                                             struct pipe_subresource sr,
-                                             unsigned usage,
-                                             const struct pipe_box *box)
+                                              struct pipe_resource *resource,
+                                              unsigned level,
+                                              unsigned usage,
+                                              const struct pipe_box *box)
 {
    struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
    if (transfer == NULL)
       return NULL;
 
    transfer->resource = resource;
-   transfer->sr = sr;
+   transfer->level = level;
    transfer->usage = usage;
    transfer->box = *box;
 
@@ -98,12 +102,12 @@ struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
 }
 
 void u_default_transfer_unmap( struct pipe_context *pipe,
-                             struct pipe_transfer *transfer )
+                               struct pipe_transfer *transfer )
 {
 }
 
 void u_default_transfer_destroy(struct pipe_context *pipe,
-                               struct pipe_transfer *transfer)
+                                struct pipe_transfer *transfer)
 {
    FREE(transfer);
 }
index e3a38730f214aea837b80e5a4fbd180cc76973c7..3412e13c3ccc9641b6e9ab718f444e83d286915e 100644 (file)
@@ -11,37 +11,37 @@ struct pipe_context;
 struct winsys_handle;
 
 boolean u_default_resource_get_handle(struct pipe_screen *screen,
-                                     struct pipe_resource *resource,
-                                     struct winsys_handle *handle);
+                                      struct pipe_resource *resource,
+                                      struct winsys_handle *handle);
 
 void u_default_transfer_inline_write( struct pipe_context *pipe,
-                             struct pipe_resource *resource,
-                             struct pipe_subresource sr,
-                             unsigned usage,
-                             const struct pipe_box *box,
-                             const void *data,
-                             unsigned stride,
-                             unsigned slice_stride);
+                                      struct pipe_resource *resource,
+                                      unsigned level,
+                                      unsigned usage,
+                                      const struct pipe_box *box,
+                                      const void *data,
+                                      unsigned stride,
+                                      unsigned layer_stride);
 
 void u_default_transfer_flush_region( struct pipe_context *pipe,
-                                     struct pipe_transfer *transfer,
-                                     const struct pipe_box *box);
+                                      struct pipe_transfer *transfer,
+                                      const struct pipe_box *box);
 
 unsigned u_default_is_resource_referenced( struct pipe_context *pipe,
-                                          struct pipe_resource *resource,
-                                          unsigned face, unsigned level);
+                                           struct pipe_resource *resource,
+                                           unsigned level, int layer);
 
 struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
-                                             struct pipe_resource *resource,
-                                             struct pipe_subresource sr,
-                                             unsigned usage,
-                                             const struct pipe_box *box);
+                                              struct pipe_resource *resource,
+                                              unsigned level,
+                                              unsigned usage,
+                                              const struct pipe_box *box);
 
 void u_default_transfer_unmap( struct pipe_context *pipe,
-                              struct pipe_transfer *transfer );
+                               struct pipe_transfer *transfer );
 
 void u_default_transfer_destroy(struct pipe_context *pipe,
-                               struct pipe_transfer *transfer);
+                                struct pipe_transfer *transfer);
 
 
 
@@ -51,43 +51,43 @@ void u_default_transfer_destroy(struct pipe_context *pipe,
 struct u_resource_vtbl {
 
    boolean (*resource_get_handle)(struct pipe_screen *,
-                                 struct pipe_resource *tex,
-                                 struct winsys_handle *handle);
+                                  struct pipe_resource *tex,
+                                  struct winsys_handle *handle);
 
    void (*resource_destroy)(struct pipe_screen *,
-                           struct pipe_resource *pt);
+                            struct pipe_resource *pt);
 
    unsigned (*is_resource_referenced)(struct pipe_context *pipe,
-                                     struct pipe_resource *texture,
-                                     unsigned face, unsigned level);
+                                      struct pipe_resource *texture,
+                                      unsigned level, int layer);
 
    struct pipe_transfer *(*get_transfer)(struct pipe_context *,
-                                        struct pipe_resource *resource,
-                                        struct pipe_subresource,
-                                        unsigned usage,
-                                        const struct pipe_box *);
+                                         struct pipe_resource *resource,
+                                         unsigned level,
+                                         unsigned usage,
+                                         const struct pipe_box *);
 
    void (*transfer_destroy)(struct pipe_context *,
-                           struct pipe_transfer *);
+                            struct pipe_transfer *);
 
    void *(*transfer_map)( struct pipe_context *,
-                         struct pipe_transfer *transfer );
+                          struct pipe_transfer *transfer );
 
    void (*transfer_flush_region)( struct pipe_context *,
-                                 struct pipe_transfer *transfer,
-                                 const struct pipe_box *);
+                                  struct pipe_transfer *transfer,
+                                  const struct pipe_box *);
 
    void (*transfer_unmap)( struct pipe_context *,
-                          struct pipe_transfer *transfer );
+   struct pipe_transfer *transfer );
 
    void (*transfer_inline_write)( struct pipe_context *pipe,
-                                 struct pipe_resource *resource,
-                                 struct pipe_subresource sr,
-                                 unsigned usage,
-                                 const struct pipe_box *box,
-                                 const void *data,
-                                 unsigned stride,
-                                 unsigned slice_stride);
+                                  struct pipe_resource *resource,
+                                  unsigned level,
+                                  unsigned usage,
+                                  const struct pipe_box *box,
+                                  const void *data,
+                                  unsigned stride,
+                                  unsigned layer_stride);
 };
 
 
@@ -98,43 +98,43 @@ struct u_resource {
 
 
 boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
-                             struct pipe_resource *resource,
-                             struct winsys_handle *handle);
+                                   struct pipe_resource *resource,
+                                   struct winsys_handle *handle);
 
 void u_resource_destroy_vtbl(struct pipe_screen *screen,
-                       struct pipe_resource *resource);
+                             struct pipe_resource *resource);
 
 unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
-                                       struct pipe_resource *resource,
-                                       unsigned face, unsigned level);
+                                        struct pipe_resource *resource,
+                                        unsigned level, int layer);
 
 struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
-                                    struct pipe_resource *resource,
-                                    struct pipe_subresource sr,
-                                    unsigned usage,
-                                    const struct pipe_box *box);
+                                          struct pipe_resource *resource,
+                                          unsigned level,
+                                          unsigned usage,
+                                          const struct pipe_box *box);
 
 void u_transfer_destroy_vtbl(struct pipe_context *pipe,
-                       struct pipe_transfer *transfer);
+                             struct pipe_transfer *transfer);
 
 void *u_transfer_map_vtbl( struct pipe_context *pipe,
-                     struct pipe_transfer *transfer );
+                           struct pipe_transfer *transfer );
 
 void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
-                             struct pipe_transfer *transfer,
-                             const struct pipe_box *box);
+                                   struct pipe_transfer *transfer,
+                                   const struct pipe_box *box);
 
 void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx,
-                      struct pipe_transfer *transfer );
+                            struct pipe_transfer *transfer );
 
 void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
-                                  struct pipe_resource *resource,
-                                  struct pipe_subresource sr,
-                                  unsigned usage,
-                                  const struct pipe_box *box,
-                                  const void *data,
-                                  unsigned stride,
-                                  unsigned slice_stride);
+                                   struct pipe_resource *resource,
+                                   unsigned level,
+                                   unsigned usage,
+                                   const struct pipe_box *box,
+                                   const void *data,
+                                   unsigned stride,
+                                   unsigned layer_stride);
 
 
 
index f0063a453d09a535984861d72046a433b0c035c5..ae80dc0a2748585a0030d9e73f7893f2969b6a5f 100644 (file)
@@ -523,8 +523,7 @@ vl_idct_upload_matrix(struct pipe_context *pipe)
    buf_transfer = pipe->get_transfer
    (
       pipe, matrix,
-      u_subresource(0, 0),
-      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
       &rect
    );
    pitch = buf_transfer->stride / sizeof(float);
@@ -579,6 +578,8 @@ vl_idct_cleanup(struct vl_idct *idct)
 bool
 vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, struct pipe_resource *dst)
 {
+   struct pipe_surface template;
+
    unsigned i;
 
    assert(buffer);
@@ -607,18 +608,26 @@ vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, struct
 
    buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
    for(i = 0; i < NR_RENDER_TARGETS; ++i) {
-      buffer->fb_state[0].cbufs[i] = idct->pipe->screen->get_tex_surface(
-         idct->pipe->screen, buffer->textures.individual.intermediate, 0, 0, i,
-         PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+      memset(&template, 0, sizeof(template));
+      template.format = buffer->textures.individual.intermediate->format;
+      template.u.tex.first_layer = i;
+      template.u.tex.last_layer = i;
+      template.usage = PIPE_BIND_RENDER_TARGET;
+      buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
+         idct->pipe, buffer->textures.individual.intermediate,
+         &template);
    }
 
    buffer->fb_state[1].width = buffer->destination->width0;
    buffer->fb_state[1].height = buffer->destination->height0;
 
    buffer->fb_state[1].nr_cbufs = 1;
-   buffer->fb_state[1].cbufs[0] = idct->pipe->screen->get_tex_surface(
-      idct->pipe->screen, buffer->destination, 0, 0, 0,
-      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+
+   memset(&template, 0, sizeof(template));
+   template.format = buffer->destination->format;
+   template.usage = PIPE_BIND_RENDER_TARGET;
+   buffer->fb_state[1].cbufs[0] = idct->pipe->create_surface(
+      idct->pipe, buffer->destination, &template);
 
    for(i = 0; i < 2; ++i) {
       buffer->viewport[i].scale[2] = 1;
@@ -642,10 +651,10 @@ vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
    assert(buffer);
 
    for(i = 0; i < NR_RENDER_TARGETS; ++i) {
-      idct->pipe->screen->tex_surface_destroy(buffer->fb_state[0].cbufs[i]);
+      idct->pipe->surface_destroy(idct->pipe, buffer->fb_state[0].cbufs[i]);
    }
 
-   idct->pipe->screen->tex_surface_destroy(buffer->fb_state[1].cbufs[0]);
+   idct->pipe->surface_destroy(idct->pipe, buffer->fb_state[1].cbufs[0]);
 
    cleanup_textures(idct, buffer);
    cleanup_vertex_buffers(idct, buffer);
@@ -667,8 +676,7 @@ vl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
    buffer->tex_transfer = idct->pipe->get_transfer
    (
       idct->pipe, buffer->textures.individual.source,
-      u_subresource(0, 0),
-      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
       &rect
    );
 
index f8155c828b12b74e2c8dfbba026310490fe6ce04..11e77190895672e66fd429d03e17df8158057524 100644 (file)
@@ -162,8 +162,8 @@ CreateDepthStencilState -> create_depth_stencil_alpha_state
        + Gallium has per-face writemask/valuemasks, D3D11 uses the same value for back and front
        + Gallium supports the alpha test, which D3D11 lacks
 
-CreateDepthStencilView -> get_tex_surface
-CreateRenderTargetView -> get_tex_surface
+CreateDepthStencilView -> create_surface
+CreateRenderTargetView -> create_surface
        ! Gallium merges depthstencil and rendertarget views into pipe_surface, which also doubles as a 2D surface abstraction
        - lack of texture array support
        - lack of render-to-buffer support
@@ -221,7 +221,6 @@ CreateResource -> texture_create or buffer_create
        ! D3D11 specifies mapping flags (i.e. read/write/discard);:it's unclear what they are used for here
        - D3D11 supports odd things in the D3D10_DDI_RESOURCE_MISC_FLAG enum (D3D10_DDI_RESOURCE_MISC_DISCARD_ON_PRESENT, D3D11_DDI_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS, D3D11_DDI_RESOURCE_MISC_BUFFER_STRUCTURED)
        - Gallium does not support indirect draw call parameter buffers
-       - Gallium lacks array textures
        ! D3D11 supports specifying hardware modes and other stuff here for scanout resources
        + Gallium allows specifying minimum buffer alignment
        ! D3D11 implements cube maps as 2D array textures
index e09a1304c4d3b383a6719ccc4e90013485d9e922..c33cf7c57380b04548d3fa04e2633a2a1d63beff 100644 (file)
@@ -84,7 +84,14 @@ in the result register. For example, ``swizzle_r`` specifies what is going to be
 placed in first component of result register.
 
 The ``first_level`` and ``last_level`` fields of sampler view template specify
-the LOD range the texture is going to be constrained to.
+the LOD range the texture is going to be constrained to. Note that these
+values are in addition to the respective min_lod, max_lod values in the
+pipe_sampler_state (that is if min_lod is 2.0, and first_level 3, the first mip
+level used for sampling from the resource is effectively the fifth).
+
+The ``first_layer`` and ``last_layer`` fields specify the layer range the
+texture is going to be constrained to. Similar to the LOD range, this is added
+to the array index which is used for sampling.
 
 * ``set_fragment_sampler_views`` binds an array of sampler views to
   fragment shader stage. Every binding point acquires a reference
@@ -103,6 +110,22 @@ the LOD range the texture is going to be constrained to.
 * ``sampler_view_destroy`` destroys a sampler view and releases its reference
   to associated texture.
 
+Surfaces
+^^^^^^^^
+
+These are the means to use resources as color render targets or depthstencil
+attachments. To create one, specify the mip level, the range of layers, and
+the bind flags (either PIPE_BIND_DEPTH_STENCIL or PIPE_BIND_RENDER_TARGET).
+Note that layer values are in addition to what is indicated by the geometry
+shader output variable XXX_FIXME (that is if first_layer is 3 and geometry
+shader indicates index 2, the 5th layer of the resource will be used). These
+first_layer and last_layer parameters will only be used for 1d array, 2d array,
+cube, and 3d textures otherwise they are 0.
+
+* ``create_surface`` creates a new surface.
+
+* ``surface_destroy`` destroys a surface and releases its reference to the
+  associated resource.
 
 Clearing
 ^^^^^^^^
@@ -118,8 +141,7 @@ used by GL), and always clears the whole surfaces (no scissoring as used by
 GL clear or explicit rectangles like d3d9 uses). It can, however, also clear
 only depth or stencil in a combined depth/stencil surface, if the driver
 supports PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE.
-If a surface includes several layers/slices (XXX: not yet...) then all layers
-will be cleared.
+If a surface includes several layers then all layers will be cleared.
 
 ``clear_render_target`` clears a single color rendertarget with the specified
 color value. While it is only possible to clear one surface at a time (which can
@@ -271,12 +293,12 @@ These methods operate directly on ``pipe_resource`` objects, and stand
 apart from any 3D state in the context.  Blitting functionality may be
 moved to a separate abstraction at some point in the future.
 
-``resource_copy_region`` blits a region of a subresource of a resource to a
-region of another subresource of a resource, provided that both resources have
-the same format, or compatible formats, i.e., formats for which copying the
-bytes from the source resource unmodified to the destination resource will
-achieve the same effect of a textured quad blitter. The source and destination
-may be the same resource, but overlapping blits are not permitted.
+``resource_copy_region`` blits a region of a resource to a region of another
+resource, provided that both resources have the same format, or compatible
+formats, i.e., formats for which copying the bytes from the source resource
+unmodified to the destination resource will achieve the same effect of a
+textured quad blitter.. The source and destination may be the same resource,
+but overlapping blits are not permitted.
 
 ``resource_resolve`` resolves a multisampled resource into a non-multisampled
 one. Formats and dimensions must match. This function must be present if a driver
index acde56eafc493d6ad3674894beebf4aeb2723a4a..c749d0c95561b8c61d7ebbdfc69467752eff0911 100644 (file)
@@ -22,6 +22,14 @@ Glossary
       Level of Detail. Also spelled "LoD." The value that determines when the
       switches between mipmaps occur during texture sampling.
 
+   layer
+      This term is used as the name of the "3rd coordinate" of a resource.
+      3D textures have zslices, cube maps have faces, 1D and 2D array textures
+      have array members (other resources do not have multiple layers).
+      Since the functions only take one parameter no matter what type of
+      resource is used, use the term "layer" instead of a resource type
+      specific one.
+
    GLSL
       GL Shading Language. The official, common high-level shader language used
       in GL 2.0 and above.
index e3ef49c862c3f290eeb0150a49d39ce4193137bc..09edbaa673d08bcb61f4a364a1287cdd8027b49b 100644 (file)
@@ -258,25 +258,33 @@ resource_create
 Create a new resource from a template.
 The following fields of the pipe_resource must be specified in the template:
 
-target
+**target** one of the pipe_texture_target enums.
+Note that PIPE_BUFFER and PIPE_TEXTURE_X are not really fundamentally different.
+Modern APIs allow using buffers as shader resources.
 
-format
+**format** one of the pipe_format enums.
 
-width0
+**width0** the width of the base mip level of the texture or size of the buffer.
 
-height0
+**height0** the height of the base mip level of the texture
+(1 for 1D or 1D array textures).
 
-depth0
+**depth0** the depth of the base mip level of the texture
+(1 for everything else).
 
-last_level
+**array_size the array size for 1D and 2D array textures.
+For cube maps this must be 6, for other textures 1.
 
-nr_samples
+**last_level** the last mip map level present.
 
-usage
+**nr_samples** the nr of msaa samples. 0 (or 1) specifies a resource
+which isn't multisampled.
 
-bind
+**usage** one of the PIPE_USAGE flags.
 
-flags
+**bind** bitmask of the PIPE_BIND flags.
+
+**flags** bitmask of PIPE_RESOURCE_FLAG flags.
 
 
 
index 143eca848f1813d36ad02408e5cc5c34187d8ce2..b6b3a700cda8ce8154ab85366d226c2c4570bfbd 100644 (file)
@@ -100,8 +100,8 @@ static const struct debug_named_value cell_debug_flags[] = {
 
 static unsigned int
 cell_is_resource_referenced( struct pipe_context *pipe,
-                           struct pipe_resource *texture,
-                           unsigned face, unsigned level)
+                             struct pipe_resource *texture,
+                             unsigned level, int layer)
 {
    /**
     * FIXME: Optimize.
index b3042df77922c556948e7e85e5deb686f16756ca..946a7050e5fe7b1103715bd2ab5ecf1d89dc91e4 100644 (file)
@@ -304,47 +304,34 @@ untwiddle_image_uint(uint w, uint h, uint tile_size, uint *dst,
 
 
 static struct pipe_surface *
-cell_get_tex_surface(struct pipe_screen *screen,
-                     struct pipe_resource *pt,
-                     unsigned face, unsigned level, unsigned zslice,
-                     unsigned usage)
+cell_create_surface(struct pipe_context *ctx,
+                    struct pipe_resource *pt,
+                    const struct pipe_surface *surf_tmpl)
 {
    struct cell_resource *ct = cell_resource(pt);
    struct pipe_surface *ps;
 
+   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
    ps = CALLOC_STRUCT(pipe_surface);
    if (ps) {
       pipe_reference_init(&ps->reference, 1);
       pipe_resource_reference(&ps->texture, pt);
-      ps->format = pt->format;
-      ps->width = u_minify(pt->width0, level);
-      ps->height = u_minify(pt->height0, level);
-      ps->offset = ct->level_offset[level];
+      ps->format = surf_tmpl->format;
+      ps->context = ctx;
+      ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
+      ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
       /* XXX may need to override usage flags (see sp_texture.c) */
-      ps->usage = usage;
-      ps->face = face;
-      ps->level = level;
-      ps->zslice = zslice;
-
-      if (pt->target == PIPE_TEXTURE_CUBE) {
-         unsigned h_tile = align(ps->height, TILE_SIZE);
-         ps->offset += face * util_format_get_nblocksy(ps->format, h_tile) * ct->stride[level];
-      }
-      else if (pt->target == PIPE_TEXTURE_3D) {
-         unsigned h_tile = align(ps->height, TILE_SIZE);
-         ps->offset += zslice * util_format_get_nblocksy(ps->format, h_tile) * ct->stride[level];
-      }
-      else {
-         assert(face == 0);
-         assert(zslice == 0);
-      }
+      ps->usage = surf_tmpl->usage;
+      ps->u.tex.level = surf_tmpl->u.tex.level;
+      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
    }
    return ps;
 }
 
 
 static void 
-cell_tex_surface_destroy(struct pipe_surface *surf)
+cell_surface_destroy(struct pipe_context *ctx, struct pipe_surface *surf)
 {
    pipe_resource_reference(&surf->texture, NULL);
    FREE(surf);
@@ -358,44 +345,39 @@ cell_tex_surface_destroy(struct pipe_surface *surf)
  */
 static struct pipe_transfer *
 cell_get_transfer(struct pipe_context *ctx,
-                 struct pipe_resource *resource,
-                 struct pipe_subresource sr,
-                 unsigned usage,
-                 const struct pipe_box *box)
+                  struct pipe_resource *resource,
+                  unsigned level,
+                  unsigned usage,
+                  const struct pipe_box *box)
 {
    struct cell_resource *ct = cell_resource(resource);
    struct cell_transfer *ctrans;
    enum pipe_format format = resource->format;
 
    assert(resource);
-   assert(sr.level <= resource->last_level);
+   assert(level <= resource->last_level);
 
    /* make sure the requested region is in the image bounds */
-   assert(box->x + box->width <= u_minify(resource->width0, sr.level));
-   assert(box->y + box->height <= u_minify(resource->height0, sr.level));
-   assert(box->z + box->depth <= u_minify(resource->depth0, sr.level));
+   assert(box->x + box->width <= u_minify(resource->width0, level));
+   assert(box->y + box->height <= u_minify(resource->height0, level));
+   assert(box->z + box->depth <= (u_minify(resource->depth0, level) + resource->array_size - 1));
 
    ctrans = CALLOC_STRUCT(cell_transfer);
    if (ctrans) {
       struct pipe_transfer *pt = &ctrans->base;
       pipe_resource_reference(&pt->resource, resource);
-      pt->sr = sr;
+      pt->level = level;
       pt->usage = usage;
       pt->box = *box;
-      pt->stride = ct->stride[sr.level];
+      pt->stride = ct->stride[level];
 
-      ctrans->offset = ct->level_offset[sr.level];
+      ctrans->offset = ct->level_offset[level];
 
-      if (resource->target == PIPE_TEXTURE_CUBE) {
-         unsigned h_tile = align(u_minify(resource->height0, sr.level), TILE_SIZE);
-         ctrans->offset += sr.face * util_format_get_nblocksy(format, h_tile) * pt->stride;
-      }
-      else if (resource->target == PIPE_TEXTURE_3D) {
-         unsigned h_tile = align(u_minify(resource->height0, sr.level), TILE_SIZE);
+      if (resource->target == PIPE_TEXTURE_CUBE || resource->target == PIPE_TEXTURE_3D) {
+         unsigned h_tile = align(u_minify(resource->height0, level), TILE_SIZE);
          ctrans->offset += box->z * util_format_get_nblocksy(format, h_tile) * pt->stride;
       }
       else {
-         assert(sr.face == 0);
          assert(box->z == 0);
       }
 
@@ -439,7 +421,7 @@ cell_transfer_map(struct pipe_context *ctx, struct pipe_transfer *transfer)
    /* Better test would be resource->is_linear
     */
    if (transfer->resource->target != PIPE_BUFFER) {
-      const uint level = ctrans->base.sr.level;
+      const uint level = ctrans->base.level;
       const uint texWidth = u_minify(pt->width0, level);
       const uint texHeight = u_minify(pt->height0, level);
       unsigned size;
@@ -500,7 +482,7 @@ cell_transfer_unmap(struct pipe_context *ctx,
    struct cell_transfer *ctrans = cell_transfer(transfer);
    struct pipe_resource *pt = transfer->resource;
    struct cell_resource *ct = cell_resource(pt);
-   const uint level = ctrans->base.sr.level;
+   const uint level = ctrans->base.level;
    const uint texWidth = u_minify(pt->width0, level);
    const uint texHeight = u_minify(pt->height0, level);
    const uint stride = ct->stride[level];
@@ -548,12 +530,13 @@ cell_transfer_unmap(struct pipe_context *ctx,
  */
 static void
 cell_flush_frontbuffer(struct pipe_screen *_screen,
-                       struct pipe_surface *surface,
+                       struct pipe_resource *resource,
+                       unsigned level, unsigned layer,
                        void *context_private)
 {
    struct cell_screen *screen = cell_screen(_screen);
    struct sw_winsys *winsys = screen->winsys;
-   struct cell_resource *ct = cell_resource(surface->texture);
+   struct cell_resource *ct = cell_resource(resource);
 
    if (!ct->dt)
       return;
@@ -564,10 +547,10 @@ cell_flush_frontbuffer(struct pipe_screen *_screen,
       unsigned *map = winsys->displaytarget_map(winsys, ct->dt,
                                                 (PIPE_TRANSFER_READ |
                                                  PIPE_TRANSFER_WRITE));
-      unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]);
+      unsigned *src = (unsigned *)(ct->data + ct->level_offset[level]);
 
-      untwiddle_image_uint(surface->width,
-                           surface->height,
+      untwiddle_image_uint(u_minify(resource->width0, level),
+                           u_minify(resource->height0, level),
                            TILE_SIZE,
                            map,
                            ct->dt_stride,
@@ -605,6 +588,7 @@ cell_user_buffer_create(struct pipe_screen *screen,
    buffer->base.width0 = bytes;
    buffer->base.height0 = 1;
    buffer->base.depth0 = 1;
+   buffer->base.array_size = 1;
    buffer->userBuffer = TRUE;
    buffer->data = ptr;
 
@@ -641,9 +625,6 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen)
    screen->resource_get_handle = cell_resource_get_handle;
    screen->user_buffer_create = cell_user_buffer_create;
 
-   screen->get_tex_surface = cell_get_tex_surface;
-   screen->tex_surface_destroy = cell_tex_surface_destroy;
-
    screen->flush_frontbuffer = cell_flush_frontbuffer;
 }
 
@@ -657,4 +638,7 @@ cell_init_texture_transfer_funcs(struct cell_context *cell)
 
    cell->pipe.transfer_flush_region = u_default_transfer_flush_region;
    cell->pipe.transfer_inline_write = u_default_transfer_inline_write;
+
+   cell->pipe.create_surface = cell_create_surface;
+   cell->pipe.surface_destroy = cell_surface_destroy;
 }
index ec3609291e9a51e423a79905e1c1a9ba8e776481..e4d289c8a4d1b10ded434bc9cdad30e5b011413a 100644 (file)
@@ -89,14 +89,14 @@ static void failover_draw_vbo( struct pipe_context *pipe,
 
 static unsigned int
 failover_is_resource_referenced( struct pipe_context *_pipe,
-                                struct pipe_resource *resource,
-                                unsigned face, unsigned level)
+                                 struct pipe_resource *resource,
+                                 unsigned level, int layer)
 {
    struct failover_context *failover = failover_context( _pipe );
    struct pipe_context *pipe = (failover->mode == FO_HW) ?
       failover->hw : failover->sw;
 
-   return pipe->is_resource_referenced(pipe, resource, face, level);
+   return pipe->is_resource_referenced(pipe, resource, level, layer);
 }
 
 struct pipe_context *failover_create( struct pipe_context *hw,
@@ -137,10 +137,10 @@ struct pipe_context *failover_create( struct pipe_context *hw,
    failover->pipe.resource_copy_region = hw->resource_copy_region;
 
 #if 0
-   failover->pipe.texture_create = hw->texture_create;
-   failover->pipe.texture_destroy = hw->texture_destroy;
-   failover->pipe.get_tex_surface = hw->get_tex_surface;
-   failover->pipe.texture_update = hw->texture_update;
+   failover->pipe.resource_create = hw->resource_create;
+   failover->pipe.resource_destroy = hw->resource_destroy;
+   failover->pipe.create_surface = hw->create_surface;
+   failover->pipe.surface_destroy = hw->surface_destroy;
 #endif
 
    failover->pipe.flush = hw->flush;
index 50f66079c2a5e7c50175109ce1e63be1e2ec14a4..a572ad22bd01e0d77bf68c0485a5bf562ca7ac98 100644 (file)
@@ -662,17 +662,13 @@ galahad_set_index_buffer(struct pipe_context *_pipe,
 static void
 galahad_resource_copy_region(struct pipe_context *_pipe,
                               struct pipe_resource *_dst,
-                              struct pipe_subresource subdst,
+                              unsigned dst_level,
                               unsigned dstx,
                               unsigned dsty,
                               unsigned dstz,
                               struct pipe_resource *_src,
-                              struct pipe_subresource subsrc,
-                              unsigned srcx,
-                              unsigned srcy,
-                              unsigned srcz,
-                              unsigned width,
-                              unsigned height)
+                              unsigned src_level,
+                              const struct pipe_box *src_box)
 {
    struct galahad_context *glhd_pipe = galahad_context(_pipe);
    struct galahad_resource *glhd_resource_dst = galahad_resource(_dst);
@@ -689,17 +685,13 @@ galahad_resource_copy_region(struct pipe_context *_pipe,
 
    pipe->resource_copy_region(pipe,
                               dst,
-                              subdst,
+                              dst_level,
                               dstx,
                               dsty,
                               dstz,
                               src,
-                              subsrc,
-                              srcx,
-                              srcy,
-                              srcz,
-                              width,
-                              height);
+                              src_level,
+                              src_box);
 }
 
 static void
@@ -781,8 +773,8 @@ galahad_flush(struct pipe_context *_pipe,
 static unsigned int
 galahad_is_resource_referenced(struct pipe_context *_pipe,
                                 struct pipe_resource *_resource,
-                                unsigned face,
-                                unsigned level)
+                                unsigned level,
+                                int layer)
 {
    struct galahad_context *glhd_pipe = galahad_context(_pipe);
    struct galahad_resource *glhd_resource = galahad_resource(_resource);
@@ -791,8 +783,8 @@ galahad_is_resource_referenced(struct pipe_context *_pipe,
 
    return pipe->is_resource_referenced(pipe,
                                        resource,
-                                       face,
-                                       level);
+                                       level,
+                                       layer);
 }
 
 static struct pipe_sampler_view *
@@ -823,10 +815,40 @@ galahad_context_sampler_view_destroy(struct pipe_context *_pipe,
                                  galahad_sampler_view(_view));
 }
 
+static struct pipe_surface *
+galahad_context_create_surface(struct pipe_context *_pipe,
+                                struct pipe_resource *_resource,
+                                const struct pipe_surface *templ)
+{
+   struct galahad_context *glhd_context = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_context *pipe = glhd_context->pipe;
+   struct pipe_resource *resource = glhd_resource->resource;
+   struct pipe_surface *result;
+
+   result = pipe->create_surface(pipe,
+                                 resource,
+                                 templ);
+
+   if (result)
+      return galahad_surface_create(glhd_context, glhd_resource, result);
+   return NULL;
+}
+
+static void
+galahad_context_surface_destroy(struct pipe_context *_pipe,
+                                struct pipe_surface *_surface)
+{
+   galahad_surface_destroy(galahad_context(_pipe),
+                           galahad_surface(_surface));
+}
+
+
+
 static struct pipe_transfer *
 galahad_context_get_transfer(struct pipe_context *_context,
                               struct pipe_resource *_resource,
-                              struct pipe_subresource sr,
+                              unsigned level,
                               unsigned usage,
                               const struct pipe_box *box)
 {
@@ -838,7 +860,7 @@ galahad_context_get_transfer(struct pipe_context *_context,
 
    result = context->get_transfer(context,
                                   resource,
-                                  sr,
+                                  level,
                                   usage,
                                   box);
 
@@ -915,7 +937,7 @@ galahad_context_transfer_unmap(struct pipe_context *_context,
 static void
 galahad_context_transfer_inline_write(struct pipe_context *_context,
                                        struct pipe_resource *_resource,
-                                       struct pipe_subresource sr,
+                                       unsigned level,
                                        unsigned usage,
                                        const struct pipe_box *box,
                                        const void *data,
@@ -929,7 +951,7 @@ galahad_context_transfer_inline_write(struct pipe_context *_context,
 
    context->transfer_inline_write(context,
                                   resource,
-                                  sr,
+                                  level,
                                   usage,
                                   box,
                                   data,
@@ -1004,6 +1026,8 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    glhd_pipe->base.is_resource_referenced = galahad_is_resource_referenced;
    glhd_pipe->base.create_sampler_view = galahad_context_create_sampler_view;
    glhd_pipe->base.sampler_view_destroy = galahad_context_sampler_view_destroy;
+   glhd_pipe->base.create_surface = galahad_context_create_surface;
+   glhd_pipe->base.surface_destroy = galahad_context_surface_destroy;
    glhd_pipe->base.get_transfer = galahad_context_get_transfer;
    glhd_pipe->base.transfer_destroy = galahad_context_transfer_destroy;
    glhd_pipe->base.transfer_map = galahad_context_transfer_map;
index 6c5a21ae704900ad85702d619a7704fc79572150..b50d85655e8e453ab80c35349d419e08d0e104fc 100644 (file)
@@ -71,7 +71,8 @@ galahad_resource_destroy(struct galahad_resource *glhd_resource)
 
 
 struct pipe_surface *
-galahad_surface_create(struct galahad_resource *glhd_resource,
+galahad_surface_create(struct galahad_context *glhd_context,
+                        struct galahad_resource *glhd_resource,
                         struct pipe_surface *surface)
 {
    struct galahad_surface *glhd_surface;
@@ -100,10 +101,11 @@ error:
 }
 
 void
-galahad_surface_destroy(struct galahad_surface *glhd_surface)
+galahad_surface_destroy(struct galahad_context *glhd_context,
+                         struct galahad_surface *glhd_surface)
 {
    pipe_resource_reference(&glhd_surface->base.texture, NULL);
-   pipe_surface_reference(&glhd_surface->surface, NULL);
+   glhd_context->pipe->surface_destroy(glhd_context->pipe, glhd_surface->surface);
    FREE(glhd_surface);
 }
 
index dc74c5bebc9635f170f781240ef5a6816bd3b275..13dc7485887877ed5b56c7e7d2682b09a3a27178 100644 (file)
@@ -149,11 +149,13 @@ void
 galahad_resource_destroy(struct galahad_resource *glhd_resource);
 
 struct pipe_surface *
-galahad_surface_create(struct galahad_resource *glhd_resource,
+galahad_surface_create(struct galahad_context *glhd_context,
+                       struct galahad_resource *glhd_resource,
                         struct pipe_surface *surface);
 
 void
-galahad_surface_destroy(struct galahad_surface *glhd_surface);
+galahad_surface_destroy(struct galahad_context *glhd_context,
+                         struct galahad_surface *glhd_surface);
 
 struct pipe_sampler_view *
 galahad_sampler_view_create(struct galahad_context *glhd_context,
index b6cc41d908be607ab332c67285d7c45ed81eb7cf..b4825bef66dafb04609b78b22527b360fc062d4f 100644 (file)
@@ -223,39 +223,6 @@ galahad_screen_resource_destroy(struct pipe_screen *screen,
    galahad_resource_destroy(galahad_resource(_resource));
 }
 
-static struct pipe_surface *
-galahad_screen_get_tex_surface(struct pipe_screen *_screen,
-                                struct pipe_resource *_resource,
-                                unsigned face,
-                                unsigned level,
-                                unsigned zslice,
-                                unsigned usage)
-{
-   struct galahad_screen *glhd_screen = galahad_screen(_screen);
-   struct galahad_resource *glhd_resource = galahad_resource(_resource);
-   struct pipe_screen *screen = glhd_screen->screen;
-   struct pipe_resource *resource = glhd_resource->resource;
-   struct pipe_surface *result;
-
-   result = screen->get_tex_surface(screen,
-                                    resource,
-                                    face,
-                                    level,
-                                    zslice,
-                                    usage);
-
-   if (result)
-      return galahad_surface_create(glhd_resource, result);
-   return NULL;
-}
-
-static void
-galahad_screen_tex_surface_destroy(struct pipe_surface *_surface)
-{
-   galahad_surface_destroy(galahad_surface(_surface));
-}
-
-
 
 static struct pipe_resource *
 galahad_screen_user_buffer_create(struct pipe_screen *_screen,
@@ -281,16 +248,18 @@ galahad_screen_user_buffer_create(struct pipe_screen *_screen,
 
 static void
 galahad_screen_flush_frontbuffer(struct pipe_screen *_screen,
-                                  struct pipe_surface *_surface,
+                                  struct pipe_resource *_resource,
+                                  unsigned level, unsigned layer,
                                   void *context_private)
 {
    struct galahad_screen *glhd_screen = galahad_screen(_screen);
-   struct galahad_surface *glhd_surface = galahad_surface(_surface);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
    struct pipe_screen *screen = glhd_screen->screen;
-   struct pipe_surface *surface = glhd_surface->surface;
+   struct pipe_resource *resource = glhd_resource->resource;
 
    screen->flush_frontbuffer(screen,
-                             surface,
+                             resource,
+                             level, layer,
                              context_private);
 }
 
@@ -360,8 +329,6 @@ galahad_screen_create(struct pipe_screen *screen)
    glhd_screen->base.resource_from_handle = galahad_screen_resource_from_handle;
    glhd_screen->base.resource_get_handle = galahad_screen_resource_get_handle;
    glhd_screen->base.resource_destroy = galahad_screen_resource_destroy;
-   glhd_screen->base.get_tex_surface = galahad_screen_get_tex_surface;
-   glhd_screen->base.tex_surface_destroy = galahad_screen_tex_surface_destroy;
    glhd_screen->base.user_buffer_create = galahad_screen_user_buffer_create;
    glhd_screen->base.flush_frontbuffer = galahad_screen_flush_frontbuffer;
    glhd_screen->base.fence_reference = galahad_screen_fence_reference;
diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO
new file mode 100644 (file)
index 0000000..94c428b
--- /dev/null
@@ -0,0 +1,25 @@
+Random list of problems with i915g:
+
+- Dies with BadDrawable on GLXFBconfig changes/destruction. Makes piglit totally
+  unusable :( Upgrading xserver helped here, it doesn't crash anymore. Still
+  broken, it doesn't update the viewport/get new buffers.
+
+- Tends to hang the chip after a few minutes of openarena. Looks tiling related,
+  at the last frame rendered has tiling corruption over the complete frame.
+
+- Kills the chip in 3D_PRIMITIVE LINELIST with mesa-demos/fbotexture in
+  wireframe mode.
+
+- Tiling is funny: If unlucky, it renders/samples all black. No clue yet what's
+  going on. Seems to depend on tiny details like whethever the sampler
+  relocation is fenced/unfenced (broken _with_ fenced reloc using tiling bits!).
+
+- Y-tiling is even more fun. i915c doesn't use it, maybe there's a reason?
+  Texture sampling from Y-tiled buffers seems to work, though (save above
+  problems).
+
+- Need to validate buffers before usage. Currently do_exec on the batchbuffer
+  can fail with -ENOSPC.
+
+Other bugs can be found here:
+https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g
index c411b84ccd4756f72b5c8a0f9248d42c20f34f61..6e93da76209937aab21c556be8cdcf1eb4520149 100644 (file)
    i915_winsys_batchbuffer_dword(i915->batch, dword)
 
 #define OUT_RELOC(buf, usage, offset) \
-   i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset)
+   i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, false)
+
+#define OUT_RELOC_FENCED(buf, usage, offset) \
+   i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, true)
 
 #define FLUSH_BATCH(fence) \
    i915_flush(i915, fence)
index c1cd314e7b8aca94664ebd2c9b7f0166cd3ce3c8..d92b2ccb31effd846aebfd0a0b4915e7719a609a 100644 (file)
 #define I915_BATCHBUFFER_H
 
 #include "i915_winsys.h"
+#include "util/u_debug.h"
 
 struct i915_context;
 
+static INLINE size_t
+i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
+{
+   return batch->size - (batch->ptr - batch->map);
+}
+
 static INLINE boolean
 i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch,
                               size_t dwords,
                               size_t relocs)
 {
-   return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
+   return dwords * 4 <= i915_winsys_batchbuffer_space(batch) &&
           relocs <= (batch->max_relocs - batch->relocs);
 }
 
-static INLINE size_t
-i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
+static INLINE void
+i915_winsys_batchbuffer_dword_unchecked(struct i915_winsys_batchbuffer *batch,
+                              unsigned dword)
 {
-   return batch->size - (batch->ptr - batch->map);
+   *(unsigned *)batch->ptr = dword;
+   batch->ptr += 4;
 }
 
 static INLINE void
 i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch,
                               unsigned dword)
 {
-   if (i915_winsys_batchbuffer_space(batch) < 4)
-      return;
-
-   *(unsigned *)batch->ptr = dword;
-   batch->ptr += 4;
+   assert (i915_winsys_batchbuffer_space(batch) >= 4);
+   i915_winsys_batchbuffer_dword_unchecked(batch, dword);
 }
 
 static INLINE void
 i915_winsys_batchbuffer_write(struct i915_winsys_batchbuffer *batch,
-                       void *data,
-                       size_t size)
+                             void *data,
+                             size_t size)
 {
-   if (i915_winsys_batchbuffer_space(batch) < size)
-      return;
+   assert (i915_winsys_batchbuffer_space(batch) >= size);
 
    memcpy(data, batch->ptr, size);
    batch->ptr += size;
@@ -74,9 +79,9 @@ static INLINE int
 i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch,
                               struct i915_winsys_buffer *buffer,
                               enum i915_winsys_buffer_usage usage,
-                              size_t offset)
+                              size_t offset, bool fenced)
 {
-   return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
+   return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset, fenced);
 }
 
 #endif
index cdf20c0055a73e124e34c746d55ea369d59350ff..97c256651563486ba8c541ec65af8486ff240efb 100644 (file)
@@ -74,7 +74,7 @@ i915_fill_blit(struct i915_context *i915,
    OUT_BATCH(BR13);
    OUT_BATCH((y << 16) | x);
    OUT_BATCH(((y + h) << 16) | (x + w));
-   OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
+   OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
    OUT_BATCH(color);
 }
 
@@ -138,8 +138,8 @@ i915_copy_blit(struct i915_context *i915,
    OUT_BATCH(BR13);
    OUT_BATCH((dst_y << 16) | dst_x);
    OUT_BATCH((dst_y2 << 16) | dst_x2);
-   OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
+   OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
    OUT_BATCH((src_y << 16) | src_x);
    OUT_BATCH(((int) src_pitch & 0xffff));
-   OUT_RELOC(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
+   OUT_RELOC_FENCED(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
 }
index 3ae61d0ea70c0a0cfd4a5347e80ef775ba844ac7..7103a1b8c16969695553eb89f59885fb731149b9 100644 (file)
@@ -193,8 +193,7 @@ struct i915_velems_state {
 };
 
 
-struct i915_context
-{
+struct i915_context {
    struct pipe_context base;
 
    struct i915_winsys *iws;
index 57d3390dea37d3bea34ae2116487142c086ae10a..d7150c99c4e6513bfb117dbd11e674b424128438 100644 (file)
@@ -46,10 +46,12 @@ static const struct debug_named_value debug_options[] = {
 };
 
 unsigned i915_debug = 0;
+boolean i915_tiling = TRUE;
 
 void i915_debug_init(struct i915_screen *screen)
 {
    i915_debug = debug_get_flags_option("I915_DEBUG", debug_options, 0);
+   i915_tiling = !debug_get_bool_option("I915_NO_TILING", FALSE);
 }
 
 
index fa60799d0c55669253ae9ab3ae4327764a96a54a..11af7662f0a614e75f7f9d52ae27bc336460b011 100644 (file)
@@ -46,6 +46,7 @@ struct i915_winsys_batchbuffer;
 #define DBG_CONSTANTS 0x20
 
 extern unsigned i915_debug;
+extern boolean i915_tiling;
 
 #ifdef DEBUG
 static INLINE boolean
index bd046bd9058463ecb1d9a6356aeff344cebf0c82..baebbc7bae3a471594507761fdbf1d2af4ff975a 100644 (file)
@@ -172,6 +172,7 @@ i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
  *
  * Side effects:
  *    Updates hw_offset, sw_offset, index and allocates a new buffer.
+ *    Will set i915->vbo to null on buffer allocation.
  */
 static void
 i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
@@ -179,8 +180,16 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
    struct i915_context *i915 = i915_render->i915;
    struct i915_winsys *iws = i915->iws;
 
-   if (i915_render->vbo)
+   if (i915_render->vbo) {
       iws->buffer_destroy(iws, i915_render->vbo);
+      /*
+       * XXX If buffers where referenced then this should be done in
+       * update_vbo_state but since they arn't and malloc likes to reuse
+       * memory we need to set it to null
+       */
+      i915->vbo = NULL;
+      i915_render->vbo = NULL;
+   }
 
    i915->vbo_flushed = 0;
 
@@ -198,7 +207,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
 #endif
 
    i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size,
-                                         64, I915_NEW_VERTEX);
+                                         I915_NEW_VERTEX);
 }
 
 /**
@@ -726,7 +735,7 @@ i915_vbuf_render_create(struct i915_context *i915)
    i915_render->pool_fifo = u_fifo_create(6);
    for (i = 0; i < 6; i++)
       u_fifo_add(i915_render->pool_fifo,
-                 iws->buffer_create(iws, i915_render->pool_buffer_size, 64,
+                 iws->buffer_create(iws, i915_render->pool_buffer_size,
                                     I915_NEW_VERTEX));
 #else
    (void)i;
index cc28891e4ac0e6c11710b92ac94b24d227a17346..5e4e80ddf6b2504a308bb298d5dd793ac9194294 100644 (file)
 #define    MT_COMPRESS_DXT1_RGB                   (4<<3)
 #define MS3_USE_FENCE_REGS              (1<<2)
 #define MS3_TILED_SURFACE             (1<<1)
-#define MS3_TILE_WALK                 (1<<0)
+#define MS3_TILE_WALK_Y                (1<<0)
 
 #define MS4_PITCH_SHIFT                 21
 #define MS4_CUBE_FACE_ENA_NEGX          (1<<20)
 #define MI_FLUSH                   ((0<<29)|(4<<23))
 #define FLUSH_MAP_CACHE            (1<<0)
 #define INHIBIT_FLUSH_RENDER_CACHE (1<<2)
+#define MI_NOOP                    0
 
 
 #define CMD_3D (0x3<<29)
index 753bd266b1200be43b8bed721de0c68ce231823d..86620e6a123e5926b1fca4867bc36a154258d85b 100644 (file)
@@ -49,6 +49,10 @@ struct i915_buffer {
 #define I915_MAX_TEXTURE_3D_LEVELS  8  /* max 128x128x128 */
 
 
+struct offset_pair {
+       unsigned short nblocksx;
+       unsigned short nblocksy;
+};
 
 struct i915_texture {
    struct u_resource b;
@@ -63,14 +67,18 @@ struct i915_texture {
 
    /* Explicitly store the offset of each image for each cube face or
     * depth value.
+    *
+    * Array [depth] off offsets.
     */
-   unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS];   /**< array [depth] of offsets */
+   struct offset_pair *image_offset[I915_MAX_TEXTURE_2D_LEVELS];
 
    /* The data is held here:
     */
    struct i915_winsys_buffer *buffer;
 };
 
+unsigned i915_texture_offset(struct i915_texture *tex,
+                             unsigned level, unsigned layer);
 void i915_init_screen_resource_functions(struct i915_screen *is);
 void i915_init_resource_functions(struct i915_context *i915);
 
index 0d379497dfc1329f551444a2d2c478d47743482f..450203d60a9700e3a854675ceeda2bbcc5c747ff 100644 (file)
@@ -62,7 +62,7 @@ i915_buffer_destroy(struct pipe_screen *screen,
 
 static void *
 i915_buffer_transfer_map( struct pipe_context *pipe,
-                         struct pipe_transfer *transfer )
+                          struct pipe_transfer *transfer )
 {
    struct i915_buffer *buffer = i915_buffer(transfer->resource);
    return buffer->data + transfer->box.x;
@@ -71,19 +71,19 @@ i915_buffer_transfer_map( struct pipe_context *pipe,
 
 static void
 i915_buffer_transfer_inline_write( struct pipe_context *rm_ctx,
-                                  struct pipe_resource *resource,
-                                  struct pipe_subresource sr,
-                                  unsigned usage,
-                                  const struct pipe_box *box,
-                                  const void *data,
-                                  unsigned stride,
-                                  unsigned slice_stride)
+                                   struct pipe_resource *resource,
+                                   unsigned level,
+                                   unsigned usage,
+                                   const struct pipe_box *box,
+                                   const void *data,
+                                   unsigned stride,
+                                   unsigned layer_stride)
 {
    struct i915_buffer *buffer = i915_buffer(resource);
 
    memcpy(buffer->data + box->x,
-         data,
-         box->width);
+          data,
+          box->width);
 }
 
 
@@ -115,7 +115,7 @@ i915_buffer_create(struct pipe_screen *screen,
    buf->b.vtbl = &i915_buffer_vtbl;
    pipe_reference_init(&buf->b.b.reference, 1);
    buf->b.b.screen = screen;
-   
+
    buf->data = MALLOC(template->width0);
    buf->free_on_destroy = TRUE;
 
@@ -135,7 +135,7 @@ struct pipe_resource *
 i915_user_buffer_create(struct pipe_screen *screen,
                         void *ptr,
                         unsigned bytes,
-                       unsigned bind)
+                        unsigned bind)
 {
    struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
 
@@ -152,6 +152,7 @@ i915_user_buffer_create(struct pipe_screen *screen,
    buf->b.b.width0 = bytes;
    buf->b.b.height0 = 1;
    buf->b.b.depth0 = 1;
+   buf->b.b.array_size = 1;
 
    buf->data = ptr;
    buf->free_on_destroy = FALSE;
index d45346b32ada1433e1c1dd777988a4a78c6796d7..f19106f3414a65825ff7acf88ed22928ee9362e2 100644 (file)
@@ -106,6 +106,23 @@ get_pot_stride(enum pipe_format format, unsigned width)
    return util_next_power_of_two(util_format_get_stride(format, width));
 }
 
+static INLINE const char*
+get_tiling_string(enum i915_winsys_buffer_tile tile)
+{
+   switch(tile) {
+   case I915_TILE_NONE:
+      return "none";
+   case I915_TILE_X:
+      return "x";
+   case I915_TILE_Y:
+      return "y";
+   default:
+      assert(FALSE);
+      return "?";
+   }
+}
+
+
 /*
  * More advanced helper funcs
  */
@@ -120,28 +137,56 @@ i915_texture_set_level_info(struct i915_texture *tex,
    assert(!tex->image_offset[level]);
 
    tex->nr_images[level] = nr_images;
-   tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
-   tex->image_offset[level][0] = 0;
+   tex->image_offset[level] = MALLOC(nr_images * sizeof(struct offset_pair));
+   tex->image_offset[level][0].nblocksx = 0;
+   tex->image_offset[level][0].nblocksy = 0;
+}
+
+INLINE unsigned i915_texture_offset(struct i915_texture *tex,
+                                    unsigned level, unsigned layer)
+{
+   unsigned x, y;
+   x = tex->image_offset[level][layer].nblocksx
+      * util_format_get_blocksize(tex->b.b.format);
+   y = tex->image_offset[level][layer].nblocksy;
+
+   return y * tex->stride + x;
 }
 
 static void
 i915_texture_set_image_offset(struct i915_texture *tex,
                               unsigned level, unsigned img,
-                              unsigned x, unsigned y)
+                              unsigned nblocksx, unsigned nblocksy)
 {
    /* for the first image and level make sure offset is zero */
-   assert(!(img == 0 && level == 0) || (x == 0 && y == 0));
+   assert(!(img == 0 && level == 0) || (nblocksx == 0 && nblocksy == 0));
    assert(img < tex->nr_images[level]);
 
-   tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->b.b.format);
+   tex->image_offset[level][img].nblocksx = nblocksx;
+   tex->image_offset[level][img].nblocksy = nblocksy;
 
 #if DEBUG_TEXTURES
-   debug_printf("%s: %p level %u, img %u (%u, %u) %p\n", __FUNCTION__,
-                tex, level, img, x, y,
-                (void*)(uintptr_t)tex->image_offset[level][img]);
+   debug_printf("%s: %p level %u, img %u (%u, %u)\n", __FUNCTION__,
+                tex, level, img, x, y);
 #endif
 }
 
+static enum i915_winsys_buffer_tile
+i915_texture_tiling(struct pipe_resource *pt)
+{
+   if (!i915_tiling)
+      return I915_TILE_NONE;
+
+   if (pt->target == PIPE_TEXTURE_1D)
+      return I915_TILE_NONE;
+
+   if (util_format_is_s3tc(pt->format))
+      /* XXX X-tiling might make sense */
+      return I915_TILE_NONE;
+
+   return I915_TILE_X;
+}
+
 
 /*
  * Shared layout functions
@@ -163,9 +208,10 @@ i9x5_scanout_layout(struct i915_texture *tex)
    i915_texture_set_image_offset(tex, 0, 0, 0, 0);
 
    if (pt->width0 >= 240) {
-      tex->stride = get_pot_stride(pt->format, pt->width0);
+      tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64);
       tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
       tex->tiling = I915_TILE_X;
+   /* special case for cursors */
    } else if (pt->width0 == 64 && pt->height0 == 64) {
       tex->stride = get_pot_stride(pt->format, pt->width0);
       tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
@@ -200,7 +246,7 @@ i9x5_display_target_layout(struct i915_texture *tex)
    i915_texture_set_level_info(tex, 0, 1);
    i915_texture_set_image_offset(tex, 0, 0, 0, 0);
 
-   tex->stride = get_pot_stride(pt->format, pt->width0);
+   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64);
    tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
    tex->tiling = I915_TILE_X;
 
@@ -357,6 +403,8 @@ i915_texture_layout(struct i915_texture * tex)
 {
    struct pipe_resource *pt = &tex->b.b;
 
+   tex->tiling = i915_texture_tiling(pt);
+
    switch (pt->target) {
    case PIPE_TEXTURE_1D:
    case PIPE_TEXTURE_2D:
@@ -603,6 +651,8 @@ i945_texture_layout(struct i915_texture * tex)
 {
    struct pipe_resource *pt = &tex->b.b;
 
+   tex->tiling = i915_texture_tiling(pt);
+
    switch (pt->target) {
    case PIPE_TEXTURE_1D:
    case PIPE_TEXTURE_2D:
@@ -650,7 +700,7 @@ i915_texture_get_handle(struct pipe_screen * screen,
 
 static void
 i915_texture_destroy(struct pipe_screen *screen,
-                    struct pipe_resource *pt)
+                     struct pipe_resource *pt)
 {
    struct i915_texture *tex = i915_texture(pt);
    struct i915_winsys *iws = i915_screen(screen)->iws;
@@ -667,10 +717,10 @@ i915_texture_destroy(struct pipe_screen *screen,
 
 static struct pipe_transfer * 
 i915_texture_get_transfer(struct pipe_context *context,
-                         struct pipe_resource *resource,
-                         struct pipe_subresource sr,
-                         unsigned usage,
-                         const struct pipe_box *box)
+                          struct pipe_resource *resource,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box)
 {
    struct i915_texture *tex = i915_texture(resource);
    struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
@@ -678,37 +728,31 @@ i915_texture_get_transfer(struct pipe_context *context,
       return NULL;
 
    transfer->resource = resource;
-   transfer->sr = sr;
+   transfer->level = level;
    transfer->usage = usage;
    transfer->box = *box;
    transfer->stride = tex->stride;
+   /* FIXME: layer_stride */
 
    return transfer;
 }
 
-
 static void *
 i915_texture_transfer_map(struct pipe_context *pipe,
-                         struct pipe_transfer *transfer)
+                          struct pipe_transfer *transfer)
 {
    struct pipe_resource *resource = transfer->resource;
    struct i915_texture *tex = i915_texture(resource);
    struct i915_winsys *iws = i915_screen(pipe->screen)->iws;
-   struct pipe_subresource sr = transfer->sr;
    struct pipe_box *box = &transfer->box;
    enum pipe_format format = resource->format;
    unsigned offset;
    char *map;
 
-   if (resource->target == PIPE_TEXTURE_CUBE) {
-      offset = tex->image_offset[sr.level][sr.face];
-   } else if (resource->target == PIPE_TEXTURE_3D) {
-      offset = tex->image_offset[sr.level][box->z];
-   } else {
-      offset = tex->image_offset[sr.level][0];
-      assert(sr.face == 0);
+   if (resource->target != PIPE_TEXTURE_3D &&
+       resource->target != PIPE_TEXTURE_CUBE)
       assert(box->z == 0);
-   }
+   offset = i915_texture_offset(tex, transfer->level, box->z);
 
    map = iws->buffer_map(iws, tex->buffer,
                          (transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
@@ -754,7 +798,6 @@ i915_texture_create(struct pipe_screen *screen,
    struct i915_screen *is = i915_screen(screen);
    struct i915_winsys *iws = is->iws;
    struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
-   size_t tex_size;
    unsigned buf_usage = 0;
 
    if (!tex)
@@ -773,8 +816,6 @@ i915_texture_create(struct pipe_screen *screen,
          goto fail;
    }
 
-   tex_size = tex->stride * tex->total_nblocksy;
-
    /* for scanouts and cursors, cursors arn't scanouts */
 
    /* XXX: use a custom flag for cursors, don't rely on magically
@@ -785,27 +826,15 @@ i915_texture_create(struct pipe_screen *screen,
    else
       buf_usage = I915_NEW_TEXTURE;
 
-   tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
+   tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
+                                         &tex->tiling, buf_usage);
    if (!tex->buffer)
       goto fail;
 
-   /* setup any hw fences */
-   if (tex->tiling) {
-      iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->tiling);
-   }
-
-   
-#if 0
-   void *ptr = ws->buffer_map(ws, tex->buffer,
-      PIPE_BUFFER_USAGE_CPU_WRITE);
-   memset(ptr, 0x80, tex_size);
-   ws->buffer_unmap(ws, tex->buffer);
-#endif
-
-   I915_DBG(DBG_TEXTURE, "%s: %p size %u, stride %u, blocks (%u, %u)\n", __func__,
-            tex, (unsigned int)tex_size, tex->stride,
+   I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u) tiling %s\n", __func__,
+            tex, tex->stride,
             tex->stride / util_format_get_blocksize(tex->b.b.format),
-            tex->total_nblocksy);
+            tex->total_nblocksy, get_tiling_string(tex->tiling));
 
    return &tex->b.b;
 
@@ -824,10 +853,11 @@ i915_texture_from_handle(struct pipe_screen * screen,
    struct i915_winsys *iws = is->iws;
    struct i915_winsys_buffer *buffer;
    unsigned stride;
+   enum i915_winsys_buffer_tile tiling;
 
    assert(screen);
 
-   buffer = iws->buffer_from_handle(iws, whandle, &stride);
+   buffer = iws->buffer_from_handle(iws, whandle, &tiling, &stride);
 
    /* Only supports one type */
    if ((template->target != PIPE_TEXTURE_2D &&
@@ -847,6 +877,7 @@ i915_texture_from_handle(struct pipe_screen * screen,
    tex->b.b.screen = screen;
 
    tex->stride = stride;
+   tex->tiling = tiling;
    tex->total_nblocksy = align_nblocksy(tex->b.b.format, tex->b.b.height0, 8);
 
    i915_texture_set_level_info(tex, 0, 1);
@@ -854,10 +885,10 @@ i915_texture_from_handle(struct pipe_screen * screen,
 
    tex->buffer = buffer;
 
-   I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%ux%u)\n", __func__,
+   I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u) tiling %s\n", __func__,
             tex, tex->stride,
             tex->stride / util_format_get_blocksize(tex->b.b.format),
-            tex->total_nblocksy);
+            tex->total_nblocksy, get_tiling_string(tex->tiling));
 
    return &tex->b.b;
 }
index 07183253649e9ea2517b3ad3b5b21b907e4af42c..f66478e729cc91eb779b2794e2cd35325629917b 100644 (file)
@@ -189,6 +189,8 @@ i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_sha
       case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
       case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
          return 1;
+      case PIPE_SHADER_CAP_SUBROUTINES:
+         return 0;
       default:
          assert(0);
          return 0;
@@ -385,7 +387,6 @@ i915_screen_create(struct i915_winsys *iws)
    is->base.fence_finish = i915_fence_finish;
 
    i915_init_screen_resource_functions(is);
-   i915_init_screen_surface_functions(is);
 
    i915_debug_init(is);
 
index 49dff1f775c040ea0c9e6ddf18159be16d879d79..c48d53ffbb2e87365307447eeba4b46376c49af6 100644 (file)
@@ -86,6 +86,22 @@ framebuffer_size(const struct pipe_framebuffer_state *fb,
    }
 }
 
+static inline uint32_t
+buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling)
+{
+         uint32_t tiling_bits = 0;
+
+         switch (tiling) {
+         case I915_TILE_Y:
+            tiling_bits |= BUF_3D_TILE_WALK_Y;
+         case I915_TILE_X:
+            tiling_bits |= BUF_3D_TILED_SURFACE;
+         case I915_TILE_NONE:
+            break;
+         }
+
+         return tiling_bits;
+}
 
 /* Push the state into the sarea and/or texture memory.
  */
@@ -220,7 +236,6 @@ i915_emit_hardware_state(struct i915_context *i915 )
       struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
 
       if (cbuf_surface) {
-         unsigned ctile = BUF_3D_USE_FENCE;
          struct i915_texture *tex = i915_texture(cbuf_surface->texture);
          assert(tex);
 
@@ -228,30 +243,32 @@ i915_emit_hardware_state(struct i915_context *i915 )
 
          OUT_BATCH(BUF_3D_ID_COLOR_BACK |
                    BUF_3D_PITCH(tex->stride) |  /* pitch in bytes */
-                   ctile);
+                   buf_3d_tiling_bits(tex->tiling));
 
          OUT_RELOC(tex->buffer,
                    I915_USAGE_RENDER,
-                   cbuf_surface->offset);
+                   0);
       }
 
       /* What happens if no zbuf??
        */
       if (depth_surface) {
-         unsigned ztile = BUF_3D_USE_FENCE;
          struct i915_texture *tex = i915_texture(depth_surface->texture);
+         unsigned offset = i915_texture_offset(tex, depth_surface->u.tex.level,
+                                               depth_surface->u.tex.first_layer);
          assert(tex);
+         assert(offset == 0);
 
          OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
 
          assert(tex);
          OUT_BATCH(BUF_3D_ID_DEPTH |
                    BUF_3D_PITCH(tex->stride) |  /* pitch in bytes */
-                   ztile);
+                   buf_3d_tiling_bits(tex->tiling));
 
          OUT_RELOC(tex->buffer,
                    I915_USAGE_RENDER,
-                   depth_surface->offset);
+                   0);
       }
 
       {
@@ -293,12 +310,11 @@ i915_emit_hardware_state(struct i915_context *i915 )
                if (enabled & (1 << unit)) {
                   struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture);
                   struct i915_winsys_buffer *buf = texture->buffer;
-                  uint offset = 0;
                   assert(buf);
 
                   count++;
 
-                  OUT_RELOC(buf, I915_USAGE_SAMPLER, offset);
+                  OUT_RELOC(buf, I915_USAGE_SAMPLER, 0);
                   OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
                   OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
                }
@@ -391,18 +407,33 @@ i915_emit_hardware_state(struct i915_context *i915 )
 #if 01
    /* drawing surface size */
    /* 6 dwords, 0 relocs */
+   if (i915->hardware_dirty & I915_HW_STATIC)
    {
       uint w, h;
-      boolean k = framebuffer_size(&i915->framebuffer, &w, &h);
-      (void)k;
-      assert(k);
+      struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+      struct i915_texture *tex = i915_texture(cbuf_surface->texture);
+      unsigned x, y;
+      int layer;
+      uint32_t draw_offset;
+      boolean ret;
+
+      ret = framebuffer_size(&i915->framebuffer, &w, &h);
+      assert(ret);
 
+      layer = cbuf_surface->u.tex.first_layer;
+
+      x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx;
+      y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy;
+
+      draw_offset = x | (y << 16);
+
+      /* XXX flush only required when the draw_offset changes! */
+      OUT_BATCH(MI_FLUSH | INHIBIT_FLUSH_RENDER_CACHE);
       OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
-      OUT_BATCH(0);
-      OUT_BATCH(0);
-      OUT_BATCH(((w - 1) & 0xffff) | ((h - 1) << 16));
-      OUT_BATCH(0);
-      OUT_BATCH(0);
+      OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS);
+      OUT_BATCH(draw_offset);
+      OUT_BATCH((w - 1 + x) | ((h - 1 + y) << 16));
+      OUT_BATCH(draw_offset);
    }
 #endif
 
index 9771274ca1126ef34893df1f8e07008ae3843a5a..916cb767536e1ab2a1d23c67b19d66c9b70b72b1 100644 (file)
@@ -243,6 +243,23 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
    }
 }
 
+static inline uint32_t
+ms3_tiling_bits(enum i915_winsys_buffer_tile tiling)
+{
+         uint32_t tiling_bits = 0;
+
+         switch (tiling) {
+         case I915_TILE_Y:
+            tiling_bits |= MS3_TILE_WALK_Y;
+         case I915_TILE_X:
+            tiling_bits |= MS3_TILED_SURFACE;
+         case I915_TILE_NONE:
+            break;
+         }
+
+         return tiling_bits;
+}
+
 static void update_map(struct i915_context *i915,
                        uint unit,
                        const struct i915_texture *tex,
@@ -254,7 +271,6 @@ static void update_map(struct i915_context *i915,
    const uint width = pt->width0, height = pt->height0, depth = pt->depth0;
    const uint num_levels = pt->last_level;
    unsigned max_lod = num_levels * 4;
-   unsigned tiled = MS3_USE_FENCE_REGS;
 
    assert(tex);
    assert(width);
@@ -272,7 +288,7 @@ static void update_map(struct i915_context *i915,
       (((height - 1) << MS3_HEIGHT_SHIFT)
        | ((width - 1) << MS3_WIDTH_SHIFT)
        | format
-       | tiled);
+       | ms3_tiling_bits(tex->tiling));
 
    /*
     * XXX When min_filter != mag_filter and there's just one mipmap level,
index f40876e708e26d92503a70fb0e15415ac3812c23..becc6e93c2d258e047d6e621a397f6e3c54b646f 100644 (file)
  */
 static void
 i915_surface_copy(struct pipe_context *pipe,
-                  struct pipe_resource *dst, struct pipe_subresource subdst,
+                  struct pipe_resource *dst, unsigned dst_level,
                   unsigned dstx, unsigned dsty, unsigned dstz,
-                  struct pipe_resource *src, struct pipe_subresource subsrc,
-                  unsigned srcx, unsigned srcy, unsigned srcz,
-                  unsigned width, unsigned height)
+                  struct pipe_resource *src, unsigned src_level,
+                  const struct pipe_box *src_box)
 {
    struct i915_texture *dst_tex = i915_texture(dst);
    struct i915_texture *src_tex = i915_texture(src);
@@ -55,29 +54,17 @@ i915_surface_copy(struct pipe_context *pipe,
    struct pipe_resource *spt = &src_tex->b.b;
    unsigned dst_offset, src_offset;  /* in bytes */
 
-   if (dst->target == PIPE_TEXTURE_CUBE) {
-      dst_offset = dst_tex->image_offset[subdst.level][subdst.face];
-   }
-   else if (dst->target == PIPE_TEXTURE_3D) {
-      dst_offset = dst_tex->image_offset[subdst.level][dstz];
-   }
-   else {
-      dst_offset = dst_tex->image_offset[subdst.level][0];
-      assert(subdst.face == 0);
+   /* XXX cannot copy 3d regions at this time */
+   assert(src_box->depth == 1);
+   if (dst->target != PIPE_TEXTURE_CUBE &&
+       dst->target != PIPE_TEXTURE_3D)
       assert(dstz == 0);
-   }
-   if (src->target == PIPE_TEXTURE_CUBE) {
-      src_offset = src_tex->image_offset[subsrc.level][subsrc.face];
-   }
-   else if (src->target == PIPE_TEXTURE_3D) {
-      src_offset = src_tex->image_offset[subsrc.level][srcz];
-   }
-   else {
-      src_offset = src_tex->image_offset[subsrc.level][0];
-      assert(subsrc.face == 0);
-      assert(srcz == 0);
-   }
+   dst_offset = i915_texture_offset(dst_tex, dst_level, dstz);
 
+   if (src->target != PIPE_TEXTURE_CUBE &&
+       src->target != PIPE_TEXTURE_3D)
+      assert(src_box->z == 0);
+   src_offset = i915_texture_offset(src_tex, src_level, src_box->z);
 
    assert( dst != src );
    assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) );
@@ -90,7 +77,8 @@ i915_surface_copy(struct pipe_context *pipe,
                    util_format_get_blocksize(dpt->format),
                    (unsigned short) src_tex->stride, src_tex->buffer, src_offset,
                    (unsigned short) dst_tex->stride, dst_tex->buffer, dst_offset,
-                   (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height );
+                   (short) src_box->x, (short) src_box->y, (short) dstx, (short) dsty,
+                   (short) src_box->width, (short) src_box->height );
 }
 
 
@@ -104,6 +92,7 @@ i915_clear_render_target(struct pipe_context *pipe,
    struct i915_texture *tex = i915_texture(dst->texture);
    struct pipe_resource *pt = &tex->b.b;
    union util_color uc;
+   unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
 
    assert(util_format_get_blockwidth(pt->format) == 1);
    assert(util_format_get_blockheight(pt->format) == 1);
@@ -113,7 +102,7 @@ i915_clear_render_target(struct pipe_context *pipe,
                    util_format_get_blocksize(pt->format),
                    XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB,
                    (unsigned short) tex->stride,
-                   tex->buffer, dst->offset,
+                   tex->buffer, offset,
                    (short) dstx, (short) dsty,
                    (short) width, (short) height,
                    uc.ui );
@@ -132,6 +121,7 @@ i915_clear_depth_stencil(struct pipe_context *pipe,
    struct pipe_resource *pt = &tex->b.b;
    unsigned packedds;
    unsigned mask = 0;
+   unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
 
    assert(util_format_get_blockwidth(pt->format) == 1);
    assert(util_format_get_blockheight(pt->format) == 1);
@@ -151,7 +141,7 @@ i915_clear_depth_stencil(struct pipe_context *pipe,
                    util_format_get_blocksize(pt->format),
                    mask,
                    (unsigned short) tex->stride,
-                   tex->buffer, dst->offset,
+                   tex->buffer, offset,
                    (short) dstx, (short) dsty,
                    (short) width, (short) height,
                    packedds );
@@ -163,42 +153,37 @@ i915_clear_depth_stencil(struct pipe_context *pipe,
 
 
 static struct pipe_surface *
-i915_get_tex_surface(struct pipe_screen *screen,
-                     struct pipe_resource *pt,
-                     unsigned face, unsigned level, unsigned zslice,
-                     unsigned flags)
+i915_create_surface(struct pipe_context *ctx,
+                    struct pipe_resource *pt,
+                    const struct pipe_surface *surf_tmpl)
 {
-   struct i915_texture *tex = i915_texture(pt);
    struct pipe_surface *ps;
-   unsigned offset;  /* in bytes */
 
-   if (pt->target == PIPE_TEXTURE_CUBE) {
-      offset = tex->image_offset[level][face];
-   }
-   else if (pt->target == PIPE_TEXTURE_3D) {
-      offset = tex->image_offset[level][zslice];
-   }
-   else {
-      offset = tex->image_offset[level][0];
-      assert(face == 0);
-      assert(zslice == 0);
-   }
+   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+   if (pt->target != PIPE_TEXTURE_CUBE &&
+       pt->target != PIPE_TEXTURE_3D)
+      assert(surf_tmpl->u.tex.first_layer == 0);
 
    ps = CALLOC_STRUCT(pipe_surface);
    if (ps) {
+      /* could subclass pipe_surface and store offset as it used to do */
       pipe_reference_init(&ps->reference, 1);
       pipe_resource_reference(&ps->texture, pt);
-      ps->format = pt->format;
-      ps->width = u_minify(pt->width0, level);
-      ps->height = u_minify(pt->height0, level);
-      ps->offset = offset;
-      ps->usage = flags;
+      ps->format = surf_tmpl->format;
+      ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
+      ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
+      ps->u.tex.level = surf_tmpl->u.tex.level;
+      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+      ps->usage = surf_tmpl->usage;
+      ps->context = ctx;
    }
    return ps;
 }
 
 static void
-i915_tex_surface_destroy(struct pipe_surface *surf)
+i915_surface_destroy(struct pipe_context *ctx,
+                     struct pipe_surface *surf)
 {
    pipe_resource_reference(&surf->texture, NULL);
    FREE(surf);
@@ -211,13 +196,6 @@ i915_init_surface_functions(struct i915_context *i915)
    i915->base.resource_copy_region = i915_surface_copy;
    i915->base.clear_render_target = i915_clear_render_target;
    i915->base.clear_depth_stencil = i915_clear_depth_stencil;
-}
-
-/* No good reason for these to be in the screen.
- */
-void
-i915_init_screen_surface_functions(struct i915_screen *is)
-{
-   is->base.get_tex_surface = i915_get_tex_surface;
-   is->base.tex_surface_destroy = i915_tex_surface_destroy;
+   i915->base.create_surface = i915_create_surface;
+   i915->base.surface_destroy = i915_surface_destroy;
 }
index 448106d5662300ec6b05de3e6f2d6b49a7b37b95..70b61de80f2686d553dbdacb3ef3793bee090796 100644 (file)
@@ -32,7 +32,6 @@ struct i915_context;
 struct i915_screen;
 
 void i915_init_surface_functions( struct i915_context *i915 );
-void i915_init_screen_surface_functions( struct i915_screen *is );
 
 
 #endif /* I915_SCREEN_H */
index 5385e403d224e3715dd8116b2f0e92f049961c8f..24ea416f015469b84215dba63bd9f2ca1b19e624 100644 (file)
@@ -53,6 +53,7 @@ enum i915_winsys_buffer_type
    I915_NEW_VERTEX
 };
 
+/* These need to be in sync with the definitions of libdrm-intel! */
 enum i915_winsys_buffer_tile
 {
    I915_TILE_NONE,
@@ -106,7 +107,7 @@ struct i915_winsys {
    int (*batchbuffer_reloc)(struct i915_winsys_batchbuffer *batch,
                             struct i915_winsys_buffer *reloc,
                             enum i915_winsys_buffer_usage usage,
-                            unsigned offset);
+                            unsigned offset, bool fenced);
 
    /**
     * Flush a bufferbatch.
@@ -130,9 +131,23 @@ struct i915_winsys {
     */
    struct i915_winsys_buffer *
       (*buffer_create)(struct i915_winsys *iws,
-                       unsigned size, unsigned alignment,
+                       unsigned size,
                        enum i915_winsys_buffer_type type);
 
+   /**
+    * Create a tiled buffer.
+    *
+    * *stride, height are in bytes. The winsys tries to allocate the buffer with
+    * the tiling mode provide in *tiling. If tiling is no possible, *tiling will
+    * be set to I915_TILE_NONE. The calculated stride (incorporateing hw/kernel
+    * requirements) is always returned in *stride.
+    */
+   struct i915_winsys_buffer *
+      (*buffer_create_tiled)(struct i915_winsys *iws,
+                             unsigned *stride, unsigned height,
+                             enum i915_winsys_buffer_tile *tiling,
+                             enum i915_winsys_buffer_type type);
+
    /**
     * Creates a buffer from a handle.
     * Used to implement pipe_screen::resource_from_handle.
@@ -142,6 +157,7 @@ struct i915_winsys {
    struct i915_winsys_buffer *
       (*buffer_from_handle)(struct i915_winsys *iws,
                             struct winsys_handle *whandle,
+                            enum i915_winsys_buffer_tile *tiling,
                             unsigned *stride);
 
    /**
@@ -153,15 +169,6 @@ struct i915_winsys {
                                 struct winsys_handle *whandle,
                                 unsigned stride);
 
-   /**
-    * Fence a buffer with a fence reg.
-    * Not to be confused with pipe_fence_handle.
-    */
-   int (*buffer_set_fence_reg)(struct i915_winsys *iws,
-                               struct i915_winsys_buffer *buffer,
-                               unsigned stride,
-                               enum i915_winsys_buffer_tile tile);
-
    /**
     * Map a buffer.
     */
index b0b09703384d78b2062a5cb1b6edab671e5f581d..a0331f805813ccc4a06cb111724d40f997b2ebfb 100644 (file)
@@ -33,6 +33,7 @@ C_SOURCES = \
        brw_pipe_flush.c \
        brw_pipe_misc.c \
        brw_pipe_sampler.c \
+        brw_pipe_surface.c \
        brw_pipe_vertex.c \
        brw_pipe_clear.c \
        brw_pipe_rast.c \
@@ -66,7 +67,6 @@ C_SOURCES = \
        brw_resource_buffer.c \
        brw_resource_texture.c \
        brw_resource_texture_layout.c \
-       brw_screen_surface.c \
        brw_batchbuffer.c \
        brw_winsys_debug.c \
        intel_decode.c
index 019af682f68f044c90990ead8ba24f8e0450fa24..3ef6c88030588237392c31c93dbae8e288a00391 100644 (file)
@@ -36,6 +36,8 @@ i965 = env.ConvenienceLibrary(
                'brw_pipe_query.c',
                'brw_pipe_rast.c',
                'brw_pipe_sampler.c',
+                'brw_pipe_surface.c',
+                'brw_pipe_surface.c',
                'brw_pipe_shader.c',
                'brw_pipe_vertex.c',
                'brw_resource.c',
@@ -43,7 +45,6 @@ i965 = env.ConvenienceLibrary(
                'brw_resource_texture.c',
                'brw_resource_texture_layout.c',
                'brw_screen.c',
-               'brw_screen_surface.c',
                'brw_structs_dump.c',
                'brw_sf.c',
                'brw_sf_emit.c',
index 227bc790debbc6166c35ac175161e7d5611464a8..a2736f783d53bfb03832d1356b4e9797f97284e7 100644 (file)
@@ -131,6 +131,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen,
    brw_pipe_shader_init( brw );
    brw_pipe_vertex_init( brw );
    brw_pipe_clear_init( brw );
+   brw_pipe_surface_init( brw );
 
    brw_hw_cc_init( brw );
 
index 56d351f97d1f867b54b3435c631a1fe5348fcaf4..d927f382d5fbb8f87cbc534b36575c8bd4576b6e 100644 (file)
@@ -821,6 +821,7 @@ void brw_pipe_sampler_cleanup( struct brw_context *brw );
 void brw_pipe_shader_cleanup( struct brw_context *brw );
 void brw_pipe_vertex_cleanup( struct brw_context *brw );
 void brw_pipe_clear_cleanup( struct brw_context *brw );
+void brw_pipe_surface_init( struct brw_context *brw );
 
 void brw_hw_cc_init( struct brw_context *brw );
 void brw_hw_cc_cleanup( struct brw_context *brw );
index b5029ceb69fcb87e6d64acccd1406a8144b294e9..6d89b5d2baf15be26a8b328bf0f636c83de348cf 100644 (file)
@@ -287,11 +287,12 @@ static int emit_depthbuffer(struct brw_context *brw)
       OUT_BATCH(((pitch * cpp) - 1) |
                (format << 18) |
                (BRW_TILEWALK_YMAJOR << 26) |
-               ((surface->layout != PIPE_SURFACE_LAYOUT_LINEAR) << 27) |
+                /* always linear ?
+               ((surface->layout != PIPE_SURFACE_LAYOUT_LINEAR) << 27) |*/
                (BRW_SURFACE_2D << 29));
       OUT_RELOC(bo,
                BRW_USAGE_DEPTH_BUFFER,
-               surface->offset);
+               brw_surface(surface)->offset);
       OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
                ((pitch - 1) << 6) |
                ((surface->height - 1) << 19));
index d5cff338a66fb200c64b43552d559447d876832c..7bf3ea6994a8d694e7a96a592147e98ccb29c631 100644 (file)
@@ -64,7 +64,7 @@ try_clear( struct brw_context *brw,
    debug_printf("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
                 __FUNCTION__,
                 (void *)surface->bo, pitch * cpp,
-                surface->base.offset,
+                surface->offset,
                 x1, y1, x2 - x1, y2 - y1);
 
    BR13 = 0xf0 << 16;
@@ -99,7 +99,7 @@ try_clear( struct brw_context *brw,
    OUT_BATCH((y2 << 16) | x2);
    OUT_RELOC(surface->bo,
              BRW_USAGE_BLIT_DEST,
-             surface->base.offset);
+             surface->offset);
    OUT_BATCH(value);
    ADVANCE_BATCH();
 
diff --git a/src/gallium/drivers/i965/brw_pipe_surface.c b/src/gallium/drivers/i965/brw_pipe_surface.c
new file mode 100644 (file)
index 0000000..4deead9
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+#include "util/u_math.h"
+
+#include "pipe/p_screen.h"
+#include "brw_screen.h"
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_resource.h"
+#include "brw_winsys.h"
+
+enum {
+   BRW_VIEW_LINEAR,
+   BRW_VIEW_IN_PLACE
+};
+
+
+static boolean need_linear_view( struct brw_screen *brw_screen,
+                                struct brw_texture *brw_texture,
+                                union brw_surface_id id,
+                                unsigned usage )
+{
+#if 0
+   /* XXX: what about IDGNG?
+    */
+   if (!BRW_IS_G4X(brw->brw_screen->pci_id))
+   {
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+      struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+      /* The original gen4 hardware couldn't set up WM surfaces pointing
+       * at an offset within a tile, which can happen when rendering to
+       * anything but the base level of a texture or the +X face/0 depth.
+       * This was fixed with the 4 Series hardware.
+       *
+       * For these original chips, you would have to make the depth and
+       * color destination surfaces include information on the texture
+       * type, LOD, face, and various limits to use them as a destination.
+       *
+       * This is easy in Gallium as surfaces are all backed by
+       * textures, but there's also a nasty requirement that the depth
+       * and the color surfaces all be of the same LOD, which is
+       * harder to get around as we can't look at a surface in
+       * isolation and decide if it's legal.
+       *
+       * Instead, end up being pessimistic and say that for i965,
+       * ... ??
+       */
+      if (brw_tex->tiling != I915_TILING_NONE &&
+         (brw_tex_image_offset(brw_tex, face, level, zslize) & 4095)) {
+        if (BRW_DEBUG & DEBUG_VIEW)
+           debug_printf("%s: need surface view for non-aligned tex image\n",
+                        __FUNCTION__);
+        return GL_TRUE;
+      }
+   }
+#endif
+
+   /* Tiled 3d textures don't have subsets that look like 2d surfaces:
+    */
+   
+   /* Everything else should be fine to render to in-place:
+    */
+   return GL_FALSE;
+}
+
+/* Look at all texture views and figure out if any of them need to be
+ * back-copied into the texture for sampling
+ */
+void brw_update_texture( struct brw_screen *brw_screen,
+                        struct brw_texture *tex )
+{
+   /* currently nothing to do */
+}
+
+
+/* Create a new surface with linear layout to serve as a render-target
+ * where it would be illegal (perhaps due to tiling constraints) to do
+ * this in-place.
+ * 
+ * Currently not implemented, not sure if it's needed.
+ */
+static struct brw_surface *create_linear_view( struct brw_screen *brw_screen,
+                                               struct pipe_context *pipe,
+                                              struct brw_texture *tex,
+                                              union brw_surface_id id,
+                                              unsigned usage )
+{
+   return NULL;
+}
+
+
+/* Create a pipe_surface that just points directly into the existing
+ * texture's storage.
+ */
+static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen,
+                                                 struct pipe_context *pipe,
+                                                 struct brw_texture *tex,
+                                                 union brw_surface_id id,
+                                                 unsigned usage )
+{
+   struct brw_surface *surface;
+
+   surface = CALLOC_STRUCT(brw_surface);
+   if (surface == NULL)
+      return NULL;
+
+   pipe_reference_init(&surface->base.reference, 1);
+
+   /* XXX: ignoring render-to-slice-of-3d-texture
+    */
+   assert(tex->b.b.target != PIPE_TEXTURE_3D || id.bits.layer == 0);
+
+   surface->base.context = pipe;
+   surface->base.format = tex->b.b.format;
+   surface->base.width = u_minify(tex->b.b.width0, id.bits.level);
+   surface->base.height = u_minify(tex->b.b.height0, id.bits.level);
+   surface->base.usage = usage;
+   surface->base.u.tex.first_layer = id.bits.layer;
+   surface->base.u.tex.last_layer = surface->base.u.tex.first_layer;
+   surface->base.u.tex.level = id.bits.level;
+   surface->id = id;
+   surface->offset = tex->image_offset[id.bits.level][id.bits.layer];
+   surface->cpp = tex->cpp;
+   surface->pitch = tex->pitch;
+   surface->tiling = tex->tiling;
+
+   bo_reference( &surface->bo, tex->bo );
+   pipe_resource_reference( &surface->base.texture, &tex->b.b );
+
+   surface->ss.ss0.surface_format = tex->ss.ss0.surface_format;
+   surface->ss.ss0.surface_type = BRW_SURFACE_2D;
+
+   if (tex->tiling == BRW_TILING_NONE) {
+      surface->ss.ss1.base_addr = surface->offset;
+   } else {
+      uint32_t tile_offset = surface->offset % 4096;
+
+      surface->ss.ss1.base_addr = surface->offset - tile_offset;
+
+      if (brw_screen->chipset.is_g4x) {
+        if (tex->tiling == BRW_TILING_X) {
+           /* Note that the low bits of these fields are missing, so
+            * there's the possibility of getting in trouble.
+            */
+           surface->ss.ss5.x_offset = (tile_offset % 512) / tex->cpp / 4;
+           surface->ss.ss5.y_offset = tile_offset / 512 / 2;
+        } else {
+           surface->ss.ss5.x_offset = (tile_offset % 128) / tex->cpp / 4;
+           surface->ss.ss5.y_offset = tile_offset / 128 / 2;
+        }
+      }
+      else {
+        assert(tile_offset == 0);
+      }
+   }
+
+#if 0
+   if (region_bo != NULL)
+      surface->ss.ss1.base_addr += region_bo->offset; /* reloc */
+#endif
+
+   surface->ss.ss2.width = surface->base.width - 1;
+   surface->ss.ss2.height = surface->base.height - 1;
+   surface->ss.ss3.tiled_surface = tex->ss.ss3.tiled_surface;
+   surface->ss.ss3.tile_walk = tex->ss.ss3.tile_walk;
+   surface->ss.ss3.pitch = tex->ss.ss3.pitch;
+
+   return surface;
+}
+
+/* Get a surface which is view into a texture 
+ */
+static struct pipe_surface *brw_create_surface(struct pipe_context *pipe,
+                                               struct pipe_resource *pt,
+                                               const struct pipe_surface *surf_tmpl)
+{
+   struct brw_texture *tex = brw_texture(pt);
+   struct brw_screen *bscreen = brw_screen(pipe->screen);
+   struct brw_surface *surface;
+   union brw_surface_id id;
+   int type;
+
+   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+   id.bits.level = surf_tmpl->u.tex.level;
+   id.bits.layer = surf_tmpl->u.tex.first_layer;
+
+   if (need_linear_view(bscreen, tex, id, surf_tmpl->usage))
+      type = BRW_VIEW_LINEAR;
+   else
+      type = BRW_VIEW_IN_PLACE;
+
+   
+   foreach (surface, &tex->views[type]) {
+      if (id.value == surface->id.value)
+        return &surface->base;
+   }
+
+   switch (type) {
+   case BRW_VIEW_LINEAR:
+      surface = create_linear_view( bscreen, pipe, tex, id, surf_tmpl->usage );
+      break;
+   case BRW_VIEW_IN_PLACE:
+      surface = create_in_place_view( bscreen, pipe, tex, id, surf_tmpl->usage );
+      break;
+   }
+
+   insert_at_head( &tex->views[type], surface );
+   return &surface->base;
+}
+
+
+static void brw_surface_destroy( struct pipe_context *pipe,
+                                 struct pipe_surface *surf )
+{
+   struct brw_surface *surface = brw_surface(surf);
+
+   /* Unreference texture, shared buffer:
+    */
+   remove_from_list(surface);
+   bo_reference(&surface->bo, NULL);
+   pipe_resource_reference( &surface->base.texture, NULL );
+
+   FREE(surface);
+}
+
+
+void brw_pipe_surface_init( struct brw_context *brw )
+{
+   brw->base.create_surface = brw_create_surface;
+   brw->base.surface_destroy = brw_surface_destroy;
+}
index 5f9e8a87c9976e9d98a2388d4fc26e80534e27f8..afb96ee3e7fd6b0ab718cde45514f71f82974d13 100644 (file)
@@ -92,9 +92,9 @@ brw_buffer_transfer_unmap( struct pipe_context *pipe,
 
 
 static unsigned brw_buffer_is_referenced( struct pipe_context *pipe,
-                                        struct pipe_resource *resource,
-                                        unsigned face,
-                                        unsigned level)
+                                          struct pipe_resource *resource,
+                                          unsigned level,
+                                          int layer)
 {
    struct brw_context *brw = brw_context(pipe);
    struct brw_winsys_buffer *batch_bo = brw->batch->buf;
@@ -194,6 +194,7 @@ brw_user_buffer_create(struct pipe_screen *screen,
    buf->b.b.width0 = bytes;
    buf->b.b.height0 = 1;
    buf->b.b.depth0 = 1;
+   buf->b.b.array_size = 1;
 
    buf->user_buffer = ptr;
    
index 3860d18a7a2f10190d25f26efda9a20b9133bcc8..fded2da38201d3b9893e47884127ecce7c35e567 100644 (file)
@@ -229,8 +229,8 @@ static void brw_texture_destroy(struct pipe_screen *screen,
 
 static unsigned brw_texture_is_referenced( struct pipe_context *pipe,
                                           struct pipe_resource *texture,
-                                          unsigned face, 
-                                          unsigned level )
+                                          unsigned level,
+                                          int layer )
 {
    struct brw_context *brw = brw_context(pipe);
    struct brw_screen *bscreen = brw_screen(pipe->screen);
@@ -246,7 +246,7 @@ static unsigned brw_texture_is_referenced( struct pipe_context *pipe,
    if (bscreen->sws->bo_references( batch_bo, tex->bo ))
       return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
-   /* Find any view on this texture for this face/level and see if it
+   /* Find any view on this texture for this level/layer and see if it
     * is referenced:
     */
    for (i = 0; i < 2; i++) {
@@ -254,7 +254,7 @@ static unsigned brw_texture_is_referenced( struct pipe_context *pipe,
          if (surf->bo == tex->bo)
             continue;
 
-         if (surf->id.bits.face != face ||
+         if (!(layer == -1 || surf->id.bits.layer == layer) ||
              surf->id.bits.level != level)
             continue;
          
@@ -274,10 +274,10 @@ static unsigned brw_texture_is_referenced( struct pipe_context *pipe,
 
 static struct pipe_transfer * 
 brw_texture_get_transfer(struct pipe_context *context,
-                         struct pipe_resource *resource,
-                         struct pipe_subresource sr,
-                         unsigned usage,
-                         const struct pipe_box *box)
+                         struct pipe_resource *resource,
+                         unsigned level,
+                         unsigned usage,
+                         const struct pipe_box *box)
 {
    struct brw_texture *tex = brw_texture(resource);
    struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
@@ -285,10 +285,11 @@ brw_texture_get_transfer(struct pipe_context *context,
       return NULL;
 
    transfer->resource = resource;
-   transfer->sr = sr;
+   transfer->level = level;
    transfer->usage = usage;
    transfer->box = *box;
    transfer->stride = tex->pitch * tex->cpp;
+   /* FIXME: layer_stride */
 
    return transfer;
 }
@@ -301,24 +302,16 @@ brw_texture_transfer_map(struct pipe_context *pipe,
    struct pipe_resource *resource = transfer->resource;
    struct brw_texture *tex = brw_texture(transfer->resource);
    struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws;
-   struct pipe_subresource sr = transfer->sr;
    struct pipe_box *box = &transfer->box;
    enum pipe_format format = resource->format;
    unsigned usage = transfer->usage;
    unsigned offset;
    char *map;
 
-   if (resource->target == PIPE_TEXTURE_CUBE) {
-      offset = tex->image_offset[sr.level][sr.face];
-   }
-   else if (resource->target == PIPE_TEXTURE_3D) {
-      offset = tex->image_offset[sr.level][box->z];
-   }
-   else {
-      offset = tex->image_offset[sr.level][0];
-      assert(sr.face == 0);
+   if (resource->target != PIPE_TEXTURE_3D &&
+       resource->target != PIPE_TEXTURE_CUBE)
       assert(box->z == 0);
-   }
+   offset = tex->image_offset[transfer->level][box->z];
 
    map = sws->bo_map(tex->bo, 
                      BRW_DATA_OTHER,
index 57160ebb2973555fcd76a85c5645b04f92d6d380..f5b75b17e36be827e18cb69775adc399469d02fb 100644 (file)
@@ -240,6 +240,8 @@ brw_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shad
       case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
       case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
           return 1;
+      case PIPE_SHADER_CAP_SUBROUTINES:
+          return 1;
       default:
          assert(0);
          return 0;
@@ -468,7 +470,6 @@ brw_screen_create(struct brw_winsys_screen *sws)
    bscreen->base.fence_finish = brw_fence_finish;
 
    brw_init_screen_resource_functions(bscreen);
-   brw_screen_tex_surface_init(bscreen);
 
    bscreen->no_tiling = debug_get_option("BRW_NO_TILING", FALSE) != NULL;
    
index 522a3bf899528ea3046e96e7ca2506ae08ee91ac..58e293bc76f7801522aa1b9dad2f6770ae84d313 100644 (file)
@@ -52,9 +52,8 @@ struct brw_screen
 
 union brw_surface_id {
    struct {
-      unsigned face:3;
-      unsigned zslice:13;
       unsigned level:16;
+      unsigned layer:16;
    } bits;
    unsigned value;
 };
@@ -63,8 +62,9 @@ union brw_surface_id {
 struct brw_surface
 {
    struct pipe_surface base;
-   
+
    union brw_surface_id id;
+   unsigned offset;
    unsigned cpp;
    unsigned pitch;
    unsigned draw_offset;
@@ -96,7 +96,5 @@ brw_surface(struct pipe_surface *surface)
 unsigned
 brw_surface_pitch( const struct pipe_surface *surface );
 
-void brw_screen_tex_surface_init( struct brw_screen *brw_screen );
-
 
 #endif /* BRW_SCREEN_H */
diff --git a/src/gallium/drivers/i965/brw_screen_surface.c b/src/gallium/drivers/i965/brw_screen_surface.c
deleted file mode 100644 (file)
index f288fdb..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- develop this 3D driver.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  */
-
-#include "util/u_memory.h"
-#include "util/u_simple_list.h"
-#include "util/u_math.h"
-
-#include "pipe/p_screen.h"
-#include "brw_screen.h"
-#include "brw_defines.h"
-#include "brw_resource.h"
-#include "brw_winsys.h"
-
-enum {
-   BRW_VIEW_LINEAR,
-   BRW_VIEW_IN_PLACE
-};
-
-
-static boolean need_linear_view( struct brw_screen *brw_screen,
-                                struct brw_texture *brw_texture,
-                                union brw_surface_id id,
-                                unsigned usage )
-{
-#if 0
-   /* XXX: what about IDGNG?
-    */
-   if (!BRW_IS_G4X(brw->brw_screen->pci_id))
-   {
-      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
-      struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
-      /* The original gen4 hardware couldn't set up WM surfaces pointing
-       * at an offset within a tile, which can happen when rendering to
-       * anything but the base level of a texture or the +X face/0 depth.
-       * This was fixed with the 4 Series hardware.
-       *
-       * For these original chips, you would have to make the depth and
-       * color destination surfaces include information on the texture
-       * type, LOD, face, and various limits to use them as a destination.
-       *
-       * This is easy in Gallium as surfaces are all backed by
-       * textures, but there's also a nasty requirement that the depth
-       * and the color surfaces all be of the same LOD, which is
-       * harder to get around as we can't look at a surface in
-       * isolation and decide if it's legal.
-       *
-       * Instead, end up being pessimistic and say that for i965,
-       * ... ??
-       */
-      if (brw_tex->tiling != I915_TILING_NONE &&
-         (brw_tex_image_offset(brw_tex, face, level, zslize) & 4095)) {
-        if (BRW_DEBUG & DEBUG_VIEW)
-           debug_printf("%s: need surface view for non-aligned tex image\n",
-                        __FUNCTION__);
-        return GL_TRUE;
-      }
-   }
-#endif
-
-   /* Tiled 3d textures don't have subsets that look like 2d surfaces:
-    */
-   
-   /* Everything else should be fine to render to in-place:
-    */
-   return GL_FALSE;
-}
-
-/* Look at all texture views and figure out if any of them need to be
- * back-copied into the texture for sampling
- */
-void brw_update_texture( struct brw_screen *brw_screen,
-                        struct brw_texture *tex )
-{
-   /* currently nothing to do */
-}
-
-
-/* Create a new surface with linear layout to serve as a render-target
- * where it would be illegal (perhaps due to tiling constraints) to do
- * this in-place.
- * 
- * Currently not implmented, not sure if it's needed.
- */
-static struct brw_surface *create_linear_view( struct brw_screen *brw_screen,
-                                              struct brw_texture *tex,
-                                              union brw_surface_id id,
-                                              unsigned usage )
-{
-   return NULL;
-}
-
-
-/* Create a pipe_surface that just points directly into the existing
- * texture's storage.
- */
-static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen,
-                                                 struct brw_texture *tex,
-                                                 union brw_surface_id id,
-                                                 unsigned usage )
-{
-   struct brw_surface *surface;
-
-   surface = CALLOC_STRUCT(brw_surface);
-   if (surface == NULL)
-      return NULL;
-
-   pipe_reference_init(&surface->base.reference, 1);
-
-   /* XXX: ignoring render-to-slice-of-3d-texture
-    */
-   assert(id.bits.zslice == 0);
-
-   surface->base.format = tex->b.b.format;
-   surface->base.width = u_minify(tex->b.b.width0, id.bits.level);
-   surface->base.height = u_minify(tex->b.b.height0, id.bits.level);
-   surface->base.offset = tex->image_offset[id.bits.level][id.bits.face];
-   surface->base.usage = usage;
-   surface->base.zslice = id.bits.zslice;
-   surface->base.face = id.bits.face;
-   surface->base.level = id.bits.level;
-   surface->id = id;
-   surface->cpp = tex->cpp;
-   surface->pitch = tex->pitch;
-   surface->tiling = tex->tiling;
-
-   bo_reference( &surface->bo, tex->bo );
-   pipe_resource_reference( &surface->base.texture, &tex->b.b );
-
-   surface->ss.ss0.surface_format = tex->ss.ss0.surface_format;
-   surface->ss.ss0.surface_type = BRW_SURFACE_2D;
-
-   if (tex->tiling == BRW_TILING_NONE) {
-      surface->ss.ss1.base_addr = surface->base.offset;
-   } else {
-      uint32_t tile_offset = surface->base.offset % 4096;
-
-      surface->ss.ss1.base_addr = surface->base.offset - tile_offset;
-
-      if (brw_screen->chipset.is_g4x) {
-        if (tex->tiling == BRW_TILING_X) {
-           /* Note that the low bits of these fields are missing, so
-            * there's the possibility of getting in trouble.
-            */
-           surface->ss.ss5.x_offset = (tile_offset % 512) / tex->cpp / 4;
-           surface->ss.ss5.y_offset = tile_offset / 512 / 2;
-        } else {
-           surface->ss.ss5.x_offset = (tile_offset % 128) / tex->cpp / 4;
-           surface->ss.ss5.y_offset = tile_offset / 128 / 2;
-        }
-      }
-      else {
-        assert(tile_offset == 0);
-      }
-   }
-
-#if 0
-   if (region_bo != NULL)
-      surface->ss.ss1.base_addr += region_bo->offset; /* reloc */
-#endif
-
-   surface->ss.ss2.width = surface->base.width - 1;
-   surface->ss.ss2.height = surface->base.height - 1;
-   surface->ss.ss3.tiled_surface = tex->ss.ss3.tiled_surface;
-   surface->ss.ss3.tile_walk = tex->ss.ss3.tile_walk;
-   surface->ss.ss3.pitch = tex->ss.ss3.pitch;
-
-   return surface;
-}
-
-/* Get a surface which is view into a texture 
- */
-static struct pipe_surface *brw_get_tex_surface(struct pipe_screen *screen,
-                                               struct pipe_resource *pt,
-                                               unsigned face, unsigned level,
-                                               unsigned zslice,
-                                               unsigned usage )
-{
-   struct brw_texture *tex = brw_texture(pt);
-   struct brw_screen *bscreen = brw_screen(screen);
-   struct brw_surface *surface;
-   union brw_surface_id id;
-   int type;
-
-   id.bits.face = face;
-   id.bits.level = level;
-   id.bits.zslice = zslice;
-
-   if (need_linear_view(bscreen, tex, id, usage)) 
-      type = BRW_VIEW_LINEAR;
-   else
-      type = BRW_VIEW_IN_PLACE;
-
-   
-   foreach (surface, &tex->views[type]) {
-      if (id.value == surface->id.value)
-        return &surface->base;
-   }
-
-   switch (type) {
-   case BRW_VIEW_LINEAR:
-      surface = create_linear_view( bscreen, tex, id, usage );
-      break;
-   case BRW_VIEW_IN_PLACE:
-      surface = create_in_place_view( bscreen, tex, id, usage );
-      break;
-   }
-
-   insert_at_head( &tex->views[type], surface );
-   return &surface->base;
-}
-
-
-static void brw_tex_surface_destroy( struct pipe_surface *surf )
-{
-   struct brw_surface *surface = brw_surface(surf);
-
-   /* Unreference texture, shared buffer:
-    */
-   remove_from_list(surface);
-   bo_reference(&surface->bo, NULL);
-   pipe_resource_reference( &surface->base.texture, NULL );
-
-
-   FREE(surface);
-}
-
-
-void brw_screen_tex_surface_init( struct brw_screen *brw_screen )
-{
-   brw_screen->base.get_tex_surface = brw_get_tex_surface;
-   brw_screen->base.tex_surface_destroy = brw_tex_surface_destroy;
-}
index b364e0acc84a4f97d95d94b3308b53021a52f271..d24d1ec7c61f869502366dea36a54284f4bef658 100644 (file)
@@ -10,4 +10,6 @@ identity = env.ConvenienceLibrary(
                'id_screen.c',
        ])
 
+env.Alias('identity', identity)
+
 Export('identity')
index de83c249057a3bcff2cd87e2dd31e645d406e764..3efbd6a246d577d1c9d302a223ce8dade86e4c88 100644 (file)
@@ -577,17 +577,13 @@ identity_set_index_buffer(struct pipe_context *_pipe,
 static void
 identity_resource_copy_region(struct pipe_context *_pipe,
                               struct pipe_resource *_dst,
-                              struct pipe_subresource subdst,
+                              unsigned dst_level,
                               unsigned dstx,
                               unsigned dsty,
                               unsigned dstz,
                               struct pipe_resource *_src,
-                              struct pipe_subresource subsrc,
-                              unsigned srcx,
-                              unsigned srcy,
-                              unsigned srcz,
-                              unsigned width,
-                              unsigned height)
+                              unsigned src_level,
+                              const struct pipe_box *src_box)
 {
    struct identity_context *id_pipe = identity_context(_pipe);
    struct identity_resource *id_resource_dst = identity_resource(_dst);
@@ -598,17 +594,13 @@ identity_resource_copy_region(struct pipe_context *_pipe,
 
    pipe->resource_copy_region(pipe,
                               dst,
-                              subdst,
+                              dst_level,
                               dstx,
                               dsty,
                               dstz,
                               src,
-                              subsrc,
-                              srcx,
-                              srcy,
-                              srcz,
-                              width,
-                              height);
+                              src_level,
+                              src_box);
 }
 
 static void
@@ -690,8 +682,8 @@ identity_flush(struct pipe_context *_pipe,
 static unsigned int
 identity_is_resource_referenced(struct pipe_context *_pipe,
                                 struct pipe_resource *_resource,
-                                unsigned face,
-                                unsigned level)
+                                unsigned level,
+                                int layer)
 {
    struct identity_context *id_pipe = identity_context(_pipe);
    struct identity_resource *id_resource = identity_resource(_resource);
@@ -700,8 +692,8 @@ identity_is_resource_referenced(struct pipe_context *_pipe,
 
    return pipe->is_resource_referenced(pipe,
                                        resource,
-                                       face,
-                                       level);
+                                       level,
+                                       layer);
 }
 
 static struct pipe_sampler_view *
@@ -732,10 +724,38 @@ identity_context_sampler_view_destroy(struct pipe_context *_pipe,
                                  identity_sampler_view(_view));
 }
 
+static struct pipe_surface *
+identity_context_create_surface(struct pipe_context *_pipe,
+                                struct pipe_resource *_resource,
+                                const struct pipe_surface *templ)
+{
+   struct identity_context *id_context = identity_context(_pipe);
+   struct identity_resource *id_resource = identity_resource(_resource);
+   struct pipe_context *pipe = id_context->pipe;
+   struct pipe_resource *resource = id_resource->resource;
+   struct pipe_surface *result;
+
+   result = pipe->create_surface(pipe,
+                                 resource,
+                                 templ);
+
+   if (result)
+      return identity_surface_create(id_context, id_resource, result);
+   return NULL;
+}
+
+static void
+identity_context_surface_destroy(struct pipe_context *_pipe,
+                                 struct pipe_surface *_surf)
+{
+   identity_surface_destroy(identity_context(_pipe),
+                            identity_surface(_surf));
+}
+
 static struct pipe_transfer *
 identity_context_get_transfer(struct pipe_context *_context,
                               struct pipe_resource *_resource,
-                              struct pipe_subresource sr,
+                              unsigned level,
                               unsigned usage,
                               const struct pipe_box *box)
 {
@@ -747,7 +767,7 @@ identity_context_get_transfer(struct pipe_context *_context,
 
    result = context->get_transfer(context,
                                   resource,
-                                  sr,
+                                  level,
                                   usage,
                                   box);
 
@@ -812,12 +832,12 @@ identity_context_transfer_unmap(struct pipe_context *_context,
 static void 
 identity_context_transfer_inline_write(struct pipe_context *_context,
                                        struct pipe_resource *_resource,
-                                       struct pipe_subresource sr,
+                                       unsigned level,
                                        unsigned usage,
                                        const struct pipe_box *box,
                                        const void *data,
                                        unsigned stride,
-                                       unsigned slice_stride)
+                                       unsigned layer_stride)
 {
    struct identity_context *id_context = identity_context(_context);
    struct identity_resource *id_resource = identity_resource(_resource);
@@ -826,12 +846,12 @@ identity_context_transfer_inline_write(struct pipe_context *_context,
 
    context->transfer_inline_write(context,
                                   resource,
-                                  sr,
+                                  level,
                                   usage,
                                   box,
                                   data,
                                   stride,
-                                  slice_stride);
+                                  layer_stride);
 }
 
 
@@ -899,6 +919,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    id_pipe->base.clear_depth_stencil = identity_clear_depth_stencil;
    id_pipe->base.flush = identity_flush;
    id_pipe->base.is_resource_referenced = identity_is_resource_referenced;
+   id_pipe->base.create_surface = identity_context_create_surface;
+   id_pipe->base.surface_destroy = identity_context_surface_destroy;
    id_pipe->base.create_sampler_view = identity_context_create_sampler_view;
    id_pipe->base.sampler_view_destroy = identity_context_sampler_view_destroy;
    id_pipe->base.get_transfer = identity_context_get_transfer;
index 593928f399c7edaa7ee904169541f0426e617184..63454410525ee4e8639d794e8bb637962ffb6f83 100644 (file)
@@ -71,7 +71,8 @@ identity_resource_destroy(struct identity_resource *id_resource)
 
 
 struct pipe_surface *
-identity_surface_create(struct identity_resource *id_resource,
+identity_surface_create(struct identity_context *id_context,
+                        struct identity_resource *id_resource,
                         struct pipe_surface *surface)
 {
    struct identity_surface *id_surface;
@@ -100,10 +101,12 @@ error:
 }
 
 void
-identity_surface_destroy(struct identity_surface *id_surface)
+identity_surface_destroy(struct identity_context *id_context,
+                         struct identity_surface *id_surface)
 {
    pipe_resource_reference(&id_surface->base.texture, NULL);
-   pipe_surface_reference(&id_surface->surface, NULL);
+   id_context->pipe->surface_destroy(id_context->pipe,
+                                     id_surface->surface);
    FREE(id_surface);
 }
 
index e8deabf4fc7f3df6d59c141298b39252b656e484..181f2d6623e9dc635522a4f6a10bf84e879a4ffb 100644 (file)
@@ -147,11 +147,13 @@ void
 identity_resource_destroy(struct identity_resource *id_resource);
 
 struct pipe_surface *
-identity_surface_create(struct identity_resource *id_resource,
+identity_surface_create(struct identity_context *id_context,
+                        struct identity_resource *id_resource,
                         struct pipe_surface *surface);
 
 void
-identity_surface_destroy(struct identity_surface *id_surface);
+identity_surface_destroy(struct identity_context *id_context,
+                         struct identity_surface *id_surface);
 
 struct pipe_sampler_view *
 identity_sampler_view_create(struct identity_context *id_context,
index 5fb464b4148837370954788c1aba7f31a0b41168..644481bb7480e3559ff85a86677522d880941091 100644 (file)
@@ -189,39 +189,6 @@ identity_screen_resource_destroy(struct pipe_screen *screen,
    identity_resource_destroy(identity_resource(_resource));
 }
 
-static struct pipe_surface *
-identity_screen_get_tex_surface(struct pipe_screen *_screen,
-                                struct pipe_resource *_resource,
-                                unsigned face,
-                                unsigned level,
-                                unsigned zslice,
-                                unsigned usage)
-{
-   struct identity_screen *id_screen = identity_screen(_screen);
-   struct identity_resource *id_resource = identity_resource(_resource);
-   struct pipe_screen *screen = id_screen->screen;
-   struct pipe_resource *resource = id_resource->resource;
-   struct pipe_surface *result;
-
-   result = screen->get_tex_surface(screen,
-                                    resource,
-                                    face,
-                                    level,
-                                    zslice,
-                                    usage);
-
-   if (result)
-      return identity_surface_create(id_resource, result);
-   return NULL;
-}
-
-static void
-identity_screen_tex_surface_destroy(struct pipe_surface *_surface)
-{
-   identity_surface_destroy(identity_surface(_surface));
-}
-
-
 
 static struct pipe_resource *
 identity_screen_user_buffer_create(struct pipe_screen *_screen,
@@ -247,16 +214,18 @@ identity_screen_user_buffer_create(struct pipe_screen *_screen,
 
 static void
 identity_screen_flush_frontbuffer(struct pipe_screen *_screen,
-                                  struct pipe_surface *_surface,
+                                  struct pipe_resource *_resource,
+                                  unsigned level, unsigned layer,
                                   void *context_private)
 {
    struct identity_screen *id_screen = identity_screen(_screen);
-   struct identity_surface *id_surface = identity_surface(_surface);
+   struct identity_resource *id_resource = identity_resource(_resource);
    struct pipe_screen *screen = id_screen->screen;
-   struct pipe_surface *surface = id_surface->surface;
+   struct pipe_resource *resource = id_resource->resource;
 
    screen->flush_frontbuffer(screen,
-                             surface,
+                             resource,
+                             level, layer,
                              context_private);
 }
 
@@ -323,8 +292,6 @@ identity_screen_create(struct pipe_screen *screen)
    id_screen->base.resource_from_handle = identity_screen_resource_from_handle;
    id_screen->base.resource_get_handle = identity_screen_resource_get_handle;
    id_screen->base.resource_destroy = identity_screen_resource_destroy;
-   id_screen->base.get_tex_surface = identity_screen_get_tex_surface;
-   id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy;
    id_screen->base.user_buffer_create = identity_screen_user_buffer_create;
    id_screen->base.flush_frontbuffer = identity_screen_flush_frontbuffer;
    id_screen->base.fence_reference = identity_screen_fence_reference;
index 669e42e3003cfabb6bf07d29f24330a619acac56..4068bed393c92fc0a54cc0a5aea86641c5a82f82 100644 (file)
@@ -3,8 +3,6 @@ include $(TOP)/configs/current
 
 LIBNAME = llvmpipe
 
-DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
-
 C_SOURCES = \
        lp_bld_alpha.c \
        lp_bld_blend_aos.c \
index e50643790c8aa4c3f6eef0a48e31ada6c118deab..518969c3202bb8d23b08085a2fec5beff3f8976f 100644 (file)
@@ -43,7 +43,7 @@
 
 
 void
-lp_build_alpha_test(LLVMBuilderRef builder,
+lp_build_alpha_test(struct gallivm_state *gallivm,
                     unsigned func,
                     struct lp_type type,
                     struct lp_build_mask_context *mask,
@@ -54,7 +54,7 @@ lp_build_alpha_test(LLVMBuilderRef builder,
    struct lp_build_context bld;
    LLVMValueRef test;
 
-   lp_build_context_init(&bld, builder, type);
+   lp_build_context_init(&bld, gallivm, type);
 
    test = lp_build_cmp(&bld, func, alpha, ref);
 
index 27ca8aad4d4406283fbf44c4ed70d31b932a516d..5c9392504f1c349c93fcaab0cf5adf728c48268b 100644 (file)
@@ -43,7 +43,7 @@ struct lp_build_mask_context;
 
 
 void
-lp_build_alpha_test(LLVMBuilderRef builder,
+lp_build_alpha_test(struct gallivm_state *gallivm,
                     unsigned func,
                     struct lp_type type,
                     struct lp_build_mask_context *mask,
index 5cecec3d7f9f5a7b3757c3c168ec70ea9962b3f7..f82ae30bb7dc8a277f5a48b792075b03c9471b0a 100644 (file)
@@ -30,6 +30,7 @@
 
 
 #include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_init.h"
  
 #include "pipe/p_format.h"
 
@@ -61,7 +62,7 @@ lp_build_blend_func(struct lp_build_context *bld,
 
 
 LLVMValueRef
-lp_build_blend_aos(LLVMBuilderRef builder,
+lp_build_blend_aos(struct gallivm_state *gallivm,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
                    unsigned rt,
@@ -72,7 +73,7 @@ lp_build_blend_aos(LLVMBuilderRef builder,
 
 
 void
-lp_build_blend_soa(LLVMBuilderRef builder,
+lp_build_blend_soa(struct gallivm_state *gallivm,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
                    unsigned rt,
index d1c9b88f9bbf362c0a7ad2a5c9167bb3119c97b9..c342346a36ec33238877f4582b7243f5ed33fa25 100644 (file)
@@ -301,7 +301,7 @@ lp_build_blend_func(struct lp_build_context *bld,
 
 
 LLVMValueRef
-lp_build_blend_aos(LLVMBuilderRef builder,
+lp_build_blend_aos(struct gallivm_state *gallivm,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
                    unsigned rt,
@@ -322,7 +322,7 @@ lp_build_blend_aos(LLVMBuilderRef builder,
 
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
-   lp_build_context_init(&bld.base, builder, type);
+   lp_build_context_init(&bld.base, gallivm, type);
    bld.src = src;
    bld.dst = dst;
    bld.const_ = const_;
index 30d261e979f0228359f2df07ebab77fd875e5c5f..4d5bc9642d928cc328e35d883bbc8dd1208e3f48 100644 (file)
@@ -73,6 +73,7 @@
 
 #include "gallivm/lp_bld_type.h"
 #include "gallivm/lp_bld_arit.h"
+#include "gallivm/lp_bld_init.h"
 #include "lp_bld_blend.h"
 
 
@@ -211,7 +212,7 @@ lp_build_blend_factor_complementary(unsigned src_factor, unsigned dst_factor)
  * \param res  the result/output
  */
 void
-lp_build_blend_soa(LLVMBuilderRef builder,
+lp_build_blend_soa(struct gallivm_state *gallivm,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
                    unsigned rt,
@@ -220,6 +221,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
                    LLVMValueRef con[4],
                    LLVMValueRef res[4])
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_build_blend_soa_context bld;
    unsigned i, j, k;
 
@@ -227,7 +229,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
 
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
-   lp_build_context_init(&bld.base, builder, type);
+   lp_build_context_init(&bld.base, gallivm, type);
    for (i = 0; i < 4; ++i) {
       bld.src[i] = src[i];
       bld.dst[i] = dst[i];
index 7eb76d4fb31d2e3c146b46bebadc1ff9eadefd2c..1bf741194c5ec6d4e4737f380d52874f3085ec13 100644 (file)
@@ -97,6 +97,7 @@ lp_build_stencil_test_single(struct lp_build_context *bld,
                              LLVMValueRef stencilRef,
                              LLVMValueRef stencilVals)
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    const unsigned stencilMax = 255; /* XXX fix */
    struct lp_type type = bld->type;
    LLVMValueRef res;
@@ -107,10 +108,10 @@ lp_build_stencil_test_single(struct lp_build_context *bld,
 
    if (stencil->valuemask != stencilMax) {
       /* compute stencilRef = stencilRef & valuemask */
-      LLVMValueRef valuemask = lp_build_const_int_vec(type, stencil->valuemask);
-      stencilRef = LLVMBuildAnd(bld->builder, stencilRef, valuemask, "");
+      LLVMValueRef valuemask = lp_build_const_int_vec(bld->gallivm, type, stencil->valuemask);
+      stencilRef = LLVMBuildAnd(builder, stencilRef, valuemask, "");
       /* compute stencilVals = stencilVals & valuemask */
-      stencilVals = LLVMBuildAnd(bld->builder, stencilVals, valuemask, "");
+      stencilVals = LLVMBuildAnd(builder, stencilVals, valuemask, "");
    }
 
    res = lp_build_cmp(bld, stencil->func, stencilRef, stencilVals);
@@ -167,9 +168,10 @@ lp_build_stencil_op_single(struct lp_build_context *bld,
                            LLVMValueRef stencilVals)
 
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_type type = bld->type;
    LLVMValueRef res;
-   LLVMValueRef max = lp_build_const_int_vec(type, 0xff);
+   LLVMValueRef max = lp_build_const_int_vec(bld->gallivm, type, 0xff);
    unsigned stencil_op;
 
    assert(type.sign);
@@ -210,15 +212,15 @@ lp_build_stencil_op_single(struct lp_build_context *bld,
       break;
    case PIPE_STENCIL_OP_INCR_WRAP:
       res = lp_build_add(bld, stencilVals, bld->one);
-      res = LLVMBuildAnd(bld->builder, res, max, "");
+      res = LLVMBuildAnd(builder, res, max, "");
       break;
    case PIPE_STENCIL_OP_DECR_WRAP:
       res = lp_build_sub(bld, stencilVals, bld->one);
-      res = LLVMBuildAnd(bld->builder, res, max, "");
+      res = LLVMBuildAnd(builder, res, max, "");
       break;
    case PIPE_STENCIL_OP_INVERT:
-      res = LLVMBuildNot(bld->builder, stencilVals, "");
-      res = LLVMBuildAnd(bld->builder, res, max, "");
+      res = LLVMBuildNot(builder, stencilVals, "");
+      res = LLVMBuildAnd(builder, res, max, "");
       break;
    default:
       assert(0 && "bad stencil op mode");
@@ -242,6 +244,7 @@ lp_build_stencil_op(struct lp_build_context *bld,
                     LLVMValueRef front_facing)
 
 {
+   LLVMBuilderRef builder = bld->gallivm->builder;
    LLVMValueRef res;
 
    assert(stencil[0].enabled);
@@ -262,10 +265,11 @@ lp_build_stencil_op(struct lp_build_context *bld,
 
    if (stencil->writemask != 0xff) {
       /* mask &= stencil->writemask */
-      LLVMValueRef writemask = lp_build_const_int_vec(bld->type, stencil->writemask);
-      mask = LLVMBuildAnd(bld->builder, mask, writemask, "");
+      LLVMValueRef writemask = lp_build_const_int_vec(bld->gallivm, bld->type,
+                                                      stencil->writemask);
+      mask = LLVMBuildAnd(builder, mask, writemask, "");
       /* res = (res & mask) | (stencilVals & ~mask) */
-      res = lp_build_select_bitwise(bld, writemask, res, stencilVals);
+      res = lp_build_select_bitwise(bld, mask, res, stencilVals);
    }
    else {
       /* res = mask ? res : stencilVals */
@@ -411,25 +415,27 @@ get_s_shift_and_mask(const struct util_format_description *format_desc,
  * \param counter is a pointer of the uint32 counter.
  */
 void
-lp_build_occlusion_count(LLVMBuilderRef builder,
+lp_build_occlusion_count(struct gallivm_state *gallivm,
                          struct lp_type type,
                          LLVMValueRef maskvalue,
                          LLVMValueRef counter)
 {
-   LLVMValueRef countmask = lp_build_const_int_vec(type, 1);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMContextRef context = gallivm->context;
+   LLVMValueRef countmask = lp_build_const_int_vec(gallivm, type, 1);
    LLVMValueRef countv = LLVMBuildAnd(builder, maskvalue, countmask, "countv");
-   LLVMTypeRef i8v16 = LLVMVectorType(LLVMInt8Type(), 16);
+   LLVMTypeRef i8v16 = LLVMVectorType(LLVMInt8TypeInContext(context), 16);
    LLVMValueRef counti = LLVMBuildBitCast(builder, countv, i8v16, "counti");
    LLVMValueRef maskarray[4] = {
-      LLVMConstInt(LLVMInt32Type(), 0, 0),
-      LLVMConstInt(LLVMInt32Type(), 4, 0),
-      LLVMConstInt(LLVMInt32Type(), 8, 0),
-      LLVMConstInt(LLVMInt32Type(), 12, 0),
+      lp_build_const_int32(gallivm, 0),
+      lp_build_const_int32(gallivm, 4),
+      lp_build_const_int32(gallivm, 8),
+      lp_build_const_int32(gallivm, 12)
    };
    LLVMValueRef shufflemask = LLVMConstVector(maskarray, 4);
    LLVMValueRef shufflev =  LLVMBuildShuffleVector(builder, counti, LLVMGetUndef(i8v16), shufflemask, "shufflev");
-   LLVMValueRef shuffle = LLVMBuildBitCast(builder, shufflev, LLVMInt32Type(), "shuffle");
-   LLVMValueRef count = lp_build_intrinsic_unary(builder, "llvm.ctpop.i32", LLVMInt32Type(), shuffle);
+   LLVMValueRef shuffle = LLVMBuildBitCast(builder, shufflev, LLVMInt32TypeInContext(context), "shuffle");
+   LLVMValueRef count = lp_build_intrinsic_unary(builder, "llvm.ctpop.i32", LLVMInt32TypeInContext(context), shuffle);
    LLVMValueRef orig = LLVMBuildLoad(builder, counter, "orig");
    LLVMValueRef incr = LLVMBuildAdd(builder, orig, count, "incr");
    LLVMBuildStore(builder, incr, counter);
@@ -452,7 +458,7 @@ lp_build_occlusion_count(LLVMBuilderRef builder,
  * \param facing  contains boolean value indicating front/back facing polygon
  */
 void
-lp_build_depth_stencil_test(LLVMBuilderRef builder,
+lp_build_depth_stencil_test(struct gallivm_state *gallivm,
                             const struct pipe_depth_state *depth,
                             const struct pipe_stencil_state stencil[2],
                             struct lp_type z_src_type,
@@ -465,6 +471,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
                             LLVMValueRef *zs_value,
                             boolean do_branch)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type z_type;
    struct lp_build_context z_bld;
    struct lp_build_context s_bld;
@@ -537,11 +544,11 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
 
 
    /* Setup build context for Z vals */
-   lp_build_context_init(&z_bld, builder, z_type);
+   lp_build_context_init(&z_bld, gallivm, z_type);
 
    /* Setup build context for stencil vals */
    s_type = lp_type_int_vec(z_type.width);
-   lp_build_context_init(&s_bld, builder, s_type);
+   lp_build_context_init(&s_bld, gallivm, s_type);
 
    /* Load current z/stencil value from z/stencil buffer */
    zs_dst_ptr = LLVMBuildBitCast(builder,
@@ -559,14 +566,14 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
 
       if (get_z_shift_and_mask(format_desc, &z_shift, &z_width, &z_mask)) {
          if (z_mask != 0xffffffff) {
-            z_bitmask = lp_build_const_int_vec(z_type, z_mask);
+            z_bitmask = lp_build_const_int_vec(gallivm, z_type, z_mask);
          }
 
          /*
           * Align the framebuffer Z 's LSB to the right.
           */
          if (z_shift) {
-            LLVMValueRef shift = lp_build_const_int_vec(z_type, z_shift);
+            LLVMValueRef shift = lp_build_const_int_vec(gallivm, z_type, z_shift);
             z_dst = LLVMBuildLShr(builder, zs_dst, shift, "z_dst");
          } else if (z_bitmask) {
            /* TODO: Instead of loading a mask from memory and ANDing, it's
@@ -580,7 +587,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
 
       if (get_s_shift_and_mask(format_desc, &s_shift, &s_mask)) {
          if (s_shift) {
-            LLVMValueRef shift = lp_build_const_int_vec(s_type, s_shift);
+            LLVMValueRef shift = lp_build_const_int_vec(gallivm, s_type, s_shift);
             stencil_vals = LLVMBuildLShr(builder, zs_dst, shift, "");
             stencil_shift = shift;  /* used below */
          }
@@ -589,7 +596,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
          }
 
          if (s_mask != 0xffffffff) {
-            LLVMValueRef mask = lp_build_const_int_vec(s_type, s_mask);
+            LLVMValueRef mask = lp_build_const_int_vec(gallivm, s_type, s_mask);
             stencil_vals = LLVMBuildAnd(builder, stencil_vals, mask, "");
          }
 
@@ -600,12 +607,13 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
    if (stencil[0].enabled) {
 
       if (face) {
-         LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, 0);
+         LLVMValueRef zero = lp_build_const_int32(gallivm, 0);
 
          /* front_facing = face != 0 ? ~0 : 0 */
          front_facing = LLVMBuildICmp(builder, LLVMIntNE, face, zero, "");
          front_facing = LLVMBuildSExt(builder, front_facing,
-                                      LLVMIntType(s_bld.type.length*s_bld.type.width),
+                                      LLVMIntTypeInContext(gallivm->context,
+                                             s_bld.type.length*s_bld.type.width),
                                       "");
          front_facing = LLVMBuildBitCast(builder, front_facing,
                                          s_bld.int_vec_type, "");
@@ -642,7 +650,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
           */
 
          if (!z_type.floating) {
-            z_src = lp_build_clamped_float_to_unsigned_norm(builder,
+            z_src = lp_build_clamped_float_to_unsigned_norm(gallivm,
                                                             z_src_type,
                                                             z_width,
                                                             z_src);
@@ -657,7 +665,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
          assert(z_src_type.norm);
          assert(!z_type.floating);
          if (z_src_type.width > z_width) {
-            LLVMValueRef shift = lp_build_const_int_vec(z_src_type,
+            LLVMValueRef shift = lp_build_const_int_vec(gallivm, z_src_type,
                                                         z_src_type.width - z_width);
             z_src = LLVMBuildLShr(builder, z_src, shift, "");
          }
@@ -710,7 +718,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
                                             z_fail_mask, front_facing);
 
          /* apply Z-pass operator */
-         z_pass_mask = LLVMBuildAnd(z_bld.builder, orig_mask, z_pass, "");
+         z_pass_mask = LLVMBuildAnd(builder, orig_mask, z_pass, "");
          stencil_vals = lp_build_stencil_op(&s_bld, stencil, Z_PASS_OP,
                                             stencil_refs, stencil_vals,
                                             z_pass_mask, front_facing);
@@ -720,7 +728,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
       /* No depth test: apply Z-pass operator to stencil buffer values which
        * passed the stencil test.
        */
-      s_pass_mask = LLVMBuildAnd(s_bld.builder, orig_mask, s_pass_mask, "");
+      s_pass_mask = LLVMBuildAnd(builder, orig_mask, s_pass_mask, "");
       stencil_vals = lp_build_stencil_op(&s_bld, stencil, Z_PASS_OP,
                                          stencil_refs, stencil_vals,
                                          s_pass_mask, front_facing);
@@ -728,11 +736,11 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
 
    /* Put Z and ztencil bits in the right place */
    if (z_dst && z_shift) {
-      LLVMValueRef shift = lp_build_const_int_vec(z_type, z_shift);
+      LLVMValueRef shift = lp_build_const_int_vec(gallivm, z_type, z_shift);
       z_dst = LLVMBuildShl(builder, z_dst, shift, "");
    }
    if (stencil_vals && stencil_shift)
-      stencil_vals = LLVMBuildShl(s_bld.builder, stencil_vals,
+      stencil_vals = LLVMBuildShl(builder, stencil_vals,
                                   stencil_shift, "");
 
    /* Finally, merge/store the z/stencil values */
@@ -740,7 +748,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
        (stencil[0].enabled && stencil[0].writemask)) {
 
       if (z_dst && stencil_vals)
-         zs_dst = LLVMBuildOr(z_bld.builder, z_dst, stencil_vals, "");
+         zs_dst = LLVMBuildOr(builder, z_dst, stencil_vals, "");
       else if (z_dst)
          zs_dst = z_dst;
       else
@@ -775,7 +783,7 @@ lp_build_depth_write(LLVMBuilderRef builder,
 
 
 void
-lp_build_deferred_depth_write(LLVMBuilderRef builder,
+lp_build_deferred_depth_write(struct gallivm_state *gallivm,
                               struct lp_type z_src_type,
                               const struct util_format_description *format_desc,
                               struct lp_build_mask_context *mask,
@@ -785,11 +793,12 @@ lp_build_deferred_depth_write(LLVMBuilderRef builder,
    struct lp_type z_type;
    struct lp_build_context z_bld;
    LLVMValueRef z_dst;
+   LLVMBuilderRef builder = gallivm->builder;
 
    /* XXX: pointlessly redo type logic:
     */
    z_type = lp_depth_type(format_desc, z_src_type.width*z_src_type.length);
-   lp_build_context_init(&z_bld, builder, z_type);
+   lp_build_context_init(&z_bld, gallivm, z_type);
 
    zs_dst_ptr = LLVMBuildBitCast(builder, zs_dst_ptr,
                                  LLVMPointerType(z_bld.vec_type, 0), "");
index a54ef3a711e9d40ca7a2b8a27546ba517220eb37..038b136a2817bbea48f15d968e25a0444c1599a1 100644 (file)
@@ -51,7 +51,7 @@ lp_depth_type(const struct util_format_description *format_desc,
 
 
 void
-lp_build_depth_stencil_test(LLVMBuilderRef builder,
+lp_build_depth_stencil_test(struct gallivm_state *gallivm,
                             const struct pipe_depth_state *depth,
                             const struct pipe_stencil_state stencil[2],
                             struct lp_type type,
@@ -71,7 +71,7 @@ lp_build_depth_write(LLVMBuilderRef builder,
                      LLVMValueRef zs_value);
 
 void
-lp_build_deferred_depth_write(LLVMBuilderRef builder,
+lp_build_deferred_depth_write(struct gallivm_state *gallivm,
                               struct lp_type z_src_type,
                               const struct util_format_description *format_desc,
                               struct lp_build_mask_context *mask,
@@ -79,7 +79,7 @@ lp_build_deferred_depth_write(LLVMBuilderRef builder,
                               LLVMValueRef zs_value);
 
 void
-lp_build_occlusion_count(LLVMBuilderRef builder,
+lp_build_occlusion_count(struct gallivm_state *gallivm,
                          struct lp_type type,
                          LLVMValueRef maskvalue,
                          LLVMValueRef counter);
index c9da8900d0c1042510f7d6adab83a4507e68eec6..45ddf547bf0f5f7327b3aafa30181f6c43f7b6a2 100644 (file)
@@ -127,13 +127,14 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
             LLVMValueRef dady_ptr)
 {
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
-   LLVMBuilderRef builder = coeff_bld->builder;
+   struct gallivm_state *gallivm = coeff_bld->gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef zero = LLVMConstNull(coeff_bld->elem_type);
    LLVMValueRef one = LLVMConstReal(coeff_bld->elem_type, 1.0);
-   LLVMValueRef i0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   LLVMValueRef i1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-   LLVMValueRef i2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-   LLVMValueRef i3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+   LLVMValueRef i0 = lp_build_const_int32(gallivm, 0);
+   LLVMValueRef i1 = lp_build_const_int32(gallivm, 1);
+   LLVMValueRef i2 = lp_build_const_int32(gallivm, 2);
+   LLVMValueRef i3 = lp_build_const_int32(gallivm, 3);
    unsigned attrib;
    unsigned chan;
 
@@ -144,7 +145,8 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
       const unsigned interp = bld->interp[attrib];
       for (chan = 0; chan < NUM_CHANNELS; ++chan) {
          if (mask & (1 << chan)) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), attrib*NUM_CHANNELS + chan, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm,
+                                      attrib * NUM_CHANNELS + chan);
             LLVMValueRef a0 = zero;
             LLVMValueRef dadx = zero;
             LLVMValueRef dady = zero;
@@ -231,7 +233,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
              * a = {a, a, a, a}
              */
 
-            a = lp_build_broadcast(builder, coeff_bld->vec_type, a);
+            a = lp_build_broadcast(gallivm, coeff_bld->vec_type, a);
 
             /*
              * Compute the attrib values on the upper-left corner of each quad.
@@ -273,12 +275,14 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
  */
 static void
 attribs_update(struct lp_build_interp_soa_context *bld,
+               struct gallivm_state *gallivm,
                int quad_index,
                int start,
                int end)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
-   LLVMValueRef shuffle = lp_build_const_int_vec(coeff_bld->type, quad_index);
+   LLVMValueRef shuffle = lp_build_const_int_vec(gallivm, coeff_bld->type, quad_index);
    LLVMValueRef oow = NULL;
    unsigned attrib;
    unsigned chan;
@@ -308,7 +312,7 @@ attribs_update(struct lp_build_interp_soa_context *bld,
                 * Broadcast the attribute value for this quad into all elements
                 */
 
-               a = LLVMBuildShuffleVector(coeff_bld->builder,
+               a = LLVMBuildShuffleVector(builder,
                                           a, coeff_bld->undef, shuffle, "");
 
                /*
@@ -380,10 +384,11 @@ pos_init(struct lp_build_interp_soa_context *bld,
          LLVMValueRef x0,
          LLVMValueRef y0)
 {
+   LLVMBuilderRef builder = bld->coeff_bld.gallivm->builder;
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
 
-   bld->x = LLVMBuildSIToFP(coeff_bld->builder, x0, coeff_bld->elem_type, "");
-   bld->y = LLVMBuildSIToFP(coeff_bld->builder, y0, coeff_bld->elem_type, "");
+   bld->x = LLVMBuildSIToFP(builder, x0, coeff_bld->elem_type, "");
+   bld->y = LLVMBuildSIToFP(builder, y0, coeff_bld->elem_type, "");
 }
 
 
@@ -392,6 +397,7 @@ pos_init(struct lp_build_interp_soa_context *bld,
  */
 void
 lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
+                         struct gallivm_state *gallivm,
                          unsigned num_inputs,
                          const struct lp_shader_input *inputs,
                          LLVMBuilderRef builder,
@@ -417,7 +423,7 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
    /* XXX: we don't support interpolating into any other types */
    assert(memcmp(&coeff_type, &type, sizeof coeff_type) == 0);
 
-   lp_build_context_init(&bld->coeff_bld, builder, coeff_type);
+   lp_build_context_init(&bld->coeff_bld, gallivm, coeff_type);
 
    /* For convenience */
    bld->pos = bld->attribs[0];
@@ -453,19 +459,21 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
  */
 void
 lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
+                                  struct gallivm_state *gallivm,
                                   int quad_index)
 {
    assert(quad_index < 4);
 
-   attribs_update(bld, quad_index, 1, bld->num_attribs);
+   attribs_update(bld, gallivm, quad_index, 1, bld->num_attribs);
 }
 
 void
 lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
+                                  struct gallivm_state *gallivm,
                                   int quad_index)
 {
    assert(quad_index < 4);
 
-   attribs_update(bld, quad_index, 0, 1);
+   attribs_update(bld, gallivm, quad_index, 0, 1);
 }
 
index a7ebdd1bfa2771e51dc33c49397510aab84ff9de..b58b2dc11558fd706b80d40561d190a08b3ee904 100644 (file)
@@ -102,6 +102,7 @@ struct lp_build_interp_soa_context
 
 void
 lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
+                         struct gallivm_state *gallivm,
                          unsigned num_inputs,
                          const struct lp_shader_input *inputs,
                          LLVMBuilderRef builder,
@@ -114,11 +115,13 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
 
 void
 lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
-                           int quad_index);
+                                  struct gallivm_state *gallivm,
+                                  int quad_index);
 
 void
 lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
-                           int quad_index);
+                               struct gallivm_state *gallivm,
+                               int quad_index);
 
 
 #endif /* LP_BLD_INTERP_H */
index 763432ed712a197244c515151257d252a8291084..2de20d6e9a339f9db9ae442556e6a279a006d281 100644 (file)
 DEBUG_GET_ONCE_BOOL_OPTION(lp_no_rast, "LP_NO_RAST", FALSE)
 
 
+/** shared by all contexts */
+unsigned llvmpipe_variant_count;
+
+
+/**
+ * This function is called by the gallivm "garbage collector" when
+ * the LLVM global data structures are freed.  We must free all LLVM-related
+ * data.  Specifically, all JIT'd shader variants.
+ */
+static void
+garbage_collect_callback(void *cb_data)
+{
+   struct llvmpipe_context *lp = (struct llvmpipe_context *) cb_data;
+   struct lp_fs_variant_list_item *li;
+
+   /* Free all the context's shader variants */
+   li = first_elem(&lp->fs_variants_list);
+   while (!at_end(&lp->fs_variants_list, li)) {
+      struct lp_fs_variant_list_item *next = next_elem(li);
+      llvmpipe_remove_shader_variant(lp, li->base);
+      li = next;
+   }
+
+   /* Free all the context's primitive setup variants */
+   lp_delete_setup_variants(lp);
+
+   /* release references to setup variants, shaders */
+   lp_setup_set_setup_variant(lp->setup, NULL);
+   lp_setup_set_fs_variant(lp->setup, NULL);
+   lp_setup_reset(lp->setup);
+
+   /* This type will be recreated upon demand */
+   lp->jit_context_ptr_type = NULL;
+
+   /* mark all state as dirty to ensure new shaders are jit'd, etc. */
+   lp->dirty = ~0;
+}
+
+
+
 static void llvmpipe_destroy( struct pipe_context *pipe )
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
@@ -57,6 +97,9 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
 
    lp_print_counters();
 
+   gallivm_remove_garbage_collector_callback(garbage_collect_callback,
+                                             llvmpipe);
+
    /* This will also destroy llvmpipe->setup:
     */
    if (llvmpipe->draw)
@@ -82,7 +125,7 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
       }
    }
 
-   lp_delete_setup_variants(llvmpipe);
+   gallivm_destroy(llvmpipe->gallivm);
 
    align_free( llvmpipe );
 }
@@ -110,8 +153,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
    memset(llvmpipe, 0, sizeof *llvmpipe);
 
    make_empty_list(&llvmpipe->fs_variants_list);
+
    make_empty_list(&llvmpipe->setup_variants_list);
 
+
    llvmpipe->pipe.winsys = screen->winsys;
    llvmpipe->pipe.screen = screen;
    llvmpipe->pipe.priv = priv;
@@ -136,10 +181,12 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
    llvmpipe_init_context_resource_funcs( &llvmpipe->pipe );
    llvmpipe_init_surface_functions(llvmpipe);
 
+   llvmpipe->gallivm = gallivm_create();
+
    /*
     * Create drawing context and plug our rendering stage into it.
     */
-   llvmpipe->draw = draw_create(&llvmpipe->pipe);
+   llvmpipe->draw = draw_create_gallivm(&llvmpipe->pipe, llvmpipe->gallivm);
    if (!llvmpipe->draw)
       goto fail;
 
@@ -173,6 +220,9 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
 
    lp_reset_counters();
 
+   gallivm_register_garbage_collector_callback(garbage_collect_callback,
+                                               llvmpipe);
+
    return &llvmpipe->pipe;
 
  fail:
index db09c95b272c9076675482775d839fefb696192c..503f09d810c770ec058ffafdee0ed6229a9ca1dc 100644 (file)
@@ -104,9 +104,18 @@ struct llvmpipe_context {
    /** Vertex format */
    struct vertex_info vertex_info;
    
+   /** Which vertex shader output slot contains color */
+   int color_slot[2];
+
+   /** Which vertex shader output slot contains bcolor */
+   int bcolor_slot[2];
+
    /** Which vertex shader output slot contains point size */
    int psize_slot;
 
+   /**< minimum resolvable depth value, for polygon offset */   
+   double mrd;
+   
    /** The tiling engine */
    struct lp_setup_context *setup;
    struct lp_setup_variant setup_variant;
@@ -117,14 +126,27 @@ struct llvmpipe_context {
    unsigned tex_timestamp;
    boolean no_rast;
 
+   /** List of all fragment shader variants */
    struct lp_fs_variant_list_item fs_variants_list;
    unsigned nr_fs_variants;
 
+   /** JIT code generation */
+   struct gallivm_state *gallivm;
+   LLVMTypeRef jit_context_ptr_type;
+
    struct lp_setup_variant_list_item setup_variants_list;
    unsigned nr_setup_variants;
 };
 
 
+/**
+ * Fragment and setup variant count, used to trigger garbage collection.
+ * This is global since all variants in all contexts will be free when
+ * we do garbage collection.
+ */
+extern unsigned llvmpipe_variant_count;
+
+
 struct pipe_context *
 llvmpipe_create_context( struct pipe_screen *screen, void *priv );
 
index e2c723b7a873ad64936b66c95ad42ef271777d61..85e3cdec82c0b244240eb4691fa49a5ad6025599 100644 (file)
@@ -56,6 +56,13 @@ llvmpipe_flush( struct pipe_context *pipe,
    /* ask the setup module to flush */
    lp_setup_flush(llvmpipe->setup, flags, fence, reason);
 
+
+   if (llvmpipe_variant_count > 1000) {
+      /* time to do a garbage collection */
+      gallivm_garbage_collect(llvmpipe->gallivm);
+      llvmpipe_variant_count = 0;
+   }
+
    /* Enable to dump BMPs of the color/depth buffers each frame */
    if (0) {
       if (flags & PIPE_FLUSH_FRAME) {
@@ -101,8 +108,8 @@ llvmpipe_finish( struct pipe_context *pipe,
 boolean
 llvmpipe_flush_resource(struct pipe_context *pipe,
                         struct pipe_resource *resource,
-                        unsigned face,
                         unsigned level,
+                        int layer,
                         unsigned flush_flags,
                         boolean read_only,
                         boolean cpu_access,
@@ -111,7 +118,7 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
 {
    unsigned referenced;
 
-   referenced = pipe->is_resource_referenced(pipe, resource, face, level);
+   referenced = pipe->is_resource_referenced(pipe, resource, level, layer);
 
    if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
        ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
index 3626ce4a86c6249e5e3293f6b70ffea297837839..579d24c68ad185b2398070c4d0689c213f088bd6 100644 (file)
@@ -47,8 +47,8 @@ llvmpipe_finish( struct pipe_context *pipe,
 boolean
 llvmpipe_flush_resource(struct pipe_context *pipe,
                         struct pipe_resource *resource,
-                        unsigned face,
                         unsigned level,
+                        int layer,
                         unsigned flush_flags,
                         boolean read_only,
                         boolean cpu_access,
index c540f9b362880ca15e2cdf38a91fee1ae8994641..a775990f92a00417a9266b8775b50e377bc6365b 100644 (file)
  */
 
 
-#include <llvm-c/Transforms/Scalar.h>
-
 #include "util/u_memory.h"
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_debug.h"
-#include "lp_screen.h"
 #include "gallivm/lp_bld_intr.h"
+#include "lp_context.h"
+#include "lp_screen.h"
 #include "lp_jit.h"
 
 
 static void
-lp_jit_init_globals(struct llvmpipe_screen *screen)
+lp_jit_create_types(struct llvmpipe_context *lp)
 {
+   struct gallivm_state *gallivm = lp->gallivm;
+   LLVMContextRef lc = gallivm->context;
    LLVMTypeRef texture_type;
 
    /* struct lp_jit_texture */
    {
       LLVMTypeRef elem_types[LP_JIT_TEXTURE_NUM_FIELDS];
 
-      elem_types[LP_JIT_TEXTURE_WIDTH]  = LLVMInt32Type();
-      elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
-      elem_types[LP_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
-      elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
+      elem_types[LP_JIT_TEXTURE_WIDTH]  =
+      elem_types[LP_JIT_TEXTURE_HEIGHT] =
+      elem_types[LP_JIT_TEXTURE_DEPTH] =
+      elem_types[LP_JIT_TEXTURE_LAST_LEVEL] =  LLVMInt32TypeInContext(lc);
       elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
-         LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
       elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
-         LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
+         LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TEXTURE_LEVELS);
       elem_types[LP_JIT_TEXTURE_DATA] =
-         LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+         LLVMArrayType(LLVMPointerType(LLVMInt8TypeInContext(lc), 0),
                        LP_MAX_TEXTURE_LEVELS);
-      elem_types[LP_JIT_TEXTURE_MIN_LOD] = LLVMFloatType();
-      elem_types[LP_JIT_TEXTURE_MAX_LOD] = LLVMFloatType();
-      elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatType();
+      elem_types[LP_JIT_TEXTURE_MIN_LOD] =
+      elem_types[LP_JIT_TEXTURE_MAX_LOD] =
+      elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(lc);
       elem_types[LP_JIT_TEXTURE_BORDER_COLOR] = 
-         LLVMArrayType(LLVMFloatType(), 4);
+         LLVMArrayType(LLVMFloatTypeInContext(lc), 4);
 
-      texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
+      texture_type = LLVMStructTypeInContext(lc, elem_types,
+                                             Elements(elem_types), 0);
+
+      LLVMInvalidateStructLayout(gallivm->target, texture_type);
 
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_WIDTH);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, height,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_HEIGHT);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, depth,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_DEPTH);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_LAST_LEVEL);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_ROW_STRIDE);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_IMG_STRIDE);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_DATA);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, min_lod,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_MIN_LOD);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, max_lod,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_MAX_LOD);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, lod_bias,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_LOD_BIAS);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, border_color,
-                             screen->target, texture_type,
+                             gallivm->target, texture_type,
                              LP_JIT_TEXTURE_BORDER_COLOR);
 
       LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
-                           screen->target, texture_type);
+                           gallivm->target, texture_type);
 
-      LLVMAddTypeName(screen->module, "texture", texture_type);
+      LLVMAddTypeName(gallivm->module, "texture", texture_type);
    }
 
    /* struct lp_jit_context */
@@ -116,44 +119,47 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
       LLVMTypeRef context_type;
 
-      elem_types[LP_JIT_CTX_CONSTANTS] = LLVMPointerType(LLVMFloatType(), 0);
-      elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatType();
-      elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] = LLVMInt32Type();
-      elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32Type();
-      elem_types[LP_JIT_CTX_BLEND_COLOR] = LLVMPointerType(LLVMInt8Type(), 0);
+      elem_types[LP_JIT_CTX_CONSTANTS] = LLVMPointerType(LLVMFloatTypeInContext(lc), 0);
+      elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc);
+      elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] =
+      elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32TypeInContext(lc);
+      elem_types[LP_JIT_CTX_BLEND_COLOR] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
       elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type,
                                                       PIPE_MAX_SAMPLERS);
 
-      context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
+      context_type = LLVMStructTypeInContext(lc, elem_types,
+                                             Elements(elem_types), 0);
+
+      LLVMInvalidateStructLayout(gallivm->target, context_type);
 
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants,
-                             screen->target, context_type,
+                             gallivm->target, context_type,
                              LP_JIT_CTX_CONSTANTS);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
-                             screen->target, context_type,
+                             gallivm->target, context_type,
                              LP_JIT_CTX_ALPHA_REF);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front,
-                             screen->target, context_type,
+                             gallivm->target, context_type,
                              LP_JIT_CTX_STENCIL_REF_FRONT);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back,
-                             screen->target, context_type,
+                             gallivm->target, context_type,
                              LP_JIT_CTX_STENCIL_REF_BACK);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
-                             screen->target, context_type,
+                             gallivm->target, context_type,
                              LP_JIT_CTX_BLEND_COLOR);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
-                             screen->target, context_type,
+                             gallivm->target, context_type,
                              LP_JIT_CTX_TEXTURES);
       LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
-                           screen->target, context_type);
+                           gallivm->target, context_type);
 
-      LLVMAddTypeName(screen->module, "context", context_type);
+      LLVMAddTypeName(gallivm->module, "context", context_type);
 
-      screen->context_ptr_type = LLVMPointerType(context_type, 0);
+      lp->jit_context_ptr_type = LLVMPointerType(context_type, 0);
    }
 
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
-      LLVMDumpModule(screen->module);
+      LLVMDumpModule(gallivm->module);
    }
 }
 
@@ -161,8 +167,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
 void
 lp_jit_screen_cleanup(struct llvmpipe_screen *screen)
 {
-   if(screen->pass)
-      LLVMDisposePassManager(screen->pass);
+   /* nothing */
 }
 
 
@@ -170,30 +175,14 @@ void
 lp_jit_screen_init(struct llvmpipe_screen *screen)
 {
    lp_build_init();
+}
 
-   screen->module = lp_build_module;
-   screen->provider = lp_build_provider;
-   screen->engine = lp_build_engine;
-   screen->target = lp_build_target;
-
-   screen->pass = LLVMCreateFunctionPassManager(screen->provider);
-   LLVMAddTargetData(screen->target, screen->pass);
-
-   if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
-      /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-       * but there are more on SVN. */
-      /* TODO: Add more passes */
-      LLVMAddCFGSimplificationPass(screen->pass);
-      LLVMAddPromoteMemoryToRegisterPass(screen->pass);
-      LLVMAddConstantPropagationPass(screen->pass);
-      LLVMAddInstructionCombiningPass(screen->pass);
-      LLVMAddGVNPass(screen->pass);
-   } else {
-      /* We need at least this pass to prevent the backends to fail in
-       * unexpected ways.
-       */
-      LLVMAddPromoteMemoryToRegisterPass(screen->pass);
-   }
 
-   lp_jit_init_globals(screen);
+LLVMTypeRef
+lp_jit_get_context_type(struct llvmpipe_context *lp)
+{
+   if (!lp->jit_context_ptr_type)
+      lp_jit_create_types(lp);
+
+   return lp->jit_context_ptr_type;
 }
index 114f21f2d16fa4184a25364a49a807678b224ac3..a6763dce17abf5bcf155096360d1529f5d5267b8 100644 (file)
@@ -120,23 +120,23 @@ enum {
 };
 
 
-#define lp_jit_context_constants(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_CONSTANTS, "constants")
+#define lp_jit_context_constants(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_CONSTANTS, "constants")
 
-#define lp_jit_context_alpha_ref_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_ALPHA_REF, "alpha_ref_value")
+#define lp_jit_context_alpha_ref_value(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_ALPHA_REF, "alpha_ref_value")
 
-#define lp_jit_context_stencil_ref_front_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_FRONT, "stencil_ref_front")
+#define lp_jit_context_stencil_ref_front_value(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_STENCIL_REF_FRONT, "stencil_ref_front")
 
-#define lp_jit_context_stencil_ref_back_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_BACK, "stencil_ref_back")
+#define lp_jit_context_stencil_ref_back_value(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_STENCIL_REF_BACK, "stencil_ref_back")
 
-#define lp_jit_context_blend_color(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color")
+#define lp_jit_context_blend_color(_gallivm, _ptr) \
+   lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color")
 
-#define lp_jit_context_textures(_builder, _ptr) \
-   lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CTX_TEXTURES, "textures")
+#define lp_jit_context_textures(_gallivm, _ptr) \
+   lp_build_struct_get_ptr(_gallivm, _ptr, LP_JIT_CTX_TEXTURES, "textures")
 
 
 
@@ -162,4 +162,8 @@ void
 lp_jit_screen_init(struct llvmpipe_screen *screen);
 
 
+LLVMTypeRef
+lp_jit_get_context_type(struct llvmpipe_context *lp);
+
+
 #endif /* LP_JIT_H */
index decf3bd44991bc46dd3ed45d7c3a4af40e5ec1c2..dafadc1ea9bce176c3a48fa880a0cbb168d9e632 100644 (file)
@@ -47,6 +47,7 @@
 #ifdef DEBUG
 int jit_line = 0;
 const struct lp_rast_state *jit_state = NULL;
+const struct lp_rasterizer_task *jit_task = NULL;
 #endif
 
 
@@ -119,8 +120,8 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
           * and update the tile's layout info.
           */
          (void) llvmpipe_get_texture_tile(lpt,
-                                          zsbuf->face + zsbuf->zslice,
-                                          zsbuf->level,
+                                          zsbuf->u.tex.first_layer,
+                                          zsbuf->u.tex.level,
                                           usage,
                                           task->x,
                                           task->y);
@@ -288,7 +289,6 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
 
 
 
-
 /**
  * Convert the color tile from tiled to linear layout.
  * This is generally only done when we're flushing the scene just prior to
@@ -306,15 +306,15 @@ lp_rast_store_linear_color( struct lp_rasterizer_task *task )
 
    for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
       struct pipe_surface *cbuf = scene->fb.cbufs[buf];
-      const unsigned face_slice = cbuf->face + cbuf->zslice;
-      const unsigned level = cbuf->level;
+      const unsigned layer = cbuf->u.tex.first_layer;
+      const unsigned level = cbuf->u.tex.level;
       struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture);
 
       if (!task->color_tiles[buf])
          continue;
 
       llvmpipe_unswizzle_cbuf_tile(lpt,
-                                   face_slice,
+                                   layer,
                                    level,
                                    task->x, task->y,
                                    task->color_tiles[buf]);
@@ -362,7 +362,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
          depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
 
          /* run shader on 4x4 block */
-         BEGIN_JIT_CALL(state);
+         BEGIN_JIT_CALL(state, task);
          variant->jit_function[RAST_WHOLE]( &state->jit_context,
                                             tile_x + x, tile_y + y,
                                             inputs->frontfacing,
@@ -443,7 +443,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
    assert(lp_check_alignment(state->jit_context.blend_color, 16));
 
    /* run shader on 4x4 block */
-   BEGIN_JIT_CALL(state);
+   BEGIN_JIT_CALL(state, task);
    variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
                                          x, y,
                                          inputs->frontfacing,
index b30408f097bf95e5f323ad74f1b0db07d27a84e3..cd686bc82c13fc3a769359db0e62799c05133d3a 100644 (file)
  */
 #ifdef DEBUG
 
+struct lp_rasterizer_task;
 extern int jit_line;
 extern const struct lp_rast_state *jit_state;
+extern const struct lp_rasterizer_task *jit_task;
 
-#define BEGIN_JIT_CALL(state) \
+#define BEGIN_JIT_CALL(state, task)                  \
    do { \
       jit_line = __LINE__; \
       jit_state = state; \
+      jit_task = task; \
    } while (0)
 
 #define END_JIT_CALL() \
@@ -62,7 +65,7 @@ extern const struct lp_rast_state *jit_state;
 
 #else
 
-#define BEGIN_JIT_CALL(X)
+#define BEGIN_JIT_CALL(X, Y)
 #define END_JIT_CALL()
 
 #endif
@@ -191,8 +194,8 @@ lp_rast_get_color_tile_pointer(struct lp_rasterizer_task *task,
 
       if (usage != LP_TEX_USAGE_WRITE_ALL) {
          llvmpipe_swizzle_cbuf_tile(lpt,
-                                    cbuf->face + cbuf->zslice,
-                                    cbuf->level,
+                                    cbuf->u.tex.first_layer,
+                                    cbuf->u.tex.level,
                                     task->x, task->y,
                                     task->color_tiles[buf]);
       }
@@ -258,7 +261,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
    depth = lp_rast_get_depth_block_pointer(task, x, y);
 
    /* run shader on 4x4 block */
-   BEGIN_JIT_CALL(state);
+   BEGIN_JIT_CALL(state, task);
    variant->jit_function[RAST_WHOLE]( &state->jit_context,
                                       x, y,
                                       inputs->frontfacing,
index a4fdf7cff3626f8d3bf9587f988cef2b9523b285..5d0f5f8b7b58f5dcb451c658f1135b46c0f8b544 100644 (file)
@@ -74,6 +74,7 @@ lp_scene_create( struct pipe_context *pipe )
 void
 lp_scene_destroy(struct lp_scene *scene)
 {
+   lp_fence_reference(&scene->fence, NULL);
    pipe_mutex_destroy(scene->mutex);
    assert(scene->data.head->next == NULL);
    FREE(scene->data.head);
@@ -136,30 +137,30 @@ lp_scene_begin_rasterization(struct lp_scene *scene)
    int i;
 
    //LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
-   
+
    for (i = 0; i < scene->fb.nr_cbufs; i++) {
       struct pipe_surface *cbuf = scene->fb.cbufs[i];
+      assert(cbuf->u.tex.first_layer == cbuf->u.tex.last_layer);
       scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
-                                                        cbuf->level);
+                                                        cbuf->u.tex.level);
 
       scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
-                                                  cbuf->face,
-                                                  cbuf->level,
-                                                  cbuf->zslice,
+                                                  cbuf->u.tex.level,
+                                                  cbuf->u.tex.first_layer,
                                                   LP_TEX_USAGE_READ_WRITE,
                                                   LP_TEX_LAYOUT_LINEAR);
    }
 
    if (fb->zsbuf) {
       struct pipe_surface *zsbuf = scene->fb.zsbuf;
-      scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level);
+      assert(zsbuf->u.tex.first_layer == zsbuf->u.tex.last_layer);
+      scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level);
       scene->zsbuf.blocksize = 
          util_format_get_blocksize(zsbuf->texture->format);
 
       scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
-                                               zsbuf->face,
-                                               zsbuf->level,
-                                               zsbuf->zslice,
+                                               zsbuf->u.tex.level,
+                                               zsbuf->u.tex.first_layer,
                                                LP_TEX_USAGE_READ_WRITE,
                                                LP_TEX_LAYOUT_NONE);
    }
@@ -181,9 +182,8 @@ lp_scene_end_rasterization(struct lp_scene *scene )
       if (scene->cbufs[i].map) {
          struct pipe_surface *cbuf = scene->fb.cbufs[i];
          llvmpipe_resource_unmap(cbuf->texture,
-                                 cbuf->face,
-                                 cbuf->level,
-                                 cbuf->zslice);
+                                 cbuf->u.tex.level,
+                                 cbuf->u.tex.first_layer);
          scene->cbufs[i].map = NULL;
       }
    }
@@ -192,9 +192,8 @@ lp_scene_end_rasterization(struct lp_scene *scene )
    if (scene->zsbuf.map) {
       struct pipe_surface *zsbuf = scene->fb.zsbuf;
       llvmpipe_resource_unmap(zsbuf->texture,
-                             zsbuf->face,
-                             zsbuf->level,
-                             zsbuf->zslice);
+                              zsbuf->u.tex.level,
+                              zsbuf->u.tex.first_layer);
       scene->zsbuf.map = NULL;
    }
 
index ad0ea75b3a3e765fcc6e53f0bb03b168abfd2b5c..9459a3cd113c2fb691b3293d516e6990a0e84df9 100644 (file)
@@ -287,12 +287,13 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
 
 static void
 llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
-                           struct pipe_surface *surface,
+                           struct pipe_resource *resource,
+                           unsigned level, unsigned layer,
                            void *context_private)
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    struct sw_winsys *winsys = screen->winsys;
-   struct llvmpipe_resource *texture = llvmpipe_resource(surface->texture);
+   struct llvmpipe_resource *texture = llvmpipe_resource(resource);
 
    assert(texture->dt);
    if (texture->dt)
index 731526dfabebc72e28d8ddb5a0a0a30a08d29e4f..7f69a11a6e3a1ccb8c46eb35d6a48a5ddabf6097 100644 (file)
 #ifndef LP_SCREEN_H
 #define LP_SCREEN_H
 
-#include "gallivm/lp_bld.h"
-#include <llvm-c/ExecutionEngine.h>
-
-#include "os/os_thread.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_defines.h"
+#include "os/os_thread.h"
+#include "gallivm/lp_bld.h"
 
 
 struct sw_winsys;
@@ -51,14 +49,6 @@ struct llvmpipe_screen
 
    struct sw_winsys *winsys;
 
-   LLVMModuleRef module;
-   LLVMExecutionEngineRef engine;
-   LLVMModuleProviderRef provider;
-   LLVMTargetDataRef target;
-   LLVMPassManagerRef pass;
-
-   LLVMTypeRef context_ptr_type;
-
    unsigned num_threads;
 
    /* Increments whenever textures are modified.  Contexts can track this.
index 6118434d3d36ac828e26de63cedebaf5aefb856d..5d83a1e3579b5d51390b951b51096c6406ddf16a 100644 (file)
@@ -114,7 +114,7 @@ first_point( struct lp_setup_context *setup,
    setup->point( setup, v0 );
 }
 
-static void lp_setup_reset( struct lp_setup_context *setup )
+void lp_setup_reset( struct lp_setup_context *setup )
 {
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
@@ -263,7 +263,6 @@ execute_clears( struct lp_setup_context *setup )
 
 const char *states[] = {
    "FLUSHED",
-   "EMPTY  ",
    "CLEARED",
    "ACTIVE "
 };
@@ -913,6 +912,12 @@ lp_setup_update_state( struct lp_setup_context *setup,
          llvmpipe_update_derived(lp);
       }
 
+      if (lp->setup->dirty) {
+         llvmpipe_update_setup(lp);
+      }
+
+      assert(setup->setup.variant);
+
       /* Will probably need to move this somewhere else, just need  
        * to know about vertex shader point size attribute.
        */
@@ -928,7 +933,7 @@ lp_setup_update_state( struct lp_setup_context *setup,
                    setup->setup.variant->key.size) == 0);
    }
 
-   if (update_scene) {
+   if (update_scene && setup->state != SETUP_ACTIVE) {
       if (!set_scene_state( setup, SETUP_ACTIVE, __FUNCTION__ ))
          return FALSE;
    }
@@ -991,6 +996,8 @@ lp_setup_destroy( struct lp_setup_context *setup )
       lp_scene_destroy(scene);
    }
 
+   lp_fence_reference(&setup->last_fence, NULL);
+
    FREE( setup );
 }
 
index ebb18f813444b3a1c8dc84cce454705ff1c9d09f..0d6e161a2188df54d8a4169ec39bbbf16b269315 100644 (file)
@@ -45,6 +45,9 @@ struct lp_jit_context;
 struct llvmpipe_query;
 struct pipe_fence_handle;
 struct lp_setup_variant;
+struct lp_setup_context;
+
+void lp_setup_reset( struct lp_setup_context *setup );
 
 struct lp_setup_context *
 lp_setup_create( struct pipe_context *pipe,
index 9c1f0fe793903426dd70f4f7baf041d41482087b..384242f81d708ca8c8be93c02679b44d06bed7e2 100644 (file)
@@ -141,6 +141,8 @@ lp_setup_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
    const boolean flatshade_first = setup->flatshade_first;
    unsigned i;
 
+   assert(setup->setup.variant);
+
    if (!lp_setup_update_state(setup, TRUE))
       return;
 
index 0f5f7369e045c28d703d1eff673e0012ae0ad7c9..8725ea39fe971f8523a658d880bd194630c6d658 100644 (file)
@@ -53,6 +53,11 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
    unsigned vs_index;
    uint i;
 
+   llvmpipe->color_slot[0] = ~0;
+   llvmpipe->color_slot[1] = ~0;
+   llvmpipe->bcolor_slot[0] = ~0;
+   llvmpipe->bcolor_slot[1] = ~0;
+
    /*
     * Match FS inputs against VS outputs, emitting the necessary
     * attributes.  Could cache these structs and look them up with a
@@ -76,12 +81,31 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
                                          lpfs->info.base.input_semantic_name[i],
                                          lpfs->info.base.input_semantic_index[i]);
 
+      if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
+          lpfs->info.base.input_semantic_index[i] < 2) {
+         int idx = lpfs->info.base.input_semantic_index[i];
+         llvmpipe->color_slot[idx] = vinfo->num_attribs;
+      }
+
       /*
        * Emit the requested fs attribute for all but position.
        */
       draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
    }
 
+   /* Figure out if we need bcolor as well.
+    */
+   for (i = 0; i < 2; i++) {
+      vs_index = draw_find_shader_output(llvmpipe->draw,
+                                         TGSI_SEMANTIC_BCOLOR, i);
+
+      if (vs_index > 0) {
+         llvmpipe->bcolor_slot[i] = vinfo->num_attribs;
+         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
+      }
+   }
+
+
    /* Figure out if we need pointsize as well.
     */
    vs_index = draw_find_shader_output(llvmpipe->draw,
index 48971510f213d9822b7807c81d062abea18c4c40..2c4943a69f683ca24e7d808fc0a85118ef6fda4a 100644 (file)
 #include <llvm-c/BitWriter.h>
 
 
+/** Fragment shader number (for debugging) */
 static unsigned fs_no = 0;
 
 
-
 /**
  * Expand the relevent bits of mask_input to a 4-dword mask for the 
  * four pixels in a 2x2 quad.  This will set the four elements of the
@@ -115,13 +115,14 @@ static unsigned fs_no = 0;
  * \param mask_input  bitwise mask for the whole 4x4 stamp
  */
 static LLVMValueRef
-generate_quad_mask(LLVMBuilderRef builder,
+generate_quad_mask(struct gallivm_state *gallivm,
                    struct lp_type fs_type,
                    unsigned quad,
                    LLVMValueRef mask_input) /* int32 */
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_type mask_type;
-   LLVMTypeRef i32t = LLVMInt32Type();
+   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
    LLVMValueRef bits[4];
    LLVMValueRef mask;
    int shift;
@@ -136,7 +137,6 @@ generate_quad_mask(LLVMBuilderRef builder,
    /*
     * mask_input >>= (quad * 4)
     */
-   
    switch (quad) {
    case 0:
       shift = 0;
@@ -163,8 +163,9 @@ generate_quad_mask(LLVMBuilderRef builder,
    /*
     * mask = { mask_input & (1 << i), for i in [0,3] }
     */
-
-   mask = lp_build_broadcast(builder, lp_build_vec_type(mask_type), mask_input);
+   mask = lp_build_broadcast(gallivm,
+                             lp_build_vec_type(gallivm, mask_type),
+                             mask_input);
 
    bits[0] = LLVMConstInt(i32t, 1 << 0, 0);
    bits[1] = LLVMConstInt(i32t, 1 << 1, 0);
@@ -176,11 +177,10 @@ generate_quad_mask(LLVMBuilderRef builder,
    /*
     * mask = mask != 0 ? ~0 : 0
     */
-
-   mask = lp_build_compare(builder,
+   mask = lp_build_compare(gallivm,
                            mask_type, PIPE_FUNC_NOTEQUAL,
                            mask,
-                           lp_build_const_int_vec(mask_type, 0));
+                           lp_build_const_int_vec(gallivm, mask_type, 0));
 
    return mask;
 }
@@ -213,7 +213,8 @@ find_output_by_semantic( const struct tgsi_shader_info *info,
  * \param partial_mask  if 1, do mask_input testing
  */
 static void
-generate_fs(struct lp_fragment_shader *shader,
+generate_fs(struct gallivm_state *gallivm,
+            struct lp_fragment_shader *shader,
             const struct lp_fragment_shader_variant_key *key,
             LLVMBuilderRef builder,
             struct lp_type type,
@@ -278,42 +279,42 @@ generate_fs(struct lp_fragment_shader *shader,
 
    assert(i < 4);
 
-   stencil_refs[0] = lp_jit_context_stencil_ref_front_value(builder, context_ptr);
-   stencil_refs[1] = lp_jit_context_stencil_ref_back_value(builder, context_ptr);
+   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(type);
+   vec_type = lp_build_vec_type(gallivm, type);
 
-   consts_ptr = lp_jit_context_constants(builder, context_ptr);
+   consts_ptr = lp_jit_context_constants(gallivm, context_ptr);
 
    memset(outputs, 0, sizeof outputs);
 
    /* Declare the color and z variables */
    for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
-        color[cbuf][chan] = lp_build_alloca(builder, vec_type, "color");
+        color[cbuf][chan] = lp_build_alloca(gallivm, vec_type, "color");
       }
    }
 
    /* do triangle edge testing */
    if (partial_mask) {
-      *pmask = generate_quad_mask(builder, type,
+      *pmask = generate_quad_mask(gallivm, type,
                                   i, mask_input);
    }
    else {
-      *pmask = lp_build_const_int_vec(type, ~0);
+      *pmask = lp_build_const_int_vec(gallivm, type, ~0);
    }
 
    /* 'mask' will control execution based on quad's pixel alive/killed state */
-   lp_build_mask_begin(&mask, builder, type, *pmask);
+   lp_build_mask_begin(&mask, gallivm, type, *pmask);
 
    if (!(depth_mode & EARLY_DEPTH_TEST) && !simple_shader)
       lp_build_mask_check(&mask);
 
-   lp_build_interp_soa_update_pos(interp, i);
+   lp_build_interp_soa_update_pos(interp, gallivm, i);
    z = interp->pos[2];
 
    if (depth_mode & EARLY_DEPTH_TEST) {
-      lp_build_depth_stencil_test(builder,
+      lp_build_depth_stencil_test(gallivm,
                                   &key->depth,
                                   key->stencil,
                                   type,
@@ -330,14 +331,13 @@ generate_fs(struct lp_fragment_shader *shader,
       }
    }
 
-   lp_build_interp_soa_update_inputs(interp, i);
+   lp_build_interp_soa_update_inputs(interp, gallivm, i);
    
    /* Build the actual shader */
-   lp_build_tgsi_soa(builder, tokens, type, &mask,
+   lp_build_tgsi_soa(gallivm, tokens, type, &mask,
                      consts_ptr, interp->pos, interp->inputs,
                      outputs, sampler, &shader->info.base);
 
-
    /* Alpha test */
    if (key->alpha.enabled) {
       int color0 = find_output_by_semantic(&shader->info.base,
@@ -348,10 +348,10 @@ generate_fs(struct lp_fragment_shader *shader,
          LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
          LLVMValueRef alpha_ref_value;
 
-         alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr);
-         alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value);
+         alpha_ref_value = lp_jit_context_alpha_ref_value(gallivm, context_ptr);
+         alpha_ref_value = lp_build_broadcast(gallivm, vec_type, alpha_ref_value);
 
-         lp_build_alpha_test(builder, key->alpha.func, type,
+         lp_build_alpha_test(gallivm, key->alpha.func, type,
                              &mask, alpha, alpha_ref_value,
                              (depth_mode & LATE_DEPTH_TEST) != 0);
       }
@@ -367,7 +367,7 @@ generate_fs(struct lp_fragment_shader *shader,
          z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
       }
 
-      lp_build_depth_stencil_test(builder,
+      lp_build_depth_stencil_test(gallivm,
                                   &key->depth,
                                   key->stencil,
                                   type,
@@ -390,7 +390,7 @@ generate_fs(struct lp_fragment_shader *shader,
        * depth value, update from zs_value with the new mask value and
        * write that out.
        */
-      lp_build_deferred_depth_write(builder,
+      lp_build_deferred_depth_write(gallivm,
                                     type,
                                     zs_format_desc,
                                     &mask,
@@ -420,7 +420,7 @@ generate_fs(struct lp_fragment_shader *shader,
    }
 
    if (counter)
-      lp_build_occlusion_count(builder, type,
+      lp_build_occlusion_count(gallivm, type,
                                lp_build_mask_value(&mask), counter);
 
    *pmask = lp_build_mask_end(&mask);
@@ -437,7 +437,8 @@ generate_fs(struct lp_fragment_shader *shader,
  * \param dst_ptr  the destination color buffer pointer
  */
 static void
-generate_blend(const struct pipe_blend_state *blend,
+generate_blend(struct gallivm_state *gallivm,
+               const struct pipe_blend_state *blend,
                unsigned rt,
                LLVMBuilderRef builder,
                struct lp_type type,
@@ -456,21 +457,21 @@ generate_blend(const struct pipe_blend_state *blend,
    LLVMValueRef res[4];
    unsigned chan;
 
-   lp_build_context_init(&bld, builder, type);
+   lp_build_context_init(&bld, gallivm, type);
 
-   lp_build_mask_begin(&mask_ctx, builder, type, mask);
+   lp_build_mask_begin(&mask_ctx, gallivm, type, mask);
    if (do_branch)
       lp_build_mask_check(&mask_ctx);
 
-   vec_type = lp_build_vec_type(type);
+   vec_type = lp_build_vec_type(gallivm, type);
 
-   const_ptr = lp_jit_context_blend_color(builder, context_ptr);
+   const_ptr = lp_jit_context_blend_color(gallivm, context_ptr);
    const_ptr = LLVMBuildBitCast(builder, const_ptr,
                                 LLVMPointerType(vec_type, 0), "");
 
    /* load constant blend color and colors from the dest color buffer */
    for(chan = 0; chan < 4; ++chan) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
+      LLVMValueRef index = lp_build_const_int32(gallivm, chan);
       con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
 
       dst[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
@@ -480,12 +481,12 @@ generate_blend(const struct pipe_blend_state *blend,
    }
 
    /* do blend */
-   lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res);
+   lp_build_blend_soa(gallivm, blend, type, rt, src, dst, con, res);
 
    /* store results to color buffer */
    for(chan = 0; chan < 4; ++chan) {
       if(blend->rt[rt].colormask & (1 << chan)) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
+         LLVMValueRef index = lp_build_const_int32(gallivm, chan);
          lp_build_name(res[chan], "res.%c", "rgba"[chan]);
          res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
          LLVMBuildStore(builder, res[chan], LLVMBuildGEP(builder, dst_ptr, &index, 1, ""));
@@ -503,11 +504,12 @@ generate_blend(const struct pipe_blend_state *blend,
  * 2x2 pixels.
  */
 static void
-generate_fragment(struct llvmpipe_screen *screen,
+generate_fragment(struct llvmpipe_context *lp,
                   struct lp_fragment_shader *shader,
                   struct lp_fragment_shader_variant *variant,
                   unsigned partial_mask)
 {
+   struct gallivm_state *gallivm = lp->gallivm;
    const struct lp_fragment_shader_variant_key *key = &variant->key;
    struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
    char func_name[256];
@@ -518,6 +520,8 @@ generate_fragment(struct llvmpipe_screen *screen,
    LLVMTypeRef blend_vec_type;
    LLVMTypeRef arg_types[11];
    LLVMTypeRef func_type;
+   LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context);
+   LLVMTypeRef int8_type = LLVMInt8TypeInContext(gallivm->context);
    LLVMValueRef context_ptr;
    LLVMValueRef x;
    LLVMValueRef y;
@@ -579,29 +583,30 @@ generate_fragment(struct llvmpipe_screen *screen,
     * lp_jit.h's lp_jit_frag_func function pointer type, and vice-versa.
     */
 
-   fs_elem_type = lp_build_elem_type(fs_type);
-   fs_int_vec_type = lp_build_int_vec_type(fs_type);
+   fs_elem_type = lp_build_elem_type(gallivm, fs_type);
+   fs_int_vec_type = lp_build_int_vec_type(gallivm, fs_type);
 
-   blend_vec_type = lp_build_vec_type(blend_type);
+   blend_vec_type = lp_build_vec_type(gallivm, blend_type);
 
    util_snprintf(func_name, sizeof(func_name), "fs%u_variant%u_%s", 
                 shader->no, variant->no, partial_mask ? "partial" : "whole");
 
-   arg_types[0] = screen->context_ptr_type;            /* context */
-   arg_types[1] = LLVMInt32Type();                     /* x */
-   arg_types[2] = LLVMInt32Type();                     /* y */
-   arg_types[3] = LLVMInt32Type();                     /* facing */
+   arg_types[0] = lp_jit_get_context_type(lp);         /* context */
+   arg_types[1] = int32_type;                          /* x */
+   arg_types[2] = int32_type;                          /* y */
+   arg_types[3] = int32_type;                          /* facing */
    arg_types[4] = LLVMPointerType(fs_elem_type, 0);    /* a0 */
    arg_types[5] = LLVMPointerType(fs_elem_type, 0);    /* dadx */
    arg_types[6] = LLVMPointerType(fs_elem_type, 0);    /* dady */
    arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0);  /* color */
-   arg_types[8] = LLVMPointerType(LLVMInt8Type(), 0);  /* depth */
-   arg_types[9] = LLVMInt32Type();                     /* mask_input */
-   arg_types[10] = LLVMPointerType(LLVMInt32Type(), 0);/* counter */
+   arg_types[8] = LLVMPointerType(int8_type, 0);       /* depth */
+   arg_types[9] = int32_type;                          /* mask_input */
+   arg_types[10] = LLVMPointerType(int32_type, 0);     /* counter */
 
-   func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
+   func_type = LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context),
+                                arg_types, Elements(arg_types), 0);
 
-   function = LLVMAddFunction(screen->module, func_name, func_type);
+   function = LLVMAddFunction(gallivm->module, func_name, func_type);
    LLVMSetFunctionCallConv(function, LLVMCCallConv);
 
    variant->function[partial_mask] = function;
@@ -643,8 +648,9 @@ generate_fragment(struct llvmpipe_screen *screen,
     * Function body
     */
 
-   block = LLVMAppendBasicBlock(function, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
+   builder = gallivm->builder;
+   assert(builder);
    LLVMPositionBuilderAtEnd(builder, block);
 
    /*
@@ -653,6 +659,7 @@ generate_fragment(struct llvmpipe_screen *screen,
     * already included in the shader key.
     */
    lp_build_interp_soa_init(&interp, 
+                            gallivm,
                             shader->info.base.num_inputs,
                             inputs,
                             builder, fs_type,
@@ -666,7 +673,7 @@ generate_fragment(struct llvmpipe_screen *screen,
    zs_format_desc = util_format_description(key->zsbuf_format);
 
    for(i = 0; i < num_fs; ++i) {
-      LLVMValueRef depth_offset = LLVMConstInt(LLVMInt32Type(),
+      LLVMValueRef depth_offset = LLVMConstInt(int32_type,
                                                i*fs_type.length*zs_format_desc->block.bits/8,
                                                0);
       LLVMValueRef out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS];
@@ -674,7 +681,8 @@ generate_fragment(struct llvmpipe_screen *screen,
 
       depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &depth_offset, 1, "");
 
-      generate_fs(shader, key,
+      generate_fs(gallivm,
+                  shader, key,
                   builder,
                   fs_type,
                   context_ptr,
@@ -700,7 +708,7 @@ generate_fragment(struct llvmpipe_screen *screen,
     */
    for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
       LLVMValueRef color_ptr;
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf, 0);
+      LLVMValueRef index = lp_build_const_int32(gallivm, cbuf);
       LLVMValueRef blend_in_color[NUM_CHANNELS];
       unsigned rt;
 
@@ -715,7 +723,7 @@ generate_fragment(struct llvmpipe_screen *screen,
                LLVMBuildLoad(builder, fs_out_color[cbuf][chan][i], "fs_color_vals");
          }
 
-        lp_build_conv(builder, fs_type, blend_type,
+        lp_build_conv(gallivm, fs_type, blend_type,
                        fs_color_vals,
                        num_fs,
                       &blend_in_color[chan], 1);
@@ -724,11 +732,11 @@ generate_fragment(struct llvmpipe_screen *screen,
       }
 
       if (partial_mask || !variant->opaque) {
-         lp_build_conv_mask(builder, fs_type, blend_type,
+         lp_build_conv_mask(lp->gallivm, fs_type, blend_type,
                             fs_mask, num_fs,
                             &blend_mask, 1);
       } else {
-         blend_mask = lp_build_const_int_vec(blend_type, ~0);
+         blend_mask = lp_build_const_int_vec(lp->gallivm, blend_type, ~0);
       }
 
       color_ptr = LLVMBuildLoad(builder, 
@@ -749,7 +757,8 @@ generate_fragment(struct llvmpipe_screen *screen,
                               !key->alpha.enabled &&
                               !shader->info.base.uses_kill);
 
-         generate_blend(&key->blend,
+         generate_blend(lp->gallivm,
+                        &key->blend,
                         rt,
                         builder,
                         blend_type,
@@ -763,9 +772,6 @@ generate_fragment(struct llvmpipe_screen *screen,
 
    LLVMBuildRetVoid(builder);
 
-   LLVMDisposeBuilder(builder);
-
-
    /* Verify the LLVM IR.  If invalid, dump and abort */
 #ifdef DEBUG
    if(LLVMVerifyFunction(function, LLVMPrintMessageAction)) {
@@ -776,7 +782,7 @@ generate_fragment(struct llvmpipe_screen *screen,
 #endif
 
    /* Apply optimizations to LLVM IR */
-   LLVMRunFunctionPassManager(screen->pass, function);
+   LLVMRunFunctionPassManager(gallivm->passmgr, function);
 
    if ((gallivm_debug & GALLIVM_DEBUG_IR) || (LP_DEBUG & DEBUG_FS)) {
       /* Print the LLVM IR to stderr */
@@ -786,14 +792,14 @@ generate_fragment(struct llvmpipe_screen *screen,
 
    /* Dump byte code to a file */
    if (0) {
-      LLVMWriteBitcodeToFile(lp_build_module, "llvmpipe.bc");
+      LLVMWriteBitcodeToFile(gallivm->module, "llvmpipe.bc");
    }
 
    /*
     * Translate the LLVM IR into machine code.
     */
    {
-      void *f = LLVMGetPointerToGlobal(screen->engine, function);
+      void *f = LLVMGetPointerToGlobal(gallivm->engine, function);
 
       variant->jit_function[partial_mask] = (lp_jit_frag_func)pointer_to_func(f);
 
@@ -897,8 +903,13 @@ lp_debug_fs_variant(const struct lp_fragment_shader_variant *variant)
    debug_printf("\n");
 }
 
+
+/**
+ * Generate a new fragment shader variant from the shader code and
+ * other state indicated by the key.
+ */
 static struct lp_fragment_shader_variant *
-generate_variant(struct llvmpipe_screen *screen,
+generate_variant(struct llvmpipe_context *lp,
                  struct lp_fragment_shader *shader,
                  const struct lp_fragment_shader_variant_key *key)
 {
@@ -944,11 +955,11 @@ generate_variant(struct llvmpipe_screen *screen,
       lp_debug_fs_variant(variant);
    }
 
-   generate_fragment(screen, shader, variant, RAST_EDGE_TEST);
+   generate_fragment(lp, shader, variant, RAST_EDGE_TEST);
 
    if (variant->opaque) {
       /* Specialized shader, which doesn't need to read the color buffer. */
-      generate_fragment(screen, shader, variant, RAST_WHOLE);
+      generate_fragment(lp, shader, variant, RAST_WHOLE);
    } else {
       variant->jit_function[RAST_WHOLE] = variant->jit_function[RAST_EDGE_TEST];
    }
@@ -1033,7 +1044,8 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
 
    if (LP_DEBUG & DEBUG_TGSI) {
       unsigned attrib;
-      debug_printf("llvmpipe: Create fragment shader #%u %p:\n", shader->no, (void *) shader);
+      debug_printf("llvmpipe: Create fragment shader #%u %p:\n",
+                   shader->no, (void *) shader);
       tgsi_dump(templ->tokens, 0);
       debug_printf("usage masks:\n");
       for (attrib = 0; attrib < shader->info.base.num_inputs; ++attrib) {
@@ -1070,33 +1082,49 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
    llvmpipe->dirty |= LP_NEW_FS;
 }
 
-static void
-remove_shader_variant(struct llvmpipe_context *lp,
-                      struct lp_fragment_shader_variant *variant)
+
+/**
+ * Remove shader variant from two lists: the shader's variant list
+ * and the context's variant list.
+ */
+void
+llvmpipe_remove_shader_variant(struct llvmpipe_context *lp,
+                               struct lp_fragment_shader_variant *variant)
 {
-   struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
    unsigned i;
 
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
-      debug_printf("llvmpipe: del fs #%u var #%u v created #%u v cached #%u v total cached #%u\n",
-                    variant->shader->no, variant->no, variant->shader->variants_created,
-                    variant->shader->variants_cached, lp->nr_fs_variants);
+      debug_printf("llvmpipe: del fs #%u var #%u v created #%u v cached"
+                   " #%u v total cached #%u\n",
+                   variant->shader->no,
+                   variant->no,
+                   variant->shader->variants_created,
+                   variant->shader->variants_cached,
+                   lp->nr_fs_variants);
    }
+
+   /* free all the variant's JIT'd functions */
    for (i = 0; i < Elements(variant->function); i++) {
       if (variant->function[i]) {
          if (variant->jit_function[i])
-            LLVMFreeMachineCodeForFunction(screen->engine,
+            LLVMFreeMachineCodeForFunction(lp->gallivm->engine,
                                            variant->function[i]);
          LLVMDeleteFunction(variant->function[i]);
       }
    }
+
+   /* remove from shader's list */
    remove_from_list(&variant->list_item_local);
    variant->shader->variants_cached--;
+
+   /* remove from context's list */
    remove_from_list(&variant->list_item_global);
    lp->nr_fs_variants--;
+
    FREE(variant);
 }
 
+
 static void
 llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
 {
@@ -1105,23 +1133,23 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
    struct lp_fs_variant_list_item *li;
 
    assert(fs != llvmpipe->fs);
-   (void) llvmpipe;
 
    /*
     * XXX: we need to flush the context until we have some sort of reference
     * counting in fragment shaders as they may still be binned
     * Flushing alone might not sufficient we need to wait on it too.
     */
-
    llvmpipe_finish(pipe, __FUNCTION__);
 
+   /* Delete all the variants */
    li = first_elem(&shader->variants);
    while(!at_end(&shader->variants, li)) {
       struct lp_fs_variant_list_item *next = next_elem(li);
-      remove_shader_variant(llvmpipe, li->base);
+      llvmpipe_remove_shader_variant(llvmpipe, li->base);
       li = next;
    }
 
+   /* Delete draw module's data */
    draw_delete_fragment_shader(llvmpipe->draw, shader->draw_data);
 
    assert(shader->variants_cached == 0);
@@ -1277,14 +1305,15 @@ make_variant_key(struct llvmpipe_context *lp,
    }
 }
 
+
+
 /**
- * Update fragment state.  This is called just prior to drawing
+ * Update fragment shader state.  This is called just prior to drawing
  * something when some fragment-related state has changed.
  */
 void 
 llvmpipe_update_fs(struct llvmpipe_context *lp)
 {
-   struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
    struct lp_fragment_shader *shader = lp->fs;
    struct lp_fragment_shader_variant_key key;
    struct lp_fragment_shader_variant *variant = NULL;
@@ -1292,6 +1321,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
 
    make_variant_key(lp, shader, &key);
 
+   /* Search the variants for one which matches the key */
    li = first_elem(&shader->variants);
    while(!at_end(&shader->variants, li)) {
       if(memcmp(&li->base->key, &key, shader->variant_key_size) == 0) {
@@ -1302,36 +1332,49 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
    }
 
    if (variant) {
+      /* Move this variant to the head of the list to implement LRU
+       * deletion of shader's when we have too many.
+       */
       move_to_head(&lp->fs_variants_list, &variant->list_item_global);
    }
    else {
-      int64_t t0, t1;
-      int64_t dt;
+      /* variant not found, create it now */
+      int64_t t0, t1, dt;
       unsigned i;
+
+      /* First, check if we've exceeded the max number of shader variants.
+       * If so, free 25% of them (the least recently used ones).
+       */
       if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
          struct pipe_context *pipe = &lp->pipe;
 
          /*
-          * XXX: we need to flush the context until we have some sort of reference
-          * counting in fragment shaders as they may still be binned
+          * XXX: we need to flush the context until we have some sort of
+          * reference counting in fragment shaders as they may still be binned
           * Flushing alone might not be sufficient we need to wait on it too.
           */
          llvmpipe_finish(pipe, __FUNCTION__);
 
          for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
-            struct lp_fs_variant_list_item *item = last_elem(&lp->fs_variants_list);
-            remove_shader_variant(lp, item->base);
+            struct lp_fs_variant_list_item *item;
+            item = last_elem(&lp->fs_variants_list);
+            llvmpipe_remove_shader_variant(lp, item->base);
          }
       }
-      t0 = os_time_get();
-
-      variant = generate_variant(screen, shader, &key);
 
+      /*
+       * Generate the new variant.
+       */
+      t0 = os_time_get();
+      variant = generate_variant(lp, shader, &key);
       t1 = os_time_get();
       dt = t1 - t0;
       LP_COUNT_ADD(llvm_compile_time, dt);
       LP_COUNT_ADD(nr_llvm_compiles, 2);  /* emit vs. omit in/out test */
 
+      llvmpipe_variant_count++;
+
+      /* Put the new variant into the list */
       if (variant) {
          insert_at_head(&shader->variants, &variant->list_item_local);
          insert_at_head(&lp->fs_variants_list, &variant->list_item_global);
@@ -1340,6 +1383,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
       }
    }
 
+   /* Bind this variant */
    lp_setup_set_fs_variant(lp->setup, variant);
 }
 
index 7d58c4936c7944580f7639c8eb74b7b34926e07e..98410c69359c1ce02825392be3a516f7ef298ba8 100644 (file)
@@ -69,12 +69,15 @@ struct lp_fragment_shader_variant_key
    struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
 };
 
+
+/** doubly-linked list item */
 struct lp_fs_variant_list_item
 {
    struct lp_fragment_shader_variant *base;
    struct lp_fs_variant_list_item *next, *prev;
 };
 
+
 struct lp_fragment_shader_variant
 {
    struct lp_fragment_shader_variant_key key;
@@ -118,5 +121,9 @@ struct lp_fragment_shader
 void
 lp_debug_fs_variant(const struct lp_fragment_shader_variant *variant);
 
+void
+llvmpipe_remove_shader_variant(struct llvmpipe_context *lp,
+                               struct lp_fragment_shader_variant *variant);
+
 
 #endif /* LP_STATE_FS_H_ */
index dbd73812e458ce4541c9e5493c385d9ab21ccb9a..574f9e940efe7eaa4564a385597c5680ada5992c 100644 (file)
 #include "lp_setup.h"
 #include "draw/draw_context.h"
 
+struct lp_rast_state {
+   struct pipe_rasterizer_state lp_state;
+   struct pipe_rasterizer_state draw_state;
+};
+
+/* State which might be handled in either the draw module or locally.
+ * This function is used to turn that state off in one of the two
+ * places.
+ */
+static void
+clear_flags(struct pipe_rasterizer_state *rast)
+{
+   rast->light_twoside = 0;
+   rast->offset_tri = 0;
+}
+
 
 
 static void *
 llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
                                  const struct pipe_rasterizer_state *rast)
 {
-   /* We do nothing special with rasterizer state.
-    * The CSO handle is just a pointer to a pipe_rasterizer_state object.
+   boolean need_pipeline;
+
+   /* Partition rasterizer state into what we want the draw module to
+    * handle, and what we'll look after ourselves.
+    */
+   struct lp_rast_state *state = MALLOC_STRUCT(lp_rast_state);
+   if (state == NULL)
+      return NULL;
+
+   memcpy(&state->draw_state, rast, sizeof *rast);
+   memcpy(&state->lp_state, rast, sizeof *rast);
+
+   /* We rely on draw module to do unfilled polyons, AA lines and
+    * points and stipple.
+    * 
+    * Over time, reduce this list of conditions, and expand the list
+    * of flags which get cleared in clear_flags().
     */
-   return mem_dup(rast, sizeof(*rast));
+   need_pipeline = (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
+                   rast->fill_back != PIPE_POLYGON_MODE_FILL ||
+                   rast->point_smooth ||
+                   rast->line_smooth ||
+                   rast->line_stipple_enable ||
+                   rast->poly_stipple_enable);
+
+   /* If not using the pipeline, clear out the flags which we can
+    * handle ourselves.  If we *are* using the pipeline, do everything
+    * on the pipeline and clear those flags on our internal copy of
+    * the state.
+    */
+   if (need_pipeline)
+      clear_flags(&state->lp_state);
+   else
+      clear_flags(&state->draw_state);
+
+   return state;
 }
 
 
@@ -50,36 +98,33 @@ static void
 llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
-   const struct pipe_rasterizer_state *rasterizer =
-      (const struct pipe_rasterizer_state *) handle;
-
-   if (llvmpipe->rasterizer == rasterizer)
-      return;
+   const struct lp_rast_state *state =
+      (const struct lp_rast_state *) handle;
 
-   /* pass-through to draw module */
-   draw_set_rasterizer_state(llvmpipe->draw, rasterizer, handle);
+   if (state) {
+      llvmpipe->rasterizer = &state->lp_state;
+      draw_set_rasterizer_state(llvmpipe->draw, &state->draw_state, handle);
 
-   llvmpipe->rasterizer = rasterizer;
-
-   /* Note: we can immediately set the triangle state here and
-    * not worry about binning because we handle culling during
-    * triangle setup, not when rasterizing the bins.
-    */
-   if (llvmpipe->rasterizer) {
+      /* XXX: just pass lp_state directly to setup.
+       */
       lp_setup_set_triangle_state( llvmpipe->setup,
-                   llvmpipe->rasterizer->cull_face,
-                   llvmpipe->rasterizer->front_ccw,
-                   llvmpipe->rasterizer->scissor,
-                   llvmpipe->rasterizer->gl_rasterization_rules);
+                                  state->lp_state.cull_face,
+                                  state->lp_state.front_ccw,
+                                  state->lp_state.scissor,
+                                  state->lp_state.gl_rasterization_rules);
       lp_setup_set_flatshade_first( llvmpipe->setup,
-                   llvmpipe->rasterizer->flatshade_first);
+                                   state->lp_state.flatshade_first);
       lp_setup_set_line_state( llvmpipe->setup,
-                   llvmpipe->rasterizer->line_width);
+                              state->lp_state.line_width);
       lp_setup_set_point_state( llvmpipe->setup,
-                   llvmpipe->rasterizer->point_size,
-                   llvmpipe->rasterizer->point_size_per_vertex,
-                   llvmpipe->rasterizer->sprite_coord_enable,
-                   llvmpipe->rasterizer->sprite_coord_mode);
+                               state->lp_state.point_size,
+                               state->lp_state.point_size_per_vertex,
+                               state->lp_state.sprite_coord_enable,
+                               state->lp_state.sprite_coord_mode);
+   }
+   else {
+      llvmpipe->rasterizer = NULL;
+      draw_set_rasterizer_state(llvmpipe->draw, NULL, handle);      
    }
 
    llvmpipe->dirty |= LP_NEW_RASTERIZER;
index 2c8b8b9a928af603a66c4b26e5ce6161fd8889f6..ad751b9ef42f1e78f13dc54593dee3f05cffaff3 100644 (file)
 #include "util/u_memory.h"
 #include "util/u_simple_list.h"
 #include "os/os_time.h"
+#include "gallivm/lp_bld_arit.h"
+#include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_debug.h"
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_intr.h"
+#include "gallivm/lp_bld_flow.h"
+#include "gallivm/lp_bld_type.h"
 #include <llvm-c/Analysis.h>   /* for LLVMVerifyFunction */
 
 #include "lp_perf.h"
@@ -40,8 +44,6 @@
 #include "lp_flush.h"
 #include "lp_screen.h"
 #include "lp_context.h"
-#include "lp_setup_context.h"
-#include "lp_rast.h"
 #include "lp_state.h"
 #include "lp_state_fs.h"
 #include "lp_state_setup.h"
@@ -74,26 +76,37 @@ struct lp_setup_args
    LLVMValueRef dy01_ooa;
    LLVMValueRef dx20_ooa;
    LLVMValueRef dx01_ooa;
+
+   /* Temporary, per-attribute:
+    */
+   LLVMValueRef v0a;
+   LLVMValueRef v1a;
+   LLVMValueRef v2a;
 };
 
-static LLVMTypeRef type4f(void)
+
+
+static LLVMTypeRef
+type4f(struct gallivm_state *gallivm)
 {
-   return LLVMVectorType(LLVMFloatType(), 4);
+   return LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4);
 }
 
 
 /* Equivalent of _mm_setr_ps(a,b,c,d)
  */
-static LLVMValueRef vec4f(LLVMBuilderRef bld,
-                         LLVMValueRef a, LLVMValueRef b, LLVMValueRef c, LLVMValueRef d,
-                         const char *name)
+static LLVMValueRef
+vec4f(struct gallivm_state *gallivm,
+      LLVMValueRef a, LLVMValueRef b, LLVMValueRef c, LLVMValueRef d,
+      const char *name)
 {
-   LLVMValueRef i0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   LLVMValueRef i1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-   LLVMValueRef i2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-   LLVMValueRef i3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+   LLVMBuilderRef bld = gallivm->builder;
+   LLVMValueRef i0 = lp_build_const_int32(gallivm, 0);
+   LLVMValueRef i1 = lp_build_const_int32(gallivm, 1);
+   LLVMValueRef i2 = lp_build_const_int32(gallivm, 2);
+   LLVMValueRef i3 = lp_build_const_int32(gallivm, 3);
 
-   LLVMValueRef res = LLVMGetUndef(type4f());
+   LLVMValueRef res = LLVMGetUndef(type4f(gallivm));
 
    res = LLVMBuildInsertElement(bld, res, a, i0, "");
    res = LLVMBuildInsertElement(bld, res, b, i1, "");
@@ -105,15 +118,17 @@ static LLVMValueRef vec4f(LLVMBuilderRef bld,
 
 /* Equivalent of _mm_set1_ps(a)
  */
-static LLVMValueRef vec4f_from_scalar(LLVMBuilderRef bld,
-                                     LLVMValueRef a,
-                                     const char *name)
+static LLVMValueRef
+vec4f_from_scalar(struct gallivm_state *gallivm,
+                  LLVMValueRef a,
+                  const char *name)
 {
-   LLVMValueRef res = LLVMGetUndef(type4f());
+   LLVMBuilderRef bld = gallivm->builder;
+   LLVMValueRef res = LLVMGetUndef(type4f(gallivm));
    int i;
 
    for(i = 0; i < 4; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef index = lp_build_const_int32(gallivm, i);
       res = LLVMBuildInsertElement(bld, res, a, index, i == 3 ? name : "");
    }
 
@@ -121,14 +136,15 @@ static LLVMValueRef vec4f_from_scalar(LLVMBuilderRef bld,
 }
 
 static void
-store_coef(LLVMBuilderRef builder,
+store_coef(struct gallivm_state *gallivm,
           struct lp_setup_args *args,
           unsigned slot,
           LLVMValueRef a0,
           LLVMValueRef dadx,
           LLVMValueRef dady)
 {
-   LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), slot, 0);
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef idx = lp_build_const_int32(gallivm, slot);
    
    LLVMBuildStore(builder,
                  a0, 
@@ -146,19 +162,14 @@ store_coef(LLVMBuilderRef builder,
 
 
 static void 
-emit_constant_coef4( LLVMBuilderRef builder,
+emit_constant_coef4(struct gallivm_state *gallivm,
                     struct lp_setup_args *args,
                     unsigned slot,
-                    LLVMValueRef vert,
-                    unsigned attr)
+                    LLVMValueRef vert)
 {
-   LLVMValueRef zero      = LLVMConstReal(LLVMFloatType(), 0.0);
-   LLVMValueRef zerovec   = vec4f_from_scalar(builder, zero, "zero");
-   LLVMValueRef idx       = LLVMConstInt(LLVMInt32Type(), attr, 0);
-   LLVMValueRef attr_ptr  = LLVMBuildGEP(builder, vert, &idx, 1, "attr_ptr");
-   LLVMValueRef vert_attr = LLVMBuildLoad(builder, attr_ptr, "vert_attr");
-
-   store_coef(builder, args, slot, vert_attr, zerovec, zerovec);
+   LLVMValueRef zero      = lp_build_const_float(gallivm, 0.0);
+   LLVMValueRef zerovec   = vec4f_from_scalar(gallivm, zero, "zero");
+   store_coef(gallivm, args, slot, vert, zerovec, zerovec);
 }
 
 
@@ -168,43 +179,194 @@ emit_constant_coef4( LLVMBuilderRef builder,
  * \param frontface  is the triangle front facing?
  */
 static void 
-emit_facing_coef( LLVMBuilderRef builder,
+emit_facing_coef(struct gallivm_state *gallivm,
                  struct lp_setup_args *args,
                  unsigned slot )
 {
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context);
    LLVMValueRef a0_0 = args->facing;
-   LLVMValueRef a0_0f = LLVMBuildSIToFP(builder, a0_0, LLVMFloatType(), "");
-   LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
-   LLVMValueRef a0      = vec4f(builder, a0_0f, zero, zero, zero, "facing");
-   LLVMValueRef zerovec = vec4f_from_scalar(builder, zero, "zero");
+   LLVMValueRef a0_0f = LLVMBuildSIToFP(builder, a0_0, float_type, "");
+   LLVMValueRef zero = lp_build_const_float(gallivm, 0.0);
+   LLVMValueRef a0 = vec4f(gallivm, a0_0f, zero, zero, zero, "facing");
+   LLVMValueRef zerovec = vec4f_from_scalar(gallivm, zero, "zero");
 
-   store_coef(builder, args, slot, a0, zerovec, zerovec);
+   store_coef(gallivm, args, slot, a0, zerovec, zerovec);
 }
 
 
 static LLVMValueRef
-vert_attrib(LLVMBuilderRef b,
+vert_attrib(struct gallivm_state *gallivm,
            LLVMValueRef vert,
            int attr,
            int elem,
            const char *name)
 {
+   LLVMBuilderRef b = gallivm->builder;
    LLVMValueRef idx[2];
-   idx[0] = LLVMConstInt(LLVMInt32Type(), attr, 0);
-   idx[1] = LLVMConstInt(LLVMInt32Type(), elem, 0);
+   idx[0] = lp_build_const_int32(gallivm, attr);
+   idx[1] = lp_build_const_int32(gallivm, elem);
    return LLVMBuildLoad(b, LLVMBuildGEP(b, vert, idx, 2, ""), name);
 }
 
+static LLVMValueRef
+vert_clamp(LLVMBuilderRef b,
+           LLVMValueRef x,
+           LLVMValueRef min,
+           LLVMValueRef max)
+{
+   LLVMValueRef min_result = LLVMBuildFCmp(b, LLVMRealUGT, min, x, "");
+   LLVMValueRef max_result = LLVMBuildFCmp(b, LLVMRealUGT, x, max, "");
+   LLVMValueRef clamp_value;
+
+   clamp_value = LLVMBuildSelect(b, min_result, min, x, "");
+   clamp_value = LLVMBuildSelect(b, max_result, max, x, "");
 
+   return clamp_value;
+}
+
+static void
+lp_twoside(struct gallivm_state *gallivm,
+           struct lp_setup_args *args,
+           const struct lp_setup_variant_key *key,
+           int bcolor_slot)
+{
+   LLVMBuilderRef b = gallivm->builder;
+   LLVMValueRef a0_back, a1_back, a2_back;
+   LLVMValueRef idx2 = lp_build_const_int32(gallivm, bcolor_slot);
+
+   LLVMValueRef facing = args->facing;
+   LLVMValueRef front_facing = LLVMBuildICmp(b, LLVMIntEQ, facing, lp_build_const_int32(gallivm, 0), ""); /** need i1 for if condition */
+   
+   a0_back = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx2, 1, ""), "v0a_back");
+   a1_back = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx2, 1, ""), "v1a_back");
+   a2_back = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx2, 1, ""), "v2a_back");
+
+   /* Possibly swap the front and back attrib values,
+    *
+    * Prefer select to if so we don't have to worry about phis or
+    * allocas.
+    */
+   args->v0a = LLVMBuildSelect(b, front_facing, a0_back, args->v0a, "");
+   args->v1a = LLVMBuildSelect(b, front_facing, a1_back, args->v1a, "");
+   args->v2a = LLVMBuildSelect(b, front_facing, a2_back, args->v2a, "");
+
+}
+
+static void
+lp_do_offset_tri(struct gallivm_state *gallivm,
+                 struct lp_setup_args *args,
+                 const struct lp_setup_variant_key *key)
+{
+   LLVMBuilderRef b = gallivm->builder;
+   struct lp_build_context bld;
+   LLVMValueRef zoffset, mult;
+   LLVMValueRef z0_new, z1_new, z2_new;
+   LLVMValueRef dzdx0, dzdx, dzdy0, dzdy;
+   LLVMValueRef max, max_value;
+   
+   LLVMValueRef one  = lp_build_const_float(gallivm, 1.0);
+   LLVMValueRef zero = lp_build_const_float(gallivm, 0.0);
+   LLVMValueRef two  = lp_build_const_int32(gallivm, 2);
+
+   /* edge vectors: e = v0 - v2, f = v1 - v2 */
+   LLVMValueRef v0_x = vert_attrib(gallivm, args->v0, 0, 0, "v0_x");
+   LLVMValueRef v1_x = vert_attrib(gallivm, args->v1, 0, 0, "v1_x");
+   LLVMValueRef v2_x = vert_attrib(gallivm, args->v2, 0, 0, "v2_x");
+   LLVMValueRef v0_y = vert_attrib(gallivm, args->v0, 0, 1, "v0_y");
+   LLVMValueRef v1_y = vert_attrib(gallivm, args->v1, 0, 1, "v1_y");
+   LLVMValueRef v2_y = vert_attrib(gallivm, args->v2, 0, 1, "v2_y");
+   LLVMValueRef v0_z = vert_attrib(gallivm, args->v0, 0, 2, "v0_z");
+   LLVMValueRef v1_z = vert_attrib(gallivm, args->v1, 0, 2, "v1_z");
+   LLVMValueRef v2_z = vert_attrib(gallivm, args->v2, 0, 2, "v2_z");
+   /* edge vectors: e = v0 - v2, f = v1 - v2 */
+   LLVMValueRef dx02 = LLVMBuildFSub(b, v0_x, v2_x, "dx02");
+   LLVMValueRef dy02 = LLVMBuildFSub(b, v0_y, v2_y, "dy02");
+   LLVMValueRef dz02 = LLVMBuildFSub(b, v0_z, v2_z, "dz02");
+   LLVMValueRef dx12 = LLVMBuildFSub(b, v1_x, v2_x, "dx12"); 
+   LLVMValueRef dy12 = LLVMBuildFSub(b, v1_y, v2_y, "dy12");
+   LLVMValueRef dz12 = LLVMBuildFSub(b, v1_z, v2_z, "dz12");
+   /* det = cross(e,f).z */
+   LLVMValueRef dx02_dy12  = LLVMBuildFMul(b, dx02, dy12, "dx02_dy12");
+   LLVMValueRef dy02_dx12  = LLVMBuildFMul(b, dy02, dx12, "dy02_dx12");
+   LLVMValueRef det  = LLVMBuildFSub(b, dx02_dy12, dy02_dx12, "det");
+   LLVMValueRef inv_det = LLVMBuildFDiv(b, one, det, "inv_det"); 
+   
+   /* (res1,res2) = cross(e,f).xy */
+   LLVMValueRef dy02_dz12    = LLVMBuildFMul(b, dy02, dz12, "dy02_dz12");
+   LLVMValueRef dz02_dy12    = LLVMBuildFMul(b, dz02, dy12, "dz02_dy12");
+   LLVMValueRef dz02_dx12    = LLVMBuildFMul(b, dz02, dx12, "dz02_dx12");
+   LLVMValueRef dx02_dz12    = LLVMBuildFMul(b, dx02, dz12, "dx02_dz12");
+   LLVMValueRef res1  = LLVMBuildFSub(b, dy02_dz12, dz02_dy12, "res1");
+   LLVMValueRef res2  = LLVMBuildFSub(b, dz02_dx12, dx02_dz12, "res2");
+
+   /* dzdx = fabsf(res1 * inv_det), dydx = fabsf(res2 * inv_det)*/
+   lp_build_context_init(&bld, gallivm, lp_type_float(32));
+   dzdx0 = LLVMBuildFMul(b, res1, inv_det, "dzdx");
+   dzdx  = lp_build_abs(&bld, dzdx0);
+   dzdy0 = LLVMBuildFMul(b, res2, inv_det, "dzdy");
+   dzdy  = lp_build_abs(&bld, dzdy0);
+
+   /* zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale */
+   max = LLVMBuildFCmp(b, LLVMRealUGT, dzdx, dzdy, "");
+   max_value = LLVMBuildSelect(b, max, dzdx, dzdy, "max"); 
+
+   mult = LLVMBuildFMul(b, max_value, lp_build_const_float(gallivm, key->scale), "");
+   zoffset = LLVMBuildFAdd(b, lp_build_const_float(gallivm, key->units), mult, "zoffset");
+
+   /* clamp and do offset */
+   z0_new = vert_clamp(b, LLVMBuildFAdd(b, v0_z, zoffset, ""), zero, one);
+   z1_new = vert_clamp(b, LLVMBuildFAdd(b, v1_z, zoffset, ""), zero, one);
+   z2_new = vert_clamp(b, LLVMBuildFAdd(b, v2_z, zoffset, ""), zero, one);
+
+   /* insert into args->a0.z, a1.z, a2.z:
+    */   
+   args->v0a = LLVMBuildInsertElement(b, args->v0a, z0_new, two, "");
+   args->v1a = LLVMBuildInsertElement(b, args->v1a, z1_new, two, "");
+   args->v2a = LLVMBuildInsertElement(b, args->v2a, z2_new, two, "");
+}
+
+static void
+load_attribute(struct gallivm_state *gallivm,
+               struct lp_setup_args *args,
+               const struct lp_setup_variant_key *key,
+               unsigned vert_attr)
+{
+   LLVMBuilderRef b = gallivm->builder;
+   LLVMValueRef idx = lp_build_const_int32(gallivm, vert_attr);
+
+   /* Load the vertex data
+    */
+   args->v0a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx, 1, ""), "v0a");
+   args->v1a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx, 1, ""), "v1a");
+   args->v2a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx, 1, ""), "v2a");
+
+
+   /* Potentially modify it according to twoside, offset, etc:
+    */
+   if (vert_attr == 0 && (key->scale != 0.0f || key->units != 0.0f)) {
+      lp_do_offset_tri(gallivm, args, key);
+   }
+
+   if (key->twoside) {
+      if (vert_attr == key->color_slot && key->bcolor_slot != ~0)
+         lp_twoside(gallivm, args, key, key->bcolor_slot);
+      else if (vert_attr == key->spec_slot && key->bspec_slot != ~0)
+         lp_twoside(gallivm, args, key, key->bspec_slot);
+   }
+}
 
 static void 
-emit_coef4( LLVMBuilderRef b,
+emit_coef4( struct gallivm_state *gallivm,
            struct lp_setup_args *args,
            unsigned slot,
            LLVMValueRef a0,
            LLVMValueRef a1,
            LLVMValueRef a2)
 {
+   LLVMBuilderRef b = gallivm->builder;
    LLVMValueRef dy20_ooa = args->dy20_ooa;
    LLVMValueRef dy01_ooa = args->dy01_ooa;
    LLVMValueRef dx20_ooa = args->dx20_ooa;
@@ -236,27 +398,24 @@ emit_coef4( LLVMBuilderRef b,
    LLVMValueRef attr_v0       = LLVMBuildFAdd(b, dadx_x0, dady_y0, "attr_v0"); 
    LLVMValueRef attr_0        = LLVMBuildFSub(b, a0, attr_v0, "attr_0"); 
 
-   store_coef(b, args, slot, attr_0, dadx, dady);
+   store_coef(gallivm, args, slot, attr_0, dadx, dady);
 }
 
 
 static void 
-emit_linear_coef( LLVMBuilderRef b,
+emit_linear_coef( struct gallivm_state *gallivm,
                  struct lp_setup_args *args,
-                 unsigned slot,
-                 unsigned vert_attr)
+                 unsigned slot)
 {
-   LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), vert_attr, 0);
-
-   LLVMValueRef a0 = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx, 1, ""), "v0a");
-   LLVMValueRef a1 = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx, 1, ""), "v1a");
-   LLVMValueRef a2 = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx, 1, ""), "v2a");
-
-   emit_coef4(b, args, slot, a0, a1, a2);
+   /* nothing to do anymore */
+   emit_coef4(gallivm,
+              args, slot, 
+              args->v0a,
+              args->v1a,
+              args->v2a);
 }
 
 
-
 /**
  * Compute a0, dadx and dady for a perspective-corrected interpolant,
  * for a triangle.
@@ -266,37 +425,32 @@ emit_linear_coef( LLVMBuilderRef b,
  * divide the interpolated value by the interpolated W at that fragment.
  */
 static void 
-emit_perspective_coef( LLVMBuilderRef b,
+emit_perspective_coef( struct gallivm_state *gallivm,
                       struct lp_setup_args *args,
-                      unsigned slot,
-                      unsigned vert_attr)
+                      unsigned slot)
 {
+   LLVMBuilderRef b = gallivm->builder;
+
    /* premultiply by 1/w  (v[0][3] is always 1/w):
     */
-   LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), vert_attr, 0);
-
-   LLVMValueRef v0a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx, 1, ""), "v0a");
-   LLVMValueRef v1a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx, 1, ""), "v1a");
-   LLVMValueRef v2a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx, 1, ""), "v2a");
-
-   LLVMValueRef v0_oow = vec4f_from_scalar(b, vert_attrib(b, args->v0, 0, 3, ""), "v0_oow");
-   LLVMValueRef v1_oow = vec4f_from_scalar(b, vert_attrib(b, args->v1, 0, 3, ""), "v1_oow");
-   LLVMValueRef v2_oow = vec4f_from_scalar(b, vert_attrib(b, args->v2, 0, 3, ""), "v2_oow");
+   LLVMValueRef v0_oow = vec4f_from_scalar(gallivm, vert_attrib(gallivm, args->v0, 0, 3, ""), "v0_oow");
+   LLVMValueRef v1_oow = vec4f_from_scalar(gallivm, vert_attrib(gallivm, args->v1, 0, 3, ""), "v1_oow");
+   LLVMValueRef v2_oow = vec4f_from_scalar(gallivm, vert_attrib(gallivm, args->v2, 0, 3, ""), "v2_oow");
 
-   LLVMValueRef v0_oow_v0a = LLVMBuildFMul(b, v0a, v0_oow, "v0_oow_v0a");
-   LLVMValueRef v1_oow_v1a = LLVMBuildFMul(b, v1a, v1_oow, "v1_oow_v1a");
-   LLVMValueRef v2_oow_v2a = LLVMBuildFMul(b, v2a, v2_oow, "v2_oow_v2a");
+   LLVMValueRef v0_oow_v0a = LLVMBuildFMul(b, args->v0a, v0_oow, "v0_oow_v0a");
+   LLVMValueRef v1_oow_v1a = LLVMBuildFMul(b, args->v1a, v1_oow, "v1_oow_v1a");
+   LLVMValueRef v2_oow_v2a = LLVMBuildFMul(b, args->v2a, v2_oow, "v2_oow_v2a");
 
-   emit_coef4(b, args, slot, v0_oow_v0a, v1_oow_v1a, v2_oow_v2a);
+   emit_coef4(gallivm, args, slot, v0_oow_v0a, v1_oow_v1a, v2_oow_v2a);
 }
 
 
 static void
-emit_position_coef( LLVMBuilderRef builder,
+emit_position_coef( struct gallivm_state *gallivm,
                    struct lp_setup_args *args,
-                   int slot, int attrib )
+                   int slot )
 {
-   emit_linear_coef(builder, args, slot, attrib);
+   emit_linear_coef(gallivm, args, slot);
 }
 
 
@@ -306,7 +460,7 @@ emit_position_coef( LLVMBuilderRef builder,
  * Compute the inputs-> dadx, dady, a0 values.
  */
 static void 
-emit_tri_coef( LLVMBuilderRef builder,
+emit_tri_coef( struct gallivm_state *gallivm,
               const struct lp_setup_variant_key *key,
               struct lp_setup_args *args )
 {
@@ -314,29 +468,34 @@ emit_tri_coef( LLVMBuilderRef builder,
 
    /* The internal position input is in slot zero:
     */
-   emit_position_coef(builder, args, 0, 0);
+   load_attribute(gallivm, args, key, 0);
+   emit_position_coef(gallivm, args, 0);
 
    /* setup interpolation for all the remaining attributes:
     */
    for (slot = 0; slot < key->num_inputs; slot++) {
-      unsigned vert_attr = key->inputs[slot].src_index;
+
+      if (key->inputs[slot].interp == LP_INTERP_CONSTANT ||
+          key->inputs[slot].interp == LP_INTERP_LINEAR ||
+          key->inputs[slot].interp == LP_INTERP_PERSPECTIVE)
+         load_attribute(gallivm, args, key, key->inputs[slot].src_index);
 
       switch (key->inputs[slot].interp) {
       case LP_INTERP_CONSTANT:
         if (key->flatshade_first) {
-           emit_constant_coef4(builder, args, slot+1, args->v0, vert_attr);
+           emit_constant_coef4(gallivm, args, slot+1, args->v0a);
         }
         else {
-           emit_constant_coef4(builder, args, slot+1, args->v2, vert_attr);
+           emit_constant_coef4(gallivm, args, slot+1, args->v2a);
         }
         break;
 
       case LP_INTERP_LINEAR:
-        emit_linear_coef(builder, args, slot+1, vert_attr);
+        emit_linear_coef(gallivm, args, slot+1);
          break;
 
       case LP_INTERP_PERSPECTIVE:
-        emit_perspective_coef(builder, args, slot+1, vert_attr);
+        emit_perspective_coef(gallivm, args, slot+1);
          break;
 
       case LP_INTERP_POSITION:
@@ -347,7 +506,7 @@ emit_tri_coef( LLVMBuilderRef builder,
          break;
 
       case LP_INTERP_FACING:
-         emit_facing_coef(builder, args, slot+1);
+         emit_facing_coef(gallivm, args, slot+1);
          break;
 
       default:
@@ -360,7 +519,7 @@ emit_tri_coef( LLVMBuilderRef builder,
 /* XXX: This is generic code, share with fs/vs codegen:
  */
 static lp_jit_setup_triangle
-finalize_function(struct llvmpipe_screen *screen,
+finalize_function(struct gallivm_state *gallivm,
                  LLVMBuilderRef builder,
                  LLVMValueRef function)
 {
@@ -376,7 +535,7 @@ finalize_function(struct llvmpipe_screen *screen,
 #endif
 
    /* Apply optimizations to LLVM IR */
-   LLVMRunFunctionPassManager(screen->pass, function);
+   LLVMRunFunctionPassManager(gallivm->passmgr, function);
 
    if (gallivm_debug & GALLIVM_DEBUG_IR)
    {
@@ -388,7 +547,7 @@ finalize_function(struct llvmpipe_screen *screen,
    /*
     * Translate the LLVM IR into machine code.
     */
-   f = LLVMGetPointerToGlobal(screen->engine, function);
+   f = LLVMGetPointerToGlobal(gallivm->engine, function);
 
    if (gallivm_debug & GALLIVM_DEBUG_ASM)
    {
@@ -403,11 +562,12 @@ finalize_function(struct llvmpipe_screen *screen,
 /* XXX: Generic code:
  */
 static void
-lp_emit_emms(LLVMBuilderRef builder)
+lp_emit_emms(struct gallivm_state *gallivm)
 {
 #ifdef PIPE_ARCH_X86
    /* Avoid corrupting the FPU stack on 32bit OSes. */
-   lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0);
+   lp_build_intrinsic(gallivm->builder, "llvm.x86.mmx.emms",
+         LLVMVoidTypeInContext(gallivm->context), NULL, 0);
 #endif
 }
 
@@ -428,21 +588,23 @@ set_noalias(LLVMBuilderRef builder,
 }
 
 static void
-init_args(LLVMBuilderRef b, 
+init_args(struct gallivm_state *gallivm,
          struct lp_setup_args *args,
          const struct lp_setup_variant *variant)
 {
-   LLVMValueRef v0_x = vert_attrib(b, args->v0, 0, 0, "v0_x");
-   LLVMValueRef v0_y = vert_attrib(b, args->v0, 0, 1, "v0_y");
+   LLVMBuilderRef b = gallivm->builder;
+
+   LLVMValueRef v0_x = vert_attrib(gallivm, args->v0, 0, 0, "v0_x");
+   LLVMValueRef v0_y = vert_attrib(gallivm, args->v0, 0, 1, "v0_y");
 
-   LLVMValueRef v1_x = vert_attrib(b, args->v1, 0, 0, "v1_x");
-   LLVMValueRef v1_y = vert_attrib(b, args->v1, 0, 1, "v1_y");
+   LLVMValueRef v1_x = vert_attrib(gallivm, args->v1, 0, 0, "v1_x");
+   LLVMValueRef v1_y = vert_attrib(gallivm, args->v1, 0, 1, "v1_y");
 
-   LLVMValueRef v2_x = vert_attrib(b, args->v2, 0, 0, "v2_x");
-   LLVMValueRef v2_y = vert_attrib(b, args->v2, 0, 1, "v2_y");
+   LLVMValueRef v2_x = vert_attrib(gallivm, args->v2, 0, 0, "v2_x");
+   LLVMValueRef v2_y = vert_attrib(gallivm, args->v2, 0, 1, "v2_y");
 
-   LLVMValueRef pixel_center = LLVMConstReal(LLVMFloatType(),
-                                            variant->key.pixel_center_half ? 0.5 : 0);
+   LLVMValueRef pixel_center = lp_build_const_float(gallivm,
+                                   variant->key.pixel_center_half ? 0.5 : 0);
 
    LLVMValueRef x0_center = LLVMBuildFSub(b, v0_x, pixel_center, "x0_center" );
    LLVMValueRef y0_center = LLVMBuildFSub(b, v0_y, pixel_center, "y0_center" );
@@ -452,7 +614,7 @@ init_args(LLVMBuilderRef b,
    LLVMValueRef dx20 = LLVMBuildFSub(b, v2_x, v0_x, "dx20");
    LLVMValueRef dy20 = LLVMBuildFSub(b, v2_y, v0_y, "dy20");
 
-   LLVMValueRef one  = LLVMConstReal(LLVMFloatType(), 1.0);
+   LLVMValueRef one  = lp_build_const_float(gallivm, 1.0);
    LLVMValueRef e    = LLVMBuildFMul(b, dx01, dy20, "e");
    LLVMValueRef f    = LLVMBuildFMul(b, dx20, dy01, "f");
    LLVMValueRef ooa  = LLVMBuildFDiv(b, one, LLVMBuildFSub(b, e, f, ""), "ooa");
@@ -462,14 +624,14 @@ init_args(LLVMBuilderRef b,
    LLVMValueRef dx20_ooa = LLVMBuildFMul(b, dx20, ooa, "dx20_ooa");
    LLVMValueRef dx01_ooa = LLVMBuildFMul(b, dx01, ooa, "dx01_ooa");
 
-   args->dy20_ooa  = vec4f_from_scalar(b, dy20_ooa, "dy20_ooa_4f");
-   args->dy01_ooa  = vec4f_from_scalar(b, dy01_ooa, "dy01_ooa_4f");
+   args->dy20_ooa  = vec4f_from_scalar(gallivm, dy20_ooa, "dy20_ooa_4f");
+   args->dy01_ooa  = vec4f_from_scalar(gallivm, dy01_ooa, "dy01_ooa_4f");
 
-   args->dx20_ooa  = vec4f_from_scalar(b, dx20_ooa, "dx20_ooa_4f");
-   args->dx01_ooa  = vec4f_from_scalar(b, dx01_ooa, "dx01_ooa_4f");
+   args->dx20_ooa  = vec4f_from_scalar(gallivm, dx20_ooa, "dx20_ooa_4f");
+   args->dx01_ooa  = vec4f_from_scalar(gallivm, dx01_ooa, "dx01_ooa_4f");
 
-   args->x0_center = vec4f_from_scalar(b, x0_center, "x0_center_4f");
-   args->y0_center = vec4f_from_scalar(b, y0_center, "y0_center_4f");
+   args->x0_center = vec4f_from_scalar(gallivm, x0_center, "x0_center_4f");
+   args->y0_center = vec4f_from_scalar(gallivm, y0_center, "y0_center_4f");
 }
 
 /**
@@ -477,8 +639,9 @@ init_args(LLVMBuilderRef b,
  *
  */
 static struct lp_setup_variant *
-generate_setup_variant(struct llvmpipe_screen *screen,
-                      struct lp_setup_variant_key *key)
+generate_setup_variant(struct gallivm_state *gallivm,
+                      struct lp_setup_variant_key *key,
+                       struct llvmpipe_context *lp)
 {
    struct lp_setup_variant *variant = NULL;
    struct lp_setup_args args;
@@ -487,7 +650,7 @@ generate_setup_variant(struct llvmpipe_screen *screen,
    LLVMTypeRef func_type;
    LLVMTypeRef arg_types[7];
    LLVMBasicBlockRef block;
-   LLVMBuilderRef builder;
+   LLVMBuilderRef builder = gallivm->builder;
    int64_t t0, t1;
 
    if (0)
@@ -512,19 +675,20 @@ generate_setup_variant(struct llvmpipe_screen *screen,
     * the vertices.
     */
 
-   vec4f_type = LLVMVectorType(LLVMFloatType(), 4);
+   vec4f_type = LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 4);
 
    arg_types[0] = LLVMPointerType(vec4f_type, 0);        /* v0 */
    arg_types[1] = LLVMPointerType(vec4f_type, 0);        /* v1 */
    arg_types[2] = LLVMPointerType(vec4f_type, 0);        /* v2 */
-   arg_types[3] = LLVMInt32Type();                     /* facing */
+   arg_types[3] = LLVMInt32TypeInContext(gallivm->context); /* facing */
    arg_types[4] = LLVMPointerType(vec4f_type, 0);      /* a0, aligned */
    arg_types[5] = LLVMPointerType(vec4f_type, 0);      /* dadx, aligned */
    arg_types[6] = LLVMPointerType(vec4f_type, 0);      /* dady, aligned */
 
-   func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
+   func_type = LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context),
+                                arg_types, Elements(arg_types), 0);
 
-   variant->function = LLVMAddFunction(screen->module, func_name, func_type);
+   variant->function = LLVMAddFunction(gallivm->module, func_name, func_type);
    if (!variant->function)
       goto fail;
 
@@ -549,19 +713,18 @@ generate_setup_variant(struct llvmpipe_screen *screen,
    /*
     * Function body
     */
-   block = LLVMAppendBasicBlock(variant->function, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(gallivm->context,
+                                         variant->function, "entry");
    LLVMPositionBuilderAtEnd(builder, block);
 
    set_noalias(builder, variant->function, arg_types, Elements(arg_types));
-   init_args(builder, &args, variant);
-   emit_tri_coef(builder, &variant->key, &args);
+   init_args(gallivm, &args, variant);
+   emit_tri_coef(gallivm, &variant->key, &args);
 
-   lp_emit_emms(builder);
+   lp_emit_emms(gallivm);
    LLVMBuildRetVoid(builder);
-   LLVMDisposeBuilder(builder);
 
-   variant->jit_function = finalize_function(screen, builder,
+   variant->jit_function = finalize_function(gallivm, builder,
                                             variant->function);
    if (!variant->jit_function)
       goto fail;
@@ -581,7 +744,7 @@ fail:
    if (variant) {
       if (variant->function) {
         if (variant->jit_function)
-           LLVMFreeMachineCodeForFunction(screen->engine,
+           LLVMFreeMachineCodeForFunction(gallivm->engine,
                                           variant->function);
         LLVMDeleteFunction(variant->function);
       }
@@ -605,14 +768,20 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp,
    key->num_inputs = fs->info.base.num_inputs;
    key->flatshade_first = lp->rasterizer->flatshade_first;
    key->pixel_center_half = lp->rasterizer->gl_rasterization_rules;
+   key->twoside = lp->rasterizer->light_twoside;
    key->size = Offset(struct lp_setup_variant_key,
                      inputs[key->num_inputs]);
+   key->color_slot = lp->color_slot[0];
+   key->bcolor_slot = lp->bcolor_slot[0];
+   key->spec_slot = lp->color_slot[1];
+   key->bspec_slot = lp->bcolor_slot[1];
+   key->units = (float) (lp->rasterizer->offset_units * lp->mrd);
+   key->scale = lp->rasterizer->offset_scale;
    key->pad = 0;
-
    memcpy(key->inputs, fs->inputs, key->num_inputs * sizeof key->inputs[0]);
    for (i = 0; i < key->num_inputs; i++) {
       if (key->inputs[i].interp == LP_INTERP_COLOR) {
-        if (lp->rasterizer->flatshade)
+         if (lp->rasterizer->flatshade)
            key->inputs[i].interp = LP_INTERP_CONSTANT;
         else
            key->inputs[i].interp = LP_INTERP_LINEAR;
@@ -626,8 +795,6 @@ static void
 remove_setup_variant(struct llvmpipe_context *lp,
                     struct lp_setup_variant *variant)
 {
-   struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
-
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
       debug_printf("llvmpipe: del setup_variant #%u total %u\n",
                   variant->no, lp->nr_setup_variants);
@@ -635,7 +802,7 @@ remove_setup_variant(struct llvmpipe_context *lp,
 
    if (variant->function) {
       if (variant->jit_function)
-        LLVMFreeMachineCodeForFunction(screen->engine,
+        LLVMFreeMachineCodeForFunction(lp->gallivm->engine,
                                        variant->function);
       LLVMDeleteFunction(variant->function);
    }
@@ -678,8 +845,6 @@ cull_setup_variants(struct llvmpipe_context *lp)
 void 
 llvmpipe_update_setup(struct llvmpipe_context *lp)
 {
-   struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
-
    struct lp_setup_variant_key *key = &lp->setup_variant.key;
    struct lp_setup_variant *variant = NULL;
    struct lp_setup_variant_list_item *li;
@@ -702,9 +867,11 @@ llvmpipe_update_setup(struct llvmpipe_context *lp)
         cull_setup_variants(lp);
       }
 
-      variant = generate_setup_variant(screen, key);
+      variant = generate_setup_variant(lp->gallivm, key, lp);
       insert_at_head(&lp->setup_variants_list, &variant->list_item_global);
       lp->nr_setup_variants++;
+
+      llvmpipe_variant_count++;
    }
 
    lp_setup_set_setup_variant(lp->setup,
index b0c81baa75f62f9ee61af18a5e35b5c6f49ed934..90c55ca4ce654a48a25c58c0e8441173602ffd6d 100644 (file)
@@ -15,11 +15,20 @@ struct lp_setup_variant_list_item
 
 
 struct lp_setup_variant_key {   
+   unsigned size:16;
    unsigned num_inputs:8;
+   unsigned color_slot:8;
+
+   unsigned bcolor_slot:8;
+   unsigned spec_slot:8;
+   unsigned bspec_slot:8;
    unsigned flatshade_first:1;
    unsigned pixel_center_half:1;
-   unsigned pad:7;
-   unsigned size:16;
+   unsigned twoside:1;
+   unsigned pad:5;
+
+   float units;
+   float scale;      
    struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
 };
 
index cd1a5b19803f841d4d03f8c1ee85881c21711d60..375ceb2b942177aadd637f81bd25be9fb18d1de9 100644 (file)
@@ -77,6 +77,7 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
          else {
             mrd = 0.00002;
          }
+         lp->mrd = mrd;
          draw_set_mrd(lp->draw, mrd);
       }
 
index 164242eda67070eefe3d4e63aa1c6680e5f50067..e7e46a628a15f0eac8b8b856ac783c707702a3e4 100644 (file)
@@ -52,19 +52,23 @@ adjust_to_tile_bounds(unsigned x, unsigned y, unsigned width, unsigned height,
 
 static void
 lp_resource_copy(struct pipe_context *pipe,
-                 struct pipe_resource *dst, struct pipe_subresource subdst,
+                 struct pipe_resource *dst, unsigned dst_level,
                  unsigned dstx, unsigned dsty, unsigned dstz,
-                 struct pipe_resource *src, struct pipe_subresource subsrc,
-                 unsigned srcx, unsigned srcy, unsigned srcz,
-                 unsigned width, unsigned height)
+                 struct pipe_resource *src, unsigned src_level,
+                 const struct pipe_box *src_box)
 {
-   /* XXX what about the dstz/srcz parameters - zslice wasn't used... */
+   /* XXX this used to ignore srcz/dstz
+    * assume it works the same for cube and 3d
+    */
    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;
+   assert(src_box->depth == 1);
 
    llvmpipe_flush_resource(pipe,
-                           dst, subdst.face, subdst.level,
+                           dst, dst_level, dstz,
                            0, /* flush_flags */
                            FALSE, /* read_only */
                            TRUE, /* cpu_access */
@@ -72,7 +76,7 @@ lp_resource_copy(struct pipe_context *pipe,
                            "blit dest");
 
    llvmpipe_flush_resource(pipe,
-                           src, subsrc.face, subsrc.level,
+                           src, src_level, src_box->z,
                            0, /* flush_flags */
                            TRUE, /* read_only */
                            TRUE, /* cpu_access */
@@ -80,9 +84,10 @@ lp_resource_copy(struct pipe_context *pipe,
                            "blit src");
 
    /*
-   printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
-          src_tex->id, dst_tex->id,
-          srcx, srcy, dstx, dsty, width, height);
+   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);
    */
 
    /* set src tiles to linear layout */
@@ -90,12 +95,13 @@ lp_resource_copy(struct pipe_context *pipe,
       unsigned tx, ty, tw, th;
       unsigned x, y;
 
-      adjust_to_tile_bounds(srcx, srcy, width, height, &tx, &ty, &tw, &th);
+      adjust_to_tile_bounds(src_box->x, src_box->y, width, height,
+                            &tx, &ty, &tw, &th);
 
       for (y = 0; y < th; y += TILE_SIZE) {
          for (x = 0; x < tw; x += TILE_SIZE) {
             (void) llvmpipe_get_texture_tile_linear(src_tex,
-                                                    subsrc.face, subsrc.level,
+                                                    src_box->z, src_level,
                                                     LP_TEX_USAGE_READ,
                                                     tx + x, ty + y);
          }
@@ -130,7 +136,7 @@ lp_resource_copy(struct pipe_context *pipe,
                usage = LP_TEX_USAGE_READ_WRITE;
 
             (void) llvmpipe_get_texture_tile_linear(dst_tex,
-                                                    subdst.face, subdst.level,
+                                                    dstz, dst_level,
                                                     usage,
                                                     tx + x, ty + y);
          }
@@ -140,22 +146,22 @@ lp_resource_copy(struct pipe_context *pipe,
    /* copy */
    {
       const ubyte *src_linear_ptr
-         = llvmpipe_get_texture_image_address(src_tex, subsrc.face,
-                                              subsrc.level,
+         = llvmpipe_get_texture_image_address(src_tex, src_box->z,
+                                              src_level,
                                               LP_TEX_LAYOUT_LINEAR);
       ubyte *dst_linear_ptr
-         = llvmpipe_get_texture_image_address(dst_tex, subdst.face,
-                                              subdst.level,
+         = llvmpipe_get_texture_image_address(dst_tex, dstz,
+                                              dst_level,
                                               LP_TEX_LAYOUT_LINEAR);
 
       if (dst_linear_ptr && src_linear_ptr) {
          util_copy_rect(dst_linear_ptr, format,
-                        llvmpipe_resource_stride(&dst_tex->base, subdst.level),
+                        llvmpipe_resource_stride(&dst_tex->base, dst_level),
                         dstx, dsty,
                         width, height,
                         src_linear_ptr,
-                        llvmpipe_resource_stride(&src_tex->base, subsrc.level),
-                        srcx, srcy);
+                        llvmpipe_resource_stride(&src_tex->base, src_level),
+                        src_box->x, src_box->y);
       }
    }
 }
index 90422e42588bf7e8fa4ca8b51a9d141e39b2e069..c64f3e149fdabf050d3156de1d9853f33143b5a2 100644 (file)
@@ -64,13 +64,14 @@ write_tsv_header(FILE *fp);
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n);
+test_some(struct gallivm_state *gallivm,unsigned verbose, FILE *fp,
+          unsigned long n);
 
 boolean
-test_single(unsigned verbose, FILE *fp);
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp);
 
 boolean
-test_all(unsigned verbose, FILE *fp);
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp);
 
 
 #if defined(PIPE_CC_MSVC)
index 8b6b5e1298f215f2a31bbaef0b44a6c7303c5037..b3ca134131d36529d2842fe414e61cbd9977c05d 100644 (file)
@@ -163,11 +163,13 @@ dump_blend_type(FILE *fp,
 
 
 static LLVMValueRef
-add_blend_test(LLVMModuleRef module,
+add_blend_test(struct gallivm_state *gallivm,
                const struct pipe_blend_state *blend,
                enum vector_mode mode,
                struct lp_type type)
 {
+   LLVMModuleRef module = gallivm->module;
+   LLVMContextRef context = gallivm->context;
    LLVMTypeRef vec_type;
    LLVMTypeRef args[4];
    LLVMValueRef func;
@@ -179,18 +181,18 @@ add_blend_test(LLVMModuleRef module,
    LLVMBuilderRef builder;
    const unsigned rt = 0;
 
-   vec_type = lp_build_vec_type(type);
+   vec_type = lp_build_vec_type(gallivm, type);
 
    args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
-   func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 4, 0));
+   func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 4, 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    src_ptr = LLVMGetParam(func, 0);
    dst_ptr = LLVMGetParam(func, 1);
    const_ptr = LLVMGetParam(func, 2);
    res_ptr = LLVMGetParam(func, 3);
 
-   block = LLVMAppendBasicBlock(func, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(context, func, "entry");
+   builder = gallivm->builder;
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (mode == AoS) {
@@ -203,7 +205,7 @@ add_blend_test(LLVMModuleRef module,
       dst = LLVMBuildLoad(builder, dst_ptr, "dst");
       con = LLVMBuildLoad(builder, const_ptr, "const");
 
-      res = lp_build_blend_aos(builder, blend, type, rt, src, dst, con, 3);
+      res = lp_build_blend_aos(gallivm, blend, type, rt, src, dst, con, 3);
 
       lp_build_name(res, "res");
 
@@ -218,7 +220,7 @@ add_blend_test(LLVMModuleRef module,
       unsigned i;
 
       for(i = 0; i < 4; ++i) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+         LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0);
          src[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, src_ptr, &index, 1, ""), "");
          dst[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
          con[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
@@ -227,10 +229,10 @@ add_blend_test(LLVMModuleRef module,
          lp_build_name(dst[i], "dst.%c", "rgba"[i]);
       }
 
-      lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res);
+      lp_build_blend_soa(gallivm, blend, type, rt, src, dst, con, res);
 
       for(i = 0; i < 4; ++i) {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+         LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0);
          lp_build_name(res[i], "res.%c", "rgba"[i]);
          LLVMBuildStore(builder, res[i], LLVMBuildGEP(builder, res_ptr, &index, 1, ""));
       }
@@ -238,7 +240,6 @@ add_blend_test(LLVMModuleRef module,
 
    LLVMBuildRetVoid(builder);;
 
-   LLVMDisposeBuilder(builder);
    return func;
 }
 
@@ -465,16 +466,16 @@ compute_blend_ref(const struct pipe_blend_state *blend,
 
 PIPE_ALIGN_STACK
 static boolean
-test_one(unsigned verbose,
+test_one(struct gallivm_state *gallivm,
+         unsigned verbose,
          FILE *fp,
          const struct pipe_blend_state *blend,
          enum vector_mode mode,
          struct lp_type type)
 {
-   LLVMModuleRef module = NULL;
+   LLVMModuleRef module = gallivm->module;
    LLVMValueRef func = NULL;
-   LLVMExecutionEngineRef engine = lp_build_engine;
-   LLVMPassManagerRef pass = NULL;
+   LLVMExecutionEngineRef engine = gallivm->engine;
    char *error = NULL;
    blend_test_ptr_t blend_test_ptr;
    boolean success;
@@ -487,9 +488,7 @@ test_one(unsigned verbose,
    if(verbose >= 1)
       dump_blend_type(stdout, blend, mode, type);
 
-   module = LLVMModuleCreateWithName("test");
-
-   func = add_blend_test(module, blend, mode, type);
+   func = add_blend_test(gallivm, blend, mode, type);
 
    if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
       LLVMDumpModule(module);
@@ -497,24 +496,6 @@ test_one(unsigned verbose,
    }
    LLVMDisposeMessage(error);
 
-#if 0
-   pass = LLVMCreatePassManager();
-   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   LLVMAddConstantPropagationPass(pass);
-   LLVMAddInstructionCombiningPass(pass);
-   LLVMAddPromoteMemoryToRegisterPass(pass);
-   LLVMAddGVNPass(pass);
-   LLVMAddCFGSimplificationPass(pass);
-   LLVMRunPassManager(pass, module);
-#else
-   (void)pass;
-#endif
-
-   if(verbose >= 2)
-      LLVMDumpModule(module);
-
    code = LLVMGetPointerToGlobal(engine, func);
    blend_test_ptr = voidptr_to_blend_test_ptr_t(code);
 
@@ -715,9 +696,6 @@ test_one(unsigned verbose,
 
    LLVMFreeMachineCodeForFunction(engine, func);
 
-   if(pass)
-      LLVMDisposePassManager(pass);
-
    return success;
 }
 
@@ -773,7 +751,7 @@ const unsigned num_types = sizeof(blend_types)/sizeof(blend_types[0]);
 
 
 boolean
-test_all(unsigned verbose, FILE *fp)
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    const unsigned *rgb_func;
    const unsigned *rgb_src_factor;
@@ -809,7 +787,7 @@ test_all(unsigned verbose, FILE *fp)
                            blend.rt[0].alpha_dst_factor  = *alpha_dst_factor;
                            blend.rt[0].colormask         = PIPE_MASK_RGBA;
 
-                           if(!test_one(verbose, fp, &blend, mode, *type))
+                           if(!test_one(gallivm, verbose, fp, &blend, mode, *type))
                              success = FALSE;
 
                         }
@@ -826,7 +804,8 @@ test_all(unsigned verbose, FILE *fp)
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n)
+test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+          unsigned long n)
 {
    const unsigned *rgb_func;
    const unsigned *rgb_src_factor;
@@ -868,7 +847,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
       blend.rt[0].alpha_dst_factor  = *alpha_dst_factor;
       blend.rt[0].colormask         = PIPE_MASK_RGBA;
 
-      if(!test_one(verbose, fp, &blend, mode, *type))
+      if(!test_one(gallivm, verbose, fp, &blend, mode, *type))
         success = FALSE;
    }
 
@@ -877,7 +856,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
 
 
 boolean
-test_single(unsigned verbose, FILE *fp)
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    printf("no test_single()");
    return TRUE;
index 3ba42bf11a6169d6018fe7f8e55f840023d0feef..f4a2f360c75522f11a066aec0e34b3acb00ce5de 100644 (file)
@@ -97,64 +97,65 @@ dump_conv_types(FILE *fp,
 
 
 static LLVMValueRef
-add_conv_test(LLVMModuleRef module,
+add_conv_test(struct gallivm_state *gallivm,
               struct lp_type src_type, unsigned num_srcs,
               struct lp_type dst_type, unsigned num_dsts)
 {
+   LLVMModuleRef module = gallivm->module;
+   LLVMContextRef context = gallivm->context;
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMTypeRef args[2];
    LLVMValueRef func;
    LLVMValueRef src_ptr;
    LLVMValueRef dst_ptr;
    LLVMBasicBlockRef block;
-   LLVMBuilderRef builder;
    LLVMValueRef src[LP_MAX_VECTOR_LENGTH];
    LLVMValueRef dst[LP_MAX_VECTOR_LENGTH];
    unsigned i;
 
-   args[0] = LLVMPointerType(lp_build_vec_type(src_type), 0);
-   args[1] = LLVMPointerType(lp_build_vec_type(dst_type), 0);
+   args[0] = LLVMPointerType(lp_build_vec_type(gallivm, src_type), 0);
+   args[1] = LLVMPointerType(lp_build_vec_type(gallivm, dst_type), 0);
 
-   func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
+   func = LLVMAddFunction(module, "test",
+                          LLVMFunctionType(LLVMVoidTypeInContext(context),
+                                           args, 2, 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    src_ptr = LLVMGetParam(func, 0);
    dst_ptr = LLVMGetParam(func, 1);
 
-   block = LLVMAppendBasicBlock(func, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(context, func, "entry");
    LLVMPositionBuilderAtEnd(builder, block);
 
    for(i = 0; i < num_srcs; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0);
       LLVMValueRef ptr = LLVMBuildGEP(builder, src_ptr, &index, 1, "");
       src[i] = LLVMBuildLoad(builder, ptr, "");
    }
 
-   lp_build_conv(builder, src_type, dst_type, src, num_srcs, dst, num_dsts);
+   lp_build_conv(gallivm, src_type, dst_type, src, num_srcs, dst, num_dsts);
 
    for(i = 0; i < num_dsts; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0);
       LLVMValueRef ptr = LLVMBuildGEP(builder, dst_ptr, &index, 1, "");
       LLVMBuildStore(builder, dst[i], ptr);
    }
 
    LLVMBuildRetVoid(builder);;
 
-   LLVMDisposeBuilder(builder);
    return func;
 }
 
 
 PIPE_ALIGN_STACK
 static boolean
-test_one(unsigned verbose,
+test_one(struct gallivm_state *gallivm, unsigned verbose,
          FILE *fp,
          struct lp_type src_type,
          struct lp_type dst_type)
 {
-   LLVMModuleRef module = NULL;
+   LLVMModuleRef module = gallivm->module;
+   LLVMExecutionEngineRef engine = gallivm->engine;
    LLVMValueRef func = NULL;
-   LLVMExecutionEngineRef engine = lp_build_engine;
-   LLVMPassManagerRef pass = NULL;
    char *error = NULL;
    conv_test_ptr_t conv_test_ptr;
    boolean success;
@@ -193,9 +194,7 @@ test_one(unsigned verbose,
 
    eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type));
 
-   module = LLVMModuleCreateWithName("test");
-
-   func = add_conv_test(module, src_type, num_srcs, dst_type, num_dsts);
+   func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts);
 
    if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
       LLVMDumpModule(module);
@@ -203,21 +202,6 @@ test_one(unsigned verbose,
    }
    LLVMDisposeMessage(error);
 
-#if 0
-   pass = LLVMCreatePassManager();
-   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   LLVMAddConstantPropagationPass(pass);
-   LLVMAddInstructionCombiningPass(pass);
-   LLVMAddPromoteMemoryToRegisterPass(pass);
-   LLVMAddGVNPass(pass);
-   LLVMAddCFGSimplificationPass(pass);
-   LLVMRunPassManager(pass, module);
-#else
-   (void)pass;
-#endif
-
    if(verbose >= 2)
       LLVMDumpModule(module);
 
@@ -342,9 +326,6 @@ test_one(unsigned verbose,
 
    LLVMFreeMachineCodeForFunction(engine, func);
 
-   if(pass)
-      LLVMDisposePassManager(pass);
-
    return success;
 }
 
@@ -390,7 +371,7 @@ const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]);
 
 
 boolean
-test_all(unsigned verbose, FILE *fp)
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    const struct lp_type *src_type;
    const struct lp_type *dst_type;
@@ -405,7 +386,7 @@ test_all(unsigned verbose, FILE *fp)
          if(src_type->norm != dst_type->norm)
             continue;
 
-         if(!test_one(verbose, fp, *src_type, *dst_type))
+         if(!test_one(gallivm, verbose, fp, *src_type, *dst_type))
            success = FALSE;
 
       }
@@ -416,7 +397,8 @@ test_all(unsigned verbose, FILE *fp)
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n)
+test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+          unsigned long n)
 {
    const struct lp_type *src_type;
    const struct lp_type *dst_type;
@@ -430,7 +412,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
          dst_type = &conv_types[rand() % num_types];
       } while (src_type == dst_type || src_type->norm != dst_type->norm);
 
-      if(!test_one(verbose, fp, *src_type, *dst_type))
+      if(!test_one(gallivm, verbose, fp, *src_type, *dst_type))
         success = FALSE;
    }
 
@@ -439,7 +421,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
 
 
 boolean
-test_single(unsigned verbose, FILE *fp)
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    /*    float, fixed,  sign,  norm, width, len */
    struct lp_type f32x4_type =
@@ -449,7 +431,7 @@ test_single(unsigned verbose, FILE *fp)
 
    boolean success;
 
-   success = test_one(verbose, fp, f32x4_type, ub8x4_type);
+   success = test_one(gallivm, verbose, fp, f32x4_type, ub8x4_type);
 
    return success;
 }
index 2855d7cea4fb5980b30185a58f7409f2edde1348..4152ca6cf6370e41e8b551cd0162c20c6008cb3b 100644 (file)
 #include <stdio.h>
 #include <float.h>
 
-#include "gallivm/lp_bld.h"
-#include "gallivm/lp_bld_debug.h"
-#include "gallivm/lp_bld_init.h"
-#include <llvm-c/Analysis.h>
-#include <llvm-c/Target.h>
-#include <llvm-c/Transforms/Scalar.h>
-
 #include "util/u_memory.h"
 #include "util/u_pointer.h"
 #include "util/u_string.h"
 #include "util/u_format_tests.h"
 #include "util/u_format_s3tc.h"
 
+#include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_debug.h"
 #include "gallivm/lp_bld_format.h"
+#include "gallivm/lp_bld_init.h"
+
 #include "lp_test.h"
 
 
@@ -78,56 +75,57 @@ typedef void
 
 
 static LLVMValueRef
-add_fetch_rgba_test(unsigned verbose,
+add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose,
                     const struct util_format_description *desc,
                     struct lp_type type)
 {
    char name[256];
+   LLVMContextRef context = gallivm->context;
+   LLVMModuleRef module = gallivm->module;
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMPassManagerRef passmgr = gallivm->passmgr;
    LLVMTypeRef args[4];
    LLVMValueRef func;
    LLVMValueRef packed_ptr;
-   LLVMValueRef offset = LLVMConstNull(LLVMInt32Type());
+   LLVMValueRef offset = LLVMConstNull(LLVMInt32TypeInContext(context));
    LLVMValueRef rgba_ptr;
    LLVMValueRef i;
    LLVMValueRef j;
    LLVMBasicBlockRef block;
-   LLVMBuilderRef builder;
    LLVMValueRef rgba;
 
    util_snprintf(name, sizeof name, "fetch_%s_%s", desc->short_name,
                  type.floating ? "float" : "unorm8");
 
-   args[0] = LLVMPointerType(lp_build_vec_type(type), 0);
-   args[1] = LLVMPointerType(LLVMInt8Type(), 0);
-   args[3] = args[2] = LLVMInt32Type();
+   args[0] = LLVMPointerType(lp_build_vec_type(gallivm, type), 0);
+   args[1] = LLVMPointerType(LLVMInt8TypeInContext(context), 0);
+   args[3] = args[2] = LLVMInt32TypeInContext(context);
 
-   func = LLVMAddFunction(lp_build_module, name,
-                          LLVMFunctionType(LLVMVoidType(), args, Elements(args), 0));
+   func = LLVMAddFunction(module, name,
+                          LLVMFunctionType(LLVMVoidTypeInContext(context),
+                                           args, Elements(args), 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    rgba_ptr = LLVMGetParam(func, 0);
    packed_ptr = LLVMGetParam(func, 1);
    i = LLVMGetParam(func, 2);
    j = LLVMGetParam(func, 3);
 
-   block = LLVMAppendBasicBlock(func, "entry");
-   builder = LLVMCreateBuilder();
+   block = LLVMAppendBasicBlockInContext(context, func, "entry");
    LLVMPositionBuilderAtEnd(builder, block);
 
-   rgba = lp_build_fetch_rgba_aos(builder, desc, type,
+   rgba = lp_build_fetch_rgba_aos(gallivm, desc, type,
                                   packed_ptr, offset, i, j);
 
    LLVMBuildStore(builder, rgba, rgba_ptr);
 
    LLVMBuildRetVoid(builder);
 
-   LLVMDisposeBuilder(builder);
-
    if (LLVMVerifyFunction(func, LLVMPrintMessageAction)) {
       LLVMDumpValue(func);
       abort();
    }
 
-   LLVMRunFunctionPassManager(lp_build_pass, func);
+   LLVMRunFunctionPassManager(passmgr, func);
 
    if (verbose >= 1) {
       LLVMDumpValue(func);
@@ -139,10 +137,11 @@ add_fetch_rgba_test(unsigned verbose,
 
 PIPE_ALIGN_STACK
 static boolean
-test_format_float(unsigned verbose, FILE *fp,
+test_format_float(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
                   const struct util_format_description *desc)
 {
    LLVMValueRef fetch = NULL;
+   LLVMExecutionEngineRef engine = gallivm->engine;
    fetch_ptr_t fetch_ptr;
    PIPE_ALIGN_VAR(16) float unpacked[4];
    boolean first = TRUE;
@@ -150,9 +149,9 @@ test_format_float(unsigned verbose, FILE *fp,
    unsigned i, j, k, l;
    void *f;
 
-   fetch = add_fetch_rgba_test(verbose, desc, lp_float32_vec4_type());
+   fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_float32_vec4_type());
 
-   f = LLVMGetPointerToGlobal(lp_build_engine, fetch);
+   f = LLVMGetPointerToGlobal(engine, fetch);
    fetch_ptr = (fetch_ptr_t) pointer_to_func(f);
 
    if (verbose >= 2) {
@@ -208,7 +207,7 @@ test_format_float(unsigned verbose, FILE *fp,
       }
    }
 
-   LLVMFreeMachineCodeForFunction(lp_build_engine, fetch);
+   LLVMFreeMachineCodeForFunction(engine, fetch);
    LLVMDeleteFunction(fetch);
 
    if(fp)
@@ -220,7 +219,8 @@ test_format_float(unsigned verbose, FILE *fp,
 
 PIPE_ALIGN_STACK
 static boolean
-test_format_unorm8(unsigned verbose, FILE *fp,
+test_format_unorm8(struct gallivm_state *gallivm,
+                   unsigned verbose, FILE *fp,
                    const struct util_format_description *desc)
 {
    LLVMValueRef fetch = NULL;
@@ -231,9 +231,9 @@ test_format_unorm8(unsigned verbose, FILE *fp,
    unsigned i, j, k, l;
    void *f;
 
-   fetch = add_fetch_rgba_test(verbose, desc, lp_unorm8_vec4_type());
+   fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_unorm8_vec4_type());
 
-   f = LLVMGetPointerToGlobal(lp_build_engine, fetch);
+   f = LLVMGetPointerToGlobal(gallivm->engine, fetch);
    fetch_ptr = (fetch_ptr_t) pointer_to_func(f);
 
    if (verbose >= 2) {
@@ -290,7 +290,7 @@ test_format_unorm8(unsigned verbose, FILE *fp,
    if (!success)
       LLVMDumpValue(fetch);
 
-   LLVMFreeMachineCodeForFunction(lp_build_engine, fetch);
+   LLVMFreeMachineCodeForFunction(gallivm->engine, fetch);
    LLVMDeleteFunction(fetch);
 
    if(fp)
@@ -303,16 +303,17 @@ test_format_unorm8(unsigned verbose, FILE *fp,
 
 
 static boolean
-test_one(unsigned verbose, FILE *fp,
+test_one(struct gallivm_state *gallivm,
+         unsigned verbose, FILE *fp,
          const struct util_format_description *format_desc)
 {
    boolean success = TRUE;
 
-   if (!test_format_float(verbose, fp, format_desc)) {
+   if (!test_format_float(gallivm, verbose, fp, format_desc)) {
      success = FALSE;
    }
 
-   if (!test_format_unorm8(verbose, fp, format_desc)) {
+   if (!test_format_unorm8(gallivm, verbose, fp, format_desc)) {
      success = FALSE;
    }
 
@@ -321,7 +322,7 @@ test_one(unsigned verbose, FILE *fp,
 
 
 boolean
-test_all(unsigned verbose, FILE *fp)
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    enum pipe_format format;
    boolean success = TRUE;
@@ -349,7 +350,7 @@ test_all(unsigned verbose, FILE *fp)
          continue;
       }
 
-      if (!test_one(verbose, fp, format_desc)) {
+      if (!test_one(gallivm, verbose, fp, format_desc)) {
            success = FALSE;
       }
    }
@@ -359,14 +360,15 @@ test_all(unsigned verbose, FILE *fp)
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n)
+test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+          unsigned long n)
 {
-   return test_all(verbose, fp);
+   return test_all(gallivm, verbose, fp);
 }
 
 
 boolean
-test_single(unsigned verbose, FILE *fp)
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    printf("no test_single()");
    return TRUE;
index 7a0d06ae2c8cd1a45fbf748e17b9e915d34d7b9b..149ee6f1256a4e9dca3c4144d8361fabeab0c8d7 100644 (file)
@@ -380,6 +380,7 @@ int main(int argc, char **argv)
    unsigned i;
    boolean success;
    boolean single = FALSE;
+   struct gallivm_state *gallivm;
 
    for(i = 1; i < argc; ++i) {
       if(strcmp(argv[i], "-v") == 0)
@@ -394,21 +395,23 @@ int main(int argc, char **argv)
 
    lp_build_init();
 
+   gallivm = gallivm_create();
+
    util_cpu_detect();
 
    if(fp) {
       /* Warm up the caches */
-      test_some(0, NULL, 100);
+      test_some(gallivm, 0, NULL, 100);
 
       write_tsv_header(fp);
    }
       
    if (single)
-      success = test_single(verbose, fp);
+      success = test_single(gallivm, verbose, fp);
    else if (n)
-      success = test_some(verbose, fp, n);
+      success = test_some(gallivm, verbose, fp, n);
    else
-      success = test_all(verbose, fp);
+      success = test_all(gallivm, verbose, fp);
 
    if(fp)
       fclose(fp);
index 4653f30e39dd3d2b1c672f92eddbabaed417dea5..620cdb57c13c8ccfaa6bc39c1775d6e833cd40ff 100644 (file)
 #include "gallivm/lp_bld_assert.h"
 #include "gallivm/lp_bld_printf.h"
 
-#include <llvm-c/Analysis.h>
-#include <llvm-c/ExecutionEngine.h>
-#include <llvm-c/Target.h>
-#include <llvm-c/Transforms/Scalar.h>
-
 #include "lp_test.h"
 
 
@@ -63,48 +58,45 @@ typedef void (*test_printf_t)(int i);
 
 
 static LLVMValueRef
-add_printf_test(LLVMModuleRef module)
+add_printf_test(struct gallivm_state *gallivm)
 {
-   LLVMTypeRef args[1] = { LLVMIntType(32) };
-   LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidType(), args, 1, 0));
-   LLVMBuilderRef builder = LLVMCreateBuilder();
-   LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
+   LLVMModuleRef module = gallivm->module;
+   LLVMTypeRef args[1] = { LLVMIntTypeInContext(gallivm->context, 32) };
+   LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0));
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, func, "entry");
 
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
 
    LLVMPositionBuilderAtEnd(builder, block);
-   lp_build_printf(builder, "hello, world\n");
-   lp_build_printf(builder, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32Type(), 5, 0),
-                               LLVMConstInt(LLVMInt32Type(), 6, 0));
+   lp_build_printf(gallivm, "hello, world\n");
+   lp_build_printf(gallivm, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 5, 0),
+                               LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 6, 0));
 
    /* Also test lp_build_assert().  This should not fail. */
-   lp_build_assert(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), "assert(1)");
+   lp_build_assert(gallivm, LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 1, 0), "assert(1)");
 
    LLVMBuildRetVoid(builder);
-   LLVMDisposeBuilder(builder);
+
    return func;
 }
 
 
 PIPE_ALIGN_STACK
 static boolean
-test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase)
+test_printf(struct gallivm_state *gallivm,
+            unsigned verbose, FILE *fp,
+            const struct printf_test_case *testcase)
 {
-   LLVMModuleRef module = NULL;
-   LLVMValueRef test = NULL;
-   LLVMExecutionEngineRef engine = NULL;
-   LLVMModuleProviderRef provider = NULL;
-   LLVMPassManagerRef pass = NULL;
+   LLVMExecutionEngineRef engine = gallivm->engine;
+   LLVMModuleRef module = gallivm->module;
+   LLVMValueRef test;
    char *error = NULL;
-   test_printf_t test_printf;
-   float unpacked[4];
-   unsigned packed;
+   test_printf_t test_printf_func;
    boolean success = TRUE;
    void *code;
 
-   module = LLVMModuleCreateWithName("test");
-
-   test = add_printf_test(module);
+   test = add_printf_test(gallivm);
 
    if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
       LLVMDumpModule(module);
@@ -112,74 +104,40 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase)
    }
    LLVMDisposeMessage(error);
 
-   provider = LLVMCreateModuleProviderForExistingModule(module);
-#if 0
-   if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
-      fprintf(stderr, "%s\n", error);
-      LLVMDisposeMessage(error);
-      abort();
-   }
-#else
-   (void) provider;
-   engine = lp_build_engine;
-#endif
-
-#if 0
-   pass = LLVMCreatePassManager();
-   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   LLVMAddConstantPropagationPass(pass);
-   LLVMAddInstructionCombiningPass(pass);
-   LLVMAddPromoteMemoryToRegisterPass(pass);
-   LLVMAddGVNPass(pass);
-   LLVMAddCFGSimplificationPass(pass);
-   LLVMRunPassManager(pass, module);
-#else
-   (void)pass;
-#endif
-
    code = LLVMGetPointerToGlobal(engine, test);
-   test_printf = (test_printf_t)pointer_to_func(code);
-
-   memset(unpacked, 0, sizeof unpacked);
-   packed = 0;
-
+   test_printf_func = (test_printf_t) pointer_to_func(code);
 
    // LLVMDumpModule(module);
 
-   test_printf(0);
+   test_printf_func(0);
 
    LLVMFreeMachineCodeForFunction(engine, test);
 
-   LLVMDisposeExecutionEngine(engine);
-   if(pass)
-      LLVMDisposePassManager(pass);
-
    return success;
 }
 
 
 boolean
-test_all(unsigned verbose, FILE *fp)
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    boolean success = TRUE;
 
-   test_printf(verbose, fp, NULL);
+   test_printf(gallivm, verbose, fp, NULL);
 
    return success;
 }
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n)
+test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+          unsigned long n)
 {
-   return test_all(verbose, fp);
+   return test_all(gallivm, verbose, fp);
 }
 
 
 boolean
-test_single(unsigned verbose, FILE *fp)
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    printf("no test_single()");
    return TRUE;
index 816518e5081f6a2e1eab92fbdd35e22692788a66..4edee4af12339161b7be145da9f884ec0ee44048 100644 (file)
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_arit.h"
 
-#include <llvm-c/Analysis.h>
-#include <llvm-c/ExecutionEngine.h>
-#include <llvm-c/Target.h>
-#include <llvm-c/Transforms/Scalar.h>
-
 #include "lp_test.h"
 
 
@@ -64,18 +59,21 @@ typedef LLVMValueRef (*lp_func_t)(struct lp_build_context *, LLVMValueRef);
 
 
 static LLVMValueRef
-add_test(LLVMModuleRef module, const char *name, lp_func_t lp_func)
+add_test(struct gallivm_state *gallivm, const char *name, lp_func_t lp_func)
 {
-   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
+   LLVMModuleRef module = gallivm->module;
+   LLVMContextRef context = gallivm->context;
+   LLVMBuilderRef builder = gallivm->builder;
+
+   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatTypeInContext(context), 4);
    LLVMTypeRef args[1] = { v4sf };
    LLVMValueRef func = LLVMAddFunction(module, name, LLVMFunctionType(v4sf, args, 1, 0));
    LLVMValueRef arg1 = LLVMGetParam(func, 0);
-   LLVMBuilderRef builder = LLVMCreateBuilder();
-   LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
+   LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(context, func, "entry");
    LLVMValueRef ret;
    struct lp_build_context bld;
 
-   lp_build_context_init(&bld, builder, lp_float32_vec4_type());
+   lp_build_context_init(&bld, gallivm, lp_float32_vec4_type());
 
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
 
@@ -84,7 +82,7 @@ add_test(LLVMModuleRef module, const char *name, lp_func_t lp_func)
    ret = lp_func(&bld, arg1);
 
    LLVMBuildRet(builder, ret);
-   LLVMDisposeBuilder(builder);
+
    return func;
 }
 
@@ -117,12 +115,11 @@ compare(v4sf x, v4sf y)
 
 PIPE_ALIGN_STACK
 static boolean
-test_round(unsigned verbose, FILE *fp)
+test_round(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
-   LLVMModuleRef module = NULL;
+   LLVMModuleRef module = gallivm->module;
    LLVMValueRef test_round = NULL, test_trunc, test_floor, test_ceil;
-   LLVMExecutionEngineRef engine = lp_build_engine;
-   LLVMPassManagerRef pass = NULL;
+   LLVMExecutionEngineRef engine = gallivm->engine;
    char *error = NULL;
    test_round_t round_func, trunc_func, floor_func, ceil_func;
    float unpacked[4];
@@ -130,12 +127,10 @@ test_round(unsigned verbose, FILE *fp)
    boolean success = TRUE;
    int i;
 
-   module = LLVMModuleCreateWithName("test");
-
-   test_round = add_test(module, "round", lp_build_round);
-   test_trunc = add_test(module, "trunc", lp_build_trunc);
-   test_floor = add_test(module, "floor", lp_build_floor);
-   test_ceil = add_test(module, "ceil", lp_build_ceil);
+   test_round = add_test(gallivm, "round", lp_build_round);
+   test_trunc = add_test(gallivm, "trunc", lp_build_trunc);
+   test_floor = add_test(gallivm, "floor", lp_build_floor);
+   test_ceil = add_test(gallivm, "ceil", lp_build_ceil);
 
    if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
       printf("LLVMVerifyModule: %s\n", error);
@@ -144,21 +139,6 @@ test_round(unsigned verbose, FILE *fp)
    }
    LLVMDisposeMessage(error);
 
-#if 0
-   pass = LLVMCreatePassManager();
-   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   LLVMAddConstantPropagationPass(pass);
-   LLVMAddInstructionCombiningPass(pass);
-   LLVMAddPromoteMemoryToRegisterPass(pass);
-   LLVMAddGVNPass(pass);
-   LLVMAddCFGSimplificationPass(pass);
-   LLVMRunPassManager(pass, module);
-#else
-   (void)pass;
-#endif
-
    round_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_round));
    trunc_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_trunc));
    floor_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_floor));
@@ -229,17 +209,13 @@ test_round(unsigned verbose, FILE *fp)
    LLVMFreeMachineCodeForFunction(engine, test_floor);
    LLVMFreeMachineCodeForFunction(engine, test_ceil);
 
-   LLVMDisposeExecutionEngine(engine);
-   if(pass)
-      LLVMDisposePassManager(pass);
-
    return success;
 }
 
 #else /* !PIPE_ARCH_SSE */
 
 static boolean
-test_round(unsigned verbose, FILE *fp)
+test_round(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    return TRUE;
 }
@@ -248,20 +224,21 @@ test_round(unsigned verbose, FILE *fp)
 
 
 boolean
-test_all(unsigned verbose, FILE *fp)
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
-   return test_round(verbose, fp);
+   return test_round(gallivm, verbose, fp);
 }
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n)
+test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+          unsigned long n)
 {
-   return test_all(verbose, fp);
+   return test_all(gallivm, verbose, fp);
 }
 
 boolean
-test_single(unsigned verbose, FILE *fp)
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    printf("no test_single()");
    return TRUE;
index 79939b1a3939b0f16b95df3c58c91ad751a6334f..066d633d443b317f0747811af2eabd16dd4a8441 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 
+#include "util/u_pointer.h"
+
 #include "gallivm/lp_bld.h"
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_arit.h"
-#include "util/u_pointer.h"
-
-#include <llvm-c/Analysis.h>
-#include <llvm-c/ExecutionEngine.h>
-#include <llvm-c/Target.h>
-#include <llvm-c/Transforms/Scalar.h>
 
 #include "lp_test.h"
 
@@ -61,25 +57,25 @@ write_tsv_header(FILE *fp)
 typedef __m128 (*test_sincos_t)(__m128);
 
 static LLVMValueRef
-add_sincos_test(LLVMModuleRef module, boolean sin)
+add_sincos_test(struct gallivm_state *gallivm, LLVMModuleRef module,
+                LLVMContextRef context, boolean sin)
 {
-   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
+   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatTypeInContext(context), 4);
    LLVMTypeRef args[1] = { v4sf };
    LLVMValueRef func = LLVMAddFunction(module, "sincos", LLVMFunctionType(v4sf, args, 1, 0));
    LLVMValueRef arg1 = LLVMGetParam(func, 0);
-   LLVMBuilderRef builder = LLVMCreateBuilder();
-   LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(context, func, "entry");
    LLVMValueRef ret;
    struct lp_build_context bld;
 
-   lp_build_context_init(&bld, builder, lp_float32_vec4_type());
+   lp_build_context_init(&bld, gallivm, lp_float32_vec4_type());
 
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
 
    LLVMPositionBuilderAtEnd(builder, block);
    ret = sin ? lp_build_sin(&bld, arg1) : lp_build_cos(&bld, arg1);
    LLVMBuildRet(builder, ret);
-   LLVMDisposeBuilder(builder);
    return func;
 }
 
@@ -95,22 +91,20 @@ printv(char* string, v4sf value)
 
 PIPE_ALIGN_STACK
 static boolean
-test_sincos(unsigned verbose, FILE *fp)
+test_sincos(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
-   LLVMModuleRef module = NULL;
+   LLVMModuleRef module = gallivm->module;
    LLVMValueRef test_sin = NULL, test_cos = NULL;
-   LLVMExecutionEngineRef engine = lp_build_engine;
-   LLVMPassManagerRef pass = NULL;
+   LLVMExecutionEngineRef engine = gallivm->engine;
+   LLVMContextRef context = gallivm->context;
    char *error = NULL;
    test_sincos_t sin_func;
    test_sincos_t cos_func;
    float unpacked[4];
    boolean success = TRUE;
 
-   module = LLVMModuleCreateWithName("test");
-
-   test_sin = add_sincos_test(module, TRUE);
-   test_cos = add_sincos_test(module, FALSE);
+   test_sin = add_sincos_test(gallivm, module, context, TRUE);
+   test_cos = add_sincos_test(gallivm, module, context,FALSE);
 
    if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
       printf("LLVMVerifyModule: %s\n", error);
@@ -119,21 +113,6 @@ test_sincos(unsigned verbose, FILE *fp)
    }
    LLVMDisposeMessage(error);
 
-#if 0
-   pass = LLVMCreatePassManager();
-   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   LLVMAddConstantPropagationPass(pass);
-   LLVMAddInstructionCombiningPass(pass);
-   LLVMAddPromoteMemoryToRegisterPass(pass);
-   LLVMAddGVNPass(pass);
-   LLVMAddCFGSimplificationPass(pass);
-   LLVMRunPassManager(pass, module);
-#else
-   (void)pass;
-#endif
-
    sin_func = (test_sincos_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_sin));
    cos_func = (test_sincos_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_cos));
 
@@ -152,16 +131,13 @@ test_sincos(unsigned verbose, FILE *fp)
    LLVMFreeMachineCodeForFunction(engine, test_sin);
    LLVMFreeMachineCodeForFunction(engine, test_cos);
 
-   if(pass)
-      LLVMDisposePassManager(pass);
-
    return success;
 }
 
 #else /* !PIPE_ARCH_SSE */
 
 static boolean
-test_sincos(unsigned verbose, FILE *fp)
+test_sincos(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    return TRUE;
 }
@@ -170,24 +146,25 @@ test_sincos(unsigned verbose, FILE *fp)
 
 
 boolean
-test_all(unsigned verbose, FILE *fp)
+test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    boolean success = TRUE;
 
-   test_sincos(verbose, fp);
+   test_sincos(gallivm, verbose, fp);
 
    return success;
 }
 
 
 boolean
-test_some(unsigned verbose, FILE *fp, unsigned long n)
+test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+          unsigned long n)
 {
-   return test_all(verbose, fp);
+   return test_all(gallivm, verbose, fp);
 }
 
 boolean
-test_single(unsigned verbose, FILE *fp)
+test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 {
    printf("no test_single()");
    return TRUE;
index f417fc8a9ea5564134a2a54c487ee81d01eccc80..ed4282937f88859aea7ffe416395e1c6a67a86ee 100644 (file)
@@ -43,6 +43,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_shader_tokens.h"
 #include "gallivm/lp_bld_debug.h"
+#include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_type.h"
 #include "gallivm/lp_bld_sample.h"
 #include "gallivm/lp_bld_tgsi.h"
@@ -89,7 +90,7 @@ struct lp_llvm_sampler_soa
  */
 static LLVMValueRef
 lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
-                       LLVMBuilderRef builder,
+                       struct gallivm_state *gallivm,
                        unsigned unit,
                        unsigned member_index,
                        const char *member_name,
@@ -97,6 +98,7 @@ lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
 {
    struct llvmpipe_sampler_dynamic_state *state =
       (struct llvmpipe_sampler_dynamic_state *)base;
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef indices[4];
    LLVMValueRef ptr;
    LLVMValueRef res;
@@ -104,13 +106,13 @@ lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
    assert(unit < PIPE_MAX_SAMPLERS);
 
    /* context[0] */
-   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indices[0] = lp_build_const_int32(gallivm, 0);
    /* context[0].textures */
-   indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CTX_TEXTURES, 0);
+   indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_TEXTURES);
    /* context[0].textures[unit] */
-   indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+   indices[2] = lp_build_const_int32(gallivm, unit);
    /* context[0].textures[unit].member */
-   indices[3] = LLVMConstInt(LLVMInt32Type(), member_index, 0);
+   indices[3] = lp_build_const_int32(gallivm, member_index);
 
    ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
 
@@ -137,10 +139,10 @@ lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
 #define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load)  \
    static LLVMValueRef \
    lp_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
-                            LLVMBuilderRef builder, \
+                            struct gallivm_state *gallivm, \
                             unsigned unit) \
    { \
-      return lp_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
+      return lp_llvm_texture_member(base, gallivm, unit, _index, #_name, _emit_load ); \
    }
 
 
@@ -170,7 +172,7 @@ lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
  */
 static void
 lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
-                                     LLVMBuilderRef builder,
+                                     struct gallivm_state *gallivm,
                                      struct lp_type type,
                                      unsigned unit,
                                      unsigned num_coords,
@@ -186,11 +188,11 @@ lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
    assert(unit < PIPE_MAX_SAMPLERS);
    
    if (LP_PERF & PERF_NO_TEX) {
-      lp_build_sample_nop(type, texel);
+      lp_build_sample_nop(gallivm, type, texel);
       return;
    }
 
-   lp_build_sample_soa(builder,
+   lp_build_sample_soa(gallivm,
                        &sampler->dynamic_state.static_state[unit],
                        &sampler->dynamic_state.base,
                        type,
index a4b9f2590af2815ea4c821f554bb396471eaa161..9753da5e57e8e62663f5851cb5875c8436e4cc21 100644 (file)
@@ -49,6 +49,7 @@
 #include "lp_tile_image.h"
 #include "lp_texture.h"
 #include "lp_setup.h"
+#include "lp_state.h"
 
 #include "state_tracker/sw_winsys.h"
 
@@ -242,6 +243,7 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
       /* other data (vertex buffer, const buffer, etc) */
       const enum pipe_format format = templat->format;
       const uint w = templat->width0 / util_format_get_blockheight(format);
+      /* XXX buffers should only have one dimension, those values should be 1 */
       const uint h = templat->height0 / util_format_get_blockwidth(format);
       const uint d = templat->depth0;
       const uint bpp = util_format_get_blocksize(format);
@@ -329,17 +331,16 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
  */
 void *
 llvmpipe_resource_map(struct pipe_resource *resource,
-                     unsigned face,
-                     unsigned level,
-                     unsigned zslice,
+                      unsigned level,
+                      unsigned layer,
                       enum lp_texture_usage tex_usage,
                       enum lp_texture_layout layout)
 {
    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    uint8_t *map;
 
-   assert(face < 6);
    assert(level < LP_MAX_TEXTURE_LEVELS);
+   assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));
 
    assert(tex_usage == LP_TEX_USAGE_READ ||
           tex_usage == LP_TEX_USAGE_READ_WRITE ||
@@ -363,9 +364,8 @@ llvmpipe_resource_map(struct pipe_resource *resource,
          dt_usage = PIPE_TRANSFER_READ_WRITE;
       }
 
-      assert(face == 0);
       assert(level == 0);
-      assert(zslice == 0);
+      assert(layer == 0);
 
       /* FIXME: keep map count? */
       map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);
@@ -381,15 +381,8 @@ llvmpipe_resource_map(struct pipe_resource *resource,
       return map2;
    }
    else if (resource_is_texture(resource)) {
-      /* regular texture */
-      if (resource->target != PIPE_TEXTURE_CUBE) {
-         assert(face == 0);
-      }
-      if (resource->target != PIPE_TEXTURE_3D) {
-         assert(zslice == 0);
-      }
 
-      map = llvmpipe_get_texture_image(lpr, face + zslice, level,
+      map = llvmpipe_get_texture_image(lpr, layer, level,
                                        tex_usage, layout);
       return map;
    }
@@ -404,9 +397,8 @@ llvmpipe_resource_map(struct pipe_resource *resource,
  */
 void
 llvmpipe_resource_unmap(struct pipe_resource *resource,
-                       unsigned face,
                        unsigned level,
-                       unsigned zslice)
+                       unsigned layer)
 {
    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
 
@@ -415,12 +407,11 @@ llvmpipe_resource_unmap(struct pipe_resource *resource,
       struct llvmpipe_screen *lp_screen = llvmpipe_screen(resource->screen);
       struct sw_winsys *winsys = lp_screen->winsys;
 
-      assert(face == 0);
       assert(level == 0);
-      assert(zslice == 0);
+      assert(layer == 0);
 
       /* make sure linear image is up to date */
-      (void) llvmpipe_get_texture_image(lpr, face + zslice, level,
+      (void) llvmpipe_get_texture_image(lpr, layer, level,
                                         LP_TEX_USAGE_READ,
                                         LP_TEX_LAYOUT_LINEAR);
 
@@ -520,34 +511,35 @@ llvmpipe_resource_get_handle(struct pipe_screen *screen,
 
 
 static struct pipe_surface *
-llvmpipe_get_tex_surface(struct pipe_screen *screen,
-                         struct pipe_resource *pt,
-                         unsigned face, unsigned level, unsigned zslice,
-                         unsigned usage)
+llvmpipe_create_surface(struct pipe_context *pipe,
+                        struct pipe_resource *pt,
+                        const struct pipe_surface *surf_tmpl)
 {
    struct pipe_surface *ps;
 
-   assert(level <= pt->last_level);
+   assert(surf_tmpl->u.tex.level <= pt->last_level);
 
    ps = CALLOC_STRUCT(pipe_surface);
    if (ps) {
       pipe_reference_init(&ps->reference, 1);
       pipe_resource_reference(&ps->texture, pt);
-      ps->format = pt->format;
-      ps->width = u_minify(pt->width0, level);
-      ps->height = u_minify(pt->height0, level);
-      ps->usage = usage;
-
-      ps->face = face;
-      ps->level = level;
-      ps->zslice = zslice;
+      ps->context = pipe;
+      ps->format = surf_tmpl->format;
+      ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
+      ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
+      ps->usage = surf_tmpl->usage;
+
+      ps->u.tex.level = surf_tmpl->u.tex.level;
+      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
    }
    return ps;
 }
 
 
 static void 
-llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
+llvmpipe_surface_destroy(struct pipe_context *pipe,
+                         struct pipe_surface *surf)
 {
    /* Effectively do the texture_update work here - if texture images
     * needed post-processing to put them into hardware layout, this is
@@ -561,16 +553,17 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
 
 static struct pipe_transfer *
 llvmpipe_get_transfer(struct pipe_context *pipe,
-                     struct pipe_resource *resource,
-                     struct pipe_subresource sr,
-                     unsigned usage,
-                     const struct pipe_box *box)
+                      struct pipe_resource *resource,
+                      unsigned level,
+                      unsigned usage,
+                      const struct pipe_box *box)
 {
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    struct llvmpipe_resource *lprex = llvmpipe_resource(resource);
    struct llvmpipe_transfer *lpr;
 
    assert(resource);
-   assert(sr.level <= resource->last_level);
+   assert(level <= resource->last_level);
 
    /*
     * Transfers, like other pipe operations, must happen in order, so flush the
@@ -580,7 +573,8 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
       boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
       boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
       if (!llvmpipe_flush_resource(pipe, resource,
-                                   sr.face, sr.level,
+                                   level,
+                                   box->depth > 1 ? -1 : box->z,
                                    0, /* flush_flags */
                                    read_only,
                                    TRUE, /* cpu_access */
@@ -594,14 +588,17 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
       }
    }
 
+   if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][0])
+      llvmpipe->dirty |= LP_NEW_CONSTANTS;
+
    lpr = CALLOC_STRUCT(llvmpipe_transfer);
    if (lpr) {
       struct pipe_transfer *pt = &lpr->base;
       pipe_resource_reference(&pt->resource, resource);
       pt->box = *box;
-      pt->sr = sr;
-      pt->stride = lprex->row_stride[sr.level];
-      pt->slice_stride = lprex->img_stride[sr.level];
+      pt->level = level;
+      pt->stride = lprex->row_stride[level];
+      pt->layer_stride = lprex->img_stride[level];
       pt->usage = usage;
 
       return pt;
@@ -635,8 +632,7 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
    enum lp_texture_usage tex_usage;
    const char *mode;
 
-   assert(transfer->sr.face < 6);
-   assert(transfer->sr.level < LP_MAX_TEXTURE_LEVELS);
+   assert(transfer->level < LP_MAX_TEXTURE_LEVELS);
 
    /*
    printf("tex_transfer_map(%d, %d  %d x %d of %d x %d,  usage %d )\n",
@@ -666,9 +662,8 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
    format = lpr->base.format;
 
    map = llvmpipe_resource_map(transfer->resource,
-                              transfer->sr.face,
-                              transfer->sr.level,
-                              transfer->box.z,
+                               transfer->level,
+                               transfer->box.z,
                                tex_usage, LP_TEX_LAYOUT_LINEAR);
 
 
@@ -680,7 +675,7 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
        */
       screen->timestamp++;
    }
-   
+
    map +=
       transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
       transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
@@ -696,21 +691,20 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe,
    assert(transfer->resource);
 
    llvmpipe_resource_unmap(transfer->resource,
-                          transfer->sr.face,
-                          transfer->sr.level,
-                          transfer->box.z);
+                           transfer->level,
+                           transfer->box.z);
 }
 
 static unsigned int
 llvmpipe_is_resource_referenced( struct pipe_context *pipe,
-                               struct pipe_resource *presource,
-                               unsigned face, unsigned level)
+                                 struct pipe_resource *presource,
+                                 unsigned level, int layer)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
 
    if (presource->target == PIPE_BUFFER)
       return PIPE_UNREFERENCED;
-   
+
    return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
 }
 
@@ -740,6 +734,7 @@ llvmpipe_user_buffer_create(struct pipe_screen *screen,
    buffer->base.width0 = bytes;
    buffer->base.height0 = 1;
    buffer->base.depth0 = 1;
+   buffer->base.array_size = 1;
    buffer->userBuffer = TRUE;
    buffer->data = ptr;
 
@@ -1396,8 +1391,6 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
    screen->resource_get_handle = llvmpipe_resource_get_handle;
    screen->user_buffer_create = llvmpipe_user_buffer_create;
 
-   screen->get_tex_surface = llvmpipe_get_tex_surface;
-   screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
 }
 
 
@@ -1412,4 +1405,7 @@ llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
  
    pipe->transfer_flush_region = u_default_transfer_flush_region;
    pipe->transfer_inline_write = u_default_transfer_inline_write;
+
+   pipe->create_surface = llvmpipe_create_surface;
+   pipe->surface_destroy = llvmpipe_surface_destroy;
 }
index 4e4a65dcb401d1e260b79655ab301a45e6e8c2f1..b789c0f4090a1bd1602627db9b84cc2f210e9746 100644 (file)
@@ -172,17 +172,15 @@ llvmpipe_resource_stride(struct pipe_resource *resource,
 
 void *
 llvmpipe_resource_map(struct pipe_resource *resource,
-                     unsigned face_slice,
-                     unsigned level,
-                     unsigned zslice,
+                      unsigned level,
+                      unsigned layer,
                       enum lp_texture_usage tex_usage,
                       enum lp_texture_layout layout);
 
 void
 llvmpipe_resource_unmap(struct pipe_resource *resource,
-                       unsigned face_slice,
                        unsigned level,
-                       unsigned zslice);
+                       unsigned layer);
 
 
 void *
index fb5cdb460935c37b4b684292faa0c6b3c838c660..c9c463f470f7f848ff41dfe533b9917950fce399 100644 (file)
@@ -83,7 +83,7 @@ struct noop_resource {
 
 static unsigned noop_is_resource_referenced(struct pipe_context *pipe,
                                                struct pipe_resource *resource,
-                                               unsigned face, unsigned level)
+                                               unsigned level, int layer)
 {
        return PIPE_UNREFERENCED;
 }
@@ -193,7 +193,7 @@ static struct pipe_resource *noop_user_buffer_create(struct pipe_screen *screen,
  */
 static struct pipe_transfer *noop_get_transfer(struct pipe_context *context,
                                                struct pipe_resource *resource,
-                                               struct pipe_subresource sr,
+                                               unsigned level,
                                                enum pipe_transfer_usage usage,
                                                const struct pipe_box *box)
 {
@@ -203,11 +203,11 @@ static struct pipe_transfer *noop_get_transfer(struct pipe_context *context,
        if (transfer == NULL)
                return NULL;
        pipe_resource_reference(&transfer->resource, resource);
-       transfer->sr = sr;
+       transfer->level = level;
        transfer->usage = usage;
        transfer->box = *box;
        transfer->stride = 1;
-       transfer->slice_stride = 1;
+       transfer->layer_stride = 1;
        return transfer;
 }
 
@@ -239,12 +239,12 @@ static void noop_transfer_destroy(struct pipe_context *pipe,
 
 static void noop_transfer_inline_write(struct pipe_context *pipe,
                                        struct pipe_resource *resource,
-                                       struct pipe_subresource sr,
+                                       unsigned level,
                                        unsigned usage,
                                        const struct pipe_box *box,
                                        const void *data,
                                        unsigned stride,
-                                       unsigned slice_stride)
+                                       unsigned layer_stride)
 {
 }
 
@@ -277,12 +277,11 @@ static void noop_clear_depth_stencil(struct pipe_context *ctx,
 
 static void noop_resource_copy_region(struct pipe_context *ctx,
                                      struct pipe_resource *dst,
-                                     struct pipe_subresource subdst,
+                                     unsigned dst_level,
                                      unsigned dstx, unsigned dsty, unsigned dstz,
                                      struct pipe_resource *src,
-                                     struct pipe_subresource subsrc,
-                                     unsigned srcx, unsigned srcy, unsigned srcz,
-                                     unsigned width, unsigned height)
+                                     unsigned src_level,
+                                     const struct pipe_box *src_box)
 {
 }
 
@@ -332,46 +331,14 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, void
        return ctx;
 }
 
-/*
- * texture
- */
-static struct pipe_surface *noop_get_tex_surface(struct pipe_screen *screen,
-                                               struct pipe_resource *texture,
-                                               unsigned face, unsigned level,
-                                               unsigned zslice, unsigned flags)
-{
-       struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
-
-       if (surface == NULL)
-               return NULL;
-       pipe_reference_init(&surface->reference, 1);
-       pipe_resource_reference(&surface->texture, texture);
-       surface->format = texture->format;
-       surface->width = texture->width0;
-       surface->height = texture->height0;
-       surface->offset = 0;
-       surface->usage = flags;
-       surface->zslice = zslice;
-       surface->texture = texture;
-       surface->face = face;
-       surface->level = level;
-
-       return surface;
-}
-
-static void noop_tex_surface_destroy(struct pipe_surface *surface)
-{
-       pipe_resource_reference(&surface->texture, NULL);
-       FREE(surface);
-}
-
 
 /*
  * pipe_screen
  */
 static void noop_flush_frontbuffer(struct pipe_screen *_screen,
-                                       struct pipe_surface *surface,
-                                       void *context_private)
+                                  struct pipe_resource *resource,
+                                  unsigned level, unsigned layer,
+                                  void *context_private)
 {
 }
 
@@ -537,8 +504,6 @@ struct pipe_screen *noop_screen_create(struct sw_winsys *winsys)
        screen->get_paramf = noop_get_paramf;
        screen->is_format_supported = noop_is_format_supported;
        screen->context_create = noop_create_context;
-       screen->get_tex_surface = noop_get_tex_surface;
-       screen->tex_surface_destroy = noop_tex_surface_destroy;
        screen->resource_create = noop_resource_create;
        screen->resource_from_handle = noop_resource_from_handle;
        screen->resource_get_handle = noop_resource_get_handle;
index 048ed42a9b666c0da4ef7160ea51c872f56955b5..ad324774c0347de38f50260accf28e2f0786dd13 100644 (file)
@@ -101,6 +101,28 @@ static struct pipe_sampler_view *noop_create_sampler_view(struct pipe_context *c
        return sampler_view;
 }
 
+static struct pipe_surface *noop_create_surface(struct pipe_context *ctx,
+                                               struct pipe_resource *texture,
+                                               const struct pipe_surface *surf_tmpl)
+{
+       struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
+
+       if (surface == NULL)
+               return NULL;
+       pipe_reference_init(&surface->reference, 1);
+       pipe_resource_reference(&surface->texture, texture);
+       surface->context = ctx;
+       surface->format = surf_tmpl->format;
+       surface->width = texture->width0;
+       surface->height = texture->height0;
+       surface->usage = surf_tmpl->usage;
+       surface->texture = texture;
+       surface->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+       surface->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+       surface->u.tex.level = surf_tmpl->u.tex.level;
+
+       return surface;
+}
 static void noop_set_vs_sampler_view(struct pipe_context *ctx, unsigned count,
                                        struct pipe_sampler_view **views)
 {
@@ -163,6 +185,14 @@ static void noop_sampler_view_destroy(struct pipe_context *ctx,
        FREE(state);
 }
 
+
+static void noop_surface_destroy(struct pipe_context *ctx,
+                                struct pipe_surface *surface)
+{
+       pipe_resource_reference(&surface->texture, NULL);
+       FREE(surface);
+}
+
 static void noop_bind_state(struct pipe_context *ctx, void *state)
 {
 }
@@ -213,6 +243,8 @@ static void *noop_create_shader_state(struct pipe_context *ctx,
        return nstate;
 }
 
+void noop_init_state_functions(struct pipe_context *ctx);
+
 void noop_init_state_functions(struct pipe_context *ctx)
 {
        ctx->create_blend_state = noop_create_blend_state;
@@ -221,6 +253,7 @@ void noop_init_state_functions(struct pipe_context *ctx)
        ctx->create_rasterizer_state = noop_create_rs_state;
        ctx->create_sampler_state = noop_create_sampler_state;
        ctx->create_sampler_view = noop_create_sampler_view;
+       ctx->create_surface = noop_create_surface;
        ctx->create_vertex_elements_state = noop_create_vertex_elements;
        ctx->create_vs_state = noop_create_shader_state;
        ctx->bind_blend_state = noop_bind_state;
@@ -252,5 +285,6 @@ void noop_init_state_functions(struct pipe_context *ctx)
        ctx->set_vertex_sampler_views = noop_set_vs_sampler_view;
        ctx->set_viewport_state = noop_set_viewport_state;
        ctx->sampler_view_destroy = noop_sampler_view_destroy;
+       ctx->surface_destroy = noop_surface_destroy;
        ctx->draw_vbo = noop_draw_vbo;
 }
index dacfee9799c89f8993ab7a0ecd61560fb96aba84..45356f9f637c290f06f6707f472b7df99de2e916 100644 (file)
@@ -136,6 +136,7 @@ nv50_user_buffer_create(struct pipe_screen *pscreen,
        buffer->base.width0 = bytes;
        buffer->base.height0 = 1;
        buffer->base.depth0 = 1;
+       buffer->base.array_size = 1;
 
        buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
        if (!buffer->bo)
index bf6a577188be55bafa193188c07c520ab596b015..b2b0b72fe265e1e33b6e23999b7697cb9648d328 100644 (file)
@@ -108,6 +108,7 @@ get_tile_depth(uint32_t tile_mode)
 
 struct nv50_surface {
        struct pipe_surface base;
+       unsigned offset;
 };
 
 static INLINE struct nv50_surface *
index dd0e8fd41b1b4a238853bc1ab804770397106602..309b6503ca52e8a7010ba0626d984257a568336a 100644 (file)
@@ -276,46 +276,53 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
  */
 
 struct pipe_surface *
-nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
-                        unsigned face, unsigned level, unsigned zslice,
-                        unsigned flags)
+nv50_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
+                        const struct pipe_surface *surf_tmpl)
 {
+       unsigned level = surf_tmpl->u.tex.level;
        struct nv50_miptree *mt = nv50_miptree(pt);
        struct nv50_miptree_level *lvl = &mt->level[level];
-       struct pipe_surface *ps;
-       unsigned img = 0;
+       struct nv50_surface *ns;
+       unsigned img = 0, zslice = 0;
 
+       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+
+       /* XXX can't unify these here? */
        if (pt->target == PIPE_TEXTURE_CUBE)
-               img = face;
+               img = surf_tmpl->u.tex.first_layer;
+       else if (pt->target == PIPE_TEXTURE_3D)
+               zslice = surf_tmpl->u.tex.first_layer;
 
-       ps = CALLOC_STRUCT(pipe_surface);
-       if (!ps)
+       ns = CALLOC_STRUCT(nv50_surface);
+       if (!ns)
                return NULL;
-       pipe_resource_reference(&ps->texture, pt);
-       ps->format = pt->format;
-       ps->width = u_minify(pt->width0, level);
-       ps->height = u_minify(pt->height0, level);
-       ps->usage = flags;
-       pipe_reference_init(&ps->reference, 1);
-       ps->face = face;
-       ps->level = level;
-       ps->zslice = zslice;
-       ps->offset = lvl->image_offset[img];
+       pipe_resource_reference(&ns->base.texture, pt);
+       ns->base.context = pipe;
+       ns->base.format = pt->format;
+       ns->base.width = u_minify(pt->width0, level);
+       ns->base.height = u_minify(pt->height0, level);
+       ns->base.usage = surf_tmpl->usage;
+       pipe_reference_init(&ns->base.reference, 1);
+       ns->base.u.tex.level = level;
+       ns->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+       ns->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+       ns->offset = lvl->image_offset[img];
 
        if (pt->target == PIPE_TEXTURE_3D) {
-               unsigned nb_h = util_format_get_nblocksy(pt->format, ps->height);
-               ps->offset += get_zslice_offset(lvl->tile_mode, zslice,
+               unsigned nb_h = util_format_get_nblocksy(pt->format, ns->base.height);
+               ns->offset += get_zslice_offset(lvl->tile_mode, zslice,
                                                lvl->pitch, nb_h);
        }
 
-       return ps;
+       return &ns->base;
 }
 
 void
-nv50_miptree_surface_del(struct pipe_surface *ps)
+nv50_miptree_surface_del(struct pipe_context *pipe,
+                        struct pipe_surface *ps)
 {
        struct nv50_surface *s = nv50_surface(ps);
 
-       pipe_resource_reference(&ps->texture, NULL);
+       pipe_resource_reference(&s->base.texture, NULL);
        FREE(s);
 }
index cfdb60418b5efcf1601521d2d29a26cd0eb3f60e..6c0a9696355de2d5bbdf25408344ebcedd88f5af 100644 (file)
@@ -15,7 +15,7 @@
 static unsigned int
 nv50_resource_is_referenced(struct pipe_context *pipe,
                            struct pipe_resource *resource,
-                           unsigned face, unsigned level)
+                           unsigned level, int layer)
 {
        return nouveau_reference_flags(nv50_resource(resource)->bo);
 }
@@ -51,6 +51,9 @@ nv50_init_resource_functions(struct pipe_context *pcontext)
        pcontext->transfer_destroy = u_transfer_destroy_vtbl;
        pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
        pcontext->is_resource_referenced = nv50_resource_is_referenced;
+
+       pcontext->create_surface = nv50_miptree_surface_new;
+       pcontext->surface_destroy = nv50_miptree_surface_del;
 }
 
 void
@@ -61,7 +64,4 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen)
        pscreen->resource_get_handle = u_resource_get_handle_vtbl;
        pscreen->resource_destroy = u_resource_destroy_vtbl;
        pscreen->user_buffer_create = nv50_user_buffer_create;
-   
-       pscreen->get_tex_surface = nv50_miptree_surface_new;
-       pscreen->tex_surface_destroy = nv50_miptree_surface_del;
 }
index f435a5892e51b96ea648f51fa80740caa5276612..4b2a75e11ad9341e94891a0671f4c287178b1db7 100644 (file)
@@ -87,12 +87,11 @@ nv50_user_buffer_create(struct pipe_screen *screen,
 
 
 struct pipe_surface *
-nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
-                        unsigned face, unsigned level, unsigned zslice,
-                        unsigned flags);
+nv50_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
+                        const struct pipe_surface *surf_tmpl);
 
 void
-nv50_miptree_surface_del(struct pipe_surface *ps);
+nv50_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps);
 
 
 #endif
index 51eab3a0b039889a61c2463a3b38ef6849d3cdfe..edc3d54d01287c57621beb92cadeec4d32d01a4a 100644 (file)
@@ -127,6 +127,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return 0;
        case PIPE_CAP_DEPTH_CLAMP:
                return 1;
+       case PIPE_CAP_SHADER_STENCIL_EXPORT:
+               return 0;
+       case PIPE_CAP_PRIMITIVE_RESTART:
+               return 0;
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
@@ -176,6 +180,8 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
                return 1;
+       case PIPE_SHADER_CAP_SUBROUTINES:
+               return 0;
        default:
                return 0;
        }
index 16c2dab9af658d8f1f40c16f12582f6045a7c8fa..ae02143e352f92e38e6885e8199aa95e3e64c8e2 100644 (file)
@@ -63,13 +63,13 @@ validate_fb(struct nv50_context *nv50)
                so_data  (so, fb->cbufs[i]->height);
 
                so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5);
-               so_reloc (so, bo, fb->cbufs[i]->offset, NOUVEAU_BO_VRAM |
+               so_reloc (so, bo, ((struct nv50_surface *)fb->cbufs[i])->offset, NOUVEAU_BO_VRAM |
                              NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0);
-               so_reloc (so, bo, fb->cbufs[i]->offset, NOUVEAU_BO_VRAM |
+               so_reloc (so, bo, ((struct nv50_surface *)fb->cbufs[i])->offset, NOUVEAU_BO_VRAM |
                              NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
                so_data  (so, nv50_format_table[fb->cbufs[i]->format].rt);
                so_data  (so, nv50_miptree(pt)->
-                             level[fb->cbufs[i]->level].tile_mode << 4);
+                             level[fb->cbufs[i]->u.tex.level].tile_mode << 4);
                so_data(so, 0x00000000);
 
                so_method(so, tesla, NV50TCL_RT_ARRAY_MODE, 1);
@@ -92,13 +92,13 @@ validate_fb(struct nv50_context *nv50)
                assert(nv50_format_table[fb->zsbuf->format].rt);
 
                so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
-               so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM |
+               so_reloc (so, bo, ((struct nv50_surface *)(fb->zsbuf))->offset, NOUVEAU_BO_VRAM |
                              NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0);
-               so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM |
+               so_reloc (so, bo, ((struct nv50_surface *)(fb->zsbuf))->offset, NOUVEAU_BO_VRAM |
                              NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
                so_data  (so, nv50_format_table[fb->zsbuf->format].rt);
                so_data  (so, nv50_miptree(pt)->
-                             level[fb->zsbuf->level].tile_mode << 4);
+                             level[fb->zsbuf->u.tex.level].tile_mode << 4);
                so_data  (so, 0x00000000);
 
                so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1);
index f70c138fe1a3e75183c31af38c941aeb94623b62..ce48022db4e73373d83dc202af7237073f681e3f 100644 (file)
@@ -97,23 +97,23 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
                OUT_RING  (chan, format);
                OUT_RING  (chan, 1);
                BEGIN_RING(chan, eng2d, mthd + 0x14, 5);
-               OUT_RING  (chan, mt->level[ps->level].pitch);
+               OUT_RING  (chan, mt->level[ps->u.tex.level].pitch);
                OUT_RING  (chan, ps->width);
                OUT_RING  (chan, ps->height);
-               OUT_RELOCh(chan, bo, ps->offset, flags);
-               OUT_RELOCl(chan, bo, ps->offset, flags);
+               OUT_RELOCh(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
+               OUT_RELOCl(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
        } else {
                BEGIN_RING(chan, eng2d, mthd, 5);
                OUT_RING  (chan, format);
                OUT_RING  (chan, 0);
-               OUT_RING  (chan, mt->level[ps->level].tile_mode << 4);
+               OUT_RING  (chan, mt->level[ps->u.tex.level].tile_mode << 4);
                OUT_RING  (chan, 1);
                OUT_RING  (chan, 0);
                BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
                OUT_RING  (chan, ps->width);
                OUT_RING  (chan, ps->height);
-               OUT_RELOCh(chan, bo, ps->offset, flags);
-               OUT_RELOCl(chan, bo, ps->offset, flags);
+               OUT_RELOCh(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
+               OUT_RELOCl(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
        }
  
 #if 0
@@ -173,30 +173,41 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst,
 
 static void
 nv50_surface_copy(struct pipe_context *pipe,
-                 struct pipe_resource *dest, struct pipe_subresource subdst,
+                 struct pipe_resource *dest, unsigned dst_level,
                  unsigned destx, unsigned desty, unsigned destz,
-                 struct pipe_resource *src, struct pipe_subresource subsrc,
-                 unsigned srcx, unsigned srcy, unsigned srcz,
-                 unsigned width, unsigned height)
+                 struct pipe_resource *src, unsigned src_level,
+                 const struct pipe_box *src_box)
 {
        struct nv50_context *nv50 = nv50_context(pipe);
        struct nv50_screen *screen = nv50->screen;
-       struct pipe_surface *ps_dst, *ps_src;
+       struct pipe_surface *ps_dst, *ps_src, surf_tmpl;
+
 
        assert((src->format == dest->format) ||
               (nv50_2d_format_faithful(src->format) &&
                nv50_2d_format_faithful(dest->format)));
-
-       ps_src = nv50_miptree_surface_new(pipe->screen, src, subsrc.face,
-                                         subsrc.level, srcz, 0 /* bind flags */);
-       ps_dst = nv50_miptree_surface_new(pipe->screen, dest, subdst.face,
-                                         subdst.level, destz, 0 /* bindflags */);
-
-       nv50_surface_do_copy(screen, ps_dst, destx, desty, ps_src, srcx,
-                            srcy, width, height);
-
-       nv50_miptree_surface_del(ps_src);
-       nv50_miptree_surface_del(ps_dst);
+       assert(src_box->depth == 1);
+
+       memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+       surf_tmpl.format = src->format;
+       surf_tmpl.usage = 0; /* no bind flag - not a surface */
+       surf_tmpl.u.tex.level = src_level;
+       surf_tmpl.u.tex.first_layer = src_box->z;
+       surf_tmpl.u.tex.last_layer = src_box->z;
+       /* XXX really need surfaces here? */
+       ps_src = nv50_miptree_surface_new(pipe, src, &surf_tmpl);
+       surf_tmpl.format = dest->format;
+       surf_tmpl.usage = 0; /* no bind flag - not a surface */
+       surf_tmpl.u.tex.level = dst_level;
+       surf_tmpl.u.tex.first_layer = destz;
+       surf_tmpl.u.tex.last_layer = destz;
+       ps_dst = nv50_miptree_surface_new(pipe, dest, &surf_tmpl);
+
+       nv50_surface_do_copy(screen, ps_dst, destx, desty, ps_src, src_box->x,
+                            src_box->y, src_box->width, src_box->height);
+
+       nv50_miptree_surface_del(pipe, ps_src);
+       nv50_miptree_surface_del(pipe, ps_dst);
 }
 
 static void
@@ -225,10 +236,10 @@ nv50_clear_render_target(struct pipe_context *pipe,
        BEGIN_RING(chan, tesla, NV50TCL_RT_CONTROL, 1);
        OUT_RING  (chan, 1);
        BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5);
-       OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCh(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
        OUT_RING  (chan, nv50_format_table[dst->format].rt);
-       OUT_RING  (chan, mt->level[dst->level].tile_mode << 4);
+       OUT_RING  (chan, mt->level[dst->u.tex.level].tile_mode << 4);
        OUT_RING  (chan, 0);
        BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2);
        OUT_RING  (chan, dst->width);
@@ -281,10 +292,10 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
                return;
 
        BEGIN_RING(chan, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
-       OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCh(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
        OUT_RING  (chan, nv50_format_table[dst->format].rt);
-       OUT_RING  (chan, mt->level[dst->level].tile_mode << 4);
+       OUT_RING  (chan, mt->level[dst->u.tex.level].tile_mode << 4);
        OUT_RING  (chan, 0);
        BEGIN_RING(chan, tesla, NV50TCL_ZETA_ENABLE, 1);
        OUT_RING  (chan, 1);
index 658324ec5bebc1aba6c266c860b3b1971946e24b..9243f9edceda320bb2c3c448f625fe2aa073ac98 100644 (file)
@@ -106,7 +106,7 @@ nv50_tex_construct(struct nv50_sampler_view *view)
 
        tic[6] = 0x03000000;
 
-       tic[7] = (view->pipe.last_level << 4) | view->pipe.first_level;
+       tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
 
        return TRUE;
 }
index 0cc2f4a837f0dcefa3cc36643b76519865636256..bf5af4ddc653cf580f4aa2546ab20d28688dc45b 100644 (file)
@@ -126,20 +126,23 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
 struct pipe_transfer *
 nv50_miptree_transfer_new(struct pipe_context *pcontext,
                          struct pipe_resource *pt,
-                         struct pipe_subresource sr,
+                         unsigned level,
                          unsigned usage,
                          const struct pipe_box *box)
 {
         struct pipe_screen *pscreen = pcontext->screen;
        struct nouveau_device *dev = nouveau_screen(pscreen)->device;
        struct nv50_miptree *mt = nv50_miptree(pt);
-       struct nv50_miptree_level *lvl = &mt->level[sr.level];
+       struct nv50_miptree_level *lvl = &mt->level[level];
        struct nv50_transfer *tx;
-       unsigned nx, ny, image = 0;
+       unsigned nx, ny, image = 0, boxz = 0;
        int ret;
 
+       /* XXX can't unify these here? */
        if (pt->target == PIPE_TEXTURE_CUBE)
-               image = sr.face;
+               image = box->z;
+       else if (pt->target == PIPE_TEXTURE_3D)
+               boxz = box->z;
 
        tx = CALLOC_STRUCT(nv50_transfer);
        if (!tx)
@@ -151,21 +154,21 @@ nv50_miptree_transfer_new(struct pipe_context *pcontext,
 
 
        pipe_resource_reference(&tx->base.resource, pt);
-       tx->base.sr = sr;
+       tx->base.level = level;
        tx->base.usage = usage;
        tx->base.box = *box;
-       tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, sr.level));
-       tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, sr.level));
+       tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level));
+       tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level));
        tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format);
        tx->base.usage = usage;
 
        tx->level_pitch = lvl->pitch;
-       tx->level_width = u_minify(mt->base.base.width0, sr.level);
-       tx->level_height = u_minify(mt->base.base.height0, sr.level);
-       tx->level_depth = u_minify(mt->base.base.depth0, sr.level);
+       tx->level_width = u_minify(mt->base.base.width0, level);
+       tx->level_height = u_minify(mt->base.base.height0, level);
+       tx->level_depth = u_minify(mt->base.base.depth0, level);
        tx->level_offset = lvl->image_offset[image];
        tx->level_tiling = lvl->tile_mode;
-       tx->level_z = box->z;
+       tx->level_z = boxz;
        tx->level_x = util_format_get_nblocksx(pt->format, box->x);
        tx->level_y = util_format_get_nblocksy(pt->format, box->y);
        ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
@@ -181,7 +184,7 @@ nv50_miptree_transfer_new(struct pipe_context *pcontext,
 
                nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
                                        tx->level_pitch, tx->level_tiling,
-                                       box->x, box->y, box->z,
+                                       box->x, box->y, boxz,
                                        tx->nblocksx, tx->nblocksy,
                                        tx->level_depth,
                                        tx->bo, 0,
index 663503547cb6b12bfe9023a6eb1708827c43155b..6699bf546eabff47a1be5c5c7ead934eb8fcab1b 100644 (file)
@@ -8,7 +8,7 @@
 struct pipe_transfer *
 nv50_miptree_transfer_new(struct pipe_context *pcontext,
                          struct pipe_resource *pt,
-                         struct pipe_subresource sr,
+                         unsigned level,
                          unsigned usage,
                          const struct pipe_box *box);
 void
index d6ede5b40a1a9be08d0c24565124006c58f7d53b..951fb202ed4ac9979af443346da0b1c1cc729403 100644 (file)
@@ -37,12 +37,12 @@ nv30_sampler_view_init(struct pipe_context *pipe,
        struct pipe_resource* pt = sv->base.texture;
        struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
        unsigned txf;
-       unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.first_level;
+       unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.u.tex.first_level;
 
        assert(tf->fmt[0] >= 0);
 
        txf = sv->u.init_fmt;
-       txf |= (level != sv->base.last_level ? NV30_3D_TEX_FORMAT_MIPMAP : 0);
+       txf |= (level != sv->base.u.tex.last_level ? NV30_3D_TEX_FORMAT_MIPMAP : 0);
        txf |= util_logbase2(u_minify(pt->width0, level)) << NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT;
        txf |= util_logbase2(u_minify(pt->height0, level)) << NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT;
        txf |= util_logbase2(u_minify(pt->depth0, level)) << NV30_3D_TEX_FORMAT_BASE_SIZE_W__SHIFT;
@@ -60,8 +60,8 @@ nv30_sampler_view_init(struct pipe_context *pipe,
        else
                sv->u.nv30.rect = !!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR);
 
-       sv->lod_offset = sv->base.first_level - level;
-       sv->max_lod_limit = sv->base.last_level - level;
+       sv->lod_offset = sv->base.u.tex.first_level - level;
+       sv->max_lod_limit = sv->base.u.tex.last_level - level;
 }
 
 void
index d4fb73702daaff49b41993b2678fe54cc370cc79..e8ab403f72240a6608b98b47db35b9eff951bf7e 100644 (file)
@@ -46,7 +46,7 @@ nv40_sampler_view_init(struct pipe_context *pipe,
        struct nvfx_miptree* mt = (struct nvfx_miptree*)pt;
        struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
        unsigned txf;
-       unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.first_level;
+       unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.u.tex.first_level;
        assert(tf->fmt[4] >= 0);
 
        txf = sv->u.init_fmt;
@@ -54,7 +54,7 @@ nv40_sampler_view_init(struct pipe_context *pipe,
        if(pt->target == PIPE_TEXTURE_CUBE)
                txf |= ((pt->last_level + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT);
        else
-               txf |= (((sv->base.last_level - sv->base.first_level) + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT);
+               txf |= (((sv->base.u.tex.last_level - sv->base.u.tex.first_level) + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT);
 
        if (!mt->linear_pitch)
                sv->u.nv40.npot_size2 = 0;
@@ -68,8 +68,8 @@ nv40_sampler_view_init(struct pipe_context *pipe,
 
        sv->u.nv40.npot_size2 |= (u_minify(pt->depth0, level) << NV40_3D_TEX_SIZE1_DEPTH__SHIFT);
 
-       sv->lod_offset = (sv->base.first_level - level) * 256;
-       sv->max_lod_limit = (sv->base.last_level - level) * 256;
+       sv->lod_offset = (sv->base.u.tex.first_level - level) * 256;
+       sv->max_lod_limit = (sv->base.u.tex.last_level - level) * 256;
 }
 
 void
index 041099e0e568ca953464fc4aa09468077f8409be..b407429731f94f3d1ee6276972464be754523d44 100644 (file)
@@ -64,6 +64,7 @@ nvfx_user_buffer_create(struct pipe_screen *pscreen,
        buffer->base.base.width0 = bytes;
        buffer->base.base.height0 = 1;
        buffer->base.base.depth0 = 1;
+       buffer->base.base.array_size = 1;
        buffer->data = ptr;
        buffer->size = bytes;
        buffer->bytes_to_draw_until_static = bytes * screen->static_reuse_threshold;
index 1d6b4e24cbc97d5a4b2839cbf55102f8a03f4232..fd0aff6a1a06740cfc48a4295f0d83950cc9b0db 100644 (file)
@@ -122,8 +122,8 @@ nvfx_create_sampler_view(struct pipe_context *pipe,
        }
        else
        {
-               sv->offset = nvfx_subresource_offset(pt, 0, sv->base.first_level, 0);
-               sv->npot_size = (u_minify(pt->width0, sv->base.first_level) << NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | u_minify(pt->height0, sv->base.first_level);
+               sv->offset = nvfx_subresource_offset(pt, 0, sv->base.u.tex.first_level, 0);
+               sv->npot_size = (u_minify(pt->width0, sv->base.u.tex.first_level) << NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | u_minify(pt->height0, sv->base.u.tex.first_level);
 
                /* apparently, we need to ignore the t coordinate for 1D textures to fix piglit tex1d-2dborder */
                if(pt->target == PIPE_TEXTURE_1D)
index 7677fde40cbfe9e806adf43ce291651d74e8124f..8c043b867bae6b8d0a122d37b02097853dbbf4f0 100644 (file)
@@ -190,25 +190,27 @@ nvfx_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource
 }
 
 struct pipe_surface *
-nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
-                        unsigned face, unsigned level, unsigned zslice,
-                        unsigned flags)
+nvfx_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
+                        const struct pipe_surface *surf_tmpl)
 {
-       struct nvfx_miptree* mt = (struct nvfx_miptree*)pt;
-       struct nvfx_surface *ns;
-
-       ns = (struct nvfx_surface*)util_surfaces_get(&mt->surfaces, sizeof(struct nvfx_surface), pscreen, pt, face, level, zslice, flags);
-       if(ns->base.base.offset == ~0) {
-               util_dirty_surface_init(&ns->base);
-               ns->pitch = nvfx_subresource_pitch(pt, level);
-               ns->base.base.offset = nvfx_subresource_offset(pt, face, level, zslice);
+       struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+       unsigned level = surf_tmpl->u.tex.level;
+       struct nvfx_surface *ns = NULL;
+
+       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+       if(util_surfaces_get(&mt->surfaces, sizeof(struct nvfx_surface), pipe,
+                             pt, level, surf_tmpl->u.tex.first_layer,
+                             surf_tmpl->usage, (struct pipe_surface **)&ns)) {
+                util_dirty_surface_init(&ns->base);
+                ns->pitch = nvfx_subresource_pitch(pt, level);
+                ns->offset = nvfx_subresource_offset(pt, surf_tmpl->u.tex.first_layer, level, surf_tmpl->u.tex.first_layer);
        }
 
        return &ns->base.base;
 }
 
 void
-nvfx_miptree_surface_del(struct pipe_surface *ps)
+nvfx_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps)
 {
        struct nvfx_surface* ns = (struct nvfx_surface*)ps;
 
index 39ae893f1b3b8c589453f2080e810c1ef4c96051..c60a7bb8b93c86c2314ce194d169914d11f5a1d5 100644 (file)
@@ -7,7 +7,7 @@
 static unsigned int
 nvfx_resource_is_referenced(struct pipe_context *pipe,
                            struct pipe_resource *pr,
-                           unsigned face, unsigned level)
+                           unsigned level, int layer)
 {
        return !!nouveau_reference_flags(nvfx_resource(pr)->bo);
 }
@@ -59,6 +59,9 @@ void
 nvfx_init_resource_functions(struct pipe_context *pipe)
 {
        pipe->is_resource_referenced = nvfx_resource_is_referenced;
+
+       pipe->create_surface = nvfx_miptree_surface_new;
+       pipe->surface_destroy = nvfx_miptree_surface_del;
 }
 
 void
@@ -69,7 +72,4 @@ nvfx_screen_init_resource_functions(struct pipe_screen *pscreen)
        pscreen->resource_get_handle = nvfx_resource_get_handle;
        pscreen->resource_destroy = nvfx_resource_destroy;
        pscreen->user_buffer_create = nvfx_user_buffer_create;
-
-       pscreen->get_tex_surface = nvfx_miptree_surface_new;
-       pscreen->tex_surface_destroy = nvfx_miptree_surface_del;
 }
index 583be4de2ae2596bca94c091fd1163fd701254b3..070f89794429254e4b7a8493dc620d73473cf361 100644 (file)
@@ -74,6 +74,7 @@ struct nvfx_miptree {
 struct nvfx_surface {
        struct util_dirty_surface base;
        unsigned pitch;
+       unsigned offset;
 
        struct nvfx_miptree* temp;
 };
@@ -116,12 +117,11 @@ nvfx_miptree_from_handle(struct pipe_screen *pscreen,
                         struct winsys_handle *whandle);
 
 void
-nvfx_miptree_surface_del(struct pipe_surface *ps);
+nvfx_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps);
 
 struct pipe_surface *
-nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
-                        unsigned face, unsigned level, unsigned zslice,
-                        unsigned flags);
+nvfx_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
+                        const struct pipe_surface *surf_tmpl);
 
 /* only for miptrees, don't use for buffers */
 
index 708fc3807dc59723b3bc86945b07ddc917c7aba6..273fac76a9ff3296084ef82cbef14bd4bdd26753 100644 (file)
@@ -124,6 +124,8 @@ nvfx_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum
                case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
                case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
                        return 0;
+               case PIPE_SHADER_CAP_SUBROUTINES:
+                       return screen->use_nv4x ? 1 : 0;
                default:
                        break;
                }
@@ -162,6 +164,8 @@ nvfx_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum
                        return 0;
                case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
                        return 1;
+               case PIPE_SHADER_CAP_SUBROUTINES:
+                       return 1;
                default:
                        break;
                }
index 30e48c807354c59d560d37561453802849d928e1..816bb89f2c649388026f896aff834e2785a74ab5 100644 (file)
@@ -7,7 +7,7 @@ nvfx_surface_linear_renderable(struct pipe_surface* surf)
 {
        /* TODO: precompute this in nvfx_surface creation */
        return (surf->texture->flags & NVFX_RESOURCE_FLAG_LINEAR)
-               && !(surf->offset & 63)
+               && !(((struct nvfx_surface*)surf)->offset & 63)
                && !(((struct nvfx_surface*)surf)->pitch & 63);
 }
 
@@ -16,8 +16,8 @@ nvfx_surface_swizzled_renderable(struct pipe_framebuffer_state* fb, struct pipe_
 {
        /* TODO: precompute this in nvfx_surface creation */
        return !((struct nvfx_miptree*)surf->texture)->linear_pitch
-               && (surf->texture->target != PIPE_TEXTURE_3D || u_minify(surf->texture->depth0, surf->level) <= 1)
-               && !(surf->offset & 127)
+               && (surf->texture->target != PIPE_TEXTURE_3D || u_minify(surf->texture->depth0, surf->u.tex.level) <= 1)
+               && !(((struct nvfx_surface*)surf)->offset & 127)
                && (surf->width == fb->width)
                && (surf->height == fb->height)
                && !((struct nvfx_surface*)surf)->temp
@@ -31,7 +31,7 @@ nvfx_surface_get_render_target(struct pipe_surface* surf, int all_swizzled, stru
        if(!ns->temp)
        {
                target->bo = ((struct nvfx_miptree*)surf->texture)->base.bo;
-               target->offset = surf->offset;
+               target->offset = ns->offset;
                target->pitch = align(ns->pitch, 64);
                assert(target->pitch);
                return FALSE;
@@ -54,7 +54,7 @@ nvfx_framebuffer_prepare(struct nvfx_context *nvfx)
        int all_swizzled = 1;
 
        if(!nvfx->is_nv4x)
-               assert(fb->nr_cbufs <= 2);
+               assert(fb->nr_cbufs <= 1);
        else
                assert(fb->nr_cbufs <= 4);
 
@@ -113,7 +113,9 @@ nvfx_framebuffer_validate(struct nvfx_context *nvfx, unsigned prepare_result)
                nvfx->state.render_temps |= nvfx_surface_get_render_target(fb->cbufs[i], prepare_result, &nvfx->hw_rt[i]) << i;
 
        for(; i < 4; ++i)
-               nvfx->hw_rt[i].bo = 0;
+               nvfx->hw_rt[i].bo = NULL;
+
+       nvfx->hw_zeta.bo = NULL;
 
        if (fb->zsbuf) {
                nvfx->state.render_temps |= nvfx_surface_get_render_target(fb->zsbuf, prepare_result, &nvfx->hw_zeta) << 7;
index 70adebc1be5d4dd826f1d49dde0c1bbaddccf434..6fd6c47081bf18e101c13bf1060602b87ea3fbca 100644 (file)
@@ -99,17 +99,17 @@ nvfx_region_init_for_surface(struct nv04_region* rgn, struct nvfx_surface* surf,
                        util_dirty_surface_set_dirty(nvfx_surface_get_dirty_surfaces(&surf->base.base), &surf->base);
        } else {
                rgn->bo = ((struct nvfx_resource*)surf->base.base.texture)->bo;
-               rgn->offset = surf->base.base.offset;
+               rgn->offset = surf->offset;
 
                if(surf->base.base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)
                        rgn->pitch = surf->pitch;
                else
                {
                        rgn->pitch = 0;
-                       rgn->z = surf->base.base.zslice;
+                       rgn->z = surf->base.base.u.tex.first_layer;
                        rgn->w = surf->base.base.width;
                        rgn->h = surf->base.base.height;
-                       rgn->d = u_minify(surf->base.base.texture->depth0, surf->base.base.level);
+                       rgn->d = u_minify(surf->base.base.texture->depth0, surf->base.base.u.tex.level);
                }
        }
 
@@ -119,11 +119,11 @@ nvfx_region_init_for_surface(struct nv04_region* rgn, struct nvfx_surface* surf,
 }
 
 static INLINE void
-nvfx_region_init_for_subresource(struct nv04_region* rgn, struct pipe_resource* pt, struct pipe_subresource sub, unsigned x, unsigned y, unsigned z, bool for_write)
+nvfx_region_init_for_subresource(struct nv04_region* rgn, struct pipe_resource* pt, unsigned level, unsigned x, unsigned y, unsigned z, bool for_write)
 {
        if(pt->target != PIPE_BUFFER)
        {
-               struct nvfx_surface* ns = (struct nvfx_surface*)util_surfaces_peek(&((struct nvfx_miptree*)pt)->surfaces, pt, sub.face, sub.level, z);
+               struct nvfx_surface* ns = (struct nvfx_surface*)util_surfaces_peek(&((struct nvfx_miptree*)pt)->surfaces, pt, level, z);
                if(ns && util_dirty_surface_is_dirty(&ns->base))
                {
                        nvfx_region_init_for_surface(rgn, ns, x, y, for_write);
@@ -132,22 +132,22 @@ nvfx_region_init_for_subresource(struct nv04_region* rgn, struct pipe_resource*
        }
 
        rgn->bo = ((struct nvfx_resource*)pt)->bo;
-       rgn->offset = nvfx_subresource_offset(pt, sub.face, sub.level, z);
+       rgn->offset = nvfx_subresource_offset(pt, z, level, z);
        rgn->x = x;
        rgn->y = y;
 
        if(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)
        {
-               rgn->pitch = nvfx_subresource_pitch(pt, sub.level);
+               rgn->pitch = nvfx_subresource_pitch(pt, level);
                rgn->z = 0;
        }
        else
        {
                rgn->pitch = 0;
                rgn->z = z;
-               rgn->w = u_minify(pt->width0, sub.level);
-               rgn->h = u_minify(pt->height0, sub.level);
-               rgn->d = u_minify(pt->depth0, sub.level);
+               rgn->w = u_minify(pt->width0, level);
+               rgn->h = u_minify(pt->height0, level);
+               rgn->d = u_minify(pt->depth0, level);
        }
 
        nvfx_region_set_format(rgn, pt->format);
@@ -234,11 +234,10 @@ nvfx_region_clone(struct nv04_2d_context* ctx, struct nv04_region* rgn, unsigned
 
 static void
 nvfx_resource_copy_region(struct pipe_context *pipe,
-                 struct pipe_resource *dstr, struct pipe_subresource subdst,
-                 unsigned dstx, unsigned dsty, unsigned dstz,
-                 struct pipe_resource *srcr, struct pipe_subresource subsrc,
-                 unsigned srcx, unsigned srcy, unsigned srcz,
-                 unsigned w, unsigned h)
+                         struct pipe_resource *dstr, unsigned dst_level,
+                         unsigned dstx, unsigned dsty, unsigned dstz,
+                         struct pipe_resource *srcr, unsigned src_level,
+                         const struct pipe_box *src_box)
 {
        static int copy_threshold = -1;
        struct nv04_2d_context *ctx = nvfx_screen(pipe->screen)->eng2d;
@@ -247,6 +246,8 @@ nvfx_resource_copy_region(struct pipe_context *pipe,
        int src_on_gpu;
        boolean small;
        int ret;
+       unsigned w = src_box->width;
+       unsigned h = src_box->height;
 
        if(!w || !h)
                return;
@@ -257,8 +258,8 @@ nvfx_resource_copy_region(struct pipe_context *pipe,
        dst_to_gpu = dstr->usage != PIPE_USAGE_DYNAMIC && dstr->usage != PIPE_USAGE_STAGING;
        src_on_gpu = nvfx_resource_on_gpu(srcr);
 
-       nvfx_region_init_for_subresource(&dst, dstr, subdst, dstx, dsty, dstz, TRUE);
-       nvfx_region_init_for_subresource(&src, srcr, subsrc, srcx, srcy, srcz, FALSE);
+       nvfx_region_init_for_subresource(&dst, dstr, dst_level, dstx, dsty, dstz, TRUE);
+       nvfx_region_init_for_subresource(&src, srcr, src_level, src_box->x, src_box->y, src_box->z, FALSE);
        w = util_format_get_stride(dstr->format, w) >> dst.bpps;
        h = util_format_get_nblocksy(dstr->format, h);
 
@@ -279,7 +280,7 @@ nvfx_resource_copy_region(struct pipe_context *pipe,
                 * TODO: perhaps support reinterpreting the formats
                 */
                struct blitter_context* blitter = nvfx_get_blitter(pipe, 1);
-               util_blitter_copy_region(blitter, dstr, subdst, dstx, dsty, dstz, srcr, subsrc, srcx, srcy, srcz, w, h, TRUE);
+               util_blitter_copy_region(blitter, dstr, dst_level, dstx, dsty, dstz, srcr, src_level, src_box, TRUE);
                nvfx_put_blitter(pipe, blitter);
        }
        else
@@ -371,7 +372,7 @@ static void
 nvfx_surface_copy_temp(struct pipe_context* pipe, struct pipe_surface* surf, int to_temp)
 {
        struct nvfx_surface* ns = (struct nvfx_surface*)surf;
-       struct pipe_subresource tempsr, surfsr;
+       struct pipe_box box;
        struct nvfx_context* nvfx = nvfx_context(pipe);
        struct nvfx_miptree* temp;
        unsigned use_vertex_buffers;
@@ -387,15 +388,20 @@ nvfx_surface_copy_temp(struct pipe_context* pipe, struct pipe_surface* surf, int
        use_index_buffer = nvfx->use_index_buffer;
        base_vertex = nvfx->base_vertex;
 
-       tempsr.face = 0;
-       tempsr.level = 0;
-       surfsr.face = surf->face;
-       surfsr.level = surf->level;
+       box.x = box.y = 0;
+       assert(surf->u.tex.first_layer == surf->u.tex.last_layer);
+       box.width = surf->width;
+       box.height = surf->height;
+       box.depth = 1;
 
-       if(to_temp)
-               nvfx_resource_copy_region(pipe, &temp->base.base, tempsr, 0, 0, 0, surf->texture, surfsr, 0, 0, surf->zslice, surf->width, surf->height);
-       else
-               nvfx_resource_copy_region(pipe, surf->texture, surfsr, 0, 0, surf->zslice, &temp->base.base, tempsr, 0, 0, 0, surf->width, surf->height);
+       if(to_temp) {
+               box.z = surf->u.tex.first_layer;
+               nvfx_resource_copy_region(pipe, &temp->base.base, 0, 0, 0, 0, surf->texture, surf->u.tex.level, &box);
+       }
+       else {
+               box.z = 0;
+               nvfx_resource_copy_region(pipe, surf->texture, surf->u.tex.level, 0, 0, surf->u.tex.first_layer, &temp->base.base, 0, &box);
+       }
 
        /* If this triggers, it probably means we attempted to use the blitter
         * but failed due to non-renderability of the target.
index 7cb47a20f645818ecb046b24a258051b3e312c4f..2debcb6eb8f92578fcb9221009438f0f16321549 100644 (file)
@@ -21,10 +21,10 @@ struct nvfx_staging_transfer
 
 struct pipe_transfer *
 nvfx_transfer_new(struct pipe_context *pipe,
-                         struct pipe_resource *pt,
-                         struct pipe_subresource sr,
-                         unsigned usage,
-                         const struct pipe_box *box)
+                 struct pipe_resource *pt,
+                 unsigned level,
+                 unsigned usage,
+                 const struct pipe_box *box)
 {
         if((usage & (PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_DONTBLOCK)) == PIPE_TRANSFER_DONTBLOCK)
         {
@@ -44,11 +44,11 @@ nvfx_transfer_new(struct pipe_context *pipe,
                        return NULL;
 
                pipe_resource_reference(&tx->resource, pt);
-               tx->sr = sr;
+               tx->level = level;
                tx->usage = usage;
                tx->box = *box;
 
-               tx->slice_stride = tx->stride = util_format_get_stride(pt->format, box->width);
+               tx->layer_stride = tx->stride = util_format_get_stride(pt->format, box->width);
                tx->data = buffer->data + util_format_get_stride(pt->format, box->x);
 
                return tx;
@@ -62,20 +62,20 @@ nvfx_transfer_new(struct pipe_context *pipe,
                if(!tx)
                        return NULL;
 
-               util_staging_transfer_init(pipe, pt, sr, usage, box, direct, &tx->base);
+               util_staging_transfer_init(pipe, pt, level, usage, box, direct, &tx->base);
 
                if(direct)
                {
-                       tx->base.base.stride = nvfx_subresource_pitch(pt, sr.level);
-                       tx->base.base.slice_stride = tx->base.base.stride * u_minify(pt->height0, sr.level);
-                       tx->offset = nvfx_subresource_offset(pt, sr.face, sr.level, box->z)
+                       tx->base.base.stride = nvfx_subresource_pitch(pt, level);
+                       tx->base.base.layer_stride = tx->base.base.stride * u_minify(pt->height0, level);
+                       tx->offset = nvfx_subresource_offset(pt, box->z, level, box->z)
                                + util_format_get_2d_size(pt->format, tx->base.base.stride, box->y)
                                + util_format_get_stride(pt->format, box->x);
                }
                else
                {
                        tx->base.base.stride = nvfx_subresource_pitch(tx->base.staging_resource, 0);
-                       tx->base.base.slice_stride = tx->base.base.stride * tx->base.staging_resource->height0;
+                       tx->base.base.layer_stride = tx->base.base.stride * tx->base.staging_resource->height0;
                        tx->offset = 0;
                }
 
@@ -187,7 +187,7 @@ nvfx_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
 
 static void nvfx_transfer_inline_write( struct pipe_context *pipe,
                                      struct pipe_resource *pr,
-                                     struct pipe_subresource sr,
+                                     unsigned level,
                                      unsigned usage,
                                      const struct pipe_box *box,
                                      const void *data,
@@ -196,7 +196,7 @@ static void nvfx_transfer_inline_write( struct pipe_context *pipe,
 {
        if(pr->target != PIPE_BUFFER)
        {
-               u_default_transfer_inline_write(pipe, pr, sr, usage, box, data, stride, slice_stride);
+               u_default_transfer_inline_write(pipe, pr, level, usage, box, data, stride, slice_stride);
        }
        else
        {
index 20f20d5b0b8b0e0ae106670282853d9f71b5cc0b..682f428b793dd478d410d82f02e8157933a17472 100644 (file)
@@ -9,7 +9,7 @@
 struct pipe_transfer *
 nvfx_transfer_new(struct pipe_context *pcontext,
                          struct pipe_resource *pt,
-                         struct pipe_subresource sr,
+                         unsigned level,
                          unsigned usage,
                          const struct pipe_box *box);
 
index 0ac4e4c6f128cd4fd5d7a3dec9caf0abeef421bb..6e886433bc55e8428fd154f7ceb251251bd25adc 100644 (file)
@@ -186,12 +186,12 @@ static void r300_clear(struct pipe_context* pipe,
             r300_depth_clear_value(fb->zsbuf->format, depth, stencil);
 
         r300_mark_fb_state_dirty(r300, R300_CHANGED_ZCLEAR_FLAG);
-        if (zstex->zmask_mem[fb->zsbuf->level]) {
-            r300->zmask_clear.dirty = TRUE;
+        if (zstex->zmask_mem[fb->zsbuf->u.tex.level]) {
+            r300_mark_atom_dirty(r300, &r300->zmask_clear);
             buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
         }
-        if (zstex->hiz_mem[fb->zsbuf->level])
-            r300->hiz_clear.dirty = TRUE;
+        if (zstex->hiz_mem[fb->zsbuf->u.tex.level])
+            r300_mark_atom_dirty(r300, &r300->hiz_clear);
     }
 
     /* Enable CBZB clear. */
@@ -230,7 +230,7 @@ static void r300_clear(struct pipe_context* pipe,
                  r300_get_num_cs_end_dwords(r300);
 
         /* Reserve CS space. */
-        if (dwords > (r300->cs->ndw - r300->cs->cdw)) {
+        if (dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) {
             r300->context.flush(&r300->context, 0, NULL);
         }
 
@@ -259,9 +259,9 @@ static void r300_clear(struct pipe_context* pipe,
      * If we cleared zmask/hiz, it's in use now. The Hyper-Z state update
      * looks if zmask/hiz is in use and enables fastfill accordingly. */
     if (zstex &&
-        (zstex->zmask_in_use[fb->zsbuf->level] ||
-         zstex->hiz_in_use[fb->zsbuf->level])) {
-        r300->hyperz_state.dirty = TRUE;
+        (zstex->zmask_in_use[fb->zsbuf->u.tex.level] ||
+         zstex->hiz_in_use[fb->zsbuf->u.tex.level])) {
+        r300_mark_atom_dirty(r300, &r300->hyperz_state);
     }
 }
 
@@ -300,58 +300,61 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe,
 /* Flush a depth stencil buffer. */
 void r300_flush_depth_stencil(struct pipe_context *pipe,
                               struct pipe_resource *dst,
-                              struct pipe_subresource subdst,
-                              unsigned zslice)
+                              unsigned level,
+                              unsigned layer)
 {
     struct r300_context *r300 = r300_context(pipe);
-    struct pipe_surface *dstsurf;
+    struct pipe_surface *dstsurf, surf_tmpl;
     struct r300_texture *tex = r300_texture(dst);
 
-    if (!tex->zmask_mem[subdst.level])
+    if (!tex->zmask_mem[level])
         return;
-    if (!tex->zmask_in_use[subdst.level])
+    if (!tex->zmask_in_use[level])
         return;
 
-    dstsurf = pipe->screen->get_tex_surface(pipe->screen, dst,
-                                            subdst.face, subdst.level, zslice,
-                                            PIPE_BIND_DEPTH_STENCIL);
+    surf_tmpl.format = dst->format;
+    surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL;
+    surf_tmpl.u.tex.level = level;
+    surf_tmpl.u.tex.first_layer = layer;
+    surf_tmpl.u.tex.last_layer = layer;
+    dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
+
     r300->z_decomp_rd = TRUE;
     r300_blitter_begin(r300, R300_CLEAR_SURFACE);
     util_blitter_flush_depth_stencil(r300->blitter, dstsurf);
     r300_blitter_end(r300);
     r300->z_decomp_rd = FALSE;
 
-    tex->zmask_in_use[subdst.level] = FALSE;
+    tex->zmask_in_use[level] = FALSE;
 }
 
 /* Copy a block of pixels from one surface to another using HW. */
 static void r300_hw_copy_region(struct pipe_context* pipe,
                                 struct pipe_resource *dst,
-                                struct pipe_subresource subdst,
+                                unsigned dst_level,
                                 unsigned dstx, unsigned dsty, unsigned dstz,
                                 struct pipe_resource *src,
-                                struct pipe_subresource subsrc,
-                                unsigned srcx, unsigned srcy, unsigned srcz,
-                                unsigned width, unsigned height)
+                                unsigned src_level,
+                                const struct pipe_box *src_box)
 {
     struct r300_context* r300 = r300_context(pipe);
 
     r300_blitter_begin(r300, R300_COPY);
-    util_blitter_copy_region(r300->blitter, dst, subdst, dstx, dsty, dstz,
-                             src, subsrc, srcx, srcy, srcz, width, height,
-                             TRUE);
+
+    /* Do a copy */
+    util_blitter_copy_region(r300->blitter, dst, dst_level, dstx, dsty, dstz,
+                             src, src_level, src_box, TRUE);
     r300_blitter_end(r300);
 }
 
 /* Copy a block of pixels from one surface to another. */
 static void r300_resource_copy_region(struct pipe_context *pipe,
                                       struct pipe_resource *dst,
-                                      struct pipe_subresource subdst,
+                                      unsigned dst_level,
                                       unsigned dstx, unsigned dsty, unsigned dstz,
                                       struct pipe_resource *src,
-                                      struct pipe_subresource subsrc,
-                                      unsigned srcx, unsigned srcy, unsigned srcz,
-                                      unsigned width, unsigned height)
+                                      unsigned src_level,
+                                      const struct pipe_box *src_box)
 {
     enum pipe_format old_format = dst->format;
     enum pipe_format new_format = old_format;
@@ -384,7 +387,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
 
     is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
     if (is_depth) {
-        r300_flush_depth_stencil(pipe, src, subsrc, srcz);
+        r300_flush_depth_stencil(pipe, src, src_level, src_box->z);
     }
     if (old_format != new_format) {
         r300_texture_reinterpret_format(pipe->screen,
@@ -393,8 +396,8 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
                                         src, new_format);
     }
 
-    r300_hw_copy_region(pipe, dst, subdst, dstx, dsty, dstz,
-                        src, subsrc, srcx, srcy, srcz, width, height);
+    r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
+                        src, src_level, src_box);
 
     if (old_format != new_format) {
         r300_texture_reinterpret_format(pipe->screen,
index 48c24092114013332c04e5134ca2ec3120989b8e..583e981a4d207d7b766f8f814c92f606bbf9dd4a 100644 (file)
@@ -424,4 +424,5 @@ void r300_parse_chipset(struct r300_capabilities* caps)
     }
 
     caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
+    caps->dxtc_swizzle = caps->is_r400 || caps->is_r500;
 }
index e7ca642b4f3e4876901410018cc7e6bbdd99847f..f2035d2009243733f58548bcf1b153e3d65682c6 100644 (file)
@@ -79,6 +79,10 @@ struct r300_capabilities {
     boolean is_r500;
     /* Whether or not the second pixel pipe is accessed with the high bit */
     boolean high_second_pipe;
+    /* DXTC texture swizzling. */
+    boolean dxtc_swizzle;
+    /* Index bias (AKA index offset). */
+    boolean index_bias_supported;
 };
 
 /* Enumerations for legibility and telling which card we're running on. */
index e8c09b214af4fa8e189bc64e11792f786757515f..67b011a145cbb4aee6bcec9d8d0ae07d9be6ea25 100644 (file)
@@ -44,14 +44,14 @@ static void r300_update_num_contexts(struct r300_screen *r300screen,
         p_atomic_inc(&r300screen->num_contexts);
 
         if (r300screen->num_contexts > 1)
-            util_mempool_set_thread_safety(&r300screen->pool_buffers,
-                                           UTIL_MEMPOOL_MULTITHREADED);
+            util_slab_set_thread_safety(&r300screen->pool_buffers,
+                                        UTIL_SLAB_MULTITHREADED);
     } else {
         p_atomic_dec(&r300screen->num_contexts);
 
         if (r300screen->num_contexts <= 1)
-            util_mempool_set_thread_safety(&r300screen->pool_buffers,
-                                           UTIL_MEMPOOL_SINGLETHREADED);
+            util_slab_set_thread_safety(&r300screen->pool_buffers,
+                                        UTIL_SLAB_SINGLETHREADED);
     }
 }
 
@@ -100,23 +100,12 @@ static void r300_release_referenced_objects(struct r300_context *r300)
 static void r300_destroy_context(struct pipe_context* context)
 {
     struct r300_context* r300 = r300_context(context);
-    struct r300_atom *atom;
 
     if (r300->blitter)
         util_blitter_destroy(r300->blitter);
     if (r300->draw)
         draw_destroy(r300->draw);
 
-    /* Print stats, if enabled. */
-    if (SCREEN_DBG_ON(r300->screen, DBG_STATS)) {
-        fprintf(stderr, "r300: Stats for context %p:\n", r300);
-        fprintf(stderr, "    : Flushes: %" PRIu64 "\n", r300->flush_counter);
-        foreach(atom, &r300->atom_list) {
-            fprintf(stderr, "    : %s: %" PRIu64 " emits\n",
-                atom->name, atom->counter);
-        }
-    }
-
     if (r300->upload_vb)
         u_upload_destroy(r300->upload_vb);
     if (r300->upload_ib)
@@ -135,7 +124,7 @@ static void r300_destroy_context(struct pipe_context* context)
         r300->rws->cs_destroy(r300->cs);
 
     /* XXX: No way to tell if this was initialized or not? */
-    util_mempool_destroy(&r300->pool_transfers);
+    util_slab_destroy(&r300->pool_transfers);
 
     r300_update_num_contexts(r300->screen, -1);
 
@@ -177,10 +166,16 @@ void r300_flush_cb(void *data)
     r300->atomname.size = atomsize; \
     r300->atomname.emit = r300_emit_##atomname; \
     r300->atomname.dirty = FALSE; \
-    insert_at_tail(&r300->atom_list, &r300->atomname); \
  } while (0)
 
-static void r300_setup_atoms(struct r300_context* r300)
+#define R300_ALLOC_ATOM(atomname, statetype) \
+do { \
+    r300->atomname.state = CALLOC_STRUCT(statetype); \
+    if (r300->atomname.state == NULL) \
+        return FALSE; \
+} while (0)
+
+static boolean r300_setup_atoms(struct r300_context* r300)
 {
     boolean is_rv350 = r300->screen->caps.is_rv350;
     boolean is_r500 = r300->screen->caps.is_r500;
@@ -191,9 +186,6 @@ static void r300_setup_atoms(struct r300_context* r300)
     boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0;
 
     /* Create the actual atom list.
-     *
-     * Each atom is examined and emitted in the order it appears here, which
-     * can affect performance and conformance if not handled with care.
      *
      * Some atoms never change size, others change every emit - those have
      * the size of 0 here.
@@ -206,7 +198,6 @@ static void r300_setup_atoms(struct r300_context* r300)
      * - fb_state_pipelined (pipelined regs)
      * The motivation behind this is to be able to emit a strict
      * subset of the regs, and to have reasonable register ordering. */
-    make_empty_list(&r300->atom_list);
     /* SC, GB (unpipelined), RB3D (unpipelined), ZB (unpipelined). */
     R300_INIT_ATOM(gpu_flush, 9);
     R300_INIT_ATOM(aa_state, 4);
@@ -261,23 +252,23 @@ static void r300_setup_atoms(struct r300_context* r300)
     }
 
     /* Some non-CSO atoms need explicit space to store the state locally. */
-    r300->aa_state.state = CALLOC_STRUCT(r300_aa_state);
-    r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
-    r300->clip_state.state = CALLOC_STRUCT(r300_clip_state);
-    r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state);
-    r300->gpu_flush.state = CALLOC_STRUCT(pipe_framebuffer_state);
-    r300->hyperz_state.state = CALLOC_STRUCT(r300_hyperz_state);
-    r300->invariant_state.state = CALLOC_STRUCT(r300_invariant_state);
-    r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
-    r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
-    r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
-    r300->vap_invariant_state.state = CALLOC_STRUCT(r300_vap_invariant_state);
-    r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
-    r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
-    r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
-    r300->vs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
+    R300_ALLOC_ATOM(aa_state, r300_aa_state);
+    R300_ALLOC_ATOM(blend_color_state, r300_blend_color_state);
+    R300_ALLOC_ATOM(clip_state, r300_clip_state);
+    R300_ALLOC_ATOM(hyperz_state, r300_hyperz_state);
+    R300_ALLOC_ATOM(invariant_state, r300_invariant_state);
+    R300_ALLOC_ATOM(textures_state, r300_textures_state);
+    R300_ALLOC_ATOM(vap_invariant_state, r300_vap_invariant_state);
+    R300_ALLOC_ATOM(viewport_state, r300_viewport_state);
+    R300_ALLOC_ATOM(ztop_state, r300_ztop_state);
+    R300_ALLOC_ATOM(fb_state, pipe_framebuffer_state);
+    R300_ALLOC_ATOM(gpu_flush, pipe_framebuffer_state);
+    R300_ALLOC_ATOM(scissor_state, pipe_scissor_state);
+    R300_ALLOC_ATOM(rs_block_state, r300_rs_block);
+    R300_ALLOC_ATOM(fs_constants, r300_constant_buffer);
+    R300_ALLOC_ATOM(vs_constants, r300_constant_buffer);
     if (!r300->screen->caps.has_tcl) {
-        r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
+        R300_ALLOC_ATOM(vertex_stream_state, r300_vertex_stream_state);
     }
 
     /* Some non-CSO atoms don't use the state pointer. */
@@ -289,11 +280,13 @@ static void r300_setup_atoms(struct r300_context* r300)
 
     /* Some states must be marked as dirty here to properly set up
      * hardware in the first command stream. */
-    r300->invariant_state.dirty = TRUE;
-    r300->pvs_flush.dirty = TRUE;
-    r300->vap_invariant_state.dirty = TRUE;
-    r300->texture_cache_inval.dirty = TRUE;
-    r300->textures_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->invariant_state);
+    r300_mark_atom_dirty(r300, &r300->pvs_flush);
+    r300_mark_atom_dirty(r300, &r300->vap_invariant_state);
+    r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
+    r300_mark_atom_dirty(r300, &r300->textures_state);
+
+    return TRUE;
 }
 
 /* Not every state tracker calls every driver function before the first draw
@@ -319,7 +312,7 @@ static void r300_init_states(struct pipe_context *pipe)
     pipe->set_scissor_state(pipe, &ss);
 
     /* Initialize the clip state. */
-    if (r300_context(pipe)->screen->caps.has_tcl) {
+    if (r300->screen->caps.has_tcl) {
         pipe->set_clip_state(pipe, &cs);
     } else {
         BEGIN_CB(clip->cb, 2);
@@ -421,9 +414,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     make_empty_list(&r300->query_list);
 
-    util_mempool_create(&r300->pool_transfers,
-                        sizeof(struct pipe_transfer), 64,
-                        UTIL_MEMPOOL_SINGLETHREADED);
+    util_slab_create(&r300->pool_transfers,
+                     sizeof(struct pipe_transfer), 64,
+                     UTIL_SLAB_SINGLETHREADED);
 
     r300->cs = rws->cs_create(rws);
     if (r300->cs == NULL)
@@ -432,6 +425,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     if (!r300screen->caps.has_tcl) {
         /* Create a Draw. This is used for SW TCL. */
         r300->draw = draw_create(&r300->context);
+        if (r300->draw == NULL)
+            goto fail;
         /* Enable our renderer. */
         draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
         /* Disable converting points/lines to triangles. */
@@ -439,7 +434,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
         draw_wide_point_threshold(r300->draw, 10000000.f);
     }
 
-    r300_setup_atoms(r300);
+    if (!r300_setup_atoms(r300))
+        goto fail;
 
     r300_init_blit_functions(r300);
     r300_init_flush_functions(r300);
index 7217c51b9516cf05307a6c99d391de3a69718e38..39dcde0610690ab6ecfc5ff5813956c76272e35a 100644 (file)
@@ -43,12 +43,8 @@ struct r300_vertex_shader;
 struct r300_stencilref_context;
 
 struct r300_atom {
-    /* List pointers. */
-    struct r300_atom *prev, *next;
     /* Name, for debugging. */
     const char* name;
-    /* Stat counter. */
-    uint64_t counter;
     /* Opaque state. */
     void* state;
     /* Emit the state to the context. */
@@ -258,6 +254,8 @@ struct r300_constant_buffer {
     uint32_t *ptr;
     /* Remapping table. */
     unsigned *remap_table;
+    /* const buffer base */
+    uint32_t buffer_base;
 };
 
 /* Query object.
@@ -282,6 +280,7 @@ struct r300_query {
 
     /* The buffer where query results are stored. */
     struct r300_winsys_buffer *buffer;
+    struct r300_winsys_cs_buffer *cs_buffer;
     /* The size of the buffer. */
     unsigned buffer_size;
     /* The domain of the buffer. */
@@ -313,6 +312,7 @@ struct r300_surface {
 
     /* Winsys buffer backing the texture. */
     struct r300_winsys_buffer *buffer;
+    struct r300_winsys_cs_buffer *cs_buffer;
 
     enum r300_buffer_domain domain;
 
@@ -396,6 +396,7 @@ struct r300_texture {
 
     /* Pipe buffer backing this texture. */
     struct r300_winsys_buffer *buffer;
+    struct r300_winsys_cs_buffer *cs_buffer;
 
     /* Registers carrying texture format data. */
     /* Only format-independent bits should be filled in. */
@@ -492,65 +493,68 @@ struct r300_context {
     struct r300_query query_list;
 
     /* Various CSO state objects. */
-    /* Beginning of atom list. */
-    struct r300_atom atom_list;
+
+    /* Each atom is emitted in the order it appears here, which can affect
+     * performance and stability if not handled with care. */
+    /* GPU flush. */
+    struct r300_atom gpu_flush;
     /* Anti-aliasing (MSAA) state. */
     struct r300_atom aa_state;
+    /* Framebuffer state. */
+    struct r300_atom fb_state;
+    /* HyperZ state (various SC/ZB bits). */
+    struct r300_atom hyperz_state;
+    /* ZTOP state. */
+    struct r300_atom ztop_state;
+    /* Depth, stencil, and alpha state. */
+    struct r300_atom dsa_state;
     /* Blend state. */
     struct r300_atom blend_state;
     /* Blend color state. */
     struct r300_atom blend_color_state;
+    /* Scissor state. */
+    struct r300_atom scissor_state;
+    /* Invariant state. This must be emitted to get the engine started. */
+    struct r300_atom invariant_state;
+    /* Viewport state. */
+    struct r300_atom viewport_state;
+    /* PVS flush. */
+    struct r300_atom pvs_flush;
+    /* VAP invariant state. */
+    struct r300_atom vap_invariant_state;
+    /* Vertex stream formatting state. */
+    struct r300_atom vertex_stream_state;
+    /* Vertex shader. */
+    struct r300_atom vs_state;
     /* User clip planes. */
     struct r300_atom clip_state;
-    /* Depth, stencil, and alpha state. */
-    struct r300_atom dsa_state;
+    /* RS block state + VAP (vertex shader) output mapping state. */
+    struct r300_atom rs_block_state;
+    /* Rasterizer state. */
+    struct r300_atom rs_state;
+    /* Framebuffer state (pipelined regs). */
+    struct r300_atom fb_state_pipelined;
     /* Fragment shader. */
     struct r300_atom fs;
     /* Fragment shader RC_CONSTANT_STATE variables. */
     struct r300_atom fs_rc_constant_state;
     /* Fragment shader constant buffer. */
     struct r300_atom fs_constants;
-    /* Framebuffer state. */
-    struct r300_atom fb_state;
-    /* Framebuffer state (pipelined regs). */
-    struct r300_atom fb_state_pipelined;
-    /* HyperZ state (various SC/ZB bits). */
-    struct r300_atom hyperz_state;
-    /* Occlusion query. */
-    struct r300_atom query_start;
-    /* Rasterizer state. */
-    struct r300_atom rs_state;
-    /* RS block state + VAP (vertex shader) output mapping state. */
-    struct r300_atom rs_block_state;
-    /* Scissor state. */
-    struct r300_atom scissor_state;
-    /* Textures state. */
-    struct r300_atom textures_state;
-    /* Vertex stream formatting state. */
-    struct r300_atom vertex_stream_state;
-    /* Vertex shader. */
-    struct r300_atom vs_state;
     /* Vertex shader constant buffer. */
     struct r300_atom vs_constants;
-    /* Viewport state. */
-    struct r300_atom viewport_state;
-    /* ZTOP state. */
-    struct r300_atom ztop_state;
-    /* PVS flush. */
-    struct r300_atom pvs_flush;
-    /* VAP invariant state. */
-    struct r300_atom vap_invariant_state;
     /* Texture cache invalidate. */
     struct r300_atom texture_cache_inval;
-    /* GPU flush. */
-    struct r300_atom gpu_flush;
+    /* Textures state. */
+    struct r300_atom textures_state;
     /* HiZ clear */
     struct r300_atom hiz_clear;
     /* zmask clear */
     struct r300_atom zmask_clear;
+    /* Occlusion query. */
+    struct r300_atom query_start;
 
-    /* Invariant state. This must be emitted to get the engine started. */
-    struct r300_atom invariant_state;
+    /* The pointers to the first and the last atom. */
+    struct r300_atom *first_dirty, *last_dirty;
 
     /* Vertex buffers for Gallium. */
     struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
@@ -599,12 +603,29 @@ struct r300_context {
     struct u_upload_mgr *upload_vb;
     struct u_upload_mgr *upload_ib;
 
-    struct util_mempool pool_transfers;
+    struct util_slab_mempool pool_transfers;
 
     /* Stat counter. */
     uint64_t flush_counter;
+
+    /* const tracking for VS */
+    int vs_const_base;
+
+    /* AOS (PACKET3_3D_LOAD_VBPNTR) command buffer for the case offset=0. */
+    uint32_t aos_cb[(16 * 3 + 1) / 2];
+    boolean aos_dirty;
+
+    /* Whether any buffer (FB, textures, VBOs) has been set, but buffers
+     * haven't been validated yet. */
+    boolean validate_buffers;
 };
 
+#define foreach_atom(r300, atom) \
+    for (atom = &r300->gpu_flush; atom != (&r300->query_start)+1; atom++)
+
+#define foreach_dirty_atom(r300, atom) \
+    for (atom = r300->first_dirty; atom != r300->last_dirty; atom++)
+
 /* Convenience cast wrappers. */
 static INLINE struct r300_query* r300_query(struct pipe_query* q)
 {
@@ -649,8 +670,8 @@ void r300_init_resource_functions(struct r300_context* r300);
 /* r300_blit.c */
 void r300_flush_depth_stencil(struct pipe_context *pipe,
                               struct pipe_resource *dst,
-                              struct pipe_subresource subdst,
-                              unsigned zslice);
+                              unsigned level,
+                              unsigned layer);
 
 /* r300_query.c */
 void r300_resume_query(struct r300_context *r300,
@@ -670,7 +691,6 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300);
 
 /* r300_render.c */
 void r300_draw_flush_vbuf(struct r300_context *r300);
-boolean r500_index_bias_supported(struct r300_context *r300);
 void r500_emit_index_bias(struct r300_context *r300, int index_bias);
 
 /* r300_state.c */
@@ -684,6 +704,22 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
                               enum r300_fb_state_change change);
 void r300_mark_fs_code_dirty(struct r300_context *r300);
 
+static INLINE void r300_mark_atom_dirty(struct r300_context *r300,
+                                        struct r300_atom *atom)
+{
+    atom->dirty = TRUE;
+
+    if (!r300->first_dirty) {
+        r300->first_dirty = atom;
+        r300->last_dirty = atom+1;
+    } else {
+        if (atom < r300->first_dirty)
+            r300->first_dirty = atom;
+        if (atom+1 > r300->last_dirty)
+            r300->last_dirty = atom+1;
+    }
+}
+
 /* r300_debug.c */
 void r500_dump_rs_block(struct r300_rs_block *rs);
 
index c194d6a1b08c3ebff2c61b5e8d78efe58f2f7c8d..67fb0096a8c23427b331acc337c6bd22470884a3 100644 (file)
@@ -51,7 +51,7 @@
     int cs_count = 0; (void) cs_count; (void) cs_winsys;
 
 #define BEGIN_CS(size) do { \
-    assert(size <= (cs_copy->ndw - cs_copy->cdw)); \
+    assert(size <= (R300_MAX_CMDBUF_DWORDS - cs_copy->cdw)); \
     CS_DEBUG(cs_count = size;) \
 } while (0)
 
@@ -72,7 +72,7 @@
  */
 
 #define OUT_CS(value) do { \
-    cs_copy->ptr[cs_copy->cdw++] = (value); \
+    cs_copy->buf[cs_copy->cdw++] = (value); \
     CS_DEBUG(cs_count--;) \
 } while (0)
 
@@ -96,7 +96,7 @@
     OUT_CS(CP_PACKET3(op, count))
 
 #define OUT_CS_TABLE(values, count) do { \
-    memcpy(cs_copy->ptr + cs_copy->cdw, values, count * 4); \
+    memcpy(cs_copy->buf + cs_copy->cdw, values, count * 4); \
     cs_copy->cdw += count; \
     CS_DEBUG(cs_count -= count;) \
 } while (0)
 
 #define OUT_CS_BUF_RELOC(bo, offset, rd, wd) do { \
     assert(bo); \
-    OUT_CS_RELOC(r300_buffer(bo)->buf, offset, rd, wd); \
+    OUT_CS_RELOC(r300_buffer(bo)->cs_buf, offset, rd, wd); \
 } while (0)
 
 #define OUT_CS_TEX_RELOC(tex, offset, rd, wd) do { \
     assert(tex); \
-    OUT_CS_RELOC(tex->buffer, offset, rd, wd); \
+    OUT_CS_RELOC(tex->cs_buffer, offset, rd, wd); \
 } while (0)
 
 #define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd) do { \
     assert(bo); \
-    cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->buf, rd, wd); \
+    cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->cs_buf, rd, wd); \
     CS_DEBUG(cs_count -= 2;) \
 } while (0)
 
 
 #define WRITE_CS_TABLE(values, count) do { \
     CS_DEBUG(assert(cs_count == 0);) \
-    memcpy(cs_copy->ptr + cs_copy->cdw, (values), (count) * 4); \
+    memcpy(cs_copy->buf + cs_copy->cdw, (values), (count) * 4); \
     cs_copy->cdw += (count); \
 } while (0)
 
index f78fe34790c47847fd69bdca08c621fb3beb7bb1..52031dd97b5c239da488cfa1a6d414740f5cd5b0 100644 (file)
@@ -40,7 +40,6 @@ static const struct debug_named_value debug_options[] = {
     { "rs", DBG_RS, "Log rasterizer" },
     { "fb", DBG_FB, "Log framebuffer" },
     { "cbzb", DBG_CBZB, "Log fast color clear info" },
-    { "stats", DBG_STATS, "Log emission statistics" },
     { "hyperz", DBG_HYPERZ, "Log HyperZ info" },
     { "scissor", DBG_SCISSOR, "Log scissor info" },
     { "fakeocc", DBG_FAKE_OCC, "Use fake occlusion queries" },
index 896aeef395d7544c0b443d531958fe24e5aa7aa6..2d111f9158d0db9dec79eaf928ea22c10a1274cd 100644 (file)
@@ -43,8 +43,8 @@ enum r300_buffer_tiling {
 };
 
 enum r300_buffer_domain { /* bitfield */
-    R300_DOMAIN_GTT  = 1,
-    R300_DOMAIN_VRAM = 2
+    R300_DOMAIN_GTT  = 2,
+    R300_DOMAIN_VRAM = 4
 };
 
 #endif
index c187f115da43a7c756480366a076e2cdef783f9c..04a5bd92d12581f26f2a20fe512d97683d21776f 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_simple_list.h"
 
 #include "r300_context.h"
+#include "r300_cb.h"
 #include "r300_cs.h"
 #include "r300_emit.h"
 #include "r300_fs.h"
@@ -83,16 +84,20 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
     }
 }
 
-static const float * get_rc_constant_state(
+static void get_rc_constant_state(
+    float vec[4],
     struct r300_context * r300,
     struct rc_constant * constant)
 {
     struct r300_textures_state* texstate = r300->textures_state.state;
-    static float vec[4] = { 0.0, 0.0, 0.0, 1.0 };
     struct r300_texture *tex;
 
     assert(constant->Type == RC_CONSTANT_STATE);
 
+    /* vec should either be (0, 0, 0, 1), which should be a relatively safe
+     * RGBA or STRQ value, or it could be one of the RC_CONSTANT_STATE
+     * state factors. */
+
     switch (constant->u.State[0]) {
         /* Factor for converting rectangle coords to
          * normalized coords. Should only show up on non-r500. */
@@ -100,6 +105,8 @@ static const float * get_rc_constant_state(
             tex = r300_texture(texstate->sampler_views[constant->u.State[1]]->base.texture);
             vec[0] = 1.0 / tex->desc.width0;
             vec[1] = 1.0 / tex->desc.height0;
+            vec[2] = 0;
+            vec[3] = 1;
             break;
 
         case RC_STATE_R300_TEXSCALE_FACTOR:
@@ -108,29 +115,31 @@ static const float * get_rc_constant_state(
             vec[0] = tex->desc.b.b.width0  / (tex->desc.width0  + 0.001f);
             vec[1] = tex->desc.b.b.height0 / (tex->desc.height0 + 0.001f);
             vec[2] = tex->desc.b.b.depth0  / (tex->desc.depth0  + 0.001f);
+            vec[3] = 1;
             break;
 
         case RC_STATE_R300_VIEWPORT_SCALE:
             vec[0] = r300->viewport.scale[0];
             vec[1] = r300->viewport.scale[1];
             vec[2] = r300->viewport.scale[2];
+            vec[3] = 1;
             break;
 
         case RC_STATE_R300_VIEWPORT_OFFSET:
             vec[0] = r300->viewport.translate[0];
             vec[1] = r300->viewport.translate[1];
             vec[2] = r300->viewport.translate[2];
+            vec[3] = 1;
             break;
 
         default:
             fprintf(stderr, "r300: Implementation error: "
                 "Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
+            vec[0] = 0;
+            vec[1] = 0;
+            vec[2] = 0;
+            vec[3] = 1;
     }
-
-    /* This should either be (0, 0, 0, 1), which should be a relatively safe
-     * RGBA or STRQ value, or it could be one of the RC_CONSTANT_STATE
-     * state factors. */
-    return vec;
 }
 
 /* Convert a normal single-precision float into the 7.16 format
@@ -220,8 +229,9 @@ void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
     BEGIN_CS(size);
     for(i = first; i < end; ++i) {
         if (constants->Constants[i].Type == RC_CONSTANT_STATE) {
-            const float *data =
-                    get_rc_constant_state(r300, &constants->Constants[i]);
+            float data[4];
+
+            get_rc_constant_state(data, r300, &constants->Constants[i]);
 
             OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4);
             for (j = 0; j < 4; j++)
@@ -279,8 +289,9 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
     BEGIN_CS(size);
     for(i = first; i < end; ++i) {
         if (constants->Constants[i].Type == RC_CONSTANT_STATE) {
-            const float *data =
-                    get_rc_constant_state(r300, &constants->Constants[i]);
+            float data[4];
+
+            get_rc_constant_state(data, r300, &constants->Constants[i]);
 
             OUT_CS_REG(R500_GA_US_VECTOR_INDEX,
                        R500_GA_US_VECTOR_INDEX_TYPE_CONST |
@@ -343,10 +354,10 @@ void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state)
 
     if (aa->dest) {
         OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 1);
-        OUT_CS_RELOC(aa->dest->buffer, aa->dest->offset, 0, aa->dest->domain);
+        OUT_CS_RELOC(aa->dest->cs_buffer, aa->dest->offset, 0, aa->dest->domain);
 
         OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_PITCH, 1);
-        OUT_CS_RELOC(aa->dest->buffer, aa->dest->pitch, 0, aa->dest->domain);
+        OUT_CS_RELOC(aa->dest->cs_buffer, aa->dest->pitch, 0, aa->dest->domain);
     }
 
     OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, aa->aaresolve_ctl);
@@ -377,10 +388,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         surf = r300_surface(fb->cbufs[i]);
 
         OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
-        OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain);
+        OUT_CS_RELOC(surf->cs_buffer, surf->offset, 0, surf->domain);
 
         OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
-        OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
+        OUT_CS_RELOC(surf->cs_buffer, surf->pitch, 0, surf->domain);
     }
 
     /* Set up the ZB part of the CBZB clear. */
@@ -390,10 +401,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         OUT_CS_REG(R300_ZB_FORMAT, surf->cbzb_format);
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
-        OUT_CS_RELOC(surf->buffer, surf->cbzb_midpoint_offset, 0, surf->domain);
+        OUT_CS_RELOC(surf->cs_buffer, surf->cbzb_midpoint_offset, 0, surf->domain);
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
-        OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain);
+        OUT_CS_RELOC(surf->cs_buffer, surf->cbzb_pitch, 0, surf->domain);
 
         DBG(r300, DBG_CBZB,
             "CBZB clearing cbuf %08x %08x\n", surf->cbzb_format,
@@ -406,15 +417,15 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         OUT_CS_REG(R300_ZB_FORMAT, surf->format);
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
-        OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain);
+        OUT_CS_RELOC(surf->cs_buffer, surf->offset, 0, surf->domain);
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
-        OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
+        OUT_CS_RELOC(surf->cs_buffer, surf->pitch, 0, surf->domain);
 
         if (can_hyperz) {
             uint32_t surf_pitch;
             struct r300_texture *tex;
-            int level = surf->base.level;
+            int level = surf->base.u.tex.level;
             tex = r300_texture(surf->base.texture);
 
             surf_pitch = surf->pitch & R300_DEPTHPITCH_MASK;
@@ -549,7 +560,7 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
                                            struct r300_query *query)
 {
     struct r300_capabilities* caps = &r300->screen->caps;
-    struct r300_winsys_buffer *buf = r300->query_current->buffer;
+    struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer;
     CS_LOCALS(r300);
 
     assert(caps->num_frag_pipes);
@@ -605,7 +616,7 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
 static void rv530_emit_query_end_single_z(struct r300_context *r300,
                                           struct r300_query *query)
 {
-    struct r300_winsys_buffer *buf = r300->query_current->buffer;
+    struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer;
     CS_LOCALS(r300);
 
     BEGIN_CS(8);
@@ -619,7 +630,7 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300,
 static void rv530_emit_query_end_double_z(struct r300_context *r300,
                                           struct r300_query *query)
 {
-    struct r300_winsys_buffer *buf = r300->query_current->buffer;
+    struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer;
     CS_LOCALS(r300);
 
     BEGIN_CS(14);
@@ -796,39 +807,83 @@ void r300_emit_textures_state(struct r300_context *r300,
     END_CS;
 }
 
-void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)
+static void r300_update_aos_cb(struct r300_context *r300, unsigned packet_size)
 {
     struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
     struct pipe_vertex_element *velem = r300->velems->velem;
-    struct r300_buffer *buf;
-    int i;
     unsigned *hw_format_size = r300->velems->hw_format_size;
     unsigned size1, size2, aos_count = r300->velems->count;
-    unsigned packet_size = (aos_count * 3 + 1) / 2;
-    CS_LOCALS(r300);
-
-    BEGIN_CS(2 + packet_size + aos_count * 2);
-    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
-    OUT_CS(aos_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
+    int i;
+    CB_LOCALS;
 
+    BEGIN_CB(r300->aos_cb, packet_size);
     for (i = 0; i < aos_count - 1; i += 2) {
         vb1 = &vbuf[velem[i].vertex_buffer_index];
         vb2 = &vbuf[velem[i+1].vertex_buffer_index];
         size1 = hw_format_size[i];
         size2 = hw_format_size[i+1];
 
-        OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+        OUT_CB(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
                R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
-        OUT_CS(vb1->buffer_offset + velem[i].src_offset   + offset * vb1->stride);
-        OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
+        OUT_CB(vb1->buffer_offset + velem[i].src_offset);
+        OUT_CB(vb2->buffer_offset + velem[i+1].src_offset);
     }
 
     if (aos_count & 1) {
         vb1 = &vbuf[velem[i].vertex_buffer_index];
         size1 = hw_format_size[i];
 
-        OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
-        OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+        OUT_CB(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+        OUT_CB(vb1->buffer_offset + velem[i].src_offset);
+    }
+    END_CB;
+
+    r300->aos_dirty = FALSE;
+}
+
+void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)
+{
+    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+    struct pipe_vertex_element *velem = r300->velems->velem;
+    struct r300_buffer *buf;
+    int i;
+    unsigned aos_count = r300->velems->count;
+    unsigned packet_size = (aos_count * 3 + 1) / 2;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(2 + packet_size + aos_count * 2);
+    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
+    OUT_CS(aos_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
+
+    if (!offset) {
+        if (r300->aos_dirty) {
+            r300_update_aos_cb(r300, packet_size);
+        }
+        OUT_CS_TABLE(r300->aos_cb, packet_size);
+    } else {
+        struct pipe_vertex_buffer *vb1, *vb2;
+        unsigned *hw_format_size = r300->velems->hw_format_size;
+        unsigned size1, size2;
+
+        for (i = 0; i < aos_count - 1; i += 2) {
+            vb1 = &vbuf[velem[i].vertex_buffer_index];
+            vb2 = &vbuf[velem[i+1].vertex_buffer_index];
+            size1 = hw_format_size[i];
+            size2 = hw_format_size[i+1];
+
+            OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+                   R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
+            OUT_CS(vb1->buffer_offset + velem[i].src_offset   + offset * vb1->stride);
+            OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
+        }
+
+        if (aos_count & 1) {
+            vb1 = &vbuf[velem[i].vertex_buffer_index];
+            size1 = hw_format_size[i];
+
+            OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+            OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+        }
     }
 
     for (i = 0; i < aos_count; i++) {
@@ -914,7 +969,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
     struct r300_vertex_program_code* code = &vs->code;
     struct r300_screen* r300screen = r300->screen;
     unsigned instruction_count = code->length / 4;
-    unsigned i;
 
     unsigned vtx_mem_size = r300screen->caps.is_r500 ? 128 : 72;
     unsigned input_count = MAX2(util_bitcount(code->InputsRead), 1);
@@ -925,10 +979,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
                                   vtx_mem_size / output_count, 10);
     unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 5);
 
-    unsigned imm_first = vs->externals_count;
-    unsigned imm_end = vs->code.constants.Count;
-    unsigned imm_count = vs->immediates_count;
-
     CS_LOCALS(r300);
 
     BEGIN_CS(size);
@@ -937,12 +987,10 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
      * R300_VAP_PVS_CONST_CNTL
      * R300_VAP_PVS_CODE_CNTL_1
      * See the r5xx docs for instructions on how to use these. */
-    OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
-    OUT_CS(R300_PVS_FIRST_INST(0) |
-            R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
-            R300_PVS_LAST_INST(instruction_count - 1));
-    OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1));
-    OUT_CS(instruction_count - 1);
+    OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) |
+              R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
+              R300_PVS_LAST_INST(instruction_count - 1));
+    OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, instruction_count - 1);
 
     OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
     OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length);
@@ -954,19 +1002,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
             R300_PVS_VF_MAX_VTX_NUM(12) |
             (r300screen->caps.is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0));
 
-    /* Emit immediates. */
-    if (imm_count) {
-        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
-                   (r300->screen->caps.is_r500 ?
-                   R500_PVS_CONST_START : R300_PVS_CONST_START) +
-                   imm_first);
-        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4);
-        for (i = imm_first; i < imm_end; i++) {
-            const float *data = vs->code.constants.Constants[i].u.Immediate;
-            OUT_CS_TABLE(data, 4);
-        }
-    }
-
     /* Emit flow control instructions. */
     if (code->num_fc_ops) {
 
@@ -991,24 +1026,43 @@ void r300_emit_vs_constants(struct r300_context* r300,
     unsigned count =
         ((struct r300_vertex_shader*)r300->vs_state.state)->externals_count;
     struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
+    struct r300_vertex_shader *vs = (struct r300_vertex_shader*)r300->vs_state.state;
     unsigned i;
+    int imm_first = vs->externals_count;
+    int imm_end = vs->code.constants.Count;
+    int imm_count = vs->immediates_count;
     CS_LOCALS(r300);
 
-    if (!count)
-        return;
-
     BEGIN_CS(size);
-    OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
-               (r300->screen->caps.is_r500 ?
-               R500_PVS_CONST_START : R300_PVS_CONST_START));
-    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4);
-    if (buf->remap_table){
-        for (i = 0; i < count; i++) {
-            uint32_t *data = &buf->ptr[buf->remap_table[i]*4];
+    OUT_CS_REG(R300_VAP_PVS_CONST_CNTL,
+               R300_PVS_CONST_BASE_OFFSET(buf->buffer_base) |
+               R300_PVS_MAX_CONST_ADDR(MAX2(imm_end - 1, 0)));
+    if (vs->externals_count) {
+        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+                   (r300->screen->caps.is_r500 ?
+                   R500_PVS_CONST_START : R300_PVS_CONST_START) + buf->buffer_base);
+        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4);
+        if (buf->remap_table){
+            for (i = 0; i < count; i++) {
+                uint32_t *data = &buf->ptr[buf->remap_table[i]*4];
+                OUT_CS_TABLE(data, 4);
+            }
+        } else {
+            OUT_CS_TABLE(buf->ptr, count * 4);
+        }
+    }
+
+    /* Emit immediates. */
+    if (imm_count) {
+        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+                   (r300->screen->caps.is_r500 ?
+                   R500_PVS_CONST_START : R300_PVS_CONST_START) +
+                   buf->buffer_base + imm_first);
+        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4);
+        for (i = imm_first; i < imm_end; i++) {
+            const float *data = vs->code.constants.Constants[i].u.Immediate;
             OUT_CS_TABLE(data, 4);
         }
-    } else {
-        OUT_CS_TABLE(buf->ptr, count * 4);
     }
     END_CS;
 }
@@ -1063,8 +1117,8 @@ void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
 
     tex = r300_texture(fb->zsbuf->texture);
 
-    offset = tex->hiz_mem[fb->zsbuf->level]->ofs;
-    stride = tex->desc.stride_in_pixels[fb->zsbuf->level];
+    offset = tex->hiz_mem[fb->zsbuf->u.tex.level]->ofs;
+    stride = tex->desc.stride_in_pixels[fb->zsbuf->u.tex.level];
 
     /* convert from pixels to 4x4 blocks */
     stride = ALIGN_DIVUP(stride, 4);
@@ -1086,7 +1140,7 @@ void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
     z->current_func = -1;
 
     /* Mark the current zbuffer's hiz ram as in use. */
-    tex->hiz_in_use[fb->zsbuf->level] = TRUE;
+    tex->hiz_in_use[fb->zsbuf->u.tex.level] = TRUE;
 }
 
 void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state)
@@ -1100,9 +1154,9 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
     int mult, offset_shift;
 
     tex = r300_texture(fb->zsbuf->texture);
-    stride = tex->desc.stride_in_pixels[fb->zsbuf->level];
+    stride = tex->desc.stride_in_pixels[fb->zsbuf->u.tex.level];
 
-    offset = tex->zmask_mem[fb->zsbuf->level]->ofs;
+    offset = tex->zmask_mem[fb->zsbuf->u.tex.level]->ofs;
 
     if (r300->z_compression == RV350_Z_COMPRESS_88)
         mult = 8;
@@ -1128,7 +1182,7 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
     }
 
     /* Mark the current zbuffer's zmask as in use. */
-    tex->zmask_in_use[fb->zsbuf->level] = TRUE;
+    tex->zmask_in_use[fb->zsbuf->u.tex.level] = TRUE;
 }
 
 void r300_emit_ztop_state(struct r300_context* r300,
@@ -1165,12 +1219,6 @@ boolean r300_emit_buffer_validate(struct r300_context *r300,
     struct pipe_resource *pbuf;
     unsigned i;
 
-    /* upload buffers first */
-    if (r300->screen->caps.has_tcl && r300->any_user_vbs) {
-        r300_upload_user_buffers(r300);
-        r300->any_user_vbs = false;
-    }
-
     /* Clean out BOs. */
     r300->rws->cs_reset_buffers(r300->cs);
 
@@ -1178,14 +1226,14 @@ boolean r300_emit_buffer_validate(struct r300_context *r300,
     for (i = 0; i < fb->nr_cbufs; i++) {
         tex = r300_texture(fb->cbufs[i]->texture);
         assert(tex && tex->buffer && "cbuf is marked, but NULL!");
-        r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0,
+        r300->rws->cs_add_buffer(r300->cs, tex->cs_buffer, 0,
                                  r300_surface(fb->cbufs[i])->domain);
     }
     /* ...depth buffer... */
     if (fb->zsbuf) {
         tex = r300_texture(fb->zsbuf->texture);
         assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
-        r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0,
+        r300->rws->cs_add_buffer(r300->cs, tex->cs_buffer, 0,
                                  r300_surface(fb->zsbuf)->domain);
     }
     /* ...textures... */
@@ -1195,28 +1243,30 @@ boolean r300_emit_buffer_validate(struct r300_context *r300,
         }
 
         tex = r300_texture(texstate->sampler_views[i]->base.texture);
-        r300->rws->cs_add_buffer(r300->cs, tex->buffer, tex->domain, 0);
+        r300->rws->cs_add_buffer(r300->cs, tex->cs_buffer, tex->domain, 0);
     }
     /* ...occlusion query buffer... */
     if (r300->query_current)
-        r300->rws->cs_add_buffer(r300->cs, r300->query_current->buffer,
+        r300->rws->cs_add_buffer(r300->cs, r300->query_current->cs_buffer,
                                  0, r300->query_current->domain);
     /* ...vertex buffer for SWTCL path... */
     if (r300->vbo)
-        r300->rws->cs_add_buffer(r300->cs, r300_buffer(r300->vbo)->buf,
+        r300->rws->cs_add_buffer(r300->cs, r300_buffer(r300->vbo)->cs_buf,
                                  r300_buffer(r300->vbo)->domain, 0);
     /* ...vertex buffers for HWTCL path... */
     if (do_validate_vertex_buffers) {
         for (i = 0; i < r300->velems->count; i++) {
             pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
+            if (!pbuf)
+                continue;
 
-            r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->buf,
+            r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->cs_buf,
                                      r300_buffer(pbuf)->domain, 0);
         }
     }
     /* ...and index buffer for HWTCL path. */
     if (index_buffer)
-        r300->rws->cs_add_buffer(r300->cs, r300_buffer(index_buffer)->buf,
+        r300->rws->cs_add_buffer(r300->cs, r300_buffer(index_buffer)->cs_buf,
                                  r300_buffer(index_buffer)->domain, 0);
 
     if (!r300->rws->cs_validate(r300->cs)) {
@@ -1231,7 +1281,7 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300)
     struct r300_atom* atom;
     unsigned dwords = 0;
 
-    foreach(atom, &r300->atom_list) {
+    foreach_dirty_atom(r300, atom) {
         if (atom->dirty) {
             dwords += atom->size;
         }
@@ -1250,7 +1300,7 @@ unsigned r300_get_num_cs_end_dwords(struct r300_context *r300)
     /* Emitted in flush. */
     dwords += 26; /* emit_query_end */
     dwords += r300->hyperz_state.size + 2; /* emit_hyperz_end + zcache flush */
-    if (r500_index_bias_supported(r300))
+    if (r300->screen->caps.index_bias_supported)
         dwords += 2;
 
     return dwords;
@@ -1259,17 +1309,16 @@ unsigned r300_get_num_cs_end_dwords(struct r300_context *r300)
 /* Emit all dirty state. */
 void r300_emit_dirty_state(struct r300_context* r300)
 {
-    struct r300_atomatom;
+    struct r300_atom *atom;
 
-    foreach(atom, &r300->atom_list) {
+    foreach_dirty_atom(r300, atom) {
         if (atom->dirty) {
             atom->emit(r300, atom->size, atom->state);
-            if (SCREEN_DBG_ON(r300->screen, DBG_STATS)) {
-                atom->counter++;
-            }
             atom->dirty = FALSE;
         }
     }
 
+    r300->first_dirty = NULL;
+    r300->last_dirty = NULL;
     r300->dirty_hw++;
 }
index 1afd27f0938210fb9fdf71cd634d1b07e0ee4c94..451fe525b400b663286670cf591d378c26efc37d 100644 (file)
@@ -49,7 +49,7 @@ static void r300_flush(struct pipe_context* pipe,
     if (r300->dirty_hw) {
         r300_emit_hyperz_end(r300);
         r300_emit_query_end(r300);
-        if (r500_index_bias_supported(r300))
+        if (r300->screen->caps.index_bias_supported)
             r500_emit_index_bias(r300, 0);
 
         r300->flush_counter++;
@@ -57,9 +57,9 @@ static void r300_flush(struct pipe_context* pipe,
         r300->dirty_hw = 0;
 
         /* New kitchen sink, baby. */
-        foreach(atom, &r300->atom_list) {
+        foreach_atom(r300, atom) {
             if (atom->state || atom->allow_null_state) {
-                atom->dirty = TRUE;
+                r300_mark_atom_dirty(r300, atom);
             }
         }
 
@@ -68,6 +68,8 @@ static void r300_flush(struct pipe_context* pipe,
             r300->vs_state.dirty = FALSE;
             r300->vs_constants.dirty = FALSE;
         }
+
+        r300->validate_buffers = TRUE;
     }
 
     /* reset flushed query */
index c91532eb7b30bfff3c18b778a328c5463895efc0..2936c3486e2e0183c743b0edd4808ca3730d7fd5 100644 (file)
@@ -390,7 +390,6 @@ static void r300_translate_fragment_shader(
     compiler.Base.max_temp_regs = compiler.Base.is_r500 ? 128 : 32;
     compiler.Base.max_constants = compiler.Base.is_r500 ? 256 : 32;
     compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 512 : 64;
-    compiler.Base.remove_unused_constants = TRUE;
     compiler.AllocateHwInputs = &allocate_hardware_inputs;
     compiler.UserData = &shader->inputs;
 
@@ -408,6 +407,11 @@ static void r300_translate_fragment_shader(
 
     r300_tgsi_to_rc(&ttr, tokens);
 
+    if (!r300->screen->caps.is_r500 ||
+        compiler.Base.Program.Constants.Count > 200) {
+        compiler.Base.remove_unused_constants = TRUE;
+    }
+
     /**
      * Transform the program to support WPOS.
      *
index 79f7f8abe9bd7fb48192308c5703786f82cf8c92..c22e307c679a11c251d9131902d5379faff7c6e3 100644 (file)
@@ -158,8 +158,8 @@ static void r300_update_hyperz(struct r300_context* r300)
     if (!r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
         return;
 
-    zmask_in_use = zstex->zmask_in_use[fb->zsbuf->level];
-    hiz_in_use = zstex->hiz_in_use[fb->zsbuf->level];
+    zmask_in_use = zstex->zmask_in_use[fb->zsbuf->u.tex.level];
+    hiz_in_use = zstex->hiz_in_use[fb->zsbuf->u.tex.level];
 
     /* Z fastfill. */
     if (zmask_in_use) {
@@ -282,7 +282,7 @@ static void r300_update_ztop(struct r300_context* r300)
         ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
     }
     if (ztop_state->z_buffer_top != old_ztop)
-        r300->ztop_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->ztop_state);
 }
 
 #define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
@@ -333,7 +333,7 @@ void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf)
 {
     struct r300_texture *tex;
     uint32_t zsize, ndw;
-    int level = surf->base.level;
+    int level = surf->base.u.tex.level;
 
     tex = r300_texture(surf->base.texture);
 
@@ -352,7 +352,7 @@ void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf
 {
     int bsize = 256;
     uint32_t zsize, ndw;
-    int level = surf->base.level;
+    int level = surf->base.u.tex.level;
     struct r300_texture *tex;
 
     tex = r300_texture(surf->base.texture);
index 5f34fcb274485bd5307d46f2ee83f5fa87eb695b..6223e043210b92c94abee375f4b5c6974de582c9 100644 (file)
@@ -60,6 +60,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
     q->buffer = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096,
                                          PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM,
                                          q->domain);
+    q->cs_buffer = r300->rws->buffer_get_cs_handle(r300->rws, q->buffer);
 
     return (struct pipe_query*)q;
 }
@@ -79,7 +80,7 @@ void r300_resume_query(struct r300_context *r300,
                        struct r300_query *query)
 {
     r300->query_current = query;
-    r300->query_start.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->query_start);
 }
 
 static void r300_begin_query(struct pipe_context* pipe,
index 6bea783f69703f55f9e73dc8721a8e850a363388..613186e8156979786bc33e3357f4b849035b9197 100644 (file)
@@ -427,7 +427,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #       define R300_PVS_CONST_START          512
 #       define R500_PVS_CONST_START          1024
 #       define R300_MAX_PVS_CONST_VECS       256
-#       define R500_MAX_PVS_CONST_VECS       1024
+#       define R500_MAX_PVS_CONST_VECS       256
 #       define R300_PVS_UCP_START            1024
 #       define R500_PVS_UCP_START            1536
 #       define R300_POINT_VPORT_SCALE_OFFSET 1030
@@ -553,6 +553,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 /* Addresses are relative to the vertex program parameters area. */
 #define R300_VAP_PVS_CONST_CNTL             0x22D4
 #       define R300_PVS_CONST_BASE_OFFSET_SHIFT  0
+#       define R300_PVS_CONST_BASE_OFFSET(x)     (x)
 #       define R300_PVS_MAX_CONST_ADDR_SHIFT     16
 #       define R300_PVS_MAX_CONST_ADDR(x)        ((x) << 16)
 #define R300_VAP_PVS_CODE_CNTL_1           0x22D8
@@ -1520,11 +1521,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #      define R300_TX_TRI_PERF_3_8            (3<<15)
 #      define R300_ANISO_THRESHOLD_MASK       (7<<17)
 
+#       define R400_DXTC_SWIZZLE_ENABLE        (1<<21)
 #      define R500_MACRO_SWITCH               (1<<22)
 #       define R500_TX_MAX_ANISO(x)            ((x) << 23)
 #       define R500_TX_MAX_ANISO_MASK          (63 << 23)
 #       define R500_TX_ANISO_HIGH_QUALITY      (1 << 30)
-
 #      define R500_BORDER_FIX                 (1<<31)
 
 #define R300_TX_FORMAT0_0                   0x4480
index 60700cf30372888d7f726f85854860395194df98..b4197e03520f30b5146f6321b94602e672555e12 100644 (file)
@@ -118,12 +118,6 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
     return color_control;
 }
 
-boolean r500_index_bias_supported(struct r300_context *r300)
-{
-    return r300->screen->caps.is_r500 &&
-           r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
-}
-
 void r500_emit_index_bias(struct r300_context *r300, int index_bias)
 {
     CS_LOCALS(r300);
@@ -193,13 +187,12 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
     boolean first_draw     = flags & PREP_FIRST_DRAW;
     boolean emit_aos       = flags & PREP_EMIT_AOS;
     boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL;
-    boolean hw_index_bias  = r500_index_bias_supported(r300);
 
     /* Add dirty state, index offset, and AOS. */
     if (first_draw) {
         cs_dwords += r300_get_num_dirty_dwords(r300);
 
-        if (hw_index_bias)
+        if (r300->screen->caps.index_bias_supported)
             cs_dwords += 2; /* emit_index_offset */
 
         if (emit_aos)
@@ -212,7 +205,7 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
     cs_dwords += r300_get_num_cs_end_dwords(r300);
 
     /* Reserve requested CS space. */
-    if (cs_dwords > (r300->cs->ndw - r300->cs->cdw)) {
+    if (cs_dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) {
         r300->context.flush(&r300->context, 0, NULL);
         flushed = TRUE;
     }
@@ -239,19 +232,32 @@ static boolean r300_emit_states(struct r300_context *r300,
     boolean emit_aos       = flags & PREP_EMIT_AOS;
     boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL;
     boolean indexed        = flags & PREP_INDEXED;
-    boolean hw_index_bias  = r500_index_bias_supported(r300);
+    boolean validate_vbos  = flags & PREP_VALIDATE_VBOS;
 
     /* Validate buffers and emit dirty state if needed. */
     if (first_draw) {
-        if (!r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS,
-                                       index_buffer)) {
-            fprintf(stderr, "r300: CS space validation failed. "
-                    "(not enough memory?) Skipping rendering.\n");
-            return FALSE;
+        /* upload buffers first */
+        if (r300->screen->caps.has_tcl && r300->any_user_vbs) {
+            r300_upload_user_buffers(r300);
+            r300->any_user_vbs = false;
+        }
+
+        if (r300->validate_buffers) {
+            if (!r300_emit_buffer_validate(r300, validate_vbos,
+                                           index_buffer)) {
+                fprintf(stderr, "r300: CS space validation failed. "
+                        "(not enough memory?) Skipping rendering.\n");
+                return FALSE;
+            }
+
+            /* Consider the validation done only if everything was validated. */
+            if (validate_vbos) {
+                r300->validate_buffers = FALSE;
+            }
         }
 
         r300_emit_dirty_state(r300);
-        if (hw_index_bias) {
+        if (r300->screen->caps.index_bias_supported) {
             if (r300->screen->caps.has_tcl)
                 r500_emit_index_bias(r300, index_bias);
             else
@@ -537,7 +543,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
     int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
     unsigned new_offset;
 
-    if (indexBias && !r500_index_bias_supported(r300)) {
+    if (indexBias && !r300->screen->caps.index_bias_supported) {
         r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset);
     }
 
@@ -810,6 +816,7 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
                                       R300_MAX_DRAW_VBO_SIZE);
         r300->draw_vbo_offset = 0;
         r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE;
+        r300->validate_buffers = TRUE;
     }
 
     r300render->vertex_size = vertex_size;
@@ -967,7 +974,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
     end_cs_dwords = r300_get_num_cs_end_dwords(r300);
 
     while (count) {
-        free_dwords = r300->cs->ndw - r300->cs->cdw;
+        free_dwords = R300_MAX_CMDBUF_DWORDS - r300->cs->cdw;
 
         short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2);
 
@@ -1088,6 +1095,8 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
     const float zeros[4] = {0, 0, 0, 0};
     CS_LOCALS(r300);
 
+    r300->context.set_vertex_buffers(&r300->context, 0, NULL);
+
     if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
         r300->sprite_coord_enable = 1;
 
@@ -1144,37 +1153,45 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
 
 done:
     /* Restore the state. */
-    r300->clip_state.dirty = TRUE;
-    r300->rs_state.dirty = TRUE;
-    r300->viewport_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->clip_state);
+    r300_mark_atom_dirty(r300, &r300->rs_state);
+    r300_mark_atom_dirty(r300, &r300->viewport_state);
 
     r300->sprite_coord_enable = last_sprite_coord_enable;
 }
 
 static void r300_resource_resolve(struct pipe_context* pipe,
                                   struct pipe_resource* dest,
-                                  struct pipe_subresource subdest,
+                                  unsigned dst_layer,
                                   struct pipe_resource* src,
-                                  struct pipe_subresource subsrc)
+                                  unsigned src_layer)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct pipe_surface* srcsurf, surf_tmpl;
     struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
-    struct pipe_surface* srcsurf = src->screen->get_tex_surface(src->screen,
-            src, subsrc.face, subsrc.level, 0, 0);
     float color[] = {0, 0, 0, 0};
 
+    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+    surf_tmpl.format = src->format;
+    surf_tmpl.usage = 0; /* not really a surface hence no bind flags */
+    surf_tmpl.u.tex.level = 0; /* msaa resources cannot have mipmaps */
+    surf_tmpl.u.tex.first_layer = src_layer;
+    surf_tmpl.u.tex.last_layer = src_layer;
+    srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
+    surf_tmpl.format = dest->format;
+    surf_tmpl.u.tex.first_layer = dst_layer;
+    surf_tmpl.u.tex.last_layer = dst_layer;
+
     DBG(r300, DBG_DRAW, "r300: Resolving resource...\n");
 
     /* Enable AA resolve. */
-    aa->dest = r300_surface(
-            dest->screen->get_tex_surface(dest->screen, dest, subdest.face,
-                                          subdest.level, 0, 0));
+    aa->dest = r300_surface(pipe->create_surface(pipe, dest, &surf_tmpl));
 
     aa->aaresolve_ctl =
         R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE |
         R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE;
     r300->aa_state.size = 12;
-    r300->aa_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->aa_state);
 
     /* Resolve the surface. */
     r300->context.clear_render_target(pipe,
@@ -1183,7 +1200,7 @@ static void r300_resource_resolve(struct pipe_context* pipe,
     /* Disable AA resolve. */
     aa->aaresolve_ctl = 0;
     r300->aa_state.size = 4;
-    r300->aa_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->aa_state);
 
     pipe_surface_reference((struct pipe_surface**)&srcsurf, NULL);
     pipe_surface_reference((struct pipe_surface**)&aa->dest, NULL);
index 1f035d64a28450d75d67db3669a9c28f1d5ea30d..747594afaf2763fa7952afeb176c5f2564e7d82a 100644 (file)
@@ -66,7 +66,7 @@ static void r300_stencilref_begin(struct r300_context *r300)
     /* We *cull* pixels, therefore no need to mask out the bits. */
     rs->cb_main[rs->cull_mode_index] |= R300_CULL_BACK;
 
-    r300->rs_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->rs_state);
 }
 
 /* Set drawing for back faces. */
@@ -80,8 +80,8 @@ static void r300_stencilref_switch_side(struct r300_context *r300)
     dsa->stencil_ref_mask = dsa->stencil_ref_bf;
     r300->stencil_ref.ref_value[0] = r300->stencil_ref.ref_value[1];
 
-    r300->rs_state.dirty = TRUE;
-    r300->dsa_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->rs_state);
+    r300_mark_atom_dirty(r300, &r300->dsa_state);
 }
 
 /* Restore the original state. */
@@ -96,8 +96,8 @@ static void r300_stencilref_end(struct r300_context *r300)
     dsa->stencil_ref_mask = sr->zb_stencilrefmask;
     r300->stencil_ref.ref_value[0] = sr->ref_value_front;
 
-    r300->rs_state.dirty = TRUE;
-    r300->dsa_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->rs_state);
+    r300_mark_atom_dirty(r300, &r300->dsa_state);
 }
 
 static void r300_stencilref_draw_vbo(struct pipe_context *pipe,
index 9247064508f86cd5ec411d31bb941b2334c7105c..41a43b04de77a3ecf4ba256744f039a8b10d98f8 100644 (file)
@@ -145,6 +145,7 @@ void r300_begin_vertex_translate(struct r300_context *r300)
             vb->max_index = num_verts - 1;
             vb->stride = key.output_stride;
             r300->tran.vb_slot = i;
+            r300->validate_buffers = TRUE;
             break;
         }
     }
@@ -199,12 +200,14 @@ void r300_translate_index_buffer(struct r300_context *r300,
             util_shorten_ubyte_elts(&r300->context, index_buffer, index_offset, *start, count);
             *index_size = 2;
             *start = 0;
+            r300->validate_buffers = TRUE;
             break;
 
         case 2:
             if (*start % 2 != 0 || index_offset) {
                 util_rebuild_ushort_elts(&r300->context, index_buffer, index_offset, *start, count);
                 *start = 0;
+                r300->validate_buffers = TRUE;
             }
             break;
 
@@ -212,6 +215,7 @@ void r300_translate_index_buffer(struct r300_context *r300,
             if (index_offset) {
                 util_rebuild_uint_elts(&r300->context, index_buffer, index_offset, *start, count);
                 *start = 0;
+                r300->validate_buffers = TRUE;
             }
             break;
     }
index f6f33028dc60b15007e74407681458713b7ffee4..dd1df970594c00c1ec3b25970b56a08e2c230eb4 100644 (file)
@@ -58,6 +58,8 @@ void r300_init_resource_functions(struct r300_context *r300)
    r300->context.transfer_destroy = u_transfer_destroy_vtbl;
    r300->context.transfer_inline_write = u_transfer_inline_write_vtbl;
    r300->context.is_resource_referenced = u_is_resource_referenced_vtbl;
+   r300->context.create_surface = r300_create_surface;
+   r300->context.surface_destroy = r300_surface_destroy;
 }
 
 void r300_init_screen_resource_functions(struct r300_screen *r300screen)
@@ -67,7 +69,4 @@ void r300_init_screen_resource_functions(struct r300_screen *r300screen)
    r300screen->screen.resource_get_handle = u_resource_get_handle_vtbl;
    r300screen->screen.resource_destroy = u_resource_destroy_vtbl;
    r300screen->screen.user_buffer_create = r300_user_buffer_create;
-
-   r300screen->screen.get_tex_surface = r300_get_tex_surface;
-   r300screen->screen.tex_surface_destroy = r300_tex_surface_destroy;
 }
index 759d0e669686f3f7b685575f40ece2351be12387..921d6f1e676f78a14c8d82ef3f124c940e1903fc 100644 (file)
@@ -116,8 +116,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
         case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-        case PIPE_CAP_TEXTURE_SWIZZLE:
             return 1;
+        case PIPE_CAP_TEXTURE_SWIZZLE:
+            return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1;
 
         /* Unsupported features (boolean caps). */
         case PIPE_CAP_TIMER_QUERY:
@@ -214,6 +215,8 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
             return 0;
+        case PIPE_SHADER_CAP_SUBROUTINES:
+            return 0;
         }
         break;
     case PIPE_SHADER_VERTEX:
@@ -251,6 +254,8 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
             return 0;
         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
             return 1;
+        case PIPE_SHADER_CAP_SUBROUTINES:
+            return 0;
         default:
             break;
         }
@@ -395,7 +400,7 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
     struct r300_screen* r300screen = r300_screen(pscreen);
     struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
 
-    util_mempool_destroy(&r300screen->pool_buffers);
+    util_slab_destroy(&r300screen->pool_buffers);
 
     if (rws)
       rws->destroy(rws);
@@ -452,9 +457,13 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
     r300_init_debug(r300screen);
     r300_parse_chipset(&r300screen->caps);
 
-    util_mempool_create(&r300screen->pool_buffers,
-                        sizeof(struct r300_buffer), 64,
-                        UTIL_MEMPOOL_SINGLETHREADED);
+    r300screen->caps.index_bias_supported =
+            r300screen->caps.is_r500 &&
+            rws->get_value(rws, R300_VID_DRM_2_3_0);
+
+    util_slab_create(&r300screen->pool_buffers,
+                     sizeof(struct r300_buffer), 64,
+                     UTIL_SLAB_SINGLETHREADED);
 
     r300screen->rws = rws;
     r300screen->screen.winsys = (struct pipe_winsys*)rws;
index 8b7f1fab61bb170021fdd6d49f80f00e82af2845..5847fe1ffc892048226f67b51ea13091d5cd6cf4 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "r300_chipset.h"
 
-#include "util/u_mempool.h"
+#include "util/u_slab.h"
 
 #include <stdio.h>
 
@@ -44,7 +44,7 @@ struct r300_screen {
     struct r300_capabilities caps;
 
     /* Memory pools. */
-    struct util_mempool pool_buffers;
+    struct util_slab_mempool pool_buffers;
 
     /** Combination of DBG_xxx flags */
     unsigned debug;
@@ -101,7 +101,6 @@ r300_winsys_screen(struct pipe_screen *screen) {
 #define DBG_NO_OPT      (1 << 20)
 #define DBG_NO_CBZB     (1 << 21)
 /* Statistics. */
-#define DBG_STATS       (1 << 24)
 #define DBG_P_STAT      (1 << 25)
 /*@}*/
 
index 37a080ba48b940bf5850d0a8967c51349d63d9c3..44364435221c9dc83ec0d55a01fe114b905c20b4 100644 (file)
@@ -43,7 +43,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
     if (r300_buffer_is_user_buffer(buf))
        return PIPE_UNREFERENCED;
 
-    if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->buf, domain))
+    if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain))
         return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
     return PIPE_UNREFERENCED;
@@ -51,7 +51,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
 
 static unsigned r300_buffer_is_referenced_by_cs(struct pipe_context *context,
                                                 struct pipe_resource *buf,
-                                                unsigned face, unsigned level)
+                                                unsigned level, int layer)
 {
     return r300_buffer_is_referenced(context, buf, R300_REF_CS);
 }
@@ -118,6 +118,7 @@ int r300_upload_user_buffers(struct r300_context *r300)
             pipe_resource_reference(&vb->buffer, NULL);
             vb->buffer = upload_buffer;
             vb->buffer_offset = upload_offset;
+            r300->validate_buffers = TRUE;
         }
     }
     return ret;
@@ -136,26 +137,26 @@ static void r300_buffer_destroy(struct pipe_screen *screen,
     if (rbuf->buf)
         rws->buffer_reference(rws, &rbuf->buf, NULL);
 
-    util_mempool_free(&r300screen->pool_buffers, rbuf);
+    util_slab_free(&r300screen->pool_buffers, rbuf);
 }
 
 static struct pipe_transfer*
-r300_default_get_transfer(struct pipe_context *context,
-                          struct pipe_resource *resource,
-                          struct pipe_subresource sr,
-                          unsigned usage,
-                          const struct pipe_box *box)
+r300_buffer_get_transfer(struct pipe_context *context,
+                         struct pipe_resource *resource,
+                         unsigned level,
+                         unsigned usage,
+                         const struct pipe_box *box)
 {
    struct r300_context *r300 = r300_context(context);
    struct pipe_transfer *transfer =
-         util_mempool_malloc(&r300->pool_transfers);
+         util_slab_alloc(&r300->pool_transfers);
 
    transfer->resource = resource;
-   transfer->sr = sr;
+   transfer->level = level;
    transfer->usage = usage;
    transfer->box = *box;
    transfer->stride = 0;
-   transfer->slice_stride = 0;
+   transfer->layer_stride = 0;
    transfer->data = NULL;
 
    /* Note strides are zero, this is ok for buffers, but not for
@@ -164,11 +165,11 @@ r300_default_get_transfer(struct pipe_context *context,
    return transfer;
 }
 
-static void r300_default_transfer_destroy(struct pipe_context *pipe,
-                                          struct pipe_transfer *transfer)
+static void r300_buffer_transfer_destroy(struct pipe_context *pipe,
+                                         struct pipe_transfer *transfer)
 {
    struct r300_context *r300 = r300_context(pipe);
-   util_mempool_free(&r300->pool_transfers, transfer);
+   util_slab_free(&r300->pool_transfers, transfer);
 }
 
 static void *
@@ -206,6 +207,9 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
                                                    rbuf->b.b.bind,
                                                    rbuf->b.b.usage,
                                                    rbuf->domain);
+                rbuf->cs_buf =
+                    r300screen->rws->buffer_get_cs_handle(r300screen->rws,
+                                                          rbuf->buf);
                break;
            }
        }
@@ -265,17 +269,45 @@ static void r300_buffer_transfer_unmap( struct pipe_context *pipe,
     }
 }
 
+static void r300_buffer_transfer_inline_write(struct pipe_context *pipe,
+                                              struct pipe_resource *resource,
+                                              unsigned level,
+                                              unsigned usage,
+                                              const struct pipe_box *box,
+                                              const void *data,
+                                              unsigned stride,
+                                              unsigned layer_stride)
+{
+    struct r300_buffer *rbuf = r300_buffer(resource);
+    struct pipe_transfer *transfer = NULL;
+    uint8_t *map = NULL;
+
+    if (rbuf->constant_buffer) {
+        memcpy(rbuf->constant_buffer + box->x, data, box->width);
+        return;
+    }
+
+    transfer = r300_buffer_get_transfer(pipe, resource, 0,
+                        PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, box);
+    map = r300_buffer_transfer_map(pipe, transfer);
+
+    memcpy(map, data, box->width);
+
+    r300_buffer_transfer_unmap(pipe, transfer);
+    r300_buffer_transfer_destroy(pipe, transfer);
+}
+
 struct u_resource_vtbl r300_buffer_vtbl = 
 {
    u_default_resource_get_handle,      /* get_handle */
    r300_buffer_destroy,                /* resource_destroy */
    r300_buffer_is_referenced_by_cs,    /* is_buffer_referenced */
-   r300_default_get_transfer,          /* get_transfer */
-   r300_default_transfer_destroy,      /* transfer_destroy */
+   r300_buffer_get_transfer,           /* get_transfer */
+   r300_buffer_transfer_destroy,       /* transfer_destroy */
    r300_buffer_transfer_map,           /* transfer_map */
    r300_buffer_transfer_flush_region,  /* transfer_flush_region */
    r300_buffer_transfer_unmap,         /* transfer_unmap */
-   u_default_transfer_inline_write     /* transfer_inline_write */
+   r300_buffer_transfer_inline_write   /* transfer_inline_write */
 };
 
 struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
@@ -285,7 +317,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
     struct r300_buffer *rbuf;
     unsigned alignment = 16;
 
-    rbuf = util_mempool_malloc(&r300screen->pool_buffers);
+    rbuf = util_slab_alloc(&r300screen->pool_buffers);
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
@@ -310,9 +342,11 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
                                        rbuf->b.b.width0, alignment,
                                        rbuf->b.b.bind, rbuf->b.b.usage,
                                        rbuf->domain);
+    rbuf->cs_buf =
+        r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf);
 
     if (!rbuf->buf) {
-        util_mempool_free(&r300screen->pool_buffers, rbuf);
+        util_slab_free(&r300screen->pool_buffers, rbuf);
         return NULL;
     }
 
@@ -327,7 +361,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
     struct r300_screen *r300screen = r300_screen(screen);
     struct r300_buffer *rbuf;
 
-    rbuf = util_mempool_malloc(&r300screen->pool_buffers);
+    rbuf = util_slab_alloc(&r300screen->pool_buffers);
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
@@ -341,6 +375,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
     rbuf->b.b.width0 = bytes;
     rbuf->b.b.height0 = 1;
     rbuf->b.b.depth0 = 1;
+    rbuf->b.b.array_size = 1;
     rbuf->b.b.flags = 0;
     rbuf->domain = R300_DOMAIN_GTT;
     rbuf->num_ranges = 0;
index cafa9f96f20f957e5f8874541b6baca8b93c1708..0b3555dd813583d62cb0ebcf0a83d66389f5770c 100644 (file)
@@ -51,11 +51,12 @@ struct r300_buffer
     uint32_t magic;
 
     struct r300_winsys_buffer *buf;
+    struct r300_winsys_cs_buffer *cs_buf;
 
     enum r300_buffer_domain domain;
 
-    void *user_buffer;
-    void *constant_buffer;
+    uint8_t *user_buffer;
+    uint8_t *constant_buffer;
     struct r300_buffer_range ranges[R300_BUFFER_MAX_RANGES];
     unsigned num_ranges;
 };
@@ -86,11 +87,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
 
 static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer)
 {
-    if (buffer) {
-       assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC);
-       return (struct r300_buffer *)buffer;
-    }
-    return NULL;
+    return (struct r300_buffer *)buffer;
 }
 
 static INLINE boolean r300_buffer_is_user_buffer(struct pipe_resource *buffer)
index 247c22216e18806bc573e9958d50b8eb4c0ab355..752925324051fde22f847a0ff2529492f9bcfe4e 100644 (file)
@@ -52,7 +52,7 @@
 #define UPDATE_STATE(cso, atom) \
     if (cso != atom.state) { \
         atom.state = cso;    \
-        atom.dirty = TRUE;   \
+        r300_mark_atom_dirty(r300, &(atom));   \
     }
 
 static boolean blend_discard_if_src_alpha_0(unsigned srcRGB, unsigned srcA,
@@ -417,7 +417,7 @@ static void r300_set_blend_color(struct pipe_context* pipe,
         END_CB;
     }
 
-    r300->blend_color_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->blend_color_state);
 }
 
 static void r300_set_clip_state(struct pipe_context* pipe,
@@ -446,7 +446,7 @@ static void r300_set_clip_state(struct pipe_context* pipe,
                 (state->depth_clamp ? R300_CLIP_DISABLE : 0));
         END_CB;
 
-        r300->clip_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->clip_state);
     } else {
         draw_set_clip_state(r300->draw, state);
     }
@@ -594,7 +594,7 @@ static void r300_bind_dsa_state(struct pipe_context* pipe,
 
     UPDATE_STATE(state, r300->dsa_state);
 
-    r300->hyperz_state.dirty = TRUE; /* Will be updated before the emission. */
+    r300_mark_atom_dirty(r300, &r300->hyperz_state); /* Will be updated before the emission. */
     r300_dsa_inject_stencilref(r300);
 }
 
@@ -613,7 +613,7 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
     r300->stencil_ref = *sr;
 
     r300_dsa_inject_stencilref(r300);
-    r300->dsa_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->dsa_state);
 }
 
 static void r300_tex_set_tiling_flags(struct r300_context *r300,
@@ -626,7 +626,7 @@ static void r300_tex_set_tiling_flags(struct r300_context *r300,
         /* Tiling determines how DRM treats the buffer data.
          * We must flush CS when changing it if the buffer is referenced. */
         if (r300->rws->cs_is_buffer_referenced(r300->cs,
-                                               tex->buffer, R300_REF_CS))
+                                               tex->cs_buffer, R300_REF_CS))
             r300->context.flush(&r300->context, 0, NULL);
 
         r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
@@ -647,12 +647,12 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300,
     for (i = 0; i < state->nr_cbufs; i++) {
         r300_tex_set_tiling_flags(r300,
                                   r300_texture(state->cbufs[i]->texture),
-                                  state->cbufs[i]->level);
+                                  state->cbufs[i]->u.tex.level);
     }
     if (state->zsbuf) {
         r300_tex_set_tiling_flags(r300,
                                   r300_texture(state->zsbuf->texture),
-                                  state->zsbuf->level);
+                                  state->zsbuf->u.tex.level);
     }
 }
 
@@ -663,14 +663,14 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
     struct r300_texture *rtex = r300_texture(tex);
 
     fprintf(stderr,
-            "r300:   %s[%i] Dim: %ix%i, Offset: %i, ZSlice: %i, "
-            "Face: %i, Level: %i, Format: %s\n"
+            "r300:   %s[%i] Dim: %ix%i, Firstlayer: %i, "
+            "Lastlayer: %i, Level: %i, Format: %s\n"
 
             "r300:     TEX: Macro: %s, Micro: %s, Pitch: %i, "
             "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
 
-            binding, index, surf->width, surf->height, surf->offset,
-            surf->zslice, surf->face, surf->level,
+            binding, index, surf->width, surf->height,
+            surf->u.tex.first_layer, surf->u.tex.last_layer, surf->u.tex.level,
             util_format_short_name(surf->format),
 
             rtex->desc.macrotile[0] ? "YES" : " NO",
@@ -687,13 +687,13 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
     boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
 
     /* What is marked as dirty depends on the enum r300_fb_state_change. */
-    r300->gpu_flush.dirty = TRUE;
-    r300->fb_state.dirty = TRUE;
-    r300->hyperz_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->gpu_flush);
+    r300_mark_atom_dirty(r300, &r300->fb_state);
+    r300_mark_atom_dirty(r300, &r300->hyperz_state);
 
     if (change == R300_CHANGED_FB_STATE) {
-        r300->aa_state.dirty = TRUE;
-        r300->fb_state_pipelined.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->aa_state);
+        r300_mark_atom_dirty(r300, &r300->fb_state_pipelined);
     }
 
     /* Now compute the fb_state atom size. */
@@ -738,11 +738,11 @@ static void
 
     /* If nr_cbufs is changed from zero to non-zero or vice versa... */
     if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
-        r300->blend_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->blend_state);
     }
     /* If zsbuf is set from NULL to non-NULL or vice versa.. */
     if (!!old_state->zsbuf != !!state->zsbuf) {
-        r300->dsa_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->dsa_state);
     }
 
     /* The tiling flags are dependent on the surface miplevel, unfortunately. */
@@ -751,6 +751,7 @@ static void
     util_copy_framebuffer_state(r300->fb_state.state, state);
 
     r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
+    r300->validate_buffers = TRUE;
 
     r300->z_compression = false;
     
@@ -768,7 +769,7 @@ static void
             struct r300_surface *zs_surf = r300_surface(state->zsbuf);
             struct r300_texture *tex;
             int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44;
-            int level = zs_surf->base.level;
+            int level = zs_surf->base.u.tex.level;
 
             tex = r300_texture(zs_surf->base.texture);
 
@@ -795,7 +796,7 @@ static void
             r300->zbuffer_bpp = zbuffer_bpp;
 
             if (r300->polygon_offset_enabled)
-                r300->rs_state.dirty = TRUE;
+                r300_mark_atom_dirty(r300, &r300->rs_state);
         }
     }
 
@@ -853,9 +854,9 @@ void r300_mark_fs_code_dirty(struct r300_context *r300)
 {
     struct r300_fragment_shader* fs = r300_fs(r300);
 
-    r300->fs.dirty = TRUE;
-    r300->fs_rc_constant_state.dirty = TRUE;
-    r300->fs_constants.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->fs);
+    r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);
+    r300_mark_atom_dirty(r300, &r300->fs_constants);
     r300->fs.size = fs->shader->cb_code_size;
 
     if (r300->screen->caps.is_r500) {
@@ -885,7 +886,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
     r300_pick_fragment_shader(r300);
     r300_mark_fs_code_dirty(r300);
 
-    r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+    r300_mark_atom_dirty(r300, &r300->rs_block_state); /* Will be updated before the emission. */
 }
 
 /* Delete fragment shader state. */
@@ -1137,7 +1138,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
 
     if (last_sprite_coord_enable != r300->sprite_coord_enable ||
         last_two_sided_color != r300->two_sided_color) {
-        r300->rs_block_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->rs_block_state);
     }
 }
 
@@ -1235,7 +1236,7 @@ static void r300_bind_sampler_states(struct pipe_context* pipe,
     memcpy(state->sampler_states, states, sizeof(void*) * count);
     state->sampler_state_count = count;
 
-    r300->textures_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->textures_state);
 }
 
 static void r300_lacks_vertex_textures(struct pipe_context* pipe,
@@ -1313,7 +1314,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
              * Needed for RECT and NPOT fallback. */
             texture = r300_texture(views[i]->texture);
             if (texture->desc.is_npot) {
-                r300->fs_rc_constant_state.dirty = TRUE;
+                r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);
             }
 
             state->sampler_views[i]->texcache_region =
@@ -1332,10 +1333,11 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
 
     state->sampler_view_count = count;
 
-    r300->textures_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->textures_state);
+    r300->validate_buffers = TRUE;
 
     if (dirty_tex) {
-        r300->texture_cache_inval.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
     }
 }
 
@@ -1347,6 +1349,7 @@ r300_create_sampler_view(struct pipe_context *pipe,
     struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
     struct r300_texture *tex = r300_texture(texture);
     boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
+    boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle;
 
     if (view) {
         view->base = *templ;
@@ -1363,7 +1366,8 @@ r300_create_sampler_view(struct pipe_context *pipe,
         view->format = tex->tx_format;
         view->format.format1 |= r300_translate_texformat(templ->format,
                                                          view->swizzle,
-                                                         is_r500);
+                                                         is_r500,
+                                                         dxtc_swizzle);
         if (is_r500) {
             view->format.format2 |= r500_tx_format_msb_bit(templ->format);
         }
@@ -1388,7 +1392,7 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
     memcpy(r300->scissor_state.state, state,
         sizeof(struct pipe_scissor_state));
 
-    r300->scissor_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->scissor_state);
 }
 
 static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -1434,9 +1438,9 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
         viewport->vte_control |= R300_VPORT_Z_OFFSET_ENA;
     }
 
-    r300->viewport_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->viewport_state);
     if (r300->fs.state && r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) {
-        r300->fs_rc_constant_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);
     }
 }
 
@@ -1507,7 +1511,8 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
 
         r300->any_user_vbs = any_user_buffer;
         r300->vertex_buffer_max_index = max_index;
-
+        r300->aos_dirty = TRUE;
+        r300->validate_buffers = TRUE;
     } else {
         /* SW TCL. */
         draw_set_vertex_buffers(r300->draw, count, buffers);
@@ -1543,10 +1548,10 @@ static void r300_set_index_buffer(struct pipe_context* pipe,
     }
 
     if (r300->screen->caps.has_tcl) {
-       /* TODO make this more like a state */
+        r300->validate_buffers = TRUE;
     }
     else {
-       draw_set_index_buffer(r300->draw, ib);
+        draw_set_index_buffer(r300->draw, ib);
     }
 }
 
@@ -1714,6 +1719,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
 
     UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
     r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
+    r300->aos_dirty = TRUE;
 }
 
 static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
@@ -1756,27 +1762,25 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
     r300->vs_state.state = vs;
 
     /* The majority of the RS block bits is dependent on the vertex shader. */
-    r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+    r300_mark_atom_dirty(r300, &r300->rs_block_state); /* Will be updated before the emission. */
 
     if (r300->screen->caps.has_tcl) {
         unsigned fc_op_dwords = r300->screen->caps.is_r500 ? 3 : 2;
-        r300->vs_state.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->vs_state);
         r300->vs_state.size =
                 vs->code.length + 9 +
-                (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0) +
         (vs->code.num_fc_ops ? vs->code.num_fc_ops * fc_op_dwords + 4 : 0);
 
-        if (vs->externals_count) {
-            r300->vs_constants.dirty = TRUE;
-            r300->vs_constants.size = vs->externals_count * 4 + 3;
-        } else {
-            r300->vs_constants.size = 0;
-        }
+        r300_mark_atom_dirty(r300, &r300->vs_constants);
+        r300->vs_constants.size =
+                2 +
+                (vs->externals_count ? vs->externals_count * 4 + 3 : 0) +
+                (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0);
 
         ((struct r300_constant_buffer*)r300->vs_constants.state)->remap_table =
                 vs->code.constants_remap_table;
 
-        r300->pvs_flush.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->pvs_flush);
     } else {
         draw_bind_vertex_shader(r300->draw,
                 (struct draw_vertex_shader*)vs->draw_vs);
@@ -1817,33 +1821,44 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             cbuf = (struct r300_constant_buffer*)r300->fs_constants.state;
             break;
         default:
-            assert(0);
             return;
     }
 
     if (buf == NULL || buf->width0 == 0 ||
-        (mapped = r300_buffer(buf)->constant_buffer) == NULL) {
+        (mapped = (uint32_t*)r300_buffer(buf)->constant_buffer) == NULL) {
         return;
     }
 
     if (shader == PIPE_SHADER_FRAGMENT ||
         (shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) {
         assert((buf->width0 % (4 * sizeof(float))) == 0);
-        cbuf->ptr = mapped + index*4;
+        cbuf->ptr = mapped;
     }
 
     if (shader == PIPE_SHADER_VERTEX) {
         if (r300->screen->caps.has_tcl) {
-            if (r300->vs_constants.size) {
-                r300->vs_constants.dirty = TRUE;
+            struct r300_vertex_shader *vs =
+                    (struct r300_vertex_shader*)r300->vs_state.state;
+
+            if (!vs) {
+                cbuf->buffer_base = 0;
+                return;
+            }
+
+            cbuf->buffer_base = r300->vs_const_base;
+            r300->vs_const_base += vs->code.constants.Count;
+            if (r300->vs_const_base > R500_MAX_PVS_CONST_VECS) {
+                r300->vs_const_base = vs->code.constants.Count;
+                cbuf->buffer_base = 0;
+                r300_mark_atom_dirty(r300, &r300->pvs_flush);
             }
-            r300->pvs_flush.dirty = TRUE;
+            r300_mark_atom_dirty(r300, &r300->vs_constants);
         } else if (r300->draw) {
             draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
                 0, mapped, buf->width0);
         }
     } else if (shader == PIPE_SHADER_FRAGMENT) {
-        r300->fs_constants.dirty = TRUE;
+        r300_mark_atom_dirty(r300, &r300->fs_constants);
     }
 }
 
index 1cff3483b50c6a1e0ad9f9c0708851dce259762b..d5fc8ece252923bedc244619e00dc4df1d44c1d0 100644 (file)
@@ -193,7 +193,7 @@ static void r300_swtcl_vertex_psc(struct r300_context *r300)
         (R300_LAST_VEC << (i & 1 ? 16 : 0));
 
     vstream->count = (i >> 1) + 1;
-    r300->vertex_stream_state.dirty = TRUE;
+    r300_mark_atom_dirty(r300, &r300->vertex_stream_state);
     r300->vertex_stream_state.size = (1 + vstream->count) * 2;
 }
 
@@ -592,7 +592,8 @@ static void r300_update_rs_block(struct r300_context *r300)
 }
 
 static uint32_t r300_get_border_color(enum pipe_format format,
-                                      const float border[4])
+                                      const float border[4],
+                                      boolean is_r500)
 {
     const struct util_format_description *desc;
     float border_swizzled[4] = {0};
@@ -601,6 +602,24 @@ static uint32_t r300_get_border_color(enum pipe_format format,
 
     desc = util_format_description(format);
 
+    /* Do depth formats first. */
+    if (util_format_is_depth_or_stencil(format)) {
+        switch (format) {
+        case PIPE_FORMAT_Z16_UNORM:
+            return util_pack_z(PIPE_FORMAT_Z16_UNORM, border[0]);
+        case PIPE_FORMAT_X8Z24_UNORM:
+        case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+            if (is_r500) {
+                return util_pack_z(PIPE_FORMAT_X8Z24_UNORM, border[0]);
+            } else {
+                return util_pack_z(PIPE_FORMAT_Z16_UNORM, border[0]) << 16;
+            }
+        default:
+            assert(0);
+            return 0;
+        }
+    }
+
     /* Apply inverse swizzle of the format. */
     for (i = 0; i < 4; i++) {
         switch (desc->swizzle[i]) {
@@ -619,6 +638,12 @@ static uint32_t r300_get_border_color(enum pipe_format format,
         }
     }
 
+    /* Compressed formats. */
+    if (util_format_is_compressed(format)) {
+        util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
+        return uc.ui;
+    }
+
     switch (desc->channel[0].size) {
         case 4:
             util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc);
@@ -642,6 +667,15 @@ static uint32_t r300_get_border_color(enum pipe_format format,
         case 10:
             util_pack_color(border_swizzled, PIPE_FORMAT_B10G10R10A2_UNORM, &uc);
             break;
+
+        case 16:
+            if (desc->nr_channels <= 2) {
+                border_swizzled[0] = border_swizzled[2];
+                util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_UNORM, &uc);
+            } else {
+                util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
+            }
+            break;
     }
 
     return uc.ui;
@@ -683,12 +717,13 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
             /* Set the border color. */
             texstate->border_color =
                 r300_get_border_color(view->base.format,
-                                      sampler->state.border_color);
+                                      sampler->state.border_color,
+                                      r300->screen->caps.is_r500);
 
             /* determine min/max levels */
-            max_level = MIN3(sampler->max_lod + view->base.first_level,
-                             tex->desc.b.b.last_level, view->base.last_level);
-            min_level = MIN2(sampler->min_lod + view->base.first_level,
+            max_level = MIN3(sampler->max_lod + view->base.u.tex.first_level,
+                             tex->desc.b.b.last_level, view->base.u.tex.last_level);
+            min_level = MIN2(sampler->min_lod + view->base.u.tex.first_level,
                              max_level);
 
             if (tex->desc.is_npot && min_level > 0) {
@@ -729,13 +764,18 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
                 if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {
                     texstate->format.format1 |=
                         r300_get_swizzle_combined(depth_swizzle,
-                                                  view->swizzle);
+                                                  view->swizzle, FALSE);
                 } else {
                     texstate->format.format1 |=
-                        r300_get_swizzle_combined(depth_swizzle, 0);
+                        r300_get_swizzle_combined(depth_swizzle, 0, FALSE);
                 }
             }
 
+            if (r300->screen->caps.dxtc_swizzle &&
+                util_format_is_compressed(tex->desc.b.b.format)) {
+                texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE;
+            }
+
             /* to emulate 1D textures through 2D ones correctly */
             if (tex->desc.b.b.target == PIPE_TEXTURE_1D) {
                 texstate->filter0 &= ~R300_TX_WRAP_T_MASK;
@@ -847,9 +887,8 @@ static void r300_flush_depth_textures(struct r300_context *r300)
             for (level = 0; level <= tex->last_level; level++)
                 if (r300_texture(tex)->zmask_in_use[level]) {
                     /* We don't handle 3D textures and cubemaps yet. */
-                    r300_flush_depth_stencil(&r300->context, tex,
-                                             u_subresource(0, level), 0);
-                }
+                    r300_flush_depth_stencil(&r300->context, tex, level, 0);
+                 }
         }
 }
 
index cee56bccdcd24de47230929cfc413e1b264c84e2..70fc5d96d83689b48c3adfaa312c6a94349a8ffb 100644 (file)
@@ -40,7 +40,8 @@
 #include "pipe/p_screen.h"
 
 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
-                                   const unsigned char *swizzle_view)
+                                   const unsigned char *swizzle_view,
+                                   boolean dxtc_swizzle)
 {
     unsigned i;
     unsigned char swizzle[4];
@@ -51,10 +52,10 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
         R300_TX_FORMAT_B_SHIFT,
         R300_TX_FORMAT_A_SHIFT
     };
-    const uint32_t swizzle_bit[4] = {
-        R300_TX_FORMAT_X,
+    uint32_t swizzle_bit[4] = {
+        dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X,
         R300_TX_FORMAT_Y,
-        R300_TX_FORMAT_Z,
+        dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z,
         R300_TX_FORMAT_W
     };
 
@@ -107,7 +108,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
  * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
 uint32_t r300_translate_texformat(enum pipe_format format,
                                   const unsigned char *swizzle_view,
-                                  boolean is_r500)
+                                  boolean is_r500,
+                                  boolean dxtc_swizzle)
 {
     uint32_t result = 0;
     const struct util_format_description *desc;
@@ -169,7 +171,8 @@ uint32_t r300_translate_texformat(enum pipe_format format,
             }
     }
 
-    result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view);
+    result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
+                    util_format_is_compressed(format) && dxtc_swizzle);
 
     /* S3TC formats. */
     if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
@@ -571,7 +574,7 @@ boolean r300_is_zs_format_supported(enum pipe_format format)
 
 boolean r300_is_sampler_format_supported(enum pipe_format format)
 {
-    return r300_translate_texformat(format, 0, TRUE) != ~0;
+    return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0;
 }
 
 void r300_texture_setup_format_state(struct r300_screen *screen,
@@ -665,21 +668,21 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
 }
 
 static unsigned r300_texture_is_referenced(struct pipe_context *context,
-                                        struct pipe_resource *texture,
-                                        unsigned face, unsigned level)
+                                           struct pipe_resource *texture,
+                                           unsigned level, int layer)
 {
     struct r300_context *r300 = r300_context(context);
     struct r300_texture *rtex = (struct r300_texture *)texture;
 
     if (r300->rws->cs_is_buffer_referenced(r300->cs,
-                                           rtex->buffer, R300_REF_CS))
+                                           rtex->cs_buffer, R300_REF_CS))
         return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
     return PIPE_UNREFERENCED;
 }
 
 static void r300_texture_destroy(struct pipe_screen *screen,
-                                struct pipe_resource* texture)
+                                 struct pipe_resource* texture)
 {
     struct r300_texture* tex = (struct r300_texture*)texture;
     struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
@@ -774,6 +777,8 @@ r300_texture_create_object(struct r300_screen *rscreen,
         }
     }
 
+    tex->cs_buffer = rws->buffer_get_cs_handle(rws, tex->buffer);
+
     rws->buffer_set_tiling(rws, tex->buffer,
             tex->desc.microtile, tex->desc.macrotile[0],
             tex->desc.stride_in_bytes[0]);
@@ -848,38 +853,40 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
 
 /* Not required to implement u_resource_vtbl, consider moving to another file:
  */
-struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
-                                          struct pipe_resource* texture,
-                                         unsigned face,
-                                         unsigned level,
-                                         unsigned zslice,
-                                         unsigned flags)
+struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
+                                         struct pipe_resource* texture,
+                                         const struct pipe_surface *surf_tmpl)
 {
     struct r300_texture* tex = r300_texture(texture);
     struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
+    unsigned level = surf_tmpl->u.tex.level;
+
+    assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
 
     if (surface) {
         uint32_t offset, tile_height;
 
         pipe_reference_init(&surface->base.reference, 1);
         pipe_resource_reference(&surface->base.texture, texture);
-        surface->base.format = texture->format;
+        surface->base.context = ctx;
+        surface->base.format = surf_tmpl->format;
         surface->base.width = u_minify(texture->width0, level);
         surface->base.height = u_minify(texture->height0, level);
-        surface->base.usage = flags;
-        surface->base.zslice = zslice;
-        surface->base.face = face;
-        surface->base.level = level;
+        surface->base.usage = surf_tmpl->usage;
+        surface->base.u.tex.level = level;
+        surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+        surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
 
         surface->buffer = tex->buffer;
+        surface->cs_buffer = tex->cs_buffer;
 
         /* Prefer VRAM if there are multiple domains to choose from. */
         surface->domain = tex->domain;
         if (surface->domain & R300_DOMAIN_VRAM)
             surface->domain &= ~R300_DOMAIN_GTT;
 
-        surface->offset = r300_texture_get_offset(&tex->desc,
-                                                  level, zslice, face);
+        surface->offset = r300_texture_get_offset(&tex->desc, level,
+                                                  surf_tmpl->u.tex.first_layer);
         surface->pitch = tex->fb_state.pitch[level];
         surface->format = tex->fb_state.format;
 
@@ -910,13 +917,13 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
         else
             surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
 
-        SCREEN_DBG(r300_screen(screen), DBG_CBZB,
-                   "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n",
-                   surface->cbzb_allowed ? "YES" : " NO",
-                   surface->cbzb_width, surface->cbzb_height,
-                   offset & 2047,
-                   tex->desc.microtile ? "YES" : " NO",
-                   tex->desc.macrotile[level] ? "YES" : " NO");
+        DBG(r300_context(ctx), DBG_CBZB,
+            "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n",
+            surface->cbzb_allowed ? "YES" : " NO",
+            surface->cbzb_width, surface->cbzb_height,
+            offset & 2047,
+            tex->desc.microtile ? "YES" : " NO",
+            tex->desc.macrotile[level] ? "YES" : " NO");
     }
 
     return &surface->base;
@@ -924,7 +931,7 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
 
 /* Not required to implement u_resource_vtbl, consider moving to another file:
  */
-void r300_tex_surface_destroy(struct pipe_surface* s)
+void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s)
 {
     pipe_resource_reference(&s->texture, NULL);
     FREE(s);
index c4588a0c90b7852dd7bf07fea939a1ca6360e285..0ab22f747e4c8814ce3395ad4acfc4133844ccdf 100644 (file)
@@ -27,6 +27,7 @@
 #include "pipe/p_format.h"
 
 struct pipe_screen;
+struct pipe_context;
 struct pipe_resource;
 struct winsys_handle;
 struct r300_texture_format_state;
@@ -35,11 +36,13 @@ struct r300_texture;
 struct r300_screen;
 
 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
-                                   const unsigned char *swizzle_view);
+                                   const unsigned char *swizzle_view,
+                                   boolean dxtc_swizzle);
 
 uint32_t r300_translate_texformat(enum pipe_format format,
                                   const unsigned char *swizzle_view,
-                                  boolean is_r500);
+                                  boolean is_r500,
+                                  boolean dxtc_swizzle);
 
 uint32_t r500_tx_format_msb_bit(enum pipe_format format);
 
@@ -68,13 +71,10 @@ r300_texture_create(struct pipe_screen* screen,
                    const struct pipe_resource* templ);
 
 
-struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
-                                         struct pipe_resource* texture,
-                                         unsigned face,
-                                         unsigned level,
-                                         unsigned zslice,
-                                         unsigned flags);
+struct pipe_surface* r300_create_surface(struct pipe_context *ctx,
+                                         struct pipe_resource* texture,
+                                         const struct pipe_surface *surf_tmpl);
 
-void r300_tex_surface_destroy(struct pipe_surface* s);
+void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s);
 
 #endif /* R300_TEXTURE_H */
index 543d0fdc15b91cbad74fde72c600f9d955f1263a..aa82c47151a14dcc0931948cb1c38324f0cb8523 100644 (file)
@@ -474,22 +474,17 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen,
 }
 
 unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
-                                 unsigned level, unsigned zslice,
-                                 unsigned face)
+                                 unsigned level, unsigned layer)
 {
     unsigned offset = desc->offset_in_bytes[level];
 
     switch (desc->b.b.target) {
         case PIPE_TEXTURE_3D:
-            assert(face == 0);
-            return offset + zslice * desc->layer_size_in_bytes[level];
-
         case PIPE_TEXTURE_CUBE:
-            assert(zslice == 0);
-            return offset + face * desc->layer_size_in_bytes[level];
+            return offset + layer * desc->layer_size_in_bytes[level];
 
         default:
-            assert(zslice == 0 && face == 0);
+            assert(layer == 0);
             return offset;
     }
 }
index 3d7fe1fb4731cc352af6ec14fe88091b74673bdf..44d88794a125707e5597a73cdc526b91c1e717b2 100644 (file)
@@ -52,7 +52,6 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen,
                                unsigned max_buffer_size);
 
 unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
-                                 unsigned level, unsigned zslice,
-                                 unsigned face);
+                                 unsigned level, unsigned layer);
 
 #endif
index 33448bf0def238225f7c7d44a1e07df6fc70b53b..15a323989b26965f43d6cd23dbfd70370c55d376 100644 (file)
@@ -57,7 +57,7 @@ static unsigned translate_opcode(unsigned opcode)
      /* case TGSI_OPCODE_DP2A: return RC_OPCODE_DP2A; */
                                         /* gap */
         case TGSI_OPCODE_FRC: return RC_OPCODE_FRC;
-     /* case TGSI_OPCODE_CLAMP: return RC_OPCODE_CLAMP; */
+        case TGSI_OPCODE_CLAMP: return RC_OPCODE_CLAMP;
         case TGSI_OPCODE_FLR: return RC_OPCODE_FLR;
      /* case TGSI_OPCODE_ROUND: return RC_OPCODE_ROUND; */
         case TGSI_OPCODE_EX2: return RC_OPCODE_EX2;
index e9333b35ef53be62420294be95fcc8859f0903b3..3b95af79bcff5c7a668d6c85f60e6da09d53e93a 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "util/u_memory.h"
 #include "util/u_format.h"
+#include "util/u_box.h"
 
 struct r300_transfer {
     /* Parent class */
@@ -52,16 +53,10 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
 {
     struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
     struct pipe_resource *tex = transfer->resource;
-    struct pipe_subresource subdst;
 
-    subdst.face = 0;
-    subdst.level = 0;
-
-    ctx->resource_copy_region(ctx, &r300transfer->linear_texture->desc.b.b, subdst,
-                             0, 0, 0,
-                             tex, transfer->sr,
-                             transfer->box.x, transfer->box.y, transfer->box.z,
-                             transfer->box.width, transfer->box.height);
+    ctx->resource_copy_region(ctx, &r300transfer->linear_texture->desc.b.b, 0,
+                              0, 0, 0,
+                              tex, transfer->level, &transfer->box);
 }
 
 /* Copy a detiled texture to a tiled one. */
@@ -70,26 +65,22 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
 {
     struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
     struct pipe_resource *tex = transfer->resource;
-    struct pipe_subresource subsrc;
-
-    subsrc.face = 0;
-    subsrc.level = 0;
+    struct pipe_box src_box;
+    u_box_origin_2d(transfer->box.width, transfer->box.height, &src_box);
 
-    ctx->resource_copy_region(ctx, tex, transfer->sr,
-                             transfer->box.x, transfer->box.y, transfer->box.z,
-                              &r300transfer->linear_texture->desc.b.b, subsrc,
-                             0, 0, 0,
-                             transfer->box.width, transfer->box.height);
+    ctx->resource_copy_region(ctx, tex, transfer->level,
+                              transfer->box.x, transfer->box.y, transfer->box.z,
+                              &r300transfer->linear_texture->desc.b.b, 0, &src_box);
 
     ctx->flush(ctx, 0, NULL);
 }
 
 struct pipe_transfer*
 r300_texture_get_transfer(struct pipe_context *ctx,
-                         struct pipe_resource *texture,
-                         struct pipe_subresource sr,
-                         unsigned usage,
-                         const struct pipe_box *box)
+                          struct pipe_resource *texture,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box)
 {
     struct r300_context *r300 = r300_context(ctx);
     struct r300_texture *tex = r300_texture(texture);
@@ -99,13 +90,13 @@ r300_texture_get_transfer(struct pipe_context *ctx,
 
     referenced_cs =
         r300->rws->cs_is_buffer_referenced(r300->cs,
-                                           tex->buffer, R300_REF_CS);
+                                           tex->cs_buffer, R300_REF_CS);
     if (referenced_cs) {
         referenced_hw = TRUE;
     } else {
         referenced_hw =
             r300->rws->cs_is_buffer_referenced(r300->cs,
-                                               tex->buffer, R300_REF_HW);
+                                               tex->cs_buffer, R300_REF_HW);
     }
 
     blittable = ctx->screen->is_format_supported(
@@ -116,25 +107,27 @@ r300_texture_get_transfer(struct pipe_context *ctx,
     if (trans) {
         /* Initialize the transfer object. */
         pipe_resource_reference(&trans->transfer.resource, texture);
-        trans->transfer.sr = sr;
+        trans->transfer.level = level;
         trans->transfer.usage = usage;
         trans->transfer.box = *box;
 
         /* If the texture is tiled, we must create a temporary detiled texture
          * for this transfer.
          * Also make write transfers pipelined. */
-        if (tex->desc.microtile || tex->desc.macrotile[sr.level] ||
+        if (tex->desc.microtile || tex->desc.macrotile[level] ||
             ((referenced_hw & !(usage & PIPE_TRANSFER_READ)) && blittable)) {
             base.target = PIPE_TEXTURE_2D;
             base.format = texture->format;
             base.width0 = box->width;
             base.height0 = box->height;
-            base.depth0 = 0;
+            /* XXX: was depth0 = 0 */
+            base.depth0 = 1;
+            base.array_size = 1;
             base.last_level = 0;
             base.nr_samples = 0;
             base.usage = PIPE_USAGE_DYNAMIC;
             base.bind = 0;
-           base.flags = R300_RESOURCE_FLAG_TRANSFER;
+            base.flags = R300_RESOURCE_FLAG_TRANSFER;
 
             /* For texture reading, the temporary (detiled) texture is used as
              * a render target when blitting from a tiled texture. */
@@ -164,7 +157,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
                 if (!trans->linear_texture) {
                     /* For linear textures, it's safe to fallback to
                      * an unpipelined transfer. */
-                    if (!tex->desc.microtile && !tex->desc.macrotile[sr.level]) {
+                    if (!tex->desc.microtile && !tex->desc.macrotile[level]) {
                         goto unpipelined;
                     }
 
@@ -182,7 +175,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
             /* Set the stride.
             *
             * Even though we are using an internal texture for this,
-            * the transfer sr, box and usage parameters still reflect
+            * the transfer level, box and usage parameters still reflect
             * the arguments received to get_transfer.  We just do the
             * right thing internally.
             */
@@ -202,9 +195,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
 
     unpipelined:
         /* Unpipelined transfer. */
-        trans->transfer.stride = tex->desc.stride_in_bytes[sr.level];
-        trans->offset = r300_texture_get_offset(&tex->desc,
-                                                sr.level, box->z, sr.face);
+        trans->transfer.stride = tex->desc.stride_in_bytes[level];
+        trans->offset = r300_texture_get_offset(&tex->desc, level, box->z);
 
         if (referenced_cs)
             ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
index 0d32a68d1fa2bec851b147b0756bfe59ffdbb89b..7977ef516f2181b380ca9d938428ad0d787e340c 100644 (file)
@@ -30,22 +30,22 @@ struct r300_context;
 
 struct pipe_transfer*
 r300_texture_get_transfer(struct pipe_context *ctx,
-                         struct pipe_resource *texture,
-                         struct pipe_subresource sr,
-                         unsigned usage,
-                         const struct pipe_box *box);
+                          struct pipe_resource *texture,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box);
 
 void
 r300_texture_transfer_destroy(struct pipe_context *ctx,
-                             struct pipe_transfer *trans);
+                              struct pipe_transfer *trans);
 
 void*
 r300_texture_transfer_map(struct pipe_context *ctx,
-                         struct pipe_transfer *transfer);
+                          struct pipe_transfer *transfer);
 
 void
 r300_texture_transfer_unmap(struct pipe_context *ctx,
-                           struct pipe_transfer *transfer);
+                            struct pipe_transfer *transfer);
 
 
 #endif
index 65696555ac3e9b8cec9404a7955eedeaf35256af..78021e2c5d4667ca544897847baba2fa6effbb13 100644 (file)
@@ -213,7 +213,6 @@ void r300_translate_vertex_shader(struct r300_context *r300,
     compiler.Base.max_temp_regs = 32;
     compiler.Base.max_constants = 256;
     compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256;
-    compiler.Base.remove_unused_constants = TRUE;
 
     if (compiler.Base.Debug & RC_DBG_LOG) {
         DBG(r300, DBG_VP, "r300: Initial vertex program\n");
@@ -227,6 +226,10 @@ void r300_translate_vertex_shader(struct r300_context *r300,
 
     r300_tgsi_to_rc(&ttr, vs->state.tokens);
 
+    if (compiler.Base.Program.Constants.Count > 200) {
+        compiler.Base.remove_unused_constants = TRUE;
+    }
+
     compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
     compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
 
index 4597332399a2321313b8084a2bf0249b026b9009..0dd330d101fde22d645da2302fea62d935267ffc 100644 (file)
 
 #include "r300_defines.h"
 
+#define R300_MAX_CMDBUF_DWORDS (16 * 1024)
+
 struct winsys_handle;
 struct r300_winsys_screen;
 
-struct r300_winsys_buffer;
+struct r300_winsys_buffer;      /* for map/unmap etc. */
+struct r300_winsys_cs_buffer;   /* for write_reloc etc. */
 
 struct r300_winsys_cs {
-    uint32_t *ptr;      /* Pointer to the beginning of the CS. */
     unsigned cdw;       /* Number of used dwords. */
-    unsigned ndw;       /* Size of the CS in dwords. */
+    uint32_t *buf;      /* The command buffer. */
 };
 
 enum r300_value_id {
@@ -102,6 +104,10 @@ struct r300_winsys_screen {
                                                 unsigned usage,
                                                 enum r300_buffer_domain domain);
 
+    struct r300_winsys_cs_buffer *(*buffer_get_cs_handle)(
+            struct r300_winsys_screen *ws,
+            struct r300_winsys_buffer *buf);
+
     /**
      * Reference a buffer object (assign with reference counting).
      *
@@ -242,7 +248,7 @@ struct r300_winsys_screen {
      *                  of the R300_DOMAIN_* flags.
      */
     void (*cs_add_buffer)(struct r300_winsys_cs *cs,
-                          struct r300_winsys_buffer *buf,
+                          struct r300_winsys_cs_buffer *buf,
                           enum r300_buffer_domain rd,
                           enum r300_buffer_domain wd);
 
@@ -263,7 +269,7 @@ struct r300_winsys_screen {
      * \param wd        A write domain containing a bitmask of the R300_DOMAIN_* flags.
      */
     void (*cs_write_reloc)(struct r300_winsys_cs *cs,
-                           struct r300_winsys_buffer *buf,
+                           struct r300_winsys_cs_buffer *buf,
                            enum r300_buffer_domain rd,
                            enum r300_buffer_domain wd);
 
@@ -303,7 +309,7 @@ struct r300_winsys_screen {
      * \param domain    A bitmask of the R300_REF_* enums.
      */
     boolean (*cs_is_buffer_referenced)(struct r300_winsys_cs *cs,
-                                       struct r300_winsys_buffer *buf,
+                                       struct r300_winsys_cs_buffer *buf,
                                        enum r300_reference_domain domain);
 };
 
index 436de9c4dbde0d46318a59d81402e5f8f804e44d..a690b671e4965b243ec63c11f00a1f1b6c30de14 100644 (file)
@@ -22,6 +22,7 @@ C_SOURCES = \
        evergreen_state.c \
        eg_asm.c \
        r600_translate.c \
-       r600_state_common.c
+       r600_state_common.c \
+       r600_upload.c
 
 include ../../Makefile.template
index 3fc1fa94c27a00730cf0736dd152990e50ef22b9..64980140963a65ad1ab2415b1cd80b633a92eaa2 100644 (file)
@@ -28,6 +28,7 @@ r600 = env.ConvenienceLibrary(
         'r600_state_common.c',
         'r600_texture.c',
         'r600_translate.c',
+        'r600_upload.c',
         'r700_asm.c',
         'evergreen_state.c',
         'eg_asm.c',
index 21d66fa9564e79097c43b6f45f45a802ef35d700..b79875c7c7580eeea593968c96eab577582759c6 100644 (file)
@@ -27,6 +27,7 @@
 #include "r600_asm.h"
 #include "eg_sq.h"
 #include "r600_opcodes.h"
+#include "evergreend.h"
 
 int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
 {
@@ -89,3 +90,37 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
        }
        return 0;
 }
+
+void eg_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count)
+{
+       struct r600_pipe_state *rstate;
+       unsigned i = 0;
+
+       if (count > 8) {
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+                               S_SQ_CF_WORD1_BARRIER(1) |
+                               S_SQ_CF_WORD1_COUNT(8 - 1);
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(40 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+                               S_SQ_CF_WORD1_BARRIER(1) |
+                               S_SQ_CF_WORD1_COUNT(count - 8 - 1);
+       } else {
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+                               S_SQ_CF_WORD1_BARRIER(1) |
+                               S_SQ_CF_WORD1_COUNT(count - 1);
+       }
+       bytecode[i++] = S_SQ_CF_WORD0_ADDR(0);
+       bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN) |
+                       S_SQ_CF_WORD1_BARRIER(1);
+
+       rstate = &ve->rstate;
+       rstate->id = R600_PIPE_STATE_FETCH_SHADER;
+       rstate->nregs = 0;
+       r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS,
+                               0x00000000, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS,
+                               (r600_bo_offset(ve->fetch_shader)) >> 8,
+                               0xFFFFFFFF, ve->fetch_shader);
+}
index 698299ec1343bd4f8e739609c2035eb6abb31ba3..ecea1db4f159c70e102cf6924ba2075a7d275410 100644 (file)
@@ -290,6 +290,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
        switch (format) {
                /* 8-bit buffers. */
        case PIPE_FORMAT_A8_UNORM:
+               return V_028C70_SWAP_ALT_REV;
        case PIPE_FORMAT_I8_UNORM:
        case PIPE_FORMAT_L8_UNORM:
        case PIPE_FORMAT_R8_UNORM:
@@ -312,6 +313,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
                return V_028C70_SWAP_STD;
 
        case PIPE_FORMAT_L8A8_UNORM:
+               return V_028C70_SWAP_ALT;
        case PIPE_FORMAT_R8G8_UNORM:
                return V_028C70_SWAP_STD;
 
index 26dad7b65c07ccfaa5ee36c690262c59071425df..a9d4a862c32f238d8592da3f9771a396db7119b5 100644 (file)
@@ -410,9 +410,9 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4,
                                word4 | S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_NORM) |
                                S_030010_SRF_MODE_ALL(V_030010_SFR_MODE_NO_ZERO) |
-                               S_030010_BASE_LEVEL(state->first_level), 0xFFFFFFFF, NULL);
+                               S_030010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5,
-                               S_030014_LAST_LEVEL(state->last_level) |
+                               S_030014_LAST_LEVEL(state->u.tex.last_level) |
                                S_030014_BASE_ARRAY(0) |
                                S_030014_LAST_ARRAY(0), 0xffffffff, NULL);
        r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, 0x0, 0xFFFFFFFF, NULL);
@@ -633,10 +633,11 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        struct r600_resource_texture *rtex;
        struct r600_resource *rbuffer;
        struct r600_surface *surf;
-       unsigned level = state->cbufs[cb]->level;
+       unsigned level = state->cbufs[cb]->u.tex.level;
        unsigned pitch, slice;
        unsigned color_info;
        unsigned format, swap, ntype;
+       unsigned offset;
        const struct util_format_description *desc;
        struct r600_bo *bo[3];
 
@@ -647,6 +648,9 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        bo[1] = rbuffer->bo;
        bo[2] = rbuffer->bo;
 
+       /* XXX quite sure for dx10+ hw don't need any offset hacks */
+       offset = r600_texture_get_offset((struct r600_resource_texture *)state->cbufs[cb]->texture,
+                                        level, state->cbufs[cb]->u.tex.first_layer);
        pitch = rtex->pitch_in_pixels[level] / 8 - 1;
        slice = rtex->pitch_in_pixels[level] * surf->aligned_height / 64 - 1;
        ntype = 0;
@@ -666,7 +670,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        /* FIXME handle enabling of CB beyond BASE8 which has different offset */
        r600_pipe_state_add_reg(rstate,
                                R_028C60_CB_COLOR0_BASE + cb * 0x3C,
-                               (state->cbufs[cb]->offset +  r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
+                               (offset +  r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
        r600_pipe_state_add_reg(rstate,
                                R_028C78_CB_COLOR0_DIM + cb * 0x3C,
                                0x0, 0xFFFFFFFF, NULL);
@@ -698,11 +702,12 @@ static void evergreen_db(struct r600_pipe_context *rctx, struct r600_pipe_state
        struct r600_surface *surf;
        unsigned level;
        unsigned pitch, slice, format, stencil_format;
+       unsigned offset;
 
        if (state->zsbuf == NULL)
                return;
 
-       level = state->zsbuf->level;
+       level = state->zsbuf->u.tex.level;
 
        surf = (struct r600_surface *)state->zsbuf;
        rtex = (struct r600_resource_texture*)state->zsbuf->texture;
@@ -712,24 +717,27 @@ static void evergreen_db(struct r600_pipe_context *rctx, struct r600_pipe_state
        rtex->depth = 1;
        rbuffer = &rtex->resource;
 
+       /* XXX quite sure for dx10+ hw don't need any offset hacks */
+       offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
+                                        level, state->zsbuf->u.tex.first_layer);
        pitch = rtex->pitch_in_pixels[level] / 8 - 1;
        slice = rtex->pitch_in_pixels[level] * surf->aligned_height / 64 - 1;
        format = r600_translate_dbformat(state->zsbuf->texture->format);
        stencil_format = r600_translate_stencilformat(state->zsbuf->texture->format);
 
        r600_pipe_state_add_reg(rstate, R_028048_DB_Z_READ_BASE,
-                               (state->zsbuf->offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
+                               (offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
        r600_pipe_state_add_reg(rstate, R_028050_DB_Z_WRITE_BASE,
-                               (state->zsbuf->offset  + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
+                               (offset  + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
 
        if (stencil_format) {
                uint32_t stencil_offset;
 
                stencil_offset = ((surf->aligned_height * rtex->pitch_in_bytes[level]) + 255) & ~255;
                r600_pipe_state_add_reg(rstate, R_02804C_DB_STENCIL_READ_BASE,
-                                       (state->zsbuf->offset + stencil_offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
+                                       (offset + stencil_offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
                r600_pipe_state_add_reg(rstate, R_028054_DB_STENCIL_WRITE_BASE,
-                                       (state->zsbuf->offset + stencil_offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
+                                       (offset + stencil_offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
        }
 
        r600_pipe_state_add_reg(rstate, R_028008_DB_DEPTH_VIEW, 0x00000000, 0xFFFFFFFF, NULL);
@@ -825,6 +833,10 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        free(rctx->states[R600_PIPE_STATE_FRAMEBUFFER]);
        rctx->states[R600_PIPE_STATE_FRAMEBUFFER] = rstate;
        r600_context_pipe_state_set(&rctx->ctx, rstate);
+
+       if (state->zsbuf) {
+               evergreen_polygon_offset_update(rctx);
+       }
 }
 
 static void evergreen_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
@@ -1036,11 +1048,33 @@ void evergreen_init_config(struct r600_pipe_context *rctx)
                num_hs_stack_entries = 85;
                num_ls_stack_entries = 85;
                break;
+       case CHIP_PALM:
+               num_ps_gprs = 93;
+               num_vs_gprs = 46;
+               num_temp_gprs = 4;
+               num_gs_gprs = 31;
+               num_es_gprs = 31;
+               num_hs_gprs = 23;
+               num_ls_gprs = 23;
+               num_ps_threads = 96;
+               num_vs_threads = 16;
+               num_gs_threads = 16;
+               num_es_threads = 16;
+               num_hs_threads = 16;
+               num_ls_threads = 16;
+               num_ps_stack_entries = 42;
+               num_vs_stack_entries = 42;
+               num_gs_stack_entries = 42;
+               num_es_stack_entries = 42;
+               num_hs_stack_entries = 42;
+               num_ls_stack_entries = 42;
+               break;
        }
 
        tmp = 0x00000000;
        switch (family) {
        case CHIP_CEDAR:
+       case CHIP_PALM:
                break;
        default:
                tmp |= S_008C00_VC_ENABLE(1);
@@ -1172,29 +1206,106 @@ void evergreen_init_config(struct r600_pipe_context *rctx)
        r600_pipe_state_add_reg(rstate, R_0283F8_SQ_VTX_SEMANTIC_30, 0x0, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_0283FC_SQ_VTX_SEMANTIC_31, 0x0, 0xFFFFFFFF, NULL);
 
-r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL,
-                       0x0, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, 0x0, 0xFFFFFFFF, NULL);
 
        r600_context_pipe_state_set(&rctx->ctx, rstate);
 }
 
-int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
-void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
+void evergreen_polygon_offset_update(struct r600_pipe_context *rctx)
+{
+       struct r600_pipe_state state;
+
+       state.id = R600_PIPE_STATE_POLYGON_OFFSET;
+       state.nregs = 0;
+       if (rctx->rasterizer && rctx->framebuffer.zsbuf) {
+               float offset_units = rctx->rasterizer->offset_units;
+               unsigned offset_db_fmt_cntl = 0, depth;
+
+               switch (rctx->framebuffer.zsbuf->texture->format) {
+               case PIPE_FORMAT_Z24X8_UNORM:
+               case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+                       depth = -24;
+                       offset_units *= 2.0f;
+                       break;
+               case PIPE_FORMAT_Z32_FLOAT:
+                       depth = -23;
+                       offset_units *= 1.0f;
+                       offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
+                       break;
+               case PIPE_FORMAT_Z16_UNORM:
+                       depth = -16;
+                       offset_units *= 4.0f;
+                       break;
+               default:
+                       return;
+               }
+               /* FIXME some of those reg can be computed with cso */
+               offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
+               r600_pipe_state_add_reg(&state,
+                               R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE,
+                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET,
+                               fui(offset_units), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE,
+                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET,
+                               fui(offset_units), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
+                               offset_db_fmt_cntl, 0xFFFFFFFF, NULL);
+               r600_context_pipe_state_set(&rctx->ctx, &state);
+       }
+}
+
+static void evergreen_spi_update(struct r600_pipe_context *rctx)
+{
+       struct r600_pipe_shader *shader = rctx->ps_shader;
+       struct r600_pipe_state rstate;
+       struct r600_shader *rshader = &shader->shader;
+       unsigned i, tmp;
+
+       rstate.nregs = 0;
+       for (i = 0; i < rshader->ninput; i++) {
+               tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
+               if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+                               rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
+                               rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
+                       tmp |= S_028644_FLAT_SHADE(rctx->flatshade);
+               }
+               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+                       rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
+                       tmp |= S_028644_PT_SPRITE_TEX(1);
+               }
+               r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
+       }
+       r600_context_pipe_state_set(&rctx->ctx, &rstate);
+}
+
+void evergreen_vertex_buffer_update(struct r600_pipe_context *rctx)
 {
-       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_pipe_state *rstate;
        struct r600_resource *rbuffer;
-       unsigned i, j, offset, prim;
-       u32 vgt_dma_index_type, vgt_draw_initiator, mask;
        struct pipe_vertex_buffer *vertex_buffer;
-       struct r600_draw rdraw;
-       struct r600_pipe_state vgt;
-       struct r600_drawl draw;
-       boolean translate = FALSE;
+       unsigned i, offset;
+
+       /* we don't update until we know vertex elements */
+       if (rctx->vertex_elements == NULL || !rctx->nvertex_buffer)
+               return;
+
+       /* delete previous translated vertex elements */
+       if (rctx->tran.new_velems) {
+               r600_end_vertex_translate(rctx);
+       }
 
        if (rctx->vertex_elements->incompatible_layout) {
+               /* translate rebind new vertex elements so
+                * return once translated
+                */
                r600_begin_vertex_translate(rctx);
-               translate = TRUE;
+               return;
        }
 
        if (rctx->any_user_vbs) {
@@ -1202,6 +1313,72 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
                rctx->any_user_vbs = FALSE;
        }
 
+       if (rctx->vertex_elements->vbuffer_need_offset) {
+               /* one resource per vertex elements */
+               rctx->nvs_resource = rctx->vertex_elements->count;
+       } else {
+               /* bind vertex buffer once */
+               rctx->nvs_resource = rctx->nvertex_buffer;
+       }
+
+       for (i = 0 ; i < rctx->nvs_resource; i++) {
+               rstate = &rctx->vs_resource[i];
+               rstate->id = R600_PIPE_STATE_RESOURCE;
+               rstate->nregs = 0;
+
+               if (rctx->vertex_elements->vbuffer_need_offset) {
+                       /* one resource per vertex elements */
+                       unsigned vbuffer_index;
+                       vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index;
+                       vertex_buffer = &rctx->vertex_buffer[vbuffer_index];
+                       rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+                       offset = rctx->vertex_elements->vbuffer_offset[i] +
+                               vertex_buffer->buffer_offset +
+                               r600_bo_offset(rbuffer->bo);
+               } else {
+                       /* bind vertex buffer once */
+                       vertex_buffer = &rctx->vertex_buffer[i];
+                       rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+                       offset = vertex_buffer->buffer_offset +
+                               r600_bo_offset(rbuffer->bo);
+               }
+
+               r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
+                                       offset, 0xFFFFFFFF, rbuffer->bo);
+               r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
+                                       rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
+                                       S_030008_STRIDE(vertex_buffer->stride),
+                                       0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3,
+                                       S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
+                                       S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) |
+                                       S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) |
+                                       S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W),
+                                       0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7,
+                                       0xC0000000, 0xFFFFFFFF, NULL);
+               evergreen_fs_resource_set(&rctx->ctx, rstate, i);
+       }
+}
+
+int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
+void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
+{
+       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+       struct r600_resource *rbuffer;
+       u32 vgt_dma_index_type, vgt_draw_initiator, mask;
+       struct r600_draw rdraw;
+       struct r600_pipe_state vgt;
+       struct r600_drawl draw;
+       unsigned prim;
+
        memset(&draw, 0, sizeof(struct r600_drawl));
        draw.ctx = ctx;
        draw.mode = info->mode;
@@ -1250,47 +1427,22 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
        }
        if (r600_conv_pipe_prim(draw.mode, &prim))
                return;
-
-       /* rebuild vertex shader if input format changed */
-       if (r600_pipe_shader_update(&rctx->context, rctx->vs_shader))
+       if (unlikely(rctx->ps_shader == NULL)) {
+               R600_ERR("missing vertex shader\n");
                return;
-       if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader))
+       }
+       if (unlikely(rctx->vs_shader == NULL)) {
+               R600_ERR("missing vertex shader\n");
                return;
-
-       for (i = 0 ; i < rctx->vertex_elements->count; i++) {
-               uint32_t word3, word2;
-               uint32_t format;
-               rstate = &rctx->vs_resource[i];
-
-               rstate->id = R600_PIPE_STATE_RESOURCE;
-               rstate->nregs = 0;
-
-               j = rctx->vertex_elements->elements[i].vertex_buffer_index;
-               vertex_buffer = &rctx->vertex_buffer[j];
-               rbuffer = (struct r600_resource*)vertex_buffer->buffer;
-               offset = rctx->vertex_elements->elements[i].src_offset +
-                       vertex_buffer->buffer_offset +
-                       r600_bo_offset(rbuffer->bo);
-
-               format = r600_translate_vertex_data_type(rctx->vertex_elements->hw_format[i]);
-
-               word2 = format | S_030008_STRIDE(vertex_buffer->stride);
-
-               word3 = S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
-                       S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) |
-                       S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) |
-                       S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W);
-
-               r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo);
-               r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, rbuffer->size - offset - 1, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, word2, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, word3, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4, 0x00000000, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, 0x00000000, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, 0x00000000, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, 0xC0000000, 0xFFFFFFFF, NULL);
-               evergreen_fs_resource_set(&rctx->ctx, rstate, i);
        }
+       /* there should be enough input */
+       if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) {
+               R600_ERR("%d resources provided, expecting %d\n",
+                       rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource);
+               return;
+       }
+
+       evergreen_spi_update(rctx);
 
        mask = 0;
        for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
@@ -1306,46 +1458,6 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
        r600_pipe_state_add_reg(&vgt, R_028404_VGT_MIN_VTX_INDX, draw.min_index, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(&vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(&vgt, R_03CFF4_SQ_VTX_START_INST_LOC, 0, 0xFFFFFFFF, NULL);
-
-       if (rctx->rasterizer && rctx->framebuffer.zsbuf) {
-               float offset_units = rctx->rasterizer->offset_units;
-               unsigned offset_db_fmt_cntl = 0, depth;
-
-               switch (rctx->framebuffer.zsbuf->texture->format) {
-               case PIPE_FORMAT_Z24X8_UNORM:
-               case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-                       depth = -24;
-                       offset_units *= 2.0f;
-                       break;
-               case PIPE_FORMAT_Z32_FLOAT:
-                       depth = -23;
-                       offset_units *= 1.0f;
-                       offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
-                       break;
-               case PIPE_FORMAT_Z16_UNORM:
-                       depth = -16;
-                       offset_units *= 4.0f;
-                       break;
-               default:
-                       return;
-               }
-               offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE,
-                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET,
-                               fui(offset_units), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE,
-                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET,
-                               fui(offset_units), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
-                               offset_db_fmt_cntl, 0xFFFFFFFF, NULL);
-       }
        r600_context_pipe_state_set(&rctx->ctx, &vgt);
 
        rdraw.vgt_num_indices = draw.count;
@@ -1360,28 +1472,22 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
        }
        evergreen_context_draw(&rctx->ctx, &rdraw);
 
-       if (translate)
-               r600_end_vertex_translate(rctx);
-
        pipe_resource_reference(&draw.index_buffer, NULL);
 }
 
 void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader)
 {
-       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_pipe_state *rstate = &shader->rstate;
        struct r600_shader *rshader = &shader->shader;
-       unsigned i, tmp, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
+       unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
        int pos_index = -1, face_index = -1;
        int ninterp = 0;
        boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
        unsigned spi_baryc_cntl;
 
-       /* clear previous register */
        rstate->nregs = 0;
 
        for (i = 0; i < rshader->ninput; i++) {
-               tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
                /* evergreen NUM_INTERP only contains values interpolated into the LDS,
                   POSITION goes via GPRs from the SC so isn't counted */
                if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
@@ -1399,16 +1505,6 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
                        if (rshader->input[i].centroid)
                                have_centroid = TRUE;
                }
-               if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
-                   rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
-                   rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
-                       tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
-               }
-               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
-                       rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
-                       tmp |= S_028644_PT_SPRITE_TEX(1);
-               }
-               r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
        }
        for (i = 0; i < rshader->noutput; i++) {
                if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
@@ -1546,15 +1642,9 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
        r600_pipe_state_add_reg(rstate,
                                R_028864_SQ_PGM_RESOURCES_2_VS,
                                0x0, 0xFFFFFFFF, NULL);
-       r600_pipe_state_add_reg(rstate,
-                       R_0288A8_SQ_PGM_RESOURCES_FS,
-                       0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                        R_02885C_SQ_PGM_START_VS,
                        (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo);
-       r600_pipe_state_add_reg(rstate,
-                       R_0288A4_SQ_PGM_START_FS,
-                       (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo_fetch);
 
        r600_pipe_state_add_reg(rstate,
                                R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,
index a337916c0981de887225d8f1d17349f4e131f59d..e67254b2560bdc9177216ac58592fecc6d3f8ed4 100644 (file)
 
 #define EVENT_TYPE_ZPASS_DONE                  0x15
 #define EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT   0x16
+#define                EVENT_TYPE(x)                           ((x) << 0)
+#define                EVENT_INDEX(x)                          ((x) << 8)
+                /* 0 - any non-TS event
+                * 1 - ZPASS_DONE
+                * 2 - SAMPLE_PIPELINESTAT
+                * 3 - SAMPLE_STREAMOUTSTAT*
+                * 4 - *S_PARTIAL_FLUSH
+                * 5 - TS events
+                */
 
 #define R600_TEXEL_PITCH_ALIGNMENT_MASK        0x7
 
index a617a5b8631b5e6fbba449d0b5d3f1ce62a2da3d..aa456d493f7b098bd2f77e4da29d002e5b46347c 100644 (file)
@@ -91,6 +91,7 @@ enum radeon_family {
        CHIP_JUNIPER,
        CHIP_CYPRESS,
        CHIP_HEMLOCK,
+       CHIP_PALM,
        CHIP_LAST,
 };
 
@@ -293,4 +294,6 @@ void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, stru
 void evergreen_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id);
 void evergreen_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id);
 
+struct radeon *radeon_decref(struct radeon *radeon);
+
 #endif
index ba1471eb78586bb5d60e2b1555cddc13eb8d8ee6..1f41269534a381cb496c8c5a67b36e594bfb559f 100644 (file)
  */
 #include <stdio.h>
 #include <errno.h>
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "pipe/p_shader_tokens.h"
 #include "r600_pipe.h"
 #include "r600_sq.h"
 #include "r600_opcodes.h"
 #include "r600_asm.h"
+#include "r600_formats.h"
+#include "r600d.h"
 
 static inline unsigned int r600_bc_get_num_operands(struct r600_bc_alu *alu)
 {
@@ -151,6 +154,7 @@ int r600_bc_init(struct r600_bc *bc, enum radeon_family family)
        case CHIP_JUNIPER:
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
+       case CHIP_PALM:
                bc->chiprev = CHIPREV_EVERGREEN;
                break;
        default:
@@ -946,3 +950,342 @@ void r600_bc_clear(struct r600_bc *bc)
 
        LIST_INITHEAD(&cf->list);
 }
+
+void r600_bc_dump(struct r600_bc *bc)
+{
+       unsigned i;
+       char chip = '6';
+
+       switch (bc->chiprev) {
+       case 1:
+               chip = '7';
+               break;
+       case 2:
+               chip = 'E';
+               break;
+       case 0:
+       default:
+               chip = '6';
+               break;
+       }
+       fprintf(stderr, "bytecode %d dw -----------------------\n", bc->ndw);
+       fprintf(stderr, "     %c\n", chip);
+       for (i = 0; i < bc->ndw; i++) {
+               fprintf(stderr, "0x%08X\n", bc->bytecode[i]);
+       }
+       fprintf(stderr, "--------------------------------------\n");
+}
+
+void r600_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count)
+{
+       struct r600_pipe_state *rstate;
+       unsigned i = 0;
+
+       if (count > 8) {
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+                                               S_SQ_CF_WORD1_BARRIER(1) |
+                                               S_SQ_CF_WORD1_COUNT(8 - 1);
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(40 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+                                               S_SQ_CF_WORD1_BARRIER(1) |
+                                               S_SQ_CF_WORD1_COUNT(count - 8 - 1);
+       } else {
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+                                               S_SQ_CF_WORD1_BARRIER(1) |
+                                               S_SQ_CF_WORD1_COUNT(count - 1);
+       }
+       bytecode[i++] = S_SQ_CF_WORD0_ADDR(0);
+       bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_RETURN) |
+                       S_SQ_CF_WORD1_BARRIER(1);
+
+       rstate = &ve->rstate;
+       rstate->id = R600_PIPE_STATE_FETCH_SHADER;
+       rstate->nregs = 0;
+       r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_RESOURCES_FS,
+                               0x00000000, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_0288DC_SQ_PGM_CF_OFFSET_FS,
+                               0x00000000, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS,
+                               r600_bo_offset(ve->fetch_shader) >> 8,
+                               0xFFFFFFFF, ve->fetch_shader);
+}
+
+void r600_cf_vtx_tc(struct r600_vertex_element *ve, u32 *bytecode, unsigned count)
+{
+       struct r600_pipe_state *rstate;
+       unsigned i = 0;
+
+       if (count > 8) {
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC) |
+                                               S_SQ_CF_WORD1_BARRIER(1) |
+                                               S_SQ_CF_WORD1_COUNT(8 - 1);
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(40 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC) |
+                                               S_SQ_CF_WORD1_BARRIER(1) |
+                                               S_SQ_CF_WORD1_COUNT((count - 8) - 1);
+       } else {
+               bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1);
+               bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC) |
+                                               S_SQ_CF_WORD1_BARRIER(1) |
+                                               S_SQ_CF_WORD1_COUNT(count - 1);
+       }
+       bytecode[i++] = S_SQ_CF_WORD0_ADDR(0);
+       bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_RETURN) |
+                       S_SQ_CF_WORD1_BARRIER(1);
+
+       rstate = &ve->rstate;
+       rstate->id = R600_PIPE_STATE_FETCH_SHADER;
+       rstate->nregs = 0;
+       r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_RESOURCES_FS,
+                               0x00000000, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_0288DC_SQ_PGM_CF_OFFSET_FS,
+                               0x00000000, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS,
+                               r600_bo_offset(ve->fetch_shader) >> 8,
+                               0xFFFFFFFF, ve->fetch_shader);
+}
+
+static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
+                               unsigned *num_format, unsigned *format_comp)
+{
+       const struct util_format_description *desc;
+       unsigned i;
+
+       *format = 0;
+       *num_format = 0;
+       *format_comp = 0;
+
+       desc = util_format_description(pformat);
+       if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
+               goto out_unknown;
+       }
+
+       /* Find the first non-VOID channel. */
+       for (i = 0; i < 4; i++) {
+               if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+                       break;
+               }
+       }
+
+       switch (desc->channel[i].type) {
+               /* Half-floats, floats, doubles */
+       case UTIL_FORMAT_TYPE_FLOAT:
+               switch (desc->channel[i].size) {
+               case 16:
+                       switch (desc->nr_channels) {
+                       case 1:
+                               *format = FMT_16_FLOAT;
+                               break;
+                       case 2:
+                               *format = FMT_16_16_FLOAT;
+                               break;
+                       case 3:
+                               *format = FMT_16_16_16_FLOAT;
+                               break;
+                       case 4:
+                               *format = FMT_16_16_16_16_FLOAT;
+                               break;
+                       }
+                       break;
+               case 32:
+                       switch (desc->nr_channels) {
+                       case 1:
+                               *format = FMT_32_FLOAT;
+                               break;
+                       case 2:
+                               *format = FMT_32_32_FLOAT;
+                               break;
+                       case 3:
+                               *format = FMT_32_32_32_FLOAT;
+                               break;
+                       case 4:
+                               *format = FMT_32_32_32_32_FLOAT;
+                               break;
+                       }
+                       break;
+               default:
+                       goto out_unknown;
+               }
+               break;
+               /* Unsigned ints */
+       case UTIL_FORMAT_TYPE_UNSIGNED:
+               /* Signed ints */
+       case UTIL_FORMAT_TYPE_SIGNED:
+               switch (desc->channel[i].size) {
+               case 8:
+                       switch (desc->nr_channels) {
+                       case 1:
+                               *format = FMT_8;
+                               break;
+                       case 2:
+                               *format = FMT_8_8;
+                               break;
+                       case 3:
+                       //      *format = FMT_8_8_8; /* fails piglit draw-vertices test */
+                       //      break;
+                       case 4:
+                               *format = FMT_8_8_8_8;
+                               break;
+                       }
+                       break;
+               case 16:
+                       switch (desc->nr_channels) {
+                       case 1:
+                               *format = FMT_16;
+                               break;
+                       case 2:
+                               *format = FMT_16_16;
+                               break;
+                       case 3:
+                       //      *format = FMT_16_16_16; /* fails piglit draw-vertices test */
+                       //      break;
+                       case 4:
+                               *format = FMT_16_16_16_16;
+                               break;
+                       }
+                       break;
+               case 32:
+                       switch (desc->nr_channels) {
+                       case 1:
+                               *format = FMT_32;
+                               break;
+                       case 2:
+                               *format = FMT_32_32;
+                               break;
+                       case 3:
+                               *format = FMT_32_32_32;
+                               break;
+                       case 4:
+                               *format = FMT_32_32_32_32;
+                               break;
+                       }
+                       break;
+               default:
+                       goto out_unknown;
+               }
+               break;
+       default:
+               goto out_unknown;
+       }
+
+       if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
+               *format_comp = 1;
+       }
+       if (desc->channel[i].normalized) {
+               *num_format = 0;
+       } else {
+               *num_format = 2;
+       }
+       return;
+out_unknown:
+       R600_ERR("unsupported vertex format %s\n", util_format_name(pformat));
+}
+
+static void r600_bc(unsigned ndw, unsigned chiprev, u32 *bytecode)
+{
+       unsigned i;
+       char chip = '6';
+
+       switch (chiprev) {
+       case 1:
+               chip = '7';
+               break;
+       case 2:
+               chip = 'E';
+               break;
+       case 0:
+       default:
+               chip = '6';
+               break;
+       }
+       fprintf(stderr, "bytecode %d dw -----------------------\n", ndw);
+       fprintf(stderr, "    %c\n", chip);
+       for (i = 0; i < ndw; i++) {
+               fprintf(stderr, "0x%08X\n", bytecode[i]);
+       }
+       fprintf(stderr, "--------------------------------------\n");
+}
+
+int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, struct r600_vertex_element *ve)
+{
+       unsigned ndw, i;
+       u32 *bytecode;
+       unsigned fetch_resource_start = 0, format, num_format, format_comp;
+       struct pipe_vertex_element *elements = ve->elements;
+       const struct util_format_description *desc;
+
+       /* 2 dwords for cf aligned to 4 + 4 dwords per input */
+       ndw = 8 + ve->count * 4;
+       ve->fs_size = ndw * 4;
+
+       /* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */
+       ve->fetch_shader = r600_bo(rctx->radeon, ndw*4, 256, PIPE_BIND_VERTEX_BUFFER, 0);
+       if (ve->fetch_shader == NULL) {
+               return -ENOMEM;
+       }
+
+       bytecode = r600_bo_map(rctx->radeon, ve->fetch_shader, 0, NULL);
+       if (bytecode == NULL) {
+               r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL);
+               return -ENOMEM;
+       }
+
+       if (rctx->family >= CHIP_CEDAR) {
+               eg_cf_vtx(ve, &bytecode[0], (ndw - 8) / 4);
+       } else {
+               r600_cf_vtx(ve, &bytecode[0], (ndw - 8) / 4);
+               fetch_resource_start = 160;
+       }
+
+       /* vertex elements offset need special handling, if offset is bigger
+        * than what we can put in fetch instruction then we need to alterate
+        * the vertex resource offset. In such case in order to simplify code
+        * we will bound one resource per elements. It's a worst case scenario.
+        */
+       for (i = 0; i < ve->count; i++) {
+               ve->vbuffer_offset[i] = C_SQ_VTX_WORD2_OFFSET & elements[i].src_offset;
+               if (ve->vbuffer_offset[i]) {
+                       ve->vbuffer_need_offset = 1;
+               }
+       }
+
+       for (i = 0; i < ve->count; i++) {
+               unsigned vbuffer_index;
+               r600_vertex_data_type(ve->hw_format[i], &format, &num_format, &format_comp);
+               desc = util_format_description(ve->hw_format[i]);
+               if (desc == NULL) {
+                       R600_ERR("unknown format %d\n", ve->hw_format[i]);
+                       r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL);
+                       return -EINVAL;
+               }
+
+               /* see above for vbuffer_need_offset explanation */
+               vbuffer_index = elements[i].vertex_buffer_index;
+               if (ve->vbuffer_need_offset) {
+                       bytecode[8 + i * 4 + 0] = S_SQ_VTX_WORD0_BUFFER_ID(i + fetch_resource_start);
+               } else {
+                       bytecode[8 + i * 4 + 0] = S_SQ_VTX_WORD0_BUFFER_ID(vbuffer_index + fetch_resource_start);
+               }
+               bytecode[8 + i * 4 + 0] |= S_SQ_VTX_WORD0_SRC_GPR(0) |
+                                       S_SQ_VTX_WORD0_SRC_SEL_X(0) |
+                                       S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F);
+               bytecode[8 + i * 4 + 1] = S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]) |
+                                       S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]) |
+                                       S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]) |
+                                       S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]) |
+                                       S_SQ_VTX_WORD1_USE_CONST_FIELDS(0) |
+                                       S_SQ_VTX_WORD1_DATA_FORMAT(format) |
+                                       S_SQ_VTX_WORD1_NUM_FORMAT_ALL(num_format) |
+                                       S_SQ_VTX_WORD1_FORMAT_COMP_ALL(format_comp) |
+                                       S_SQ_VTX_WORD1_SRF_MODE_ALL(1) |
+                                       S_SQ_VTX_WORD1_GPR_DST_GPR(i + 1);
+               bytecode[8 + i * 4 + 2] = S_SQ_VTX_WORD2_OFFSET(elements[i].src_offset) |
+                                       S_SQ_VTX_WORD2_MEGA_FETCH(1);
+               bytecode[8 + i * 4 + 3] = 0;
+       }
+       r600_bo_unmap(rctx->radeon, ve->fetch_shader);
+       return 0;
+}
index f2016af3e7264efa1eeceb4d7caa3012cbe0357b..b147f0f5c88d47d50b056844185050a7d62e578d 100644 (file)
@@ -28,6 +28,9 @@
 #define NUM_OF_CYCLES 3
 #define NUM_OF_COMPONENTS 4
 
+struct r600_vertex_element;
+struct r600_pipe_context;
+
 struct r600_bc_alu_src {
        unsigned                        sel;
        unsigned                        chan;
@@ -188,6 +191,7 @@ struct r600_bc {
 
 /* eg_asm.c */
 int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf);
+void eg_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count);
 
 /* r600_asm.c */
 int r600_bc_init(struct r600_bc *bc, enum radeon_family family);
@@ -200,6 +204,11 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output);
 int r600_bc_build(struct r600_bc *bc);
 int r600_bc_add_cfinst(struct r600_bc *bc, int inst);
 int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int type);
+void r600_bc_dump(struct r600_bc *bc);
+void r600_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count);
+void r600_cf_vtx_tc(struct r600_vertex_element *ve, u32 *bytecode, unsigned count);
+
+int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, struct r600_vertex_element *ve);
 
 /* r700_asm.c */
 int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id);
index 74cf96879996a217a03c9e115dc937e6f75161b8..0f04136fb2a44493aa153687784077f1549578f8 100644 (file)
@@ -81,16 +81,21 @@ static void r600_blitter_end(struct pipe_context *ctx)
 int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture)
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-       struct pipe_surface *zsurf, *cbsurf;
+       struct pipe_surface *zsurf, *cbsurf, surf_tmpl;
        int level = 0;
        float depth = 1.0f;
+       surf_tmpl.format = texture->resource.base.b.format;
+       surf_tmpl.u.tex.level = level;
+       surf_tmpl.u.tex.first_layer = 0;
+       surf_tmpl.u.tex.last_layer = 0;
+       surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL;
 
-       zsurf = ctx->screen->get_tex_surface(ctx->screen, &texture->resource.base.b, 0, level, 0,
-                                            PIPE_BIND_DEPTH_STENCIL);
+       zsurf = ctx->create_surface(ctx, &texture->resource.base.b, &surf_tmpl);
 
-       cbsurf = ctx->screen->get_tex_surface(ctx->screen,
-                       (struct pipe_resource*)texture->flushed_depth_texture,
-                       0, level, 0, PIPE_BIND_RENDER_TARGET);
+       surf_tmpl.format = ((struct pipe_resource*)texture->flushed_depth_texture)->format;
+       surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+       cbsurf = ctx->create_surface(ctx,
+                       (struct pipe_resource*)texture->flushed_depth_texture, &surf_tmpl);
 
        if (rctx->family == CHIP_RV610 || rctx->family == CHIP_RV630 ||
            rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635)
@@ -154,41 +159,38 @@ static void r600_clear_depth_stencil(struct pipe_context *ctx,
 
 /* Copy a block of pixels from one surface to another using HW. */
 static void r600_hw_copy_region(struct pipe_context *ctx,
-                                struct pipe_resource *dst,
-                                struct pipe_subresource subdst,
-                                unsigned dstx, unsigned dsty, unsigned dstz,
-                                struct pipe_resource *src,
-                                struct pipe_subresource subsrc,
-                                unsigned srcx, unsigned srcy, unsigned srcz,
-                                unsigned width, unsigned height)
+                               struct 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 r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 
        r600_blitter_begin(ctx, R600_COPY);
-       util_blitter_copy_region(rctx->blitter, dst, subdst, dstx, dsty, dstz,
-                                src, subsrc, srcx, srcy, srcz, width, height,
-                                TRUE);
+       util_blitter_copy_region(rctx->blitter, dst, dst_level, dstx, dsty, dstz,
+                                src, src_level, src_box, TRUE);
        r600_blitter_end(ctx);
 }
 
 static void r600_resource_copy_region(struct pipe_context *ctx,
                                      struct pipe_resource *dst,
-                                     struct pipe_subresource subdst,
+                                     unsigned dst_level,
                                      unsigned dstx, unsigned dsty, unsigned dstz,
                                      struct pipe_resource *src,
-                                     struct pipe_subresource subsrc,
-                                     unsigned srcx, unsigned srcy, unsigned srcz,
-                                     unsigned width, unsigned height)
+                                     unsigned src_level,
+                                     const struct pipe_box *src_box)
 {
        boolean is_depth;
        /* there is something wrong with depth resource copies at the moment so avoid them for now */
        is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
        if (is_depth)
-               util_resource_copy_region(ctx, dst, subdst, dstx, dsty, dstz,
-                                         src, subsrc, srcx, srcy, srcz, width, height);
+               util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
+                                         src, src_level, src_box);
        else
-               r600_hw_copy_region(ctx, dst, subdst, dstx, dsty, dstz,
-                                   src, subsrc, srcx, srcy, srcz, width, height);
+               r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
+                                   src, src_level, src_box);
 }
 
 void r600_init_blit_functions(struct r600_pipe_context *rctx)
index a432271b82d923b5b580e7d77258d972e68ba717..7d29f760a5d798815789facf68461e56c19b7adf 100644 (file)
@@ -29,7 +29,6 @@
 #include <util/u_math.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
-#include <util/u_upload_mgr.h>
 #include "state_tracker/drm_driver.h"
 #include <xf86drm.h>
 #include "radeon_drm.h"
@@ -53,12 +52,13 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
 
        rbuffer->magic = R600_BUFFER_MAGIC;
        rbuffer->user_buffer = NULL;
-       rbuffer->num_ranges = 0;
        rbuffer->r.base.b = *templ;
        pipe_reference_init(&rbuffer->r.base.b.reference, 1);
        rbuffer->r.base.b.screen = screen;
        rbuffer->r.base.vtbl = &r600_buffer_vtbl;
        rbuffer->r.size = rbuffer->r.base.b.width0;
+       rbuffer->r.bo_size = rbuffer->r.size;
+       rbuffer->uploaded = FALSE;
        bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage);
        if (bo == NULL) {
                FREE(rbuffer);
@@ -89,10 +89,12 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
        rbuffer->r.base.b.width0 = bytes;
        rbuffer->r.base.b.height0 = 1;
        rbuffer->r.base.b.depth0 = 1;
+       rbuffer->r.base.b.array_size = 1;
        rbuffer->r.base.b.flags = 0;
-       rbuffer->num_ranges = 0;
        rbuffer->r.bo = NULL;
+       rbuffer->r.bo_size = 0;
        rbuffer->user_buffer = ptr;
+       rbuffer->uploaded = FALSE;
        return &rbuffer->r.base.b;
 }
 
@@ -101,9 +103,10 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
 {
        struct r600_resource_buffer *rbuffer = r600_buffer(buf);
 
-       if (rbuffer->r.bo) {
+       if (!rbuffer->uploaded && rbuffer->r.bo) {
                r600_bo_reference((struct radeon*)screen->winsys, &rbuffer->r.bo, NULL);
        }
+       rbuffer->r.bo = NULL;
        FREE(rbuffer);
 }
 
@@ -113,29 +116,10 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
        struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
        int write = 0;
        uint8_t *data;
-       int i;
-       boolean flush = FALSE;
 
        if (rbuffer->user_buffer)
                return (uint8_t*)rbuffer->user_buffer + transfer->box.x;
 
-       if (transfer->usage & PIPE_TRANSFER_DISCARD) {
-               for (i = 0; i < rbuffer->num_ranges; i++) {
-                       if ((transfer->box.x >= rbuffer->ranges[i].start) &&
-                           (transfer->box.x < rbuffer->ranges[i].end))
-                               flush = TRUE;
-
-                       if (flush) {
-                               r600_bo_reference((struct radeon*)pipe->winsys, &rbuffer->r.bo, NULL);
-                               rbuffer->num_ranges = 0;
-                               rbuffer->r.bo = r600_bo((struct radeon*)pipe->winsys,
-                                                        rbuffer->r.base.b.width0, 0,
-                                                        rbuffer->r.base.b.bind,
-                                                        rbuffer->r.base.b.usage);
-                               break;
-                       }
-               }
-       }
        if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
                /* FIXME */
        }
@@ -154,41 +138,22 @@ static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
 {
        struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
 
+       if (rbuffer->user_buffer)
+               return;
+
        if (rbuffer->r.bo)
                r600_bo_unmap((struct radeon*)pipe->winsys, rbuffer->r.bo);
 }
 
 static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,
-                                             struct pipe_transfer *transfer,
-                                             const struct pipe_box *box)
+                                               struct pipe_transfer *transfer,
+                                               const struct pipe_box *box)
 {
-       struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
-       unsigned i;
-       unsigned offset = transfer->box.x + box->x;
-       unsigned length = box->width;
-
-       assert(box->x + box->width <= transfer->box.width);
-
-       if (rbuffer->user_buffer)
-               return;
-
-       /* mark the range as used */
-       for(i = 0; i < rbuffer->num_ranges; ++i) {
-               if(offset <= rbuffer->ranges[i].end && rbuffer->ranges[i].start <= (offset+box->width)) {
-                       rbuffer->ranges[i].start = MIN2(rbuffer->ranges[i].start, offset);
-                       rbuffer->ranges[i].end   = MAX2(rbuffer->ranges[i].end, (offset+length));
-                       return;
-               }
-       }
-
-       rbuffer->ranges[rbuffer->num_ranges].start = offset;
-       rbuffer->ranges[rbuffer->num_ranges].end = offset+length;
-       rbuffer->num_ranges++;
 }
 
 unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
                                         struct pipe_resource *buf,
-                                        unsigned face, unsigned level)
+                                        unsigned level, int layer)
 {
        /* FIXME */
        return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
@@ -235,29 +200,25 @@ struct u_resource_vtbl r600_buffer_vtbl =
 
 int r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw)
 {
-       struct pipe_resource *upload_buffer = NULL;
-       unsigned index_offset = draw->index_buffer_offset;
-       int ret = 0;
-
        if (r600_buffer_is_user_buffer(draw->index_buffer)) {
-               ret = u_upload_buffer(rctx->upload_ib,
-                                     index_offset,
-                                     draw->count * draw->index_size,
-                                     draw->index_buffer,
-                                     &index_offset,
-                                     &upload_buffer);
-               if (ret) {
-                       goto done;
-               }
-               draw->index_buffer_offset = index_offset;
-
-               /* Transfer ownership. */
-               pipe_resource_reference(&draw->index_buffer, upload_buffer);
-               pipe_resource_reference(&upload_buffer, NULL);
+               struct r600_resource_buffer *rbuffer = r600_buffer(draw->index_buffer);
+               unsigned upload_offset;
+               int ret = 0;
+
+               ret = r600_upload_buffer(rctx->rupload_vb,
+                                       draw->index_buffer_offset,
+                                       draw->count * draw->index_size,
+                                       rbuffer,
+                                       &upload_offset,
+                                       &rbuffer->r.bo_size,
+                                       &rbuffer->r.bo);
+               if (ret)
+                       return ret;
+               rbuffer->uploaded = TRUE;
+               draw->index_buffer_offset = upload_offset;
        }
 
-done:
-       return ret;
+       return 0;
 }
 
 int r600_upload_user_buffers(struct r600_pipe_context *rctx)
@@ -266,25 +227,24 @@ int r600_upload_user_buffers(struct r600_pipe_context *rctx)
        int i, nr;
 
        nr = rctx->vertex_elements->count;
+       nr = rctx->nvertex_buffer;
 
        for (i = 0; i < nr; i++) {
-               struct pipe_vertex_buffer *vb =
-                       &rctx->vertex_buffer[rctx->vertex_elements->elements[i].vertex_buffer_index];
+               struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[i];
 
                if (r600_buffer_is_user_buffer(vb->buffer)) {
-                       struct pipe_resource *upload_buffer = NULL;
-                       unsigned offset = 0; /*vb->buffer_offset * 4;*/
-                       unsigned size = vb->buffer->width0;
+                       struct r600_resource_buffer *rbuffer = r600_buffer(vb->buffer);
                        unsigned upload_offset;
-                       ret = u_upload_buffer(rctx->upload_vb,
-                                             offset, size,
-                                             vb->buffer,
-                                             &upload_offset, &upload_buffer);
+
+                       ret = r600_upload_buffer(rctx->rupload_vb,
+                                               0, vb->buffer->width0,
+                                               rbuffer,
+                                               &upload_offset,
+                                               &rbuffer->r.bo_size,
+                                               &rbuffer->r.bo);
                        if (ret)
                                return ret;
-
-                       pipe_resource_reference(&vb->buffer, NULL);
-                       vb->buffer = upload_buffer;
+                       rbuffer->uploaded = TRUE;
                        vb->buffer_offset = upload_offset;
                }
        }
index 3bfba99dcaf073dbd9da7986c01ea477232c4d38..69cb5f7751fedfb5a09c4ca8d437233b207fca1d 100644 (file)
@@ -35,7 +35,6 @@
 #include <util/u_pack_color.h>
 #include <util/u_memory.h>
 #include <util/u_inlines.h>
-#include <util/u_upload_mgr.h>
 #include <pipebuffer/pb_buffer.h>
 #include "r600.h"
 #include "r600d.h"
@@ -60,9 +59,6 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags,
        if (!rctx->ctx.pm4_cdwords)
                return;
 
-       u_upload_flush(rctx->upload_vb);
-       u_upload_flush(rctx->upload_ib);
-
 #if 0
        sprintf(dname, "gallium-%08d.bof", dc);
        if (dc < 20) {
@@ -72,6 +68,8 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags,
        dc++;
 #endif
        r600_context_flush(&rctx->ctx);
+
+       r600_upload_flush(rctx->rupload_vb);
 }
 
 static void r600_destroy_context(struct pipe_context *context)
@@ -80,6 +78,8 @@ static void r600_destroy_context(struct pipe_context *context)
 
        rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
 
+       r600_end_vertex_translate(rctx);
+
        r600_context_fini(&rctx->ctx);
 
        util_blitter_destroy(rctx->blitter);
@@ -88,8 +88,7 @@ static void r600_destroy_context(struct pipe_context *context)
                free(rctx->states[i]);
        }
 
-       u_upload_destroy(rctx->upload_vb);
-       u_upload_destroy(rctx->upload_ib);
+       r600_upload_destroy(rctx->rupload_vb);
 
        if (rctx->tran.translate_cache)
                translate_cache_destroy(rctx->tran.translate_cache);
@@ -121,6 +120,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
        r600_init_blit_functions(rctx);
        r600_init_query_functions(rctx);
        r600_init_context_resource_functions(rctx);
+       r600_init_surface_functions(rctx);
 
        switch (r600_get_family(rctx->radeon)) {
        case CHIP_R600:
@@ -148,6 +148,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
        case CHIP_JUNIPER:
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
+       case CHIP_PALM:
                rctx->context.draw_vbo = evergreen_draw;
                evergreen_init_state_functions(rctx);
                if (evergreen_context_init(&rctx->ctx, rctx->radeon)) {
@@ -162,16 +163,8 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
                return NULL;
        }
 
-       rctx->upload_ib = u_upload_create(&rctx->context, 32 * 1024, 16,
-                                         PIPE_BIND_INDEX_BUFFER);
-       if (rctx->upload_ib == NULL) {
-               r600_destroy_context(&rctx->context);
-               return NULL;
-       }
-
-       rctx->upload_vb = u_upload_create(&rctx->context, 128 * 1024, 16,
-                                         PIPE_BIND_VERTEX_BUFFER);
-       if (rctx->upload_vb == NULL) {
+       rctx->rupload_vb = r600_upload_create(rctx, 128 * 1024, 16);
+       if (rctx->rupload_vb == NULL) {
                r600_destroy_context(&rctx->context);
                return NULL;
        }
@@ -239,6 +232,7 @@ static const char *r600_get_family_name(enum radeon_family family)
        case CHIP_JUNIPER: return "AMD JUNIPER";
        case CHIP_CYPRESS: return "AMD CYPRESS";
        case CHIP_HEMLOCK: return "AMD HEMLOCK";
+       case CHIP_PALM: return "AMD PALM";
        default: return "AMD unknown";
        }
 }
@@ -253,6 +247,9 @@ static const char* r600_get_name(struct pipe_screen* pscreen)
 
 static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 {
+       struct r600_screen *rscreen = (struct r600_screen *)pscreen;
+       enum radeon_family family = r600_get_family(rscreen->radeon);
+
        switch (param) {
        /* Supported features (boolean caps). */
        case PIPE_CAP_NPOT_TEXTURES:
@@ -285,7 +282,10 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-               return 14;
+               if (family >= CHIP_CEDAR)
+                       return 15;
+               else
+                       return 14;
        case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
                /* FIXME allow this once infrastructure is there */
                return 16;
@@ -314,12 +314,18 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 
 static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
 {
+       struct r600_screen *rscreen = (struct r600_screen *)pscreen;
+       enum radeon_family family = r600_get_family(rscreen->radeon);
+
        switch (param) {
        case PIPE_CAP_MAX_LINE_WIDTH:
        case PIPE_CAP_MAX_LINE_WIDTH_AA:
        case PIPE_CAP_MAX_POINT_WIDTH:
        case PIPE_CAP_MAX_POINT_WIDTH_AA:
-               return 8192.0f;
+               if (family >= CHIP_CEDAR)
+                       return 16384.0f;
+               else
+                       return 8192.0f;
        case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
                return 16.0f;
        case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
@@ -376,6 +382,8 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
                return 1;
+       case PIPE_SHADER_CAP_SUBROUTINES:
+               return 0;
        default:
                return 0;
        }
@@ -404,9 +412,9 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
        }
 
        if ((usage & (PIPE_BIND_RENDER_TARGET |
-                  PIPE_BIND_DISPLAY_TARGET |
-                  PIPE_BIND_SCANOUT |
-                  PIPE_BIND_SHARED)) &&
+                       PIPE_BIND_DISPLAY_TARGET |
+                       PIPE_BIND_SCANOUT |
+                       PIPE_BIND_SHARED)) &&
                        r600_is_colorbuffer_format_supported(format)) {
                retval |= usage &
                        (PIPE_BIND_RENDER_TARGET |
@@ -465,7 +473,6 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)
        rscreen->screen.is_format_supported = r600_is_format_supported;
        rscreen->screen.context_create = r600_create_context;
        rscreen->screen.video_context_create = r600_video_create;
-       r600_init_screen_texture_functions(&rscreen->screen);
        r600_init_screen_resource_functions(&rscreen->screen);
 
        rscreen->tiling_info = r600_get_tiling_info(radeon);
index ba9fedf0b6cf55fea3ce3f5d4d8c777b1203aa7b..43dbee99b0f1ca06ee44391c5443cb89bbaac661 100644 (file)
@@ -53,6 +53,8 @@ enum r600_pipe_state_id {
        R600_PIPE_STATE_CONSTANT,
        R600_PIPE_STATE_SAMPLER,
        R600_PIPE_STATE_RESOURCE,
+       R600_PIPE_STATE_POLYGON_OFFSET,
+       R600_PIPE_STATE_FETCH_SHADER,
        R600_PIPE_NSTATES
 };
 
@@ -86,7 +88,15 @@ struct r600_vertex_element
        struct pipe_vertex_element      elements[PIPE_MAX_ATTRIBS];
        enum pipe_format                hw_format[PIPE_MAX_ATTRIBS];
        unsigned                        hw_format_size[PIPE_MAX_ATTRIBS];
-       boolean incompatible_layout;
+       boolean                         incompatible_layout;
+       struct r600_bo                  *fetch_shader;
+       unsigned                        fs_size;
+       struct r600_pipe_state          rstate;
+       /* if offset is to big for fetch instructio we need to alterate
+        * offset of vertex buffer, record here the offset need to add
+        */
+       unsigned                        vbuffer_need_offset;
+       unsigned                        vbuffer_offset[PIPE_MAX_ATTRIBS];
 };
 
 struct r600_pipe_shader {
@@ -101,25 +111,28 @@ struct r600_pipe_shader {
 #define NUM_TEX_UNITS 16
 
 struct r600_textures_info {
-       struct r600_pipe_sampler_view   *views[NUM_TEX_UNITS];
-       unsigned                        n_views;
+       struct r600_pipe_sampler_view   *views[NUM_TEX_UNITS];
+       unsigned                        n_views;
        void                            *samplers[NUM_TEX_UNITS];
-       unsigned                        n_samplers;
+       unsigned                        n_samplers;
 };
 
+/* vertex buffer translation context, used to translate vertex input that
+ * hw doesn't natively support, so far only FLOAT64 is unsupported.
+ */
 struct r600_translate_context {
        /* Translate cache for incompatible vertex offset/stride/format fallback. */
-       struct translate_cache *translate_cache;
-
+       struct translate_cache          *translate_cache;
        /* The vertex buffer slot containing the translated buffer. */
-       unsigned vb_slot;
-       /* Saved and new vertex element state. */
-       void *saved_velems, *new_velems;
+       unsigned                        vb_slot;
+       void                            *new_velems;
 };
 
 #define R600_CONSTANT_ARRAY_SIZE 256
 #define R600_RESOURCE_ARRAY_SIZE 160
 
+struct r600_upload;
+
 struct r600_pipe_context {
        struct pipe_context             context;
        struct blitter_context          *blitter;
@@ -140,6 +153,7 @@ struct r600_pipe_context {
        struct pipe_stencil_ref         stencil_ref;
        struct pipe_viewport_state      viewport;
        struct pipe_clip_state          clip;
+       unsigned                        nvs_resource;
        struct r600_pipe_state          *vs_resource;
        struct r600_pipe_state          *ps_resource;
        struct r600_pipe_state          config;
@@ -151,14 +165,11 @@ struct r600_pipe_context {
        /* shader information */
        unsigned                        sprite_coord_enable;
        bool                            flatshade;
-       struct u_upload_mgr             *upload_vb;
-       struct u_upload_mgr             *upload_ib;
+       struct r600_upload              *rupload_vb;
        unsigned                        any_user_vbs;
-       struct r600_textures_info       ps_samplers;
-
-       unsigned vb_max_index;
-       struct r600_translate_context tran;
-
+       struct r600_textures_info       ps_samplers;
+       unsigned                        vb_max_index;
+       struct r600_translate_context   tran;
 };
 
 struct r600_drawl {
@@ -181,6 +192,8 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
 void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader);
 void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader);
 void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx);
+void evergreen_polygon_offset_update(struct r600_pipe_context *rctx);
+void evergreen_vertex_buffer_update(struct r600_pipe_context *rctx);
 
 /* r600_blit.c */
 void r600_init_blit_functions(struct r600_pipe_context *rctx);
@@ -194,7 +207,7 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
                                              unsigned bind);
 unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
                                         struct pipe_resource *buf,
-                                        unsigned face, unsigned level);
+                                        unsigned level, int layer);
 struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
                                              struct winsys_handle *whandle);
 int r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw);
@@ -207,7 +220,7 @@ void r600_init_query_functions(struct r600_pipe_context *rctx);
 void r600_init_context_resource_functions(struct r600_pipe_context *r600);
 
 /* r600_shader.c */
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *shader);
+int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader);
 int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens);
 void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader);
 int r600_find_vs_semantic_index(struct r600_shader *vs,
@@ -218,14 +231,20 @@ void r600_init_state_functions(struct r600_pipe_context *rctx);
 void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info);
 void r600_init_config(struct r600_pipe_context *rctx);
 void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx);
+void r600_polygon_offset_update(struct r600_pipe_context *rctx);
+void r600_vertex_buffer_update(struct r600_pipe_context *rctx);
+
 /* r600_helper.h */
 int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
 
 /* r600_texture.c */
 void r600_init_screen_texture_functions(struct pipe_screen *screen);
+void r600_init_surface_functions(struct r600_pipe_context *r600);
 uint32_t r600_translate_texformat(enum pipe_format format,
                                  const unsigned char *swizzle_view, 
                                  uint32_t *word4_p, uint32_t *yuv_format_p);
+unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
+                                       unsigned level, unsigned layer);
 
 /* r600_translate.c */
 void r600_begin_vertex_translate(struct r600_pipe_context *rctx);
@@ -252,13 +271,13 @@ void r600_sampler_view_destroy(struct pipe_context *ctx,
 void r600_bind_state(struct pipe_context *ctx, void *state);
 void r600_delete_state(struct pipe_context *ctx, void *state);
 void r600_bind_vertex_elements(struct pipe_context *ctx, void *state);
-
 void *r600_create_shader_state(struct pipe_context *ctx,
                               const struct pipe_shader_state *state);
 void r600_bind_ps_shader(struct pipe_context *ctx, void *state);
 void r600_bind_vs_shader(struct pipe_context *ctx, void *state);
 void r600_delete_ps_shader(struct pipe_context *ctx, void *state);
 void r600_delete_vs_shader(struct pipe_context *ctx, void *state);
+
 /*
  * common helpers
  */
index 7a2d1f44122e85f0557c4956b0113ee36b77fc96..8ca27699206b09dfe48bd420f21298e3eff88192 100644 (file)
@@ -46,6 +46,7 @@ struct r600_resource {
        struct u_resource               base;
        struct r600_bo                  *bo;
        u32                             size;
+       unsigned                        bo_size;
 };
 
 struct r600_resource_texture {
@@ -61,7 +62,21 @@ struct r600_resource_texture {
        unsigned                        tile_type;
        unsigned                        depth;
        unsigned                        dirty;
-       struct r600_resource_texture    *flushed_depth_texture;
+       struct r600_resource_texture    *flushed_depth_texture;
+};
+
+#define R600_BUFFER_MAGIC 0xabcd1600
+
+struct r600_resource_buffer {
+       struct r600_resource            r;
+       uint32_t                        magic;
+       void                            *user_buffer;
+       bool                            uploaded;
+};
+
+struct r600_surface {
+       struct pipe_surface             base;
+       unsigned                        aligned_height;
 };
 
 void r600_init_screen_resource_functions(struct pipe_screen *screen);
@@ -73,46 +88,30 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
                                                const struct pipe_resource *base,
                                                struct winsys_handle *whandle);
 
-#define R600_BUFFER_MAGIC 0xabcd1600
-#define R600_BUFFER_MAX_RANGES 32
-
-struct r600_buffer_range {
-       uint32_t start;
-       uint32_t end;
-};
-
-struct r600_resource_buffer {
-       struct r600_resource r;
-       uint32_t magic;
-       void *user_buffer;
-       struct r600_buffer_range ranges[R600_BUFFER_MAX_RANGES];
-       unsigned num_ranges;
-};
-
 /* r600_buffer */
 static INLINE struct r600_resource_buffer *r600_buffer(struct pipe_resource *buffer)
 {
        if (buffer) {
                assert(((struct r600_resource_buffer *)buffer)->magic == R600_BUFFER_MAGIC);
                return (struct r600_resource_buffer *)buffer;
-    }
-    return NULL;
+       }
+       return NULL;
 }
 
 static INLINE boolean r600_buffer_is_user_buffer(struct pipe_resource *buffer)
 {
-    return r600_buffer(buffer)->user_buffer ? TRUE : FALSE;
+       if (r600_buffer(buffer)->uploaded)
+               return FALSE;
+       return r600_buffer(buffer)->user_buffer ? TRUE : FALSE;
 }
 
-int r600_texture_depth_flush(struct pipe_context *ctx,
-                            struct pipe_resource *texture);
-
-extern int (*r600_blit_uncompress_depth_ptr)(struct pipe_context *ctx, struct r600_resource_texture *texture);
+int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture);
+int (*r600_blit_uncompress_depth_ptr)(struct pipe_context *ctx, struct r600_resource_texture *texture);
 
 /* r600_texture.c texture transfer functions. */
 struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                                                struct pipe_resource *texture,
-                                               struct pipe_subresource sr,
+                                               unsigned level,
                                                unsigned usage,
                                                const struct pipe_box *box);
 void r600_texture_transfer_destroy(struct pipe_context *ctx,
@@ -122,9 +121,15 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
 void r600_texture_transfer_unmap(struct pipe_context *ctx,
                                 struct pipe_transfer* transfer);
 
-struct r600_surface {
-       struct pipe_surface base;
-       unsigned aligned_height;
-};
+struct r600_pipe_context;
+struct r600_upload *r600_upload_create(struct r600_pipe_context *rctx,
+                                       unsigned default_size,
+                                       unsigned alignment);
+void r600_upload_flush(struct r600_upload *upload);
+void r600_upload_destroy(struct r600_upload *upload);
+int r600_upload_buffer(struct r600_upload *upload, unsigned offset,
+                       unsigned size, struct r600_resource_buffer *in_buffer,
+                       unsigned *out_offset, unsigned *out_size,
+                       struct r600_bo **out_buffer);
 
 #endif
index 3e42309bde0cf88abbf1600d06e619367b373435..d6455023a3af94fbc86c057bdcd80aba3d22b3db 100644 (file)
@@ -44,6 +44,9 @@ static void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shade
        rstate->nregs = 0;
 
        /* so far never got proper semantic id from tgsi */
+       /* FIXME better to move this in config things so they get emited
+        * only one time per cs
+        */
        for (i = 0; i < 10; i++) {
                spi_vs_out_id[i] = 0;
        }
@@ -66,21 +69,12 @@ static void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shade
                        S_028868_NUM_GPRS(rshader->bc.ngpr) |
                        S_028868_STACK_SIZE(rshader->bc.nstack),
                        0xFFFFFFFF, NULL);
-       r600_pipe_state_add_reg(rstate,
-                       R_0288A4_SQ_PGM_RESOURCES_FS,
-                       0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                        R_0288D0_SQ_PGM_CF_OFFSET_VS,
                        0x00000000, 0xFFFFFFFF, NULL);
-       r600_pipe_state_add_reg(rstate,
-                       R_0288DC_SQ_PGM_CF_OFFSET_FS,
-                       0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                        R_028858_SQ_PGM_START_VS,
                        r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo);
-       r600_pipe_state_add_reg(rstate,
-                       R_028894_SQ_PGM_START_FS,
-                       r600_bo_offset(shader->bo_fetch) >> 8, 0xFFFFFFFF, shader->bo_fetch);
 
        r600_pipe_state_add_reg(rstate,
                                R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,
@@ -104,37 +98,20 @@ int r600_find_vs_semantic_index(struct r600_shader *vs,
 
 static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader)
 {
-       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_pipe_state *rstate = &shader->rstate;
        struct r600_shader *rshader = &shader->shader;
-       unsigned i, tmp, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
+       unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
        int pos_index = -1, face_index = -1;
 
-       /* clear previous register */
        rstate->nregs = 0;
 
        for (i = 0; i < rshader->ninput; i++) {
-               tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
-               if (rshader->input[i].centroid)
-                       tmp |= S_028644_SEL_CENTROID(1);
-               if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
-                       tmp |= S_028644_SEL_LINEAR(1);
-
                if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
                        pos_index = i;
-               if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
-                   rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
-                   rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
-                       tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
-               }
                if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
                        face_index = i;
-               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
-                       rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
-                       tmp |= S_028644_PT_SPRITE_TEX(1);
-               }
-               r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
        }
+
        for (i = 0; i < rshader->noutput; i++) {
                if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
                        r600_pipe_state_add_reg(rstate,
@@ -210,22 +187,13 @@ static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shade
                                0xFFFFFFFF, NULL);
 }
 
-static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader)
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_shader *rshader = &shader->shader;
        void *ptr;
 
        /* copy new shader */
-       if (rshader->processor_type == TGSI_PROCESSOR_VERTEX && shader->bo_fetch == NULL) {
-               shader->bo_fetch = r600_bo(rctx->radeon, rshader->bc_fetch.ndw * 4, 4096, 0, 0);
-               if (shader->bo_fetch == NULL) {
-                       return -ENOMEM;
-               }
-               ptr = r600_bo_map(rctx->radeon, shader->bo_fetch, 0, NULL);
-               memcpy(ptr, rshader->bc_fetch.bytecode, rshader->bc_fetch.ndw * 4);
-               r600_bo_unmap(rctx->radeon, shader->bo_fetch);
-       }
        if (shader->bo == NULL) {
                shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0);
                if (shader->bo == NULL) {
@@ -236,7 +204,6 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
                r600_bo_unmap(rctx->radeon, shader->bo);
        }
        /* build state */
-       rshader->flat_shade = rctx->flatshade;
        switch (rshader->processor_type) {
        case TGSI_PROCESSOR_VERTEX:
                if (rshader->family >= CHIP_CEDAR) {
@@ -255,75 +222,9 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
        default:
                return -EINVAL;
        }
-       r600_context_pipe_state_set(&rctx->ctx, &shader->rstate);
        return 0;
 }
 
-static int r600_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rshader)
-{
-       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-       struct r600_shader *shader = &rshader->shader;
-       const struct util_format_description *desc;
-       enum pipe_format resource_format[160];
-       unsigned i, nresources = 0;
-       struct r600_bc *bc = &shader->bc_fetch;
-       struct r600_bc_cf *cf;
-       struct r600_bc_vtx *vtx;
-
-       if (shader->processor_type != TGSI_PROCESSOR_VERTEX)
-               return 0;
-       /* doing a full memcmp fell over the refcount */
-       if ((rshader->vertex_elements.count == rctx->vertex_elements->count) &&
-           (!memcmp(&rshader->vertex_elements.elements, &rctx->vertex_elements->elements, 32 * sizeof(struct pipe_vertex_element)))) {
-               return 0;
-       }
-       rshader->vertex_elements = *rctx->vertex_elements;
-       for (i = 0; i < rctx->vertex_elements->count; i++) {
-               resource_format[nresources++] = rctx->vertex_elements->hw_format[i];
-       }
-       r600_bo_reference(rctx->radeon, &rshader->bo_fetch, NULL);
-       LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
-               switch (cf->inst) {
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
-                       LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
-                               desc = util_format_description(resource_format[vtx->buffer_id]);
-                               if (desc == NULL) {
-                                       R600_ERR("unknown format %d\n", resource_format[vtx->buffer_id]);
-                                       return -EINVAL;
-                               }
-                               vtx->dst_sel_x = desc->swizzle[0];
-                               vtx->dst_sel_y = desc->swizzle[1];
-                               vtx->dst_sel_z = desc->swizzle[2];
-                               vtx->dst_sel_w = desc->swizzle[3];
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-       return r600_bc_build(&shader->bc_fetch);
-}
-
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *shader)
-{
-       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-       int r;
-
-       if (shader == NULL)
-               return -EINVAL;
-       /* there should be enough input */
-       if (rctx->vertex_elements->count < shader->shader.bc.nresource) {
-               R600_ERR("%d resources provided, expecting %d\n",
-                       rctx->vertex_elements->count, shader->shader.bc.nresource);
-               return -EINVAL;
-       }
-       r = r600_shader_update(ctx, shader);
-       if (r)
-               return r;
-       return r600_pipe_shader(ctx, shader);
-}
-
 int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
 int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens)
 {
@@ -343,27 +244,17 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s
                R600_ERR("building bytecode failed !\n");
                return r;
        }
-       if (shader->shader.processor_type == TGSI_PROCESSOR_VERTEX) {
-               r = r600_bc_build(&shader->shader.bc_fetch);
-               if (r) {
-                       R600_ERR("building bytecode failed !\n");
-                       return r;
-               }
-       }
+//r600_bc_dump(&shader->shader.bc);
 //fprintf(stderr, "______________________________________________________________\n");
-       return 0;
+       return r600_pipe_shader(ctx, shader);
 }
 
-void
-r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader)
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 
        r600_bo_reference(rctx->radeon, &shader->bo, NULL);
-
        r600_bc_clear(&shader->shader.bc);
-
-       /* FIXME: is there more stuff to free? */
 }
 
 /*
@@ -380,7 +271,6 @@ struct r600_shader_ctx {
        unsigned                                temp_reg;
        struct r600_shader_tgsi_instruction     *inst_info;
        struct r600_bc                          *bc;
-       struct r600_bc                          *bc_fetch;
        struct r600_shader                      *shader;
        u32                                     value[4];
        u32                                     *literals;
@@ -500,9 +390,7 @@ static int evergreen_interp_alu(struct r600_shader_ctx *ctx, int input)
 static int tgsi_declaration(struct r600_shader_ctx *ctx)
 {
        struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
-       struct r600_bc_vtx vtx;
        unsigned i;
-       int r;
 
        switch (d->Declaration.File) {
        case TGSI_FILE_INPUT:
@@ -512,26 +400,6 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
                ctx->shader->input[i].interpolate = d->Declaration.Interpolate;
                ctx->shader->input[i].centroid = d->Declaration.Centroid;
                ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i;
-               if (ctx->type == TGSI_PROCESSOR_VERTEX) {
-                       /* turn input into fetch */
-                       memset(&vtx, 0, sizeof(struct r600_bc_vtx));
-                       vtx.inst = 0;
-                       vtx.fetch_type = 0;
-                       vtx.buffer_id = i;
-                       /* register containing the index into the buffer */
-                       vtx.src_gpr = 0;
-                       vtx.src_sel_x = 0;
-                       vtx.mega_fetch_count = 0x1F;
-                       vtx.dst_gpr = ctx->shader->input[i].gpr;
-                       vtx.dst_sel_x = 0;
-                       vtx.dst_sel_y = 1;
-                       vtx.dst_sel_z = 2;
-                       vtx.dst_sel_w = 3;
-                       vtx.use_const_fields = 1;
-                       r = r600_bc_add_vtx(ctx->bc_fetch, &vtx);
-                       if (r)
-                               return r;
-               }
                if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chiprev == CHIPREV_EVERGREEN) {
                        /* turn input into interpolate on EG */
                        if (ctx->shader->input[i].name != TGSI_SEMANTIC_POSITION) {
@@ -623,7 +491,6 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
        int i, r = 0, pos0;
 
        ctx.bc = &shader->bc;
-       ctx.bc_fetch = &shader->bc_fetch;
        ctx.shader = shader;
        r = r600_bc_init(ctx.bc, shader->family);
        if (r)
@@ -633,12 +500,6 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
        tgsi_parse_init(&ctx.parse, tokens);
        ctx.type = ctx.parse.FullHeader.Processor.Processor;
        shader->processor_type = ctx.type;
-       if (shader->processor_type == TGSI_PROCESSOR_VERTEX) {
-               r = r600_bc_init(ctx.bc_fetch, shader->family);
-               if (r)
-                       return r;
-               ctx.bc_fetch->type = -1;
-       }
        ctx.bc->type = shader->processor_type;
 
        /* register allocations */
@@ -839,14 +700,6 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
                        output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE);
                }
        }
-       /* add return to fetch shader */
-       if (ctx.type == TGSI_PROCESSOR_VERTEX) {
-               if (ctx.bc->chiprev == CHIPREV_EVERGREEN) {
-                       r600_bc_add_cfinst(ctx.bc_fetch, EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN);
-               } else {
-                       r600_bc_add_cfinst(ctx.bc_fetch, V_SQ_CF_WORD1_SQ_CF_INST_RETURN);
-               }
-       }
        /* add output to bytecode */
        for (i = 0; i < noutput; i++) {
                r = r600_bc_add_output(ctx.bc, &output[i]);
@@ -1105,10 +958,6 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx,
        if (r)
                return r;
 
-       r = tgsi_split_literal_constant(ctx, r600_src);
-       if (r)
-               return r;
-
        lit_vals[0] = fui(1.0 /(3.1415926535 * 2));
        lit_vals[1] = fui(0.5f);
 
@@ -2807,6 +2656,7 @@ static int pops(struct r600_shader_ctx *ctx, int pops)
 {
        r600_bc_add_cfinst(ctx->bc, CTX_INST(V_SQ_CF_WORD1_SQ_CF_INST_POP));
        ctx->bc->cf_last->pop_count = pops;
+       ctx->bc->cf_last->cf_addr = ctx->bc->cf_last->id + 2;
        return 0;
 }
 
index cd108da49153171a564cbce0061c448acbabe9bb..35b0331525a01adbba1ba1060b111402e5a09d35 100644 (file)
@@ -38,7 +38,6 @@ struct r600_shader_io {
 struct r600_shader {
        unsigned                processor_type;
        struct r600_bc          bc;
-       boolean                 flat_shade;
        unsigned                ninput;
        unsigned                noutput;
        unsigned                nlds;
@@ -46,7 +45,6 @@ struct r600_shader {
        struct r600_shader_io   output[32];
        enum radeon_family      family;
        boolean                 uses_kill;
-       struct r600_bc          bc_fetch;
 };
 
 int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
index 408741522741e55dd8aa69b0955c25719b76081d..63c54200d4eab6948f315512d562e87c30434f10 100644 (file)
@@ -36,7 +36,6 @@
 #include <util/u_pack_color.h>
 #include <util/u_memory.h>
 #include <util/u_inlines.h>
-#include <util/u_upload_mgr.h>
 #include <util/u_framebuffer.h>
 #include <pipebuffer/pb_buffer.h>
 #include "r600.h"
 #include "r600_pipe.h"
 #include "r600_state_inlines.h"
 
+void r600_polygon_offset_update(struct r600_pipe_context *rctx)
+{
+       struct r600_pipe_state state;
+
+       state.id = R600_PIPE_STATE_POLYGON_OFFSET;
+       state.nregs = 0;
+       if (rctx->rasterizer && rctx->framebuffer.zsbuf) {
+               float offset_units = rctx->rasterizer->offset_units;
+               unsigned offset_db_fmt_cntl = 0, depth;
+
+               switch (rctx->framebuffer.zsbuf->texture->format) {
+               case PIPE_FORMAT_Z24X8_UNORM:
+               case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+                       depth = -24;
+                       offset_units *= 2.0f;
+                       break;
+               case PIPE_FORMAT_Z32_FLOAT:
+                       depth = -23;
+                       offset_units *= 1.0f;
+                       offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
+                       break;
+               case PIPE_FORMAT_Z16_UNORM:
+                       depth = -16;
+                       offset_units *= 4.0f;
+                       break;
+               default:
+                       return;
+               }
+               /* FIXME some of those reg can be computed with cso */
+               offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
+               r600_pipe_state_add_reg(&state,
+                               R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE,
+                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET,
+                               fui(offset_units), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE,
+                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET,
+                               fui(offset_units), 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(&state,
+                               R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
+                               offset_db_fmt_cntl, 0xFFFFFFFF, NULL);
+               r600_context_pipe_state_set(&rctx->ctx, &state);
+       }
+}
+
+/* FIXME optimize away spi update when it's not needed */
+static void r600_spi_update(struct r600_pipe_context *rctx)
+{
+       struct r600_pipe_shader *shader = rctx->ps_shader;
+       struct r600_pipe_state rstate;
+       struct r600_shader *rshader = &shader->shader;
+       unsigned i, tmp;
+
+       rstate.nregs = 0;
+       for (i = 0; i < rshader->ninput; i++) {
+               tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
+               if (rshader->input[i].centroid)
+                       tmp |= S_028644_SEL_CENTROID(1);
+               if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
+                       tmp |= S_028644_SEL_LINEAR(1);
+
+               if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+                   rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
+                   rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
+                       tmp |= S_028644_FLAT_SHADE(rctx->flatshade);
+               }
+               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+                       rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
+                       tmp |= S_028644_PT_SPRITE_TEX(1);
+               }
+               r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
+       }
+       r600_context_pipe_state_set(&rctx->ctx, &rstate);
+}
+
+void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
+{
+       struct r600_pipe_state *rstate;
+       struct r600_resource *rbuffer;
+       struct pipe_vertex_buffer *vertex_buffer;
+       unsigned i, offset;
+
+       /* we don't update until we know vertex elements */
+       if (rctx->vertex_elements == NULL || !rctx->nvertex_buffer)
+               return;
+
+       /* delete previous translated vertex elements */
+       if (rctx->tran.new_velems) {
+               r600_end_vertex_translate(rctx);
+       }
+
+       if (rctx->vertex_elements->incompatible_layout) {
+               /* translate rebind new vertex elements so
+                * return once translated
+                */
+               r600_begin_vertex_translate(rctx);
+               return;
+       }
+
+       if (rctx->any_user_vbs) {
+               r600_upload_user_buffers(rctx);
+               rctx->any_user_vbs = FALSE;
+       }
+
+       if (rctx->vertex_elements->vbuffer_need_offset) {
+               /* one resource per vertex elements */
+               rctx->nvs_resource = rctx->vertex_elements->count;
+       } else {
+               /* bind vertex buffer once */
+               rctx->nvs_resource = rctx->nvertex_buffer;
+       }
+
+       for (i = 0 ; i < rctx->nvs_resource; i++) {
+               rstate = &rctx->vs_resource[i];
+               rstate->id = R600_PIPE_STATE_RESOURCE;
+               rstate->nregs = 0;
+
+               if (rctx->vertex_elements->vbuffer_need_offset) {
+                       /* one resource per vertex elements */
+                       unsigned vbuffer_index;
+                       vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index;
+                       vertex_buffer = &rctx->vertex_buffer[vbuffer_index];
+                       rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+                       offset = rctx->vertex_elements->vbuffer_offset[i] +
+                               vertex_buffer->buffer_offset +
+                               r600_bo_offset(rbuffer->bo);
+               } else {
+                       /* bind vertex buffer once */
+                       vertex_buffer = &rctx->vertex_buffer[i];
+                       rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+                       offset = vertex_buffer->buffer_offset +
+                               r600_bo_offset(rbuffer->bo);
+               }
+
+               r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0,
+                                       offset, 0xFFFFFFFF, rbuffer->bo);
+               r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1,
+                                       rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2,
+                                       S_038008_STRIDE(vertex_buffer->stride),
+                                       0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6,
+                                       0xC0000000, 0xFFFFFFFF, NULL);
+               r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
+       }
+}
+
 static void r600_draw_common(struct r600_drawl *draw)
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)draw->ctx;
-       struct r600_pipe_state *rstate;
        struct r600_resource *rbuffer;
-       unsigned i, j, offset, prim;
+       unsigned prim;
        u32 vgt_dma_index_type, vgt_draw_initiator, mask;
-       struct pipe_vertex_buffer *vertex_buffer;
        struct r600_draw rdraw;
        struct r600_pipe_state vgt;
 
@@ -76,41 +230,22 @@ static void r600_draw_common(struct r600_drawl *draw)
        }
        if (r600_conv_pipe_prim(draw->mode, &prim))
                return;
-
-
-       /* rebuild vertex shader if input format changed */
-       if (r600_pipe_shader_update(&rctx->context, rctx->vs_shader))
+       if (unlikely(rctx->ps_shader == NULL)) {
+               R600_ERR("missing vertex shader\n");
                return;
-       if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader))
+       }
+       if (unlikely(rctx->vs_shader == NULL)) {
+               R600_ERR("missing vertex shader\n");
                return;
-
-       for (i = 0 ; i < rctx->vertex_elements->count; i++) {
-               uint32_t word2, format;
-
-               rstate = &rctx->vs_resource[i];
-               rstate->id = R600_PIPE_STATE_RESOURCE;
-               rstate->nregs = 0;
-
-               j = rctx->vertex_elements->elements[i].vertex_buffer_index;
-               vertex_buffer = &rctx->vertex_buffer[j];
-               rbuffer = (struct r600_resource*)vertex_buffer->buffer;
-               offset = rctx->vertex_elements->elements[i].src_offset +
-                       vertex_buffer->buffer_offset +
-                       r600_bo_offset(rbuffer->bo);
-
-               format = r600_translate_vertex_data_type(rctx->vertex_elements->hw_format[i]);
-
-               word2 = format | S_038008_STRIDE(vertex_buffer->stride);
-
-               r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo);
-               r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, rbuffer->size - offset - 1, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2, word2, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3, 0x00000000, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4, 0x00000000, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5, 0x00000000, 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6, 0xC0000000, 0xFFFFFFFF, NULL);
-               r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
        }
+       /* there should be enough input */
+       if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) {
+               R600_ERR("%d resources provided, expecting %d\n",
+                       rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource);
+               return;
+       }
+
+       r600_spi_update(rctx);
 
        mask = 0;
        for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
@@ -126,46 +261,6 @@ static void r600_draw_common(struct r600_drawl *draw)
        r600_pipe_state_add_reg(&vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(&vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(&vgt, R_03CFF4_SQ_VTX_START_INST_LOC, 0, 0xFFFFFFFF, NULL);
-       /* build late state */
-       if (rctx->rasterizer && rctx->framebuffer.zsbuf) {
-               float offset_units = rctx->rasterizer->offset_units;
-               unsigned offset_db_fmt_cntl = 0, depth;
-
-               switch (rctx->framebuffer.zsbuf->texture->format) {
-               case PIPE_FORMAT_Z24X8_UNORM:
-               case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-                       depth = -24;
-                       offset_units *= 2.0f;
-                       break;
-               case PIPE_FORMAT_Z32_FLOAT:
-                       depth = -23;
-                       offset_units *= 1.0f;
-                       offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
-                       break;
-               case PIPE_FORMAT_Z16_UNORM:
-                       depth = -16;
-                       offset_units *= 4.0f;
-                       break;
-               default:
-                       return;
-               }
-               offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE,
-                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET,
-                               fui(offset_units), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE,
-                               fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET,
-                               fui(offset_units), 0xFFFFFFFF, NULL);
-               r600_pipe_state_add_reg(&vgt,
-                               R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
-                               offset_db_fmt_cntl, 0xFFFFFFFF, NULL);
-       }
        r600_context_pipe_state_set(&rctx->ctx, &vgt);
 
        rdraw.vgt_num_indices = draw->count;
@@ -187,15 +282,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
        struct r600_drawl draw;
        boolean translate = FALSE;
 
-       if (rctx->vertex_elements->incompatible_layout) {
-               r600_begin_vertex_translate(rctx);
-               translate = TRUE;
-       }
-
-       if (rctx->any_user_vbs) {
-               r600_upload_user_buffers(rctx);
-               rctx->any_user_vbs = FALSE;
-       }
        memset(&draw, 0, sizeof(struct r600_drawl));
        draw.ctx = ctx;
        draw.mode = info->mode;
@@ -603,9 +689,9 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
                                word4 | S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) |
                                S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) |
                                S_038010_REQUEST_SIZE(1) |
-                               S_038010_BASE_LEVEL(state->first_level), 0xFFFFFFFF, NULL);
+                               S_038010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5,
-                               S_038014_LAST_LEVEL(state->last_level) |
+                               S_038014_LAST_LEVEL(state->u.tex.last_level) |
                                S_038014_BASE_ARRAY(0) |
                                S_038014_LAST_ARRAY(0), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6,
@@ -824,10 +910,11 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
        struct r600_resource_texture *rtex;
        struct r600_resource *rbuffer;
        struct r600_surface *surf;
-       unsigned level = state->cbufs[cb]->level;
+       unsigned level = state->cbufs[cb]->u.tex.level;
        unsigned pitch, slice;
        unsigned color_info;
        unsigned format, swap, ntype;
+       unsigned offset;
        const struct util_format_description *desc;
        struct r600_bo *bo[3];
 
@@ -838,6 +925,9 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
        bo[1] = rbuffer->bo;
        bo[2] = rbuffer->bo;
 
+       /* XXX quite sure for dx10+ hw don't need any offset hacks */
+       offset = r600_texture_get_offset((struct r600_resource_texture *)state->cbufs[cb]->texture,
+                                        level, state->cbufs[cb]->u.tex.first_layer);
        pitch = rtex->pitch_in_pixels[level] / 8 - 1;
        slice = rtex->pitch_in_pixels[level] * surf->aligned_height / 64 - 1;
        ntype = 0;
@@ -868,7 +958,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 
        r600_pipe_state_add_reg(rstate,
                                R_028040_CB_COLOR0_BASE + cb * 4,
-                               (state->cbufs[cb]->offset + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
+                               (offset + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
        r600_pipe_state_add_reg(rstate,
                                R_0280A0_CB_COLOR0_INFO + cb * 4,
                                color_info, 0xFFFFFFFF, bo[0]);
@@ -899,11 +989,12 @@ static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
        struct r600_surface *surf;
        unsigned level;
        unsigned pitch, slice, format;
+       unsigned offset;
 
        if (state->zsbuf == NULL)
                return;
 
-       level = state->zsbuf->level;
+       level = state->zsbuf->u.tex.level;
 
        surf = (struct r600_surface *)state->zsbuf;
        rtex = (struct r600_resource_texture*)state->zsbuf->texture;
@@ -913,12 +1004,15 @@ static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
        rtex->depth = 1;
        rbuffer = &rtex->resource;
 
+       /* XXX quite sure for dx10+ hw don't need any offset hacks */
+       offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
+                                        level, state->zsbuf->u.tex.first_layer);
        pitch = rtex->pitch_in_pixels[level] / 8 - 1;
        slice = rtex->pitch_in_pixels[level] * surf->aligned_height / 64 - 1;
        format = r600_translate_dbformat(state->zsbuf->texture->format);
 
        r600_pipe_state_add_reg(rstate, R_02800C_DB_DEPTH_BASE,
-                               (state->zsbuf->offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
+                               (offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo);
        r600_pipe_state_add_reg(rstate, R_028000_DB_DEPTH_SIZE,
                                S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice),
                                0xFFFFFFFF, NULL);
@@ -1026,6 +1120,10 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        free(rctx->states[R600_PIPE_STATE_FRAMEBUFFER]);
        rctx->states[R600_PIPE_STATE_FRAMEBUFFER] = rstate;
        r600_context_pipe_state_set(&rctx->ctx, rstate);
+
+       if (state->zsbuf) {
+               r600_polygon_offset_update(rctx);
+       }
 }
 
 static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
index 55bc5d0d22b7cc41c87606dddcb82626e2bdafe7..c647e77b3738e2262886a0f15c75d9e9a3ed3e2f 100644 (file)
@@ -58,6 +58,12 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 
        rctx->states[rs->rstate.id] = &rs->rstate;
        r600_context_pipe_state_set(&rctx->ctx, &rs->rstate);
+
+       if (rctx->family >= CHIP_CEDAR) {
+               evergreen_polygon_offset_update(rctx);
+       } else {
+               r600_polygon_offset_update(rctx);
+       }
 }
 
 void r600_delete_rs_state(struct pipe_context *ctx, void *state)
@@ -114,6 +120,16 @@ void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
        struct r600_vertex_element *v = (struct r600_vertex_element*)state;
 
        rctx->vertex_elements = v;
+       if (v) {
+               rctx->states[v->rstate.id] = &v->rstate;
+               r600_context_pipe_state_set(&rctx->ctx, &v->rstate);
+               if (rctx->family >= CHIP_CEDAR) {
+                       evergreen_vertex_buffer_update(rctx);
+               } else {
+                       r600_vertex_buffer_update(rctx);
+               }
+       }
+
        if (v) {
 //             rctx->vs_rebuild = TRUE;
        }
@@ -122,11 +138,16 @@ void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
 void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+       struct r600_vertex_element *v = (struct r600_vertex_element*)state;
 
-       FREE(state);
-
+       if (rctx->states[v->rstate.id] == &v->rstate) {
+               rctx->states[v->rstate.id] = NULL;
+       }
        if (rctx->vertex_elements == state)
                rctx->vertex_elements = NULL;
+
+       r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL);
+       FREE(state);
 }
 
 
@@ -176,6 +197,11 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
        }
        rctx->nvertex_buffer = count;
        rctx->vb_max_index = max_index;
+       if (rctx->family >= CHIP_CEDAR) {
+               evergreen_vertex_buffer_update(rctx);
+       } else {
+               r600_vertex_buffer_update(rctx);
+       }
 }
 
 
@@ -186,9 +212,10 @@ void *r600_create_vertex_elements(struct pipe_context *ctx,
                                  unsigned count,
                                  const struct pipe_vertex_element *elements)
 {
+       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
-       int i;
        enum pipe_format *format;
+       int i;
 
        assert(count < 32);
        if (!v)
@@ -210,12 +237,16 @@ void *r600_create_vertex_elements(struct pipe_context *ctx,
                }
                v->incompatible_layout =
                        v->incompatible_layout ||
-                       v->elements[i].src_format != v->hw_format[i] ||
-                       v->elements[i].src_offset % 4 != 0;
+                       v->elements[i].src_format != v->hw_format[i];
 
                v->hw_format_size[i] = align(util_format_get_blocksize(v->hw_format[i]), 4);
        }
 
+       if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
+               FREE(v);
+               return NULL;
+       }
+
        return v;
 }
 
@@ -238,6 +269,9 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
 
        /* TODO delete old shader */
        rctx->ps_shader = (struct r600_pipe_shader *)state;
+       if (state) {
+               r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
+       }
 }
 
 void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
@@ -246,6 +280,9 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
 
        /* TODO delete old shader */
        rctx->vs_shader = (struct r600_pipe_shader *)state;
+       if (state) {
+               r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate);
+       }
 }
 
 void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
index 981f5481cdfe74051210bbeb8941b96277d0d9e3..39ca0a74f3f2f8a5682dcc963b90bc8d014e70bd 100644 (file)
@@ -282,6 +282,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
        switch (format) {
                /* 8-bit buffers. */
        case PIPE_FORMAT_A8_UNORM:
+               return V_0280A0_SWAP_ALT_REV;
        case PIPE_FORMAT_I8_UNORM:
        case PIPE_FORMAT_L8_UNORM:
        case PIPE_FORMAT_R8_UNORM:
@@ -304,6 +305,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
                return V_0280A0_SWAP_STD;
 
        case PIPE_FORMAT_L8A8_UNORM:
+               return V_0280A0_SWAP_ALT;
        case PIPE_FORMAT_R8G8_UNORM:
                return V_0280A0_SWAP_STD;
 
index 65d6acb9e4cfa7e265bb9eb5ac7a0479187ad972..23e239c006886a6534d64f8126b64edcfe542016 100644 (file)
@@ -45,14 +45,10 @@ static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_t
 {
        struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
        struct pipe_resource *texture = transfer->resource;
-       struct pipe_subresource subdst;
 
-       subdst.face = 0;
-       subdst.level = 0;
        ctx->resource_copy_region(ctx, rtransfer->staging_texture,
-                               subdst, 0, 0, 0, texture, transfer->sr,
-                               transfer->box.x, transfer->box.y, transfer->box.z,
-                               transfer->box.width, transfer->box.height);
+                               0, 0, 0, 0, texture, transfer->level,
+                               &transfer->box);
 }
 
 
@@ -61,34 +57,32 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600
 {
        struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
        struct pipe_resource *texture = transfer->resource;
-       struct pipe_subresource subsrc;
-
-       subsrc.face = 0;
-       subsrc.level = 0;
-       ctx->resource_copy_region(ctx, texture, transfer->sr,
+       struct pipe_box sbox;
+
+       sbox.x = sbox.y = sbox.z = 0;
+       sbox.width = transfer->box.width;
+       sbox.height = transfer->box.height;
+       /* XXX that might be wrong */
+       sbox.depth = 1;
+       ctx->resource_copy_region(ctx, texture, transfer->level,
                                  transfer->box.x, transfer->box.y, transfer->box.z,
-                                 rtransfer->staging_texture, subsrc,
-                                 0, 0, 0,
-                                 transfer->box.width, transfer->box.height);
+                                 rtransfer->staging_texture,
+                                 0, &sbox);
 
        ctx->flush(ctx, 0, NULL);
 }
 
-static unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
-                                       unsigned level, unsigned zslice,
-                                       unsigned face)
+unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
+                                       unsigned level, unsigned layer)
 {
        unsigned offset = rtex->offset[level];
 
        switch (rtex->resource.base.b.target) {
        case PIPE_TEXTURE_3D:
-               assert(face == 0);
-               return offset + zslice * rtex->layer_size[level];
        case PIPE_TEXTURE_CUBE:
-               assert(zslice == 0);
-               return offset + face * rtex->layer_size[level];
+               return offset + layer * rtex->layer_size[level];
        default:
-               assert(zslice == 0 && face == 0);
+               assert(layer == 0);
                return offset;
        }
 }
@@ -175,10 +169,7 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen,
                                        struct r600_resource_texture *rtex,
                                        unsigned level)
 {
-       struct r600_screen* rscreen = (struct r600_screen *)screen;
        struct pipe_resource *ptex = &rtex->resource.base.b;
-       struct radeon *radeon = (struct radeon *)screen->winsys;
-       enum chip_class chipc = r600_get_family_class(radeon);
        unsigned width, stride, tile_width;
 
        if (rtex->pitch_override)
@@ -212,11 +203,10 @@ static unsigned r600_texture_get_nblocksy(struct pipe_screen *screen,
 }
 
 /* Get a width in pixels from a stride in bytes. */
-static unsigned pitch_to_width(enum pipe_format format,
-                                unsigned pitch_in_bytes)
+static unsigned pitch_to_width(enum pipe_format format, unsigned pitch_in_bytes)
 {
-    return (pitch_in_bytes / util_format_get_blocksize(format)) *
-            util_format_get_blockwidth(format);
+       return (pitch_in_bytes / util_format_get_blocksize(format)) *
+               util_format_get_blockwidth(format);
 }
 
 static void r600_texture_set_array_mode(struct pipe_screen *screen,
@@ -335,12 +325,12 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
                                                const struct pipe_resource *templ)
 {
        unsigned array_mode = 0;
-        static int force_tiling = -1;
+       static int force_tiling = -1;
 
-        /* Would like some magic "get_bool_option_once" routine.
+       /* Would like some magic "get_bool_option_once" routine.
         */
        if (force_tiling == -1)
-                force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE);
+               force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE);
 
        if (force_tiling) {
                if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
@@ -371,8 +361,8 @@ static void r600_texture_destroy(struct pipe_screen *screen,
 }
 
 static boolean r600_texture_get_handle(struct pipe_screen* screen,
-                                       struct pipe_resource *ptex,
-                                       struct winsys_handle *whandle)
+                                       struct pipe_resource *ptex,
+                                       struct winsys_handle *whandle)
 {
        struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
        struct r600_resource *resource = &rtex->resource;
@@ -382,36 +372,39 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                        rtex->pitch_in_bytes[0], whandle);
 }
 
-static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
+static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
                                                struct pipe_resource *texture,
-                                               unsigned face, unsigned level,
-                                               unsigned zslice, unsigned flags)
+                                               const struct pipe_surface *surf_tmpl)
 {
        struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
        struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
-       unsigned offset, tile_height;
+       unsigned tile_height;
+       unsigned level = surf_tmpl->u.tex.level;
 
+       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
        if (surface == NULL)
                return NULL;
-       offset = r600_texture_get_offset(rtex, level, zslice, face);
+       /* XXX no offset */
+/*     offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/
        pipe_reference_init(&surface->base.reference, 1);
        pipe_resource_reference(&surface->base.texture, texture);
-       surface->base.format = texture->format;
+       surface->base.context = pipe;
+       surface->base.format = surf_tmpl->format;
        surface->base.width = mip_minify(texture->width0, level);
        surface->base.height = mip_minify(texture->height0, level);
-       surface->base.offset = offset;
-       surface->base.usage = flags;
-       surface->base.zslice = zslice;
+       surface->base.usage = surf_tmpl->usage;
        surface->base.texture = texture;
-       surface->base.face = face;
-       surface->base.level = level;
+       surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+       surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+       surface->base.u.tex.level = level;
 
-       tile_height = r600_get_height_alignment(screen, rtex->array_mode[level]);
+       tile_height = r600_get_height_alignment(pipe->screen, rtex->array_mode[level]);
        surface->aligned_height = align(surface->base.height, tile_height);
        return &surface->base;
 }
 
-static void r600_tex_surface_destroy(struct pipe_surface *surface)
+static void r600_surface_destroy(struct pipe_context *pipe,
+                                struct pipe_surface *surface)
 {
        pipe_resource_reference(&surface->texture, NULL);
        FREE(surface);
@@ -444,7 +437,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
 
 static unsigned int r600_texture_is_referenced(struct pipe_context *context,
                                                struct pipe_resource *texture,
-                                               unsigned face, unsigned level)
+                                               unsigned level, int layer)
 {
        /* FIXME */
        return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
@@ -491,7 +484,7 @@ out:
  */
 static INLINE unsigned u_box_volume( const struct pipe_box *box )
 {
-        return box->width * box->depth * box->height;
+       return box->width * box->depth * box->height;
 };
 
 
@@ -499,47 +492,44 @@ static INLINE unsigned u_box_volume( const struct pipe_box *box )
  * If so, don't use a staging resource.
  */
 static boolean permit_hardware_blit(struct pipe_screen *screen,
-                                    struct pipe_resource *res)
+                                       struct pipe_resource *res)
 {
-        unsigned bind;
+       unsigned bind;
 
-        if (util_format_is_depth_or_stencil(res->format))
-                bind = PIPE_BIND_DEPTH_STENCIL;
-        else
-                bind = PIPE_BIND_RENDER_TARGET;
+       if (util_format_is_depth_or_stencil(res->format))
+               bind = PIPE_BIND_DEPTH_STENCIL;
+       else
+               bind = PIPE_BIND_RENDER_TARGET;
 
        /* See r600_resource_copy_region: there is something wrong
-         * with depth resource copies at the moment so avoid them for
-         * now.
-         */
+        * with depth resource copies at the moment so avoid them for
+        * now.
+        */
        if (util_format_get_component_bits(res->format,
-                                           UTIL_FORMAT_COLORSPACE_ZS,
-                                           0) != 0)
-                return FALSE;
-
-        if (!screen->is_format_supported(screen,
-                                         res->format,
-                                         res->target,
-                                         res->nr_samples,
-                                         bind, 0))
-                return FALSE;
-
-        if (!screen->is_format_supported(screen,
-                                         res->format,
-                                         res->target,
-                                         res->nr_samples,
-                                         PIPE_BIND_SAMPLER_VIEW, 0))
-                return FALSE;
-
-       if (res->format == PIPE_FORMAT_R16_SNORM)
-                return FALSE;
-
-        return TRUE;
+                               UTIL_FORMAT_COLORSPACE_ZS,
+                               0) != 0)
+               return FALSE;
+
+       if (!screen->is_format_supported(screen,
+                               res->format,
+                               res->target,
+                               res->nr_samples,
+                               bind, 0))
+               return FALSE;
+
+       if (!screen->is_format_supported(screen,
+                               res->format,
+                               res->target,
+                               res->nr_samples,
+                               PIPE_BIND_SAMPLER_VIEW, 0))
+               return FALSE;
+
+       return TRUE;
 }
 
 struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                                                struct pipe_resource *texture,
-                                               struct pipe_subresource sr,
+                                               unsigned level,
                                                unsigned usage,
                                                const struct pipe_box *box)
 {
@@ -559,38 +549,37 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
        if (rtex->tiled)
                use_staging_texture = TRUE;
 
-       if ((usage & PIPE_TRANSFER_READ) &&
-            u_box_volume(box) > 1024)
-                use_staging_texture = TRUE;
-
-        /* XXX: Use a staging texture for uploads if the underlying BO
-         * is busy.  No interface for checking that currently? so do
-         * it eagerly whenever the transfer doesn't require a readback
-         * and might block.
-         */
-        if ((usage & PIPE_TRANSFER_WRITE) &&
-            !(usage & (PIPE_TRANSFER_READ |
-                       PIPE_TRANSFER_DONTBLOCK |
-                       PIPE_TRANSFER_UNSYNCHRONIZED)))
-                use_staging_texture = TRUE;
-
-        if (!permit_hardware_blit(ctx->screen, texture) ||
-            (texture->flags & R600_RESOURCE_FLAG_TRANSFER) ||
-            (texture->usage == PIPE_USAGE_STREAM))
-                use_staging_texture = FALSE;
+       if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
+               use_staging_texture = TRUE;
+
+       /* XXX: Use a staging texture for uploads if the underlying BO
+        * is busy.  No interface for checking that currently? so do
+        * it eagerly whenever the transfer doesn't require a readback
+        * and might block.
+        */
+       if ((usage & PIPE_TRANSFER_WRITE) &&
+                       !(usage & (PIPE_TRANSFER_READ |
+                                       PIPE_TRANSFER_DONTBLOCK |
+                                       PIPE_TRANSFER_UNSYNCHRONIZED)))
+               use_staging_texture = TRUE;
+
+       if (!permit_hardware_blit(ctx->screen, texture) ||
+               (texture->flags & R600_RESOURCE_FLAG_TRANSFER) ||
+               (texture->usage == PIPE_USAGE_STREAM))
+               use_staging_texture = FALSE;
 
        trans = CALLOC_STRUCT(r600_transfer);
        if (trans == NULL)
                return NULL;
        pipe_resource_reference(&trans->transfer.resource, texture);
-       trans->transfer.sr = sr;
+       trans->transfer.level = level;
        trans->transfer.usage = usage;
        trans->transfer.box = *box;
        if (rtex->depth) {
-                /* XXX: only readback the rectangle which is being mapped?
-                 */
-                /* XXX: when discard is true, no need to read back from depth texture
-                 */
+               /* XXX: only readback the rectangle which is being mapped?
+               */
+               /* XXX: when discard is true, no need to read back from depth texture
+               */
                r = r600_texture_depth_flush(ctx, texture);
                if (r < 0) {
                        R600_ERR("failed to create temporary texture to hold untiled copy\n");
@@ -604,6 +593,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                resource.width0 = box->width;
                resource.height0 = box->height;
                resource.depth0 = 1;
+               resource.array_size = 1;
                resource.last_level = 0;
                resource.nr_samples = 0;
                resource.usage = PIPE_USAGE_STAGING;
@@ -629,7 +619,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                }
 
                trans->transfer.stride =
-                        ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
+                       ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
                if (usage & PIPE_TRANSFER_READ) {
                        r600_copy_to_staging_texture(ctx, trans);
                        /* Always referenced in the blit. */
@@ -637,8 +627,8 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                }
                return &trans->transfer;
        }
-       trans->transfer.stride = rtex->pitch_in_bytes[sr.level];
-       trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
+       trans->transfer.stride = rtex->pitch_in_bytes[level];
+       trans->offset = r600_texture_get_offset(rtex, level, box->z);
        return &trans->transfer;
 }
 
@@ -751,10 +741,10 @@ struct u_resource_vtbl r600_texture_vtbl =
        u_default_transfer_inline_write /* transfer_inline_write */
 };
 
-void r600_init_screen_texture_functions(struct pipe_screen *screen)
+void r600_init_surface_functions(struct r600_pipe_context *r600)
 {
-       screen->get_tex_surface = r600_get_tex_surface;
-       screen->tex_surface_destroy = r600_tex_surface_destroy;
+       r600->context.create_surface = r600_create_surface;
+       r600->context.surface_destroy = r600_surface_destroy;
 }
 
 static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
@@ -855,8 +845,8 @@ uint32_t r600_translate_texformat(enum pipe_format format,
        case UTIL_FORMAT_COLORSPACE_YUV:
                yuv_format |= (1 << 30);
                switch (format) {
-                case PIPE_FORMAT_UYVY:
-                case PIPE_FORMAT_YUYV:
+               case PIPE_FORMAT_UYVY:
+               case PIPE_FORMAT_YUYV:
                default:
                        break;
                }
@@ -874,29 +864,29 @@ uint32_t r600_translate_texformat(enum pipe_format format,
 
        /* S3TC formats. TODO */
        if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-                static int r600_enable_s3tc = -1;
+               static int r600_enable_s3tc = -1;
 
-                if (r600_enable_s3tc == -1)
-                        r600_enable_s3tc = 
-                                debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
+               if (r600_enable_s3tc == -1)
+                       r600_enable_s3tc = 
+                               debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
 
-                if (!r600_enable_s3tc)
-                        goto out_unknown;
+               if (!r600_enable_s3tc)
+                       goto out_unknown;
 
                switch (format) {
                case PIPE_FORMAT_DXT1_RGB:
                case PIPE_FORMAT_DXT1_RGBA:
-                        result = FMT_BC1;
-                        goto out_word4;
+                       result = FMT_BC1;
+                       goto out_word4;
                case PIPE_FORMAT_DXT3_RGBA:
-                        result = FMT_BC2;
-                        goto out_word4;
+                       result = FMT_BC2;
+                       goto out_word4;
                case PIPE_FORMAT_DXT5_RGBA:
-                        result = FMT_BC3;
-                        goto out_word4;
-                default:
-                        goto out_unknown;
-                }
+                       result = FMT_BC3;
+                       goto out_word4;
+               default:
+                       goto out_unknown;
+               }
        }
 
 
index 9a07cf2073f4ba1f2491ba54b72906fe226d3d41..1c227d3215115319a37b300e8f284c6f2f3ceb95 100644 (file)
@@ -41,6 +41,7 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
        struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}, *out_transfer;
        struct pipe_resource *out_buffer;
        unsigned i, num_verts;
+       struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
 
        /* Initialize the translate key, i.e. the recipe how vertices should be
         * translated. */
@@ -51,9 +52,7 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
                unsigned output_format_size = ve->hw_format_size[i];
 
                /* Check for support. */
-               if (ve->elements[i].src_format == ve->hw_format[i] &&
-                   (vb->buffer_offset + ve->elements[i].src_offset) % 4 == 0 &&
-                   vb->stride % 4 == 0) {
+               if (ve->elements[i].src_format == ve->hw_format[i]) {
                        continue;
                }
 
@@ -147,29 +146,22 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
        }
 
        /* Save and replace vertex elements. */
-       {
-               struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
-
-               rctx->tran.saved_velems = rctx->vertex_elements;
-
-               for (i = 0; i < ve->count; i++) {
-                       if (vb_translated[ve->elements[i].vertex_buffer_index]) {
-                               te = &key.element[tr_elem_index[i]];
-                               new_velems[i].instance_divisor = ve->elements[i].instance_divisor;
-                               new_velems[i].src_format = te->output_format;
-                               new_velems[i].src_offset = te->output_offset;
-                               new_velems[i].vertex_buffer_index = rctx->tran.vb_slot;
-                       } else {
-                               memcpy(&new_velems[i], &ve->elements[i],
-                                      sizeof(struct pipe_vertex_element));
-                       }
+       for (i = 0; i < ve->count; i++) {
+               if (vb_translated[ve->elements[i].vertex_buffer_index]) {
+                       te = &key.element[tr_elem_index[i]];
+                       new_velems[i].instance_divisor = ve->elements[i].instance_divisor;
+                       new_velems[i].src_format = te->output_format;
+                       new_velems[i].src_offset = te->output_offset;
+                       new_velems[i].vertex_buffer_index = rctx->tran.vb_slot;
+               } else {
+                       memcpy(&new_velems[i], &ve->elements[i],
+                                       sizeof(struct pipe_vertex_element));
                }
-
-               rctx->tran.new_velems =
-                       pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
-               pipe->bind_vertex_elements_state(pipe, rctx->tran.new_velems);
        }
 
+       rctx->tran.new_velems = pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
+       pipe->bind_vertex_elements_state(pipe, rctx->tran.new_velems);
+
        pipe_resource_reference(&out_buffer, NULL);
 }
 
@@ -177,9 +169,15 @@ void r600_end_vertex_translate(struct r600_pipe_context *rctx)
 {
        struct pipe_context *pipe = &rctx->context;
 
+       if (rctx->tran.new_velems == NULL) {
+               return;
+       }
        /* Restore vertex elements. */
-       pipe->bind_vertex_elements_state(pipe, rctx->tran.saved_velems);
+       if (rctx->vertex_elements == rctx->tran.new_velems) {
+               pipe->bind_vertex_elements_state(pipe, NULL);
+       }
        pipe->delete_vertex_elements_state(pipe, rctx->tran.new_velems);
+       rctx->tran.new_velems = NULL;
 
        /* Delete the now-unused VBO. */
        pipe_resource_reference(&rctx->vertex_buffer[rctx->tran.vb_slot].buffer,
@@ -197,14 +195,7 @@ void r600_translate_index_buffer(struct r600_pipe_context *r600,
                *index_size = 2;
                *start = 0;
                break;
-
        case 2:
-               if (*start % 2 != 0) {
-                       util_rebuild_ushort_elts(&r600->context, index_buffer, 0, *start, count);
-                       *start = 0;
-               }
-               break;
-
        case 4:
                break;
        }
diff --git a/src/gallium/drivers/r600/r600_upload.c b/src/gallium/drivers/r600/r600_upload.c
new file mode 100644 (file)
index 0000000..ac72854
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *      Jerome Glisse <jglisse@redhat.com>
+ */
+#include <errno.h>
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "r600.h"
+#include "r600_pipe.h"
+#include "r600_resource.h"
+
+struct r600_upload {
+       struct r600_pipe_context        *rctx;
+       struct r600_bo                  *buffer;
+       char                            *ptr;
+       unsigned                        size;
+       unsigned                        default_size;
+       unsigned                        total_alloc_size;
+       unsigned                        offset;
+       unsigned                        alignment;
+};
+
+struct r600_upload *r600_upload_create(struct r600_pipe_context *rctx,
+                                       unsigned default_size,
+                                       unsigned alignment)
+{
+       struct r600_upload *upload = CALLOC_STRUCT(r600_upload);
+
+       if (upload == NULL)
+               return NULL;
+
+       upload->rctx = rctx;
+       upload->size = 0;
+       upload->default_size = default_size;
+       upload->alignment = alignment;
+       upload->ptr = NULL;
+       upload->buffer = NULL;
+       upload->total_alloc_size = 0;
+
+       return upload;
+}
+
+void r600_upload_flush(struct r600_upload *upload)
+{
+       if (upload->buffer) {
+               r600_bo_reference(upload->rctx->radeon, &upload->buffer, NULL);
+       }
+       upload->default_size = MAX2(upload->total_alloc_size, upload->default_size);
+       upload->total_alloc_size = 0;
+       upload->size = 0;
+       upload->ptr = NULL;
+       upload->buffer = NULL;
+}
+
+void r600_upload_destroy(struct r600_upload *upload)
+{
+       r600_upload_flush(upload);
+       FREE(upload);
+}
+
+int r600_upload_buffer(struct r600_upload *upload, unsigned offset,
+                       unsigned size, struct r600_resource_buffer *in_buffer,
+                       unsigned *out_offset, unsigned *out_size,
+                       struct r600_bo **out_buffer)
+{
+       unsigned alloc_size = align(size, upload->alignment);
+       const void *in_ptr = NULL;
+
+       if (upload->offset + alloc_size > upload->size) {
+               if (upload->size) {
+                       r600_bo_reference(upload->rctx->radeon, &upload->buffer, NULL);
+               }
+               upload->size = align(MAX2(upload->default_size, alloc_size), 4096);
+               upload->total_alloc_size += upload->size;
+               upload->offset = 0;
+               upload->buffer = r600_bo(upload->rctx->radeon, upload->size, 4096, PIPE_BIND_VERTEX_BUFFER, 0);
+               if (upload->buffer == NULL) {
+                       return -ENOMEM;
+               }
+               upload->ptr = r600_bo_map(upload->rctx->radeon, upload->buffer, 0, NULL);
+       }
+
+       in_ptr = in_buffer->user_buffer;
+       memcpy(upload->ptr + upload->offset, (uint8_t *) in_ptr + offset, size);
+       *out_offset = upload->offset;
+       *out_size = upload->size;
+       *out_buffer = upload->buffer;
+       upload->offset += alloc_size;
+
+       return 0;
+}
index 413da59e559965680febad428dec4dd66e39a859..94e57e40f86d78e7d4110dc5be00cf478897f7ea 100644 (file)
@@ -707,17 +707,13 @@ rbug_set_sample_mask(struct pipe_context *_pipe,
 static void
 rbug_resource_copy_region(struct pipe_context *_pipe,
                           struct pipe_resource *_dst,
-                          struct pipe_subresource subdst,
+                          unsigned dst_level,
                           unsigned dstx,
                           unsigned dsty,
                           unsigned dstz,
                           struct pipe_resource *_src,
-                          struct pipe_subresource subsrc,
-                          unsigned srcx,
-                          unsigned srcy,
-                          unsigned srcz,
-                          unsigned width,
-                          unsigned height)
+                          unsigned src_level,
+                          const struct pipe_box *src_box)
 {
    struct rbug_context *rb_pipe = rbug_context(_pipe);
    struct rbug_resource *rb_resource_dst = rbug_resource(_dst);
@@ -728,17 +724,13 @@ rbug_resource_copy_region(struct pipe_context *_pipe,
 
    pipe->resource_copy_region(pipe,
                               dst,
-                              subdst,
+                              dst_level,
                               dstx,
                               dsty,
                               dstz,
                               src,
-                              subsrc,
-                              srcx,
-                              srcy,
-                              srcz,
-                              width,
-                              height);
+                              src_level,
+                              src_box);
 }
 
 static void
@@ -820,8 +812,8 @@ rbug_flush(struct pipe_context *_pipe,
 static unsigned int
 rbug_is_resource_referenced(struct pipe_context *_pipe,
                             struct pipe_resource *_resource,
-                            unsigned face,
-                            unsigned level)
+                            unsigned level,
+                            int layer)
 {
    struct rbug_context *rb_pipe = rbug_context(_pipe);
    struct rbug_resource *rb_resource = rbug_resource(_resource);
@@ -830,8 +822,8 @@ rbug_is_resource_referenced(struct pipe_context *_pipe,
 
    return pipe->is_resource_referenced(pipe,
                                        resource,
-                                       face,
-                                       level);
+                                       level,
+                                       layer);
 }
 
 static struct pipe_sampler_view *
@@ -862,10 +854,40 @@ rbug_context_sampler_view_destroy(struct pipe_context *_pipe,
                              rbug_sampler_view(_view));
 }
 
+static struct pipe_surface *
+rbug_context_create_surface(struct pipe_context *_pipe,
+                            struct pipe_resource *_resource,
+                            const struct pipe_surface *surf_tmpl)
+{
+   struct rbug_context *rb_pipe = rbug_context(_pipe);
+   struct rbug_resource *rb_resource = rbug_resource(_resource);
+   struct pipe_context *pipe = rb_pipe->pipe;
+   struct pipe_resource *resource = rb_resource->resource;
+   struct pipe_surface *result;
+
+   result = pipe->create_surface(pipe,
+                                 resource,
+                                 surf_tmpl);
+
+   if (result)
+      return rbug_surface_create(rb_pipe, rb_resource, result);
+   return NULL;
+}
+
+static void
+rbug_context_surface_destroy(struct pipe_context *_pipe,
+                             struct pipe_surface *_surface)
+{
+   rbug_surface_destroy(rbug_context(_pipe),
+                        rbug_surface(_surface));
+}
+
+
+
 static struct pipe_transfer *
 rbug_context_get_transfer(struct pipe_context *_context,
                           struct pipe_resource *_resource,
-                          struct pipe_subresource sr,
+                          unsigned level,
                           unsigned usage,
                           const struct pipe_box *box)
 {
@@ -877,7 +899,7 @@ rbug_context_get_transfer(struct pipe_context *_context,
 
    result = context->get_transfer(context,
                                   resource,
-                                  sr,
+                                  level,
                                   usage,
                                   box);
 
@@ -942,12 +964,12 @@ rbug_context_transfer_unmap(struct pipe_context *_context,
 static void
 rbug_context_transfer_inline_write(struct pipe_context *_context,
                                    struct pipe_resource *_resource,
-                                   struct pipe_subresource sr,
+                                   unsigned level,
                                    unsigned usage,
                                    const struct pipe_box *box,
                                    const void *data,
                                    unsigned stride,
-                                   unsigned slice_stride)
+                                   unsigned layer_stride)
 {
    struct rbug_context *rb_pipe = rbug_context(_context);
    struct rbug_resource *rb_resource = rbug_resource(_resource);
@@ -956,12 +978,12 @@ rbug_context_transfer_inline_write(struct pipe_context *_context,
 
    context->transfer_inline_write(context,
                                   resource,
-                                  sr,
+                                  level,
                                   usage,
                                   box,
                                   data,
                                   stride,
-                                  slice_stride);
+                                  layer_stride);
 }
 
 
@@ -1042,6 +1064,8 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced;
    rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view;
    rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy;
+   rb_pipe->base.create_surface = rbug_context_create_surface;
+   rb_pipe->base.surface_destroy = rbug_context_surface_destroy;
    rb_pipe->base.get_transfer = rbug_context_get_transfer;
    rb_pipe->base.transfer_destroy = rbug_context_transfer_destroy;
    rb_pipe->base.transfer_map = rbug_context_transfer_map;
index 9dc663b079a0c6787b2739073aee4f11da354cd5..eb772d19d05ea5184572fbb5f7e76caded29b356 100644 (file)
@@ -266,9 +266,9 @@ rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_
 
    tex = tr_tex->resource;
    t = pipe_get_transfer(context, tex,
-                                gptr->face, gptr->level, gptr->zslice,
-                                PIPE_TRANSFER_READ,
-                                gptr->x, gptr->y, gptr->w, gptr->h);
+                         gptr->level, gptr->face + gptr->zslice,
+                         PIPE_TRANSFER_READ,
+                         gptr->x, gptr->y, gptr->w, gptr->h);
 
    map = context->transfer_map(context, t);
 
@@ -279,7 +279,7 @@ rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_
                                 util_format_get_blocksize(t->resource->format),
                                 (uint8_t*)map,
                                 t->stride * util_format_get_nblocksy(t->resource->format,
-                                                                    t->box.height),
+                                                                     t->box.height),
                                 t->stride,
                                 NULL);
 
index 0979fcff957590db2f35f405d56687db4452f31b..7d7cc482ae68b92020116bc10dc82e4e3ad6f038 100644 (file)
@@ -79,7 +79,8 @@ rbug_resource_destroy(struct rbug_resource *rb_resource)
 
 
 struct pipe_surface *
-rbug_surface_create(struct rbug_resource *rb_resource,
+rbug_surface_create(struct rbug_context *rb_context,
+                    struct rbug_resource *rb_resource,
                     struct pipe_surface *surface)
 {
    struct rbug_surface *rb_surface;
@@ -108,10 +109,12 @@ error:
 }
 
 void
-rbug_surface_destroy(struct rbug_surface *rb_surface)
+rbug_surface_destroy(struct rbug_context *rb_context,
+                     struct rbug_surface *rb_surface)
 {
    pipe_resource_reference(&rb_surface->base.texture, NULL);
-   pipe_surface_reference(&rb_surface->surface, NULL);
+   rb_context->pipe->surface_destroy(rb_context->pipe,
+                                     rb_surface->surface);
    FREE(rb_surface);
 }
 
index 49c128d3d1ace5cf416a00c57304d897b21d727a..3fba333422824e6c201e39096b08758ef0c8632f 100644 (file)
@@ -189,11 +189,13 @@ void
 rbug_resource_destroy(struct rbug_resource *rb_resource);
 
 struct pipe_surface *
-rbug_surface_create(struct rbug_resource *rb_resource,
+rbug_surface_create(struct rbug_context *rb_context,
+                    struct rbug_resource *rb_resource,
                     struct pipe_surface *surface);
 
 void
-rbug_surface_destroy(struct rbug_surface *rb_surface);
+rbug_surface_destroy(struct rbug_context *rb_context,
+                     struct rbug_surface *rb_surface);
 
 struct pipe_sampler_view *
 rbug_sampler_view_create(struct rbug_context *rb_context,
index 961df482c29ca4a60af2d3dd63c2fab06b594063..d635ce575c0c1bb43f40089d3e1486480d449a1c 100644 (file)
@@ -188,40 +188,6 @@ rbug_screen_resource_destroy(struct pipe_screen *screen,
    rbug_resource_destroy(rbug_resource(_resource));
 }
 
-static struct pipe_surface *
-rbug_screen_get_tex_surface(struct pipe_screen *_screen,
-                            struct pipe_resource *_resource,
-                            unsigned face,
-                            unsigned level,
-                            unsigned zslice,
-                            unsigned usage)
-{
-   struct rbug_screen *rb_screen = rbug_screen(_screen);
-   struct rbug_resource *rb_resource = rbug_resource(_resource);
-   struct pipe_screen *screen = rb_screen->screen;
-   struct pipe_resource *resource = rb_resource->resource;
-   struct pipe_surface *result;
-
-   result = screen->get_tex_surface(screen,
-                                    resource,
-                                    face,
-                                    level,
-                                    zslice,
-                                    usage);
-
-   if (result)
-      return rbug_surface_create(rb_resource, result);
-   return NULL;
-}
-
-static void
-rbug_screen_tex_surface_destroy(struct pipe_surface *_surface)
-{
-   rbug_surface_destroy(rbug_surface(_surface));
-}
-
-
-
 static struct pipe_resource *
 rbug_screen_user_buffer_create(struct pipe_screen *_screen,
                                void *ptr,
@@ -246,16 +212,18 @@ rbug_screen_user_buffer_create(struct pipe_screen *_screen,
 
 static void
 rbug_screen_flush_frontbuffer(struct pipe_screen *_screen,
-                              struct pipe_surface *_surface,
+                              struct pipe_resource *_resource,
+                              unsigned level, unsigned layer,
                               void *context_private)
 {
    struct rbug_screen *rb_screen = rbug_screen(_screen);
-   struct rbug_surface *rb_surface = rbug_surface(_surface);
+   struct rbug_resource *rb_resource = rbug_resource(_resource);
    struct pipe_screen *screen = rb_screen->screen;
-   struct pipe_surface *surface = rb_surface->surface;
+   struct pipe_resource *resource = rb_resource->resource;
 
    screen->flush_frontbuffer(screen,
-                             surface,
+                             resource,
+                             level, layer,
                              context_private);
 }
 
@@ -336,8 +304,6 @@ rbug_screen_create(struct pipe_screen *screen)
    rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle;
    rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle;
    rb_screen->base.resource_destroy = rbug_screen_resource_destroy;
-   rb_screen->base.get_tex_surface = rbug_screen_get_tex_surface;
-   rb_screen->base.tex_surface_destroy = rbug_screen_tex_surface_destroy;
    rb_screen->base.user_buffer_create = rbug_screen_user_buffer_create;
    rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer;
    rb_screen->base.fence_reference = rbug_screen_fence_reference;
index b5d30bc6fc974b985e4b22ec142d00b4f88de730..e935ce6d21b39127617e2b9c0d885c4dfbcec1aa 100644 (file)
@@ -145,15 +145,15 @@ softpipe_destroy( struct pipe_context *pipe )
  */
 static unsigned int
 softpipe_is_resource_referenced( struct pipe_context *pipe,
-                               struct pipe_resource *texture,
-                               unsigned face, unsigned level)
+                                 struct pipe_resource *texture,
+                                 unsigned level, int layer)
 {
    struct softpipe_context *softpipe = softpipe_context( pipe );
    unsigned i;
 
    if (texture->target == PIPE_BUFFER)
       return PIPE_UNREFERENCED;
-   
+
    /* check if any of the bound drawing surfaces are this texture */
    if (softpipe->dirty_render_cache) {
       for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
index 1071011db0ef1bff225eea5977a33f33cecef545..4258395063b672612ad8e831226e90a39e74bd77 100644 (file)
@@ -120,8 +120,8 @@ softpipe_flush( struct pipe_context *pipe,
 boolean
 softpipe_flush_resource(struct pipe_context *pipe,
                         struct pipe_resource *texture,
-                        unsigned face,
                         unsigned level,
+                        int layer,
                         unsigned flush_flags,
                         boolean read_only,
                         boolean cpu_access,
@@ -129,7 +129,7 @@ softpipe_flush_resource(struct pipe_context *pipe,
 {
    unsigned referenced;
 
-   referenced = pipe->is_resource_referenced(pipe, texture, face, level);
+   referenced = pipe->is_resource_referenced(pipe, texture, level, layer);
 
    if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
        ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
index cb97482a71b33300c2117ba0efaf3a17f43ae50a..22a5ceeb9ecc4fd7bc6232434bf3348c0e28a77c 100644 (file)
@@ -40,8 +40,8 @@ softpipe_flush(struct pipe_context *pipe, unsigned flags,
 boolean
 softpipe_flush_resource(struct pipe_context *pipe,
                         struct pipe_resource *texture,
-                        unsigned face,
                         unsigned level,
+                        int layer,
                         unsigned flush_flags,
                         boolean read_only,
                         boolean cpu_access,
diff --git a/src/gallium/drivers/softpipe/sp_limits.h b/src/gallium/drivers/softpipe/sp_limits.h
new file mode 100644 (file)
index 0000000..a7a24c9
--- /dev/null
@@ -0,0 +1,42 @@
+/**************************************************************************
+ * 
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef SP_LIMITS_H
+#define SP_LIMITS_H
+
+
+
+#define SP_MAX_TEXTURE_2D_LEVELS 15  /* 16K x 16K */
+#define SP_MAX_TEXTURE_3D_LEVELS 9   /* 512 x 512 x 512 */
+
+
+/** Max surface size */
+#define MAX_WIDTH (1 << (SP_MAX_TEXTURE_2D_LEVELS - 1))
+#define MAX_HEIGHT (1 << (SP_MAX_TEXTURE_2D_LEVELS - 1))
+
+
+#endif /* SP_LIMITS_H */
index 5e13d6323876048027a3e25c146b117f35d24d75..cd3b6240fe97ef8d867bcb130936718b2714038a 100644 (file)
@@ -267,12 +267,13 @@ softpipe_destroy_screen( struct pipe_screen *screen )
  */
 static void
 softpipe_flush_frontbuffer(struct pipe_screen *_screen,
-                           struct pipe_surface *surface,
+                           struct pipe_resource *resource,
+                           unsigned level, unsigned layer,
                            void *context_private)
 {
    struct softpipe_screen *screen = softpipe_screen(_screen);
    struct sw_winsys *winsys = screen->winsys;
-   struct softpipe_resource *texture = softpipe_resource(surface->texture);
+   struct softpipe_resource *texture = softpipe_resource(resource);
 
    assert(texture->dt);
    if (texture->dt)
index e817c0c8cf5c97deeef47023cbde87f10e786836..1393164150e71688e878efb6ca0150662b9513d2 100644 (file)
@@ -48,6 +48,9 @@ sp_create_tex_tile_cache( struct pipe_context *pipe )
    struct softpipe_tex_tile_cache *tc;
    uint pos;
 
+   /* make sure max texture size works */
+   assert((TILE_SIZE << TEX_ADDR_BITS) >= (1 << (SP_MAX_TEXTURE_2D_LEVELS-1)));
+
    tc = CALLOC_STRUCT( softpipe_tex_tile_cache );
    if (tc) {
       tc->pipe = pipe;
@@ -260,15 +263,14 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
          }
 
          tc->tex_trans = 
-            pipe_get_transfer(tc->pipe, tc->texture, 
-                             addr.bits.face, 
-                             addr.bits.level, 
-                             addr.bits.z, 
-                             PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
-                             0, 0,
-                             u_minify(tc->texture->width0, addr.bits.level),
-                             u_minify(tc->texture->height0, addr.bits.level));
-         
+            pipe_get_transfer(tc->pipe, tc->texture,
+                              addr.bits.level,
+                              addr.bits.face + addr.bits.z,
+                              PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
+                              0, 0,
+                              u_minify(tc->texture->width0, addr.bits.level),
+                              u_minify(tc->texture->height0, addr.bits.level));
+
          tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
 
          tc->tex_face = addr.bits.face;
index 05f25133daaaae5e282acddb3dc0409100b0c9f7..e0b66bf3f7c22670d857d8e65fe44a8f64489619 100644 (file)
@@ -30,6 +30,7 @@
 
 
 #include "pipe/p_compiler.h"
+#include "sp_limits.h"
 
 
 struct softpipe_context;
@@ -39,22 +40,26 @@ struct softpipe_tex_tile_cache;
 /**
  * Cache tile size (width and height). This needs to be a power of two.
  */
-#define TILE_SIZE 64
+#define TILE_SIZE_LOG2 6
+#define TILE_SIZE (1 << TILE_SIZE_LOG2)
 
 
-/* If we need to support > 4096, just expand this to be a 64 bit
- * union, or consider tiling in Z as well.
+#define TEX_ADDR_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1 - TILE_SIZE_LOG2)
+#define TEX_Z_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1)
+
+/**
+ * Texture tile address as a union for fast compares.
  */
 union tex_tile_address {
    struct {
-      unsigned x:6;             /* 4096 / TILE_SIZE */
-      unsigned y:6;             /* 4096 / TILE_SIZE */
-      unsigned z:12;            /* 4096 -- z not tiled */
+      unsigned 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;
-   unsigned value;
+   uint64_t value;
 };
 
 
@@ -126,10 +131,10 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
 
 static INLINE union tex_tile_address
 tex_tile_address( unsigned x,
-                 unsigned y,
-                 unsigned z,
-                 unsigned face,
-                 unsigned level )
+                  unsigned y,
+                  unsigned z,
+                  unsigned face,
+                  unsigned level )
 {
    union tex_tile_address addr;
 
@@ -139,7 +144,7 @@ tex_tile_address( unsigned x,
    addr.bits.z = z;
    addr.bits.face = face;
    addr.bits.level = level;
-      
+
    return addr;
 }
 
index 4e6123fbd07834303e2cc9ed07265f0c45c2b37f..509d9982b17b9504a413f5c9553e5f155181dca4 100644 (file)
@@ -220,23 +220,18 @@ softpipe_resource_get_handle(struct pipe_screen *screen,
  */
 static unsigned
 sp_get_tex_image_offset(const struct softpipe_resource *spr,
-                        unsigned level, unsigned face, unsigned zslice)
+                        unsigned level, unsigned layer)
 {
    const unsigned hgt = u_minify(spr->base.height0, level);
    const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt);
    unsigned offset = spr->level_offset[level];
 
-   if (spr->base.target == PIPE_TEXTURE_CUBE) {
-      assert(zslice == 0);
-      offset += face * nblocksy * spr->stride[level];
-   }
-   else if (spr->base.target == PIPE_TEXTURE_3D) {
-      assert(face == 0);
-      offset += zslice * nblocksy * spr->stride[level];
+   if (spr->base.target == PIPE_TEXTURE_CUBE ||
+       spr->base.target == PIPE_TEXTURE_3D) {
+      offset += layer * nblocksy * spr->stride[level];
    }
    else {
-      assert(face == 0);
-      assert(zslice == 0);
+      assert(layer == 0);
    }
 
    return offset;
@@ -247,39 +242,40 @@ sp_get_tex_image_offset(const struct softpipe_resource *spr,
  * Get a pipe_surface "view" into a texture resource.
  */
 static struct pipe_surface *
-softpipe_get_tex_surface(struct pipe_screen *screen,
-                         struct pipe_resource *pt,
-                         unsigned face, unsigned level, unsigned zslice,
-                         unsigned usage)
+softpipe_create_surface(struct pipe_context *pipe,
+                        struct pipe_resource *pt,
+                        const struct pipe_surface *surf_tmpl)
 {
-   struct softpipe_resource *spr = softpipe_resource(pt);
    struct pipe_surface *ps;
+   unsigned level = surf_tmpl->u.tex.level;
 
    assert(level <= pt->last_level);
+   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
 
    ps = CALLOC_STRUCT(pipe_surface);
    if (ps) {
       pipe_reference_init(&ps->reference, 1);
       pipe_resource_reference(&ps->texture, pt);
-      ps->format = pt->format;
+      ps->context = pipe;
+      ps->format = surf_tmpl->format;
       ps->width = u_minify(pt->width0, level);
       ps->height = u_minify(pt->height0, level);
-      ps->offset = sp_get_tex_image_offset(spr, level, face, zslice);
-      ps->usage = usage;
+      ps->usage = surf_tmpl->usage;
 
-      ps->face = face;
-      ps->level = level;
-      ps->zslice = zslice;
+      ps->u.tex.level = level;
+      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
    }
    return ps;
 }
 
 
 /**
- * Free a pipe_surface which was created with softpipe_get_tex_surface().
+ * Free a pipe_surface which was created with softpipe_create_surface().
  */
 static void 
-softpipe_tex_surface_destroy(struct pipe_surface *surf)
+softpipe_surface_destroy(struct pipe_context *pipe,
+                         struct pipe_surface *surf)
 {
    /* Effectively do the texture_update work here - if texture images
     * needed post-processing to put them into hardware layout, this is
@@ -302,21 +298,21 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf)
  */
 static struct pipe_transfer *
 softpipe_get_transfer(struct pipe_context *pipe,
-                     struct pipe_resource *resource,
-                     struct pipe_subresource sr,
-                     unsigned usage,
-                     const struct pipe_box *box)
+                      struct pipe_resource *resource,
+                      unsigned level,
+                      unsigned usage,
+                      const struct pipe_box *box)
 {
    struct softpipe_resource *spr = softpipe_resource(resource);
    struct softpipe_transfer *spt;
 
    assert(resource);
-   assert(sr.level <= resource->last_level);
+   assert(level <= resource->last_level);
 
    /* make sure the requested region is in the image bounds */
-   assert(box->x + box->width <= u_minify(resource->width0, sr.level));
-   assert(box->y + box->height <= u_minify(resource->height0, sr.level));
-   assert(box->z + box->depth <= u_minify(resource->depth0, sr.level));
+   assert(box->x + box->width <= u_minify(resource->width0, level));
+   assert(box->y + box->height <= u_minify(resource->height0, level));
+   assert(box->z + box->depth <= (u_minify(resource->depth0, level) + resource->array_size - 1));
 
    /*
     * Transfers, like other pipe operations, must happen in order, so flush the
@@ -326,7 +322,7 @@ softpipe_get_transfer(struct pipe_context *pipe,
       boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
       boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
       if (!softpipe_flush_resource(pipe, resource,
-                                   sr.face, sr.level,
+                                   level, box->depth > 1 ? -1 : box->z,
                                    0, /* flush_flags */
                                    read_only,
                                    TRUE, /* cpu_access */
@@ -343,21 +339,21 @@ softpipe_get_transfer(struct pipe_context *pipe,
    if (spt) {
       struct pipe_transfer *pt = &spt->base;
       enum pipe_format format = resource->format;
-      const unsigned hgt = u_minify(spr->base.height0, sr.level);
+      const unsigned hgt = u_minify(spr->base.height0, level);
       const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
 
       pipe_resource_reference(&pt->resource, resource);
-      pt->sr = sr;
+      pt->level = level;
       pt->usage = usage;
       pt->box = *box;
-      pt->stride = spr->stride[sr.level];
-      pt->slice_stride = pt->stride * nblocksy;
+      pt->stride = spr->stride[level];
+      pt->layer_stride = pt->stride * nblocksy;
 
-      spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z);
+      spt->offset = sp_get_tex_image_offset(spr, level, box->z);
  
       spt->offset += 
-        box->y / util_format_get_blockheight(format) * spt->base.stride +
-        box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+         box->y / util_format_get_blockheight(format) * spt->base.stride +
+         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
 
       return pt;
    }
@@ -454,6 +450,7 @@ softpipe_user_buffer_create(struct pipe_screen *screen,
    spr->base.width0 = bytes;
    spr->base.height0 = 1;
    spr->base.depth0 = 1;
+   spr->base.array_size = 1;
    spr->userBuffer = TRUE;
    spr->data = ptr;
 
@@ -471,6 +468,9 @@ softpipe_init_texture_funcs(struct pipe_context *pipe)
 
    pipe->transfer_flush_region = u_default_transfer_flush_region;
    pipe->transfer_inline_write = u_default_transfer_inline_write;
+
+   pipe->create_surface = softpipe_create_surface;
+   pipe->surface_destroy = softpipe_surface_destroy;
 }
 
 
@@ -483,6 +483,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
    screen->resource_get_handle = softpipe_resource_get_handle;
    screen->user_buffer_create = softpipe_user_buffer_create;
 
-   screen->get_tex_surface = softpipe_get_tex_surface;
-   screen->tex_surface_destroy = softpipe_tex_surface_destroy;
 }
index 7e3249b46f01bdf83e5f139e0fd1ae19f13923b3..533d6252e259b5ae2cbffd2956e46f989698e3c3 100644 (file)
 
 
 #include "pipe/p_state.h"
-
-
-#define SP_MAX_TEXTURE_2D_LEVELS 13  /* 4K x 4K */
-#define SP_MAX_TEXTURE_3D_LEVELS 9   /* 512 x 512 x 512 */
+#include "sp_limits.h"
 
 
 struct pipe_context;
index aa76b8aa1ec5bfcae04ab4898e6895772f0d09c9..480860af63b3cf4a543d1ba90353b3c81542bc70 100644 (file)
@@ -92,6 +92,10 @@ sp_create_tile_cache( struct pipe_context *pipe )
    maxTexSize = 1 << (maxLevels - 1);
    assert(MAX_WIDTH >= maxTexSize);
 
+   assert(sizeof(union tile_address) == 4);
+
+   assert((TILE_SIZE << TILE_ADDR_BITS) >= MAX_WIDTH);
+
    tc = CALLOC_STRUCT( softpipe_tile_cache );
    if (tc) {
       tc->pipe = pipe;
@@ -170,11 +174,11 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
    tc->surface = ps;
 
    if (ps) {
-      tc->transfer = pipe_get_transfer(pipe, ps->texture, ps->face,
-                                          ps->level, ps->zslice,
-                                          PIPE_TRANSFER_READ_WRITE |
-                                          PIPE_TRANSFER_UNSYNCHRONIZED,
-                                          0, 0, ps->width, ps->height);
+      tc->transfer = pipe_get_transfer(pipe, ps->texture,
+                                       ps->u.tex.level, ps->u.tex.first_layer,
+                                       PIPE_TRANSFER_READ_WRITE |
+                                       PIPE_TRANSFER_UNSYNCHRONIZED,
+                                       0, 0, ps->width, ps->height);
 
       tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
                            ps->format == PIPE_FORMAT_Z24X8_UNORM ||
index 4151a47c3235eb526debe8de4b3305b8ddf24cf5..68140b1d2f9f0965304feec0d90825c7ee6200af 100644 (file)
@@ -30,6 +30,7 @@
 
 
 #include "pipe/p_compiler.h"
+#include "sp_texture.h"
 
 
 struct softpipe_tile_cache;
@@ -38,18 +39,22 @@ struct softpipe_tile_cache;
 /**
  * Cache tile size (width and height). This needs to be a power of two.
  */
-#define TILE_SIZE 64
+#define TILE_SIZE_LOG2 6
+#define TILE_SIZE (1 << TILE_SIZE_LOG2)
 
 
-/* If we need to support > 4096, just expand this to be a 64 bit
- * union, or consider tiling in Z as well.
+#define TILE_ADDR_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1 - TILE_SIZE_LOG2)
+
+
+/**
+ * Surface tile address as a union for fast compares.
  */
 union tile_address {
    struct {
-      unsigned x:6;             /* 4096 / TILE_SIZE */
-      unsigned y:6;             /* 4096 / TILE_SIZE */
+      unsigned x:TILE_ADDR_BITS;     /* 16K / TILE_SIZE */
+      unsigned y:TILE_ADDR_BITS;     /* 16K / TILE_SIZE */
       unsigned invalid:1;
-      unsigned pad:19;
+      unsigned pad:15;
    } bits;
    unsigned value;
 };
@@ -70,11 +75,6 @@ struct softpipe_cached_tile
 #define NUM_ENTRIES 50
 
 
-/** XXX move these */
-#define MAX_WIDTH 4096
-#define MAX_HEIGHT 4096
-
-
 struct softpipe_tile_cache
 {
    struct pipe_context *pipe;
index 355ad75064c8d65d6862300de783c847abccf7c5..895aab1b2b1a29ce3f1e9dc075ee90f75bf6be2a 100644 (file)
@@ -153,6 +153,18 @@ sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
    }
 }
 
+static struct pipe_surface *
+sp_mpeg12_create_surface(struct pipe_video_context *vpipe,
+                         struct pipe_resource *resource,
+                         const struct pipe_surface *templat)
+{
+   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+   assert(vpipe);
+
+   return ctx->pipe->create_surface(ctx->pipe, resource, templat);
+}
+
 static boolean
 sp_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
                               enum pipe_format format,
@@ -228,26 +240,27 @@ sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
    assert(vpipe);
    assert(dst);
 
-   struct pipe_subresource subdst, subsrc;
-   subdst.face = dst->face;
-   subdst.level = dst->level;
-   subsrc.face = src->face;
-   subsrc.level = src->level;
+   struct pipe_box box;
+   box.x = srcx;
+   box.y = srcy;
+   box.z = 0;
+   box.width = width;
+   box.height = height;
 
    if (ctx->pipe->resource_copy_region)
-      ctx->pipe->resource_copy_region(ctx->pipe, dst->texture, subdst, dstx, dsty, dst->zslice,
-                                      src->texture, subsrc, srcx, srcy, src->zslice,
-                                      width, height);
+      ctx->pipe->resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
+                                      dstx, dsty, dst->u.tex.first_layer,
+                                      src->texture, src->u.tex.level, &box);
    else
-      util_resource_copy_region(ctx->pipe, dst->texture, subdst, dstx, dsty, dst->zslice,
-                                src->texture, subsrc, srcx, srcy, src->zslice,
-                                width, height);
+      util_resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
+                                dstx, dsty, dst->u.tex.first_layer,
+                                src->texture, src->u.tex.level, &box);
 }
 
 static struct pipe_transfer*
 sp_mpeg12_get_transfer(struct pipe_video_context *vpipe,
                        struct pipe_resource *resource,
-                       struct pipe_subresource subresource,
+                       unsigned level,
                        unsigned usage,  /* a combination of PIPE_TRANSFER_x */
                        const struct pipe_box *box)
 {
@@ -257,7 +270,7 @@ sp_mpeg12_get_transfer(struct pipe_video_context *vpipe,
    assert(resource);
    assert(box);
 
-   return ctx->pipe->get_transfer(ctx->pipe, resource, subresource, usage, box);
+   return ctx->pipe->get_transfer(ctx->pipe, resource, level, usage, box);
 }
 
 static void
@@ -313,7 +326,7 @@ sp_mpeg12_transfer_unmap(struct pipe_video_context *vpipe,
 static void
 sp_mpeg12_transfer_inline_write(struct pipe_video_context *vpipe,
                                 struct pipe_resource *resource,
-                                struct pipe_subresource subresource,
+                                unsigned level,
                                 unsigned usage, /* a combination of PIPE_TRANSFER_x */
                                 const struct pipe_box *box,
                                 const void *data,
@@ -328,7 +341,7 @@ sp_mpeg12_transfer_inline_write(struct pipe_video_context *vpipe,
    assert(data);
    assert(ctx->pipe->transfer_inline_write);
 
-   ctx->pipe->transfer_inline_write(ctx->pipe, resource, subresource, usage,
+   ctx->pipe->transfer_inline_write(ctx->pipe, resource, level, usage,
                                     box, data, stride, slice_stride);
 }
 
@@ -528,6 +541,7 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
    ctx->base.destroy = sp_mpeg12_destroy;
    ctx->base.get_param = sp_mpeg12_get_param;
    ctx->base.is_format_supported = sp_mpeg12_is_format_supported;
+   ctx->base.create_surface = sp_mpeg12_create_surface;
    ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
    ctx->base.render_picture = sp_mpeg12_render_picture;
    ctx->base.surface_fill = sp_mpeg12_surface_fill;
index 12ce4732d1508ebaa927ac8138c8f838d223a8cf..5455ed07573ff298d059d89abd203235065d4636 100644 (file)
@@ -73,4 +73,6 @@ svga = env.ConvenienceLibrary(
        source = sources,
 )
 
+env.Alias('svga', svga)
+
 Export('svga')
index e975f3b02fa3fcaff2e4fa23ac35236d750dca22..05eab8a517d2e752b52ba196391f821c5559148e 100644 (file)
@@ -455,8 +455,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
    cmd->guest.pitch = st->base.stride;
 
    swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
-   cmd->host.face = st->base.sr.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
-   cmd->host.mipmap = st->base.sr.level;
+   cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
+   cmd->host.mipmap = st->base.level;
 
    cmd->transfer = transfer;
 
index cd3f6b89825e846e0900234844ec5ad9e029dd7c..1e513f1039f48908854ddf3b4daa595afb0054ba 100644 (file)
@@ -109,6 +109,7 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
    svga_init_vertex_functions(svga);
    svga_init_constbuffer_functions(svga);
    svga_init_query_functions(svga);
+   svga_init_surface_functions(svga);
 
 
    /* debug */
index 1fb5a04887f70e6b52e26ee3963812f0f2c4217d..04e281a506d5e96686b33a07aa0cebb58de9ef1b 100644 (file)
@@ -422,6 +422,7 @@ void svga_init_vertex_functions( struct svga_context *svga );
 void svga_init_constbuffer_functions( struct svga_context *svga );
 void svga_init_draw_functions( struct svga_context *svga );
 void svga_init_query_functions( struct svga_context *svga );
+void svga_init_surface_functions(struct svga_context *svga);
 
 void svga_cleanup_vertex_state( struct svga_context *svga );
 void svga_cleanup_tss_binding( struct svga_context *svga );
index ca036a6463b52e8d2cea01563cc53bf4eded8825..426698806c8b181ef73d000d91f1e7288ebd6f06 100644 (file)
 #define FILE_DEBUG_FLAG DEBUG_BLIT
 
 
-/* XXX I got my doubts about this, should maybe use svga_texture_copy_handle directly? */
+/* XXX still have doubts about this... */
 static void svga_surface_copy(struct pipe_context *pipe,
                               struct pipe_resource* dst_tex,
-                              struct pipe_subresource subdst,
+                              unsigned dst_level,
                               unsigned dstx, unsigned dsty, unsigned dstz,
                               struct pipe_resource* src_tex,
-                              struct pipe_subresource subsrc,
-                              unsigned srcx, unsigned srcy, unsigned srcz,
-                              unsigned width, unsigned height)
-{
+                              unsigned src_level,
+                              const struct pipe_box *src_box)
+ {
    struct svga_context *svga = svga_context(pipe);
-   struct pipe_screen *screen = pipe->screen;
+   struct svga_texture *stex = svga_texture(src_tex);
+   struct svga_texture *dtex = svga_texture(dst_tex);
+/*   struct pipe_screen *screen = pipe->screen;
    SVGA3dCopyBox *box;
    enum pipe_error ret;
-   struct pipe_surface *srcsurf, *dstsurf;
+   struct pipe_surface *srcsurf, *dstsurf;*/
+   unsigned dst_face, dst_z, src_face, src_z;
 
    svga_hwtnl_flush_retry( svga );
 
+#if 0
    srcsurf = screen->get_tex_surface(screen, src_tex,
-                                     subsrc.face, subsrc.level, srcz,
+                                     src_level, src_box->z, src_box->z,
                                      PIPE_BIND_SAMPLER_VIEW);
 
    dstsurf = screen->get_tex_surface(screen, dst_tex,
-                                     subdst.face, subdst.level, dstz,
+                                     dst_level, dst_box->z, dst_box->z,
                                      PIPE_BIND_RENDER_TARGET);
 
    SVGA_DBG(DEBUG_DMA, "blit to sid %p (%d,%d), from sid %p (%d,%d) sz %dx%d\n",
             svga_surface(dstsurf)->handle,
             dstx, dsty,
             svga_surface(srcsurf)->handle,
-            srcx, srcy,
+            src_box->x, src_box->y,
             width, height);
 
    ret = SVGA3D_BeginSurfaceCopy(svga->swc,
@@ -88,8 +91,8 @@ static void svga_surface_copy(struct pipe_context *pipe,
    box->w = width;
    box->h = height;
    box->d = 1;
-   box->srcx = srcx;
-   box->srcy = srcy;
+   box->srcx = src_box->x;
+   box->srcy = src_box->y;
    box->srcz = 0;
 
    SVGA_FIFOCommitAll(svga->swc);
@@ -100,6 +103,37 @@ static void svga_surface_copy(struct pipe_context *pipe,
    pipe_surface_reference(&srcsurf, NULL);
    pipe_surface_reference(&dstsurf, NULL);
 
+#else
+   if (src_tex->target == PIPE_TEXTURE_CUBE) {
+      src_face = src_box->z;
+      src_z = 0;
+      assert(src_box->depth == 1);
+   }
+   else {
+      src_face = 0;
+      src_z = src_box->z;
+   }
+   /* different src/dst type???*/
+   if (dst_tex->target == PIPE_TEXTURE_CUBE) {
+      dst_face = dstz;
+      dst_z = 0;
+      assert(src_box->depth == 1);
+   }
+   else {
+      dst_face = 0;
+      dst_z = dstz;
+   }
+   svga_texture_copy_handle(svga,
+                            stex->handle,
+                            src_box->x, src_box->y, src_z,
+                            src_level, src_face,
+                            dtex->handle,
+                            dstx, dsty, dst_z,
+                            dst_level, dst_face,
+                            src_box->width, src_box->height, src_box->depth);
+
+#endif
+
 }
 
 
index 198d40133284158c18465621467e45e1bbdc16ec..f12e2b686270230b600dba255a9f04d096b869ae 100644 (file)
@@ -53,8 +53,8 @@ svga_buffer_needs_hw_storage(unsigned usage)
 
 static unsigned int
 svga_buffer_is_referenced( struct pipe_context *pipe,
-                            struct pipe_resource *buf,
-                            unsigned face, unsigned level)
+                           struct pipe_resource *buf,
+                           unsigned level, int layer)
 {
    struct svga_screen *ss = svga_screen(pipe->screen);
    struct svga_buffer *sbuf = svga_buffer(buf);
@@ -337,6 +337,7 @@ svga_user_buffer_create(struct pipe_screen *screen,
    sbuf->b.b.width0 = bytes;
    sbuf->b.b.height0 = 1;
    sbuf->b.b.depth0 = 1;
+   sbuf->b.b.array_size = 1;
 
    sbuf->swbuf = ptr;
    sbuf->user = TRUE;
index 26eb03a895a81ae4ad4ebb28c85c838f500c08a3..7c9e600b9f441664c8776360daaaa3c89bab61e5 100644 (file)
@@ -50,8 +50,8 @@
 
 static unsigned int
 svga_texture_is_referenced( struct pipe_context *pipe,
-                           struct pipe_resource *texture,
-                           unsigned face, unsigned level)
+                            struct pipe_resource *texture,
+                            unsigned level, int layer)
 {
    struct svga_texture *tex = svga_texture(texture);
    struct svga_screen *ss = svga_screen(pipe->screen);
@@ -171,20 +171,7 @@ svga_transfer_dma_band(struct svga_context *svga,
    struct svga_texture *texture = svga_texture(st->base.resource); 
    SVGA3dCopyBox box;
    enum pipe_error ret;
-   
-   SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n",
-                transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from", 
-                texture->handle,
-                st->base.sr.face,
-                st->base.box.x,
-                y,
-                st->base.box.z,
-                st->base.box.x + st->base.box.width,
-                y + h,
-                st->base.box.z + 1,
-                util_format_get_blocksize(texture->b.b.format) * 8 /
-                (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));
-   
    box.x = st->base.box.x;
    box.y = y;
    box.z = st->base.box.z;
@@ -195,6 +182,26 @@ svga_transfer_dma_band(struct svga_context *svga,
    box.srcy = srcy;
    box.srcz = 0;
 
+   if (st->base.resource->target == PIPE_TEXTURE_CUBE) {
+      st->face = st->base.box.z;
+      box.z = 0;
+   }
+   else
+      st->face = 0;
+
+   SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n",
+                transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from", 
+                texture->handle,
+                st->face,
+                st->base.box.x,
+                y,
+                box.z,
+                st->base.box.x + st->base.box.width,
+                y + h,
+                box.z + 1,
+                util_format_get_blocksize(texture->b.b.format) * 8 /
+                (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));
+
    ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
    if(ret != PIPE_OK) {
       svga->swc->flush(svga->swc, NULL);
@@ -213,7 +220,7 @@ svga_transfer_dma(struct svga_context *svga,
    struct svga_screen *screen = svga_screen(texture->b.b.screen);
    struct svga_winsys_screen *sws = screen->sws;
    struct pipe_fence_handle *fence = NULL;
-   
+
    if (transfer == SVGA3D_READ_HOST_VRAM) {
       SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
    }
@@ -221,7 +228,7 @@ svga_transfer_dma(struct svga_context *svga,
 
    if(!st->swbuf) {
       /* Do the DMA transfer in a single go */
-      
+
       svga_transfer_dma_band(svga, st, transfer, st->base.box.y, st->base.box.height, 0);
 
       if(transfer == SVGA3D_READ_HOST_VRAM) {
@@ -245,12 +252,12 @@ svga_transfer_dma(struct svga_context *svga,
          /* Transfer band must be aligned to pixel block boundaries */
          assert(y % blockheight == 0);
          assert(h % blockheight == 0);
-         
+
          offset = y * st->base.stride / blockheight;
          length = h * st->base.stride / blockheight;
 
          sw = (uint8_t *)st->swbuf + offset;
-         
+
          if(transfer == SVGA3D_WRITE_HOST_VRAM) {
             /* Wait for the previous DMAs to complete */
             /* TODO: keep one DMA (at half the size) in the background */
@@ -267,9 +274,9 @@ svga_transfer_dma(struct svga_context *svga,
                sws->buffer_unmap(sws, st->hwbuf);
             }
          }
-         
+
          svga_transfer_dma_band(svga, st, transfer, y, h, srcy);
-         
+
          if(transfer == SVGA3D_READ_HOST_VRAM) {
             svga_context_flush(svga, &fence);
             sws->fence_finish(sws, fence, 0);
@@ -336,10 +343,10 @@ svga_texture_destroy(struct pipe_screen *screen,
  */
 static struct pipe_transfer *
 svga_texture_get_transfer(struct pipe_context *pipe,
-                         struct pipe_resource *texture,
-                         struct pipe_subresource sr,
-                         unsigned usage,
-                         const struct pipe_box *box)
+                          struct pipe_resource *texture,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box)
 {
    struct svga_context *svga = svga_context(pipe);
    struct svga_screen *ss = svga_screen(pipe->screen);
@@ -352,19 +359,20 @@ svga_texture_get_transfer(struct pipe_context *pipe,
    if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
       return NULL;
 
+   assert(box->depth == 1);
    st = CALLOC_STRUCT(svga_transfer);
    if (!st)
       return NULL;
-   
+
    pipe_resource_reference(&st->base.resource, texture);
-   st->base.sr = sr;
+   st->base.level = level;
    st->base.usage = usage;
    st->base.box = *box;
    st->base.stride = nblocksx*util_format_get_blocksize(texture->format);
-   st->base.slice_stride = 0;
+   st->base.layer_stride = 0;
 
    st->hw_nblocksy = nblocksy;
-   
+
    st->hwbuf = svga_winsys_buffer_create(svga,
                                          1, 
                                          0,
@@ -391,7 +399,7 @@ svga_texture_get_transfer(struct pipe_context *pipe,
       if(!st->swbuf)
          goto no_swbuf;
    }
-   
+
    if (usage & PIPE_TRANSFER_READ)
       svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM);
 
@@ -454,8 +462,11 @@ svga_texture_transfer_destroy(struct pipe_context *pipe,
    if (st->base.usage & PIPE_TRANSFER_WRITE) {
       svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM);
       ss->texture_timestamp++;
-      tex->view_age[transfer->sr.level] = ++(tex->age);
-      tex->defined[transfer->sr.face][transfer->sr.level] = TRUE;
+      tex->view_age[transfer->level] = ++(tex->age);
+      if (transfer->resource->target == PIPE_TEXTURE_CUBE)
+         tex->defined[transfer->box.z][transfer->level] = TRUE;
+      else
+         tex->defined[0][transfer->level] = TRUE;
    }
 
    pipe_resource_reference(&st->base.resource, NULL);
@@ -490,7 +501,7 @@ svga_texture_create(struct pipe_screen *screen,
 {
    struct svga_screen *svgascreen = svga_screen(screen);
    struct svga_texture *tex = CALLOC_STRUCT(svga_texture);
-   
+
    if (!tex)
       goto error1;
 
@@ -507,7 +518,7 @@ svga_texture_create(struct pipe_screen *screen,
    tex->key.size.width = template->width0;
    tex->key.size.height = template->height0;
    tex->key.size.depth = template->depth0;
-   
+
    if(template->target == PIPE_TEXTURE_CUBE) {
       tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
       tex->key.numFaces = 6;
index 631937f2eb099d961797ef565f9a44886df4f10c..9a2911c2a95d9d7f5347efc926878de6aeeb26ba 100644 (file)
@@ -85,6 +85,8 @@ struct svga_transfer
 {
    struct pipe_transfer base;
 
+   unsigned face;
+
    struct svga_winsys_buffer *hwbuf;
 
    /* Height of the hardware buffer in pixel blocks */
index af99c41901058ec6b926ec22707385e5e2d0dc4f..078190342a139f9f246bc3bdbef7fef5f9b4739e 100644 (file)
@@ -237,6 +237,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
       case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
       case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
          return 0;
+      case PIPE_SHADER_CAP_SUBROUTINES:
+         return 0;
       }
       break;
    case PIPE_SHADER_VERTEX:
@@ -276,6 +278,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
          return 0;
       case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
          return 1;
+      case PIPE_SHADER_CAP_SUBROUTINES:
+         return 0;
       default:
          break;
       }
@@ -495,7 +499,6 @@ svga_screen_create(struct svga_winsys_screen *sws)
    screen->fence_finish = svga_fence_finish;
    svgascreen->sws = sws;
 
-   svga_screen_init_surface_functions(screen);
    svga_init_screen_resource_functions(svgascreen);
 
    svgascreen->use_ps30 =
index d34d68f5350f44642d8127cde9ed25bf07dc42b3..66fea02a4becbcba7b56ae01076b1a078b203a80 100644 (file)
@@ -114,7 +114,7 @@ static int update_need_pipeline( struct svga_context *svga,
    /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
     */
    if (svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim)) {
-      SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (%d) & prim (%x)\n", 
+      SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (0x%x) & prim (0x%x)\n",
                  __FUNCTION__,
                  svga->curr.rast->need_pipeline,
                  (1 << svga->curr.reduced_prim) );
index 4a50b19474c10214e4ae3b7fc853d76c4988df94..f8b269a101efd2df77ca47eb93ea2282cd4d81f4 100644 (file)
@@ -238,7 +238,6 @@ update_tss(struct svga_context *svga,
          // TEXCOORDINDEX -- hopefully not needed
 
          if (svga->curr.tex_flags.flag_1d & (1 << i)) {
-            debug_printf("wrap 1d tex %d\n", i);
             EMIT_TS(svga, i, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV, fail);
          }
          else
index b21dc5fd9afcaf64338aacd9f7a3df009a4af1ec..3e4bed76c052295dd00d20d25e23f4015c2cf67b 100644 (file)
@@ -179,36 +179,50 @@ svga_texture_view_surface(struct pipe_context *pipe,
 
 
 static struct pipe_surface *
-svga_get_tex_surface(struct pipe_screen *screen,
-                     struct pipe_resource *pt,
-                     unsigned face, unsigned level, unsigned zslice,
-                     unsigned flags)
+svga_create_surface(struct pipe_context *pipe,
+                    struct pipe_resource *pt,
+                    const struct pipe_surface *surf_tmpl)
 {
    struct svga_texture *tex = svga_texture(pt);
+   struct pipe_screen *screen = pipe->screen;
    struct svga_surface *s;
-   boolean render = (flags & (PIPE_BIND_RENDER_TARGET |
-                             PIPE_BIND_DEPTH_STENCIL)) ? TRUE : FALSE;
+   unsigned face, zslice;
+   /* XXX surfaces should only be used for rendering purposes nowadays */
+   boolean render = (surf_tmpl->usage & (PIPE_BIND_RENDER_TARGET |
+                                         PIPE_BIND_DEPTH_STENCIL)) ? TRUE : FALSE;
    boolean view = FALSE;
    SVGA3dSurfaceFormat format;
 
+   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+
    s = CALLOC_STRUCT(svga_surface);
    if (!s)
       return NULL;
 
+   if (pt->target == PIPE_TEXTURE_CUBE) {
+         face = surf_tmpl->u.tex.first_layer;
+         zslice = 0;
+   }
+   else {
+      face = 0;
+      zslice = surf_tmpl->u.tex.first_layer;
+   }
+
    pipe_reference_init(&s->base.reference, 1);
    pipe_resource_reference(&s->base.texture, pt);
-   s->base.format = pt->format;
-   s->base.width = u_minify(pt->width0, level);
-   s->base.height = u_minify(pt->height0, level);
-   s->base.usage = flags;
-   s->base.level = level;
-   s->base.face = face;
-   s->base.zslice = zslice;
+   s->base.context = pipe;
+   s->base.format = surf_tmpl->format;
+   s->base.width = u_minify(pt->width0, surf_tmpl->u.tex.level);
+   s->base.height = u_minify(pt->height0, surf_tmpl->u.tex.level);
+   s->base.usage = surf_tmpl->usage;
+   s->base.u.tex.level = surf_tmpl->u.tex.level;
+   s->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+   s->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
 
    if (!render)
-      format = svga_translate_format(pt->format);
+      format = svga_translate_format(surf_tmpl->format);
    else
-      format = svga_translate_format_render(pt->format);
+      format = svga_translate_format_render(surf_tmpl->format);
 
    assert(format != SVGA3D_FORMAT_INVALID);
 
@@ -217,11 +231,11 @@ svga_get_tex_surface(struct pipe_screen *screen,
 
    /* Currently only used for compressed textures */
    if (render && 
-       format != svga_translate_format(pt->format)) {
+       format != svga_translate_format(surf_tmpl->format)) {
       view = TRUE;
    }
 
-   if (level != 0 && 
+   if (surf_tmpl->u.tex.level != 0 &&
        svga_screen(screen)->debug.force_level_surface_view)
       view = TRUE;
 
@@ -233,22 +247,22 @@ svga_get_tex_surface(struct pipe_screen *screen,
 
    if (view) {
       SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
-               pt, level, face, zslice, s);
+               pt, surf_tmpl->u.tex.level, face, zslice, s);
 
-      s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
-                                            &s->key);
+      s->handle = svga_texture_view_surface(NULL, tex, format, surf_tmpl->u.tex.level,
+                                           1, face, zslice, &s->key);
       s->real_face = 0;
       s->real_level = 0;
       s->real_zslice = 0;
    } else {
       SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
-               pt, level, face, zslice, s);
+               pt, surf_tmpl->u.tex.level, face, zslice, s);
 
       memset(&s->key, 0, sizeof s->key);
       s->handle = tex->handle;
       s->real_face = face;
-      s->real_level = level;
       s->real_zslice = zslice;
+      s->real_level = surf_tmpl->u.tex.level;
    }
 
    return &s->base;
@@ -256,7 +270,8 @@ svga_get_tex_surface(struct pipe_screen *screen,
 
 
 static void
-svga_tex_surface_destroy(struct pipe_surface *surf)
+svga_surface_destroy(struct pipe_context *pipe,
+                     struct pipe_surface *surf)
 {
    struct svga_surface *s = svga_surface(surf);
    struct svga_texture *t = svga_texture(surf->texture);
@@ -282,8 +297,13 @@ svga_mark_surface_dirty(struct pipe_surface *surf)
 
       s->dirty = TRUE;
 
-      if (s->handle == tex->handle)
-         tex->defined[surf->face][surf->level] = TRUE;
+      if (s->handle == tex->handle) {
+         /* hmm so 3d textures always have all their slices marked ? */
+         if (surf->texture->target == PIPE_TEXTURE_CUBE)
+            tex->defined[surf->u.tex.first_layer][surf->u.tex.level] = TRUE;
+         else
+            tex->defined[0][surf->u.tex.level] = TRUE;
+      }
       else {
          /* this will happen later in svga_propagate_surface */
       }
@@ -314,22 +334,32 @@ svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf)
    struct svga_surface *s = svga_surface(surf);
    struct svga_texture *tex = svga_texture(surf->texture);
    struct svga_screen *ss = svga_screen(surf->texture->screen);
+   unsigned zslice, face;
 
    if (!s->dirty)
       return;
 
+   if (surf->texture->target == PIPE_TEXTURE_CUBE) {
+      zslice = 0;
+      face = surf->u.tex.first_layer;
+   }
+   else {
+      zslice = surf->u.tex.first_layer;
+      face = 0;
+   }
+
    s->dirty = FALSE;
    ss->texture_timestamp++;
-   tex->view_age[surf->level] = ++(tex->age);
+   tex->view_age[surf->u.tex.level] = ++(tex->age);
 
    if (s->handle != tex->handle) {
-      SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf);
+      SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->u.tex.level, surf);
       svga_texture_copy_handle(svga_context(pipe),
                                s->handle, 0, 0, 0, s->real_level, s->real_face,
-                               tex->handle, 0, 0, surf->zslice, surf->level, surf->face,
-                               u_minify(tex->b.b.width0, surf->level),
-                               u_minify(tex->b.b.height0, surf->level), 1);
-      tex->defined[surf->face][surf->level] = TRUE;
+                               tex->handle, 0, 0, zslice, surf->u.tex.level, face,
+                               u_minify(tex->b.b.width0, surf->u.tex.level),
+                               u_minify(tex->b.b.height0, surf->u.tex.level), 1);
+      tex->defined[face][surf->u.tex.level] = TRUE;
    }
 }
 
@@ -351,9 +381,9 @@ svga_surface_needs_propagation(struct pipe_surface *surf)
 
 
 void
-svga_screen_init_surface_functions(struct pipe_screen *screen)
+svga_init_surface_functions(struct svga_context *svga)
 {
-   screen->get_tex_surface = svga_get_tex_surface;
-   screen->tex_surface_destroy = svga_tex_surface_destroy;
+   svga->pipe.create_surface = svga_create_surface;
+   svga->pipe.surface_destroy = svga_surface_destroy;
 }
 
index 13bd5b19b61f248aebb16a2983d237f80fa8cc23..afb8326e1f38703de365dc9c32d951daf2b7d332 100644 (file)
@@ -90,7 +90,4 @@ svga_surface(struct pipe_surface *surface)
    return (struct svga_surface *)surface;
 }
 
-void
-svga_screen_init_surface_functions(struct pipe_screen *screen);
-
 #endif
index 04f30f82c3d92fe38eaca47696740957f98b6ee4..eaabae8ce422137eb4564fc9d6a1035cd9ad3557 100644 (file)
@@ -314,6 +314,9 @@ trace_context_bind_vertex_sampler_states(struct pipe_context *_pipe,
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
 
+   if (!pipe->bind_vertex_sampler_states)
+      return;
+
    trace_dump_call_begin("pipe_context", "bind_vertex_sampler_states");
 
    trace_dump_arg(ptr, pipe);
@@ -885,6 +888,60 @@ trace_sampler_view_destroy(struct pipe_context *_pipe,
    FREE(_view);
 }
 
+/********************************************************************
+ * surface
+ */
+
+
+static struct pipe_surface *
+trace_create_surface(struct pipe_context *_pipe,
+                     struct pipe_resource *_texture,
+                     const struct pipe_surface *surf_tmpl)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct trace_resource *tr_tex = trace_resource(_texture);
+   struct pipe_context *pipe = tr_ctx->pipe;
+   struct pipe_resource *texture = tr_tex->resource;
+   struct pipe_surface *result = NULL;
+
+   trace_dump_call_begin("pipe_context", "create_surface");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(ptr, texture);
+   /* hmm some values unitialized there */
+   trace_dump_arg(surface, surf_tmpl);
+
+   result = pipe->create_surface(pipe, texture, surf_tmpl);
+
+   trace_dump_ret(ptr, result);
+
+   trace_dump_call_end();
+
+   result = trace_surf_create(tr_tex, result);
+
+   return result;
+}
+
+
+static void
+trace_surface_destroy(struct pipe_context *_pipe,
+                      struct pipe_surface *_surface)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+   struct trace_surface *tr_surf = trace_surface(_surface);
+   struct pipe_surface *surface = tr_surf->surface;
+
+   trace_dump_call_begin("pipe_context", "surface_destroy");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(ptr, surface);
+
+   trace_dump_call_end();
+
+   trace_surf_destroy(tr_surf);
+}
+
 
 static INLINE void
 trace_context_set_fragment_sampler_views(struct pipe_context *_pipe,
@@ -926,6 +983,9 @@ trace_context_set_vertex_sampler_views(struct pipe_context *_pipe,
    struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
    unsigned i;
 
+   if (!pipe->set_vertex_sampler_views)
+      return;
+
    for(i = 0; i < num; ++i) {
       tr_view = trace_sampler_view(views[i]);
       unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;
@@ -1004,12 +1064,11 @@ trace_context_set_index_buffer(struct pipe_context *_pipe,
 static INLINE void
 trace_context_resource_copy_region(struct pipe_context *_pipe,
                                    struct pipe_resource *dst,
-                                   struct pipe_subresource subdst,
+                                   unsigned dst_level,
                                    unsigned dstx, unsigned dsty, unsigned dstz,
                                    struct pipe_resource *src,
-                                   struct pipe_subresource subsrc,
-                                   unsigned srcx, unsigned srcy, unsigned srcz,
-                                   unsigned width, unsigned height)
+                                   unsigned src_level,
+                                   const struct pipe_box *src_box)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
@@ -1021,21 +1080,17 @@ trace_context_resource_copy_region(struct pipe_context *_pipe,
 
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, dst);
-   trace_dump_arg_struct(subresource, subdst);
+   trace_dump_arg(uint, dst_level);
    trace_dump_arg(uint, dstx);
    trace_dump_arg(uint, dsty);
    trace_dump_arg(uint, dstz);
    trace_dump_arg(ptr, src);
-   trace_dump_arg_struct(subresource, subsrc);
-   trace_dump_arg(uint, srcx);
-   trace_dump_arg(uint, srcy);
-   trace_dump_arg(uint, srcz);
-   trace_dump_arg(uint, width);
-   trace_dump_arg(uint, height);
+   trace_dump_arg(uint, src_level);
+   trace_dump_arg(box, src_box);
 
    pipe->resource_copy_region(pipe,
-                              dst, subdst, dstx, dsty, dstz,
-                              src, subsrc, srcx, srcy, srcz, width, height);
+                              dst, dst_level, dstx, dsty, dstz,
+                              src, src_level, src_box);
 
    trace_dump_call_end();
 }
@@ -1166,8 +1221,8 @@ trace_context_destroy(struct pipe_context *_pipe)
 
 static unsigned int
 trace_is_resource_referenced( struct pipe_context *_pipe,
-                             struct pipe_resource *_resource,
-                             unsigned face, unsigned level)
+                              struct pipe_resource *_resource,
+                              unsigned level, int layer)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct trace_resource *tr_tex = trace_resource(_resource);
@@ -1178,10 +1233,10 @@ trace_is_resource_referenced( struct pipe_context *_pipe,
    trace_dump_call_begin("pipe_context", "is_resource_referenced");
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, texture);
-   trace_dump_arg(uint, face);
    trace_dump_arg(uint, level);
+   trace_dump_arg(int, layer);
 
-   referenced = pipe->is_resource_referenced(pipe, texture, face, level);
+   referenced = pipe->is_resource_referenced(pipe, texture, level, layer);
 
    trace_dump_ret(uint, referenced);
    trace_dump_call_end();
@@ -1197,10 +1252,10 @@ trace_is_resource_referenced( struct pipe_context *_pipe,
 
 static struct pipe_transfer *
 trace_context_get_transfer(struct pipe_context *_context,
-                          struct pipe_resource *_resource,
-                          struct pipe_subresource sr,
-                          unsigned usage,
-                          const struct pipe_box *box)
+                           struct pipe_resource *_resource,
+                           unsigned level,
+                           unsigned usage,
+                           const struct pipe_box *box)
 {
    struct trace_context *tr_context = trace_context(_context);
    struct trace_resource *tr_tex = trace_resource(_resource);
@@ -1215,7 +1270,7 @@ trace_context_get_transfer(struct pipe_context *_context,
     * to transfer_inline_write and ignore read transfers.
     */
 
-   result = context->get_transfer(context, texture, sr, usage, box);
+   result = context->get_transfer(context, texture, level, usage, box);
 
    if (result)
       result = trace_transfer_create(tr_context, tr_tex, result);
@@ -1226,7 +1281,7 @@ trace_context_get_transfer(struct pipe_context *_context,
 
 static void
 trace_context_transfer_destroy(struct pipe_context *_context,
-                                   struct pipe_transfer *_transfer)
+                               struct pipe_transfer *_transfer)
 {
    struct trace_context *tr_context = trace_context(_context);
    struct trace_transfer *tr_trans = trace_transfer(_transfer);
@@ -1274,7 +1329,7 @@ trace_context_transfer_flush_region( struct pipe_context *_context,
 
 static void
 trace_context_transfer_unmap(struct pipe_context *_context,
-                            struct pipe_transfer *_transfer)
+                             struct pipe_transfer *_transfer)
 {
    struct trace_context *tr_ctx = trace_context(_context);
    struct trace_transfer *tr_trans = trace_transfer(_transfer);
@@ -1287,17 +1342,17 @@ trace_context_transfer_unmap(struct pipe_context *_context,
        */
 
       struct pipe_resource *resource = transfer->resource;
-      struct pipe_subresource sr = transfer->sr;
+      unsigned level = transfer->level;
       unsigned usage = transfer->usage;
       const struct pipe_box *box = &transfer->box;
       unsigned stride = transfer->stride;
-      unsigned slice_stride = transfer->slice_stride;
+      unsigned layer_stride = transfer->layer_stride;
 
       trace_dump_call_begin("pipe_context", "transfer_inline_write");
 
       trace_dump_arg(ptr, context);
       trace_dump_arg(ptr, resource);
-      trace_dump_arg_struct(subresource, sr);
+      trace_dump_arg(uint, level);
       trace_dump_arg(uint, usage);
       trace_dump_arg(box, box);
 
@@ -1306,11 +1361,11 @@ trace_context_transfer_unmap(struct pipe_context *_context,
                            resource->format,
                            box,
                            stride,
-                           slice_stride);
+                           layer_stride);
       trace_dump_arg_end();
 
       trace_dump_arg(uint, stride);
-      trace_dump_arg(uint, slice_stride);
+      trace_dump_arg(uint, layer_stride);
 
       trace_dump_call_end();
 
@@ -1323,13 +1378,13 @@ trace_context_transfer_unmap(struct pipe_context *_context,
 
 static void
 trace_context_transfer_inline_write(struct pipe_context *_context,
-                                   struct pipe_resource *_resource,
-                                   struct pipe_subresource sr,
-                                   unsigned usage,
-                                   const struct pipe_box *box,
-                                   const void *data,
-                                   unsigned stride,
-                                   unsigned slice_stride)
+                                    struct pipe_resource *_resource,
+                                    unsigned level,
+                                    unsigned usage,
+                                    const struct pipe_box *box,
+                                    const void *data,
+                                    unsigned stride,
+                                    unsigned layer_stride)
 {
    struct trace_context *tr_context = trace_context(_context);
    struct trace_resource *tr_tex = trace_resource(_resource);
@@ -1342,7 +1397,7 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
 
    trace_dump_arg(ptr, context);
    trace_dump_arg(ptr, resource);
-   trace_dump_arg_struct(subresource, sr);
+   trace_dump_arg(uint, level);
    trace_dump_arg(uint, usage);
    trace_dump_arg(box, box);
 
@@ -1351,16 +1406,16 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
                         resource->format,
                         box,
                         stride,
-                        slice_stride);
+                        layer_stride);
    trace_dump_arg_end();
 
    trace_dump_arg(uint, stride);
-   trace_dump_arg(uint, slice_stride);
+   trace_dump_arg(uint, layer_stride);
 
    trace_dump_call_end();
 
    context->transfer_inline_write(context, resource,
-                                 sr, usage, box, data, stride, slice_stride);
+                                  level, usage, box, data, stride, layer_stride);
 }
 
 
@@ -1434,6 +1489,8 @@ trace_context_create(struct trace_screen *tr_scr,
    tr_ctx->base.set_vertex_sampler_views = trace_context_set_vertex_sampler_views;
    tr_ctx->base.create_sampler_view = trace_create_sampler_view;
    tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;
+   tr_ctx->base.create_surface = trace_create_surface;
+   tr_ctx->base.surface_destroy = trace_surface_destroy;
    tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
    tr_ctx->base.set_index_buffer = trace_context_set_index_buffer;
    tr_ctx->base.resource_copy_region = trace_context_resource_copy_region;
index 8f816060324d50558940d1ccc5165cc97d29c5b2..155c869fbd95652725ec7e5868025b3bf9e4649d 100644 (file)
@@ -71,6 +71,10 @@ void trace_dump_resource_template(const struct pipe_resource *templat)
    trace_dump_uint(templat->depth0);
    trace_dump_member_end();
 
+   trace_dump_member_begin("array_size");
+   trace_dump_uint(templat->array_size);
+   trace_dump_member_end();
+
    trace_dump_member(uint, templat, last_level);
    trace_dump_member(uint, templat, usage);
    trace_dump_member(uint, templat, bind);
@@ -80,25 +84,6 @@ void trace_dump_resource_template(const struct pipe_resource *templat)
 }
 
 
-void trace_dump_subresource(const struct pipe_subresource *subresource)
-{
-   if (!trace_dumping_enabled_locked())
-      return;
-
-   if(!subresource) {
-      trace_dump_null();
-      return;
-   }
-
-   trace_dump_struct_begin("pipe_subresource");
-
-   trace_dump_member(uint, subresource, face);
-   trace_dump_member(uint, subresource, level);
-
-   trace_dump_struct_end();
-}
-
-
 void trace_dump_box(const struct pipe_box *box)
 {
    if (!trace_dumping_enabled_locked())
@@ -445,8 +430,13 @@ void trace_dump_sampler_view_template(const struct pipe_sampler_view *state)
    trace_dump_struct_begin("pipe_sampler_view");
 
    trace_dump_member(format, state, format);
-   trace_dump_member(uint, state, first_level);
-   trace_dump_member(uint, state, last_level);
+   /* XXX */
+   trace_dump_member(uint, state, u.tex.first_level);
+   trace_dump_member(uint, state, u.tex.last_level);
+   trace_dump_member(uint, state, u.tex.first_layer);
+   trace_dump_member(uint, state, u.tex.last_layer);
+   trace_dump_member(uint, state, u.buf.first_element);
+   trace_dump_member(uint, state, u.buf.last_element);
    trace_dump_member(uint, state, swizzle_r);
    trace_dump_member(uint, state, swizzle_g);
    trace_dump_member(uint, state, swizzle_b);
@@ -472,14 +462,14 @@ void trace_dump_surface(const struct pipe_surface *state)
    trace_dump_member(uint, state, width);
    trace_dump_member(uint, state, height);
 
-   trace_dump_member(uint, state, layout);
-   trace_dump_member(uint, state, offset);
    trace_dump_member(uint, state, usage);
 
    trace_dump_member(ptr, state, texture);
-   trace_dump_member(uint, state, face);
-   trace_dump_member(uint, state, level);
-   trace_dump_member(uint, state, zslice);
+   trace_dump_member(uint, state, u.tex.level);
+   trace_dump_member(uint, state, u.tex.first_layer);
+   trace_dump_member(uint, state, u.tex.last_layer);
+   trace_dump_member(uint, state, u.buf.first_element);
+   trace_dump_member(uint, state, u.buf.last_element);
 
    trace_dump_struct_end();
 }
@@ -497,16 +487,18 @@ void trace_dump_transfer(const struct pipe_transfer *state)
 
    trace_dump_struct_begin("pipe_transfer");
 
+   trace_dump_member(uint, state, box.x);
+   trace_dump_member(uint, state, box.y);
+   trace_dump_member(uint, state, box.z);
    trace_dump_member(uint, state, box.width);
    trace_dump_member(uint, state, box.height);
+   trace_dump_member(uint, state, box.depth);
 
    trace_dump_member(uint, state, stride);
+   trace_dump_member(uint, state, layer_stride);
    trace_dump_member(uint, state, usage);
 
    trace_dump_member(ptr, state, resource);
-   trace_dump_member(uint, state, sr.face);
-   trace_dump_member(uint, state, sr.level);
-   trace_dump_member(uint, state, box.z);
 
    trace_dump_struct_end();
 }
index 078d20861096fc0fba8930da497f8bf8c336cde3..fe8ece78d437e00bbd9535fb31ca6bb139491e2d 100644 (file)
@@ -37,8 +37,6 @@ void trace_dump_format(enum pipe_format format);
 
 void trace_dump_resource_template(const struct pipe_resource *templat);
 
-void trace_dump_subresource(const struct pipe_subresource *subresource);
-
 void trace_dump_box(const struct pipe_box *box);
 
 void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state);
index 935831071e62dd34a07e93874cc6b95b98ccb91d..c2de2daa883bba8d35e40f5f59dbf9bc5c782d3e 100644 (file)
@@ -210,23 +210,26 @@ trace_screen_context_create(struct pipe_screen *_screen, void *priv)
 
 static void
 trace_screen_flush_frontbuffer(struct pipe_screen *_screen,
-                               struct pipe_surface *_surface,
+                               struct pipe_resource *_resource,
+                               unsigned level, unsigned layer,
                                void *context_private)
 {
    struct trace_screen *tr_scr = trace_screen(_screen);
-   struct trace_surface *tr_surf = trace_surface(_surface);
+   struct trace_resource *tr_res = trace_resource(_resource);
    struct pipe_screen *screen = tr_scr->screen;
-   struct pipe_surface *surface = tr_surf->surface;
+   struct pipe_resource *resource = tr_res->resource;
 
    trace_dump_call_begin("pipe_screen", "flush_frontbuffer");
 
    trace_dump_arg(ptr, screen);
-   trace_dump_arg(ptr, surface);
+   trace_dump_arg(ptr, resource);
+   trace_dump_arg(uint, level);
+   trace_dump_arg(uint, layer);
    /* XXX: hide, as there is nothing we can do with this
    trace_dump_arg(ptr, context_private);
    */
 
-   screen->flush_frontbuffer(screen, surface, context_private);
+   screen->flush_frontbuffer(screen, resource, level, layer, context_private);
 
    trace_dump_call_end();
 }
@@ -318,68 +321,6 @@ trace_screen_resource_destroy(struct pipe_screen *_screen,
 }
 
 
-/********************************************************************
- * surface
- */
-
-
-static struct pipe_surface *
-trace_screen_get_tex_surface(struct pipe_screen *_screen,
-                             struct pipe_resource *_texture,
-                             unsigned face, unsigned level,
-                             unsigned zslice,
-                             unsigned usage)
-{
-   struct trace_screen *tr_scr = trace_screen(_screen);
-   struct trace_resource *tr_tex = trace_resource(_texture);
-   struct pipe_screen *screen = tr_scr->screen;
-   struct pipe_resource *texture = tr_tex->resource;
-   struct pipe_surface *result = NULL;
-
-   assert(texture->screen == screen);
-
-   trace_dump_call_begin("pipe_screen", "get_tex_surface");
-
-   trace_dump_arg(ptr, screen);
-   trace_dump_arg(ptr, texture);
-   trace_dump_arg(uint, face);
-   trace_dump_arg(uint, level);
-   trace_dump_arg(uint, zslice);
-   trace_dump_arg(uint, usage);
-
-   result = screen->get_tex_surface(screen, texture, face, level, zslice, usage);
-
-   trace_dump_ret(ptr, result);
-
-   trace_dump_call_end();
-
-   result = trace_surface_create(tr_tex, result);
-
-   return result;
-}
-
-
-static void
-trace_screen_tex_surface_destroy(struct pipe_surface *_surface)
-{
-   struct trace_screen *tr_scr = trace_screen(_surface->texture->screen);
-   struct trace_surface *tr_surf = trace_surface(_surface);
-   struct pipe_screen *screen = tr_scr->screen;
-   struct pipe_surface *surface = tr_surf->surface;
-
-   trace_dump_call_begin("pipe_screen", "tex_surface_destroy");
-
-   trace_dump_arg(ptr, screen);
-   trace_dump_arg(ptr, surface);
-
-   trace_dump_call_end();
-
-   trace_surface_destroy(tr_surf);
-}
-
-
-
-
 
 /********************************************************************
  * buffer
@@ -580,8 +521,6 @@ trace_screen_create(struct pipe_screen *screen)
    tr_scr->base.resource_from_handle = trace_screen_resource_from_handle;
    tr_scr->base.resource_get_handle = trace_screen_resource_get_handle;
    tr_scr->base.resource_destroy = trace_screen_resource_destroy;
-   tr_scr->base.get_tex_surface = trace_screen_get_tex_surface;
-   tr_scr->base.tex_surface_destroy = trace_screen_tex_surface_destroy;
    tr_scr->base.user_buffer_create = trace_screen_user_buffer_create;
    tr_scr->base.fence_reference = trace_screen_fence_reference;
    tr_scr->base.fence_signalled = trace_screen_fence_signalled;
index 9914b98b39cd17e75cff76e133b180438b895f9d..2799734647104c7470ec434fe06982065c2e786b 100644 (file)
@@ -74,8 +74,8 @@ trace_resource_destroy(struct trace_screen *tr_scr,
 
 
 struct pipe_surface *
-trace_surface_create(struct trace_resource *tr_tex,
-                     struct pipe_surface *surface)
+trace_surf_create(struct trace_resource *tr_tex,
+                  struct pipe_surface *surface)
 {
    struct trace_surface *tr_surf;
 
@@ -104,7 +104,7 @@ error:
 
 
 void
-trace_surface_destroy(struct trace_surface *tr_surf)
+trace_surf_destroy(struct trace_surface *tr_surf)
 {
    pipe_resource_reference(&tr_surf->base.texture, NULL);
    pipe_surface_reference(&tr_surf->surface, NULL);
index 6513995d505213a8ae879cedb44874f5790f4e2b..3352c96e59ab021293e427ca2cf3108a1342ecdb 100644 (file)
@@ -125,11 +125,11 @@ trace_resource_destroy(struct trace_screen *tr_scr,
                       struct trace_resource *tr_tex);
 
 struct pipe_surface *
-trace_surface_create(struct trace_resource *tr_tex,
+trace_surf_create(struct trace_resource *tr_tex,
                      struct pipe_surface *surface);
 
 void
-trace_surface_destroy(struct trace_surface *tr_surf);
+trace_surf_destroy(struct trace_surface *tr_surf);
 
 struct pipe_transfer *
 trace_transfer_create(struct trace_context *tr_ctx,
index 0e53aef6d2e277f318f1e81907920f557b5d737b..589cac2ddd3b85da1621fed21168a49ded05f01f 100644 (file)
@@ -54,7 +54,6 @@ struct pipe_scissor_state;
 struct pipe_shader_state;
 struct pipe_stencil_ref;
 struct pipe_stream_output_state;
-struct pipe_subresource;
 struct pipe_surface;
 struct pipe_vertex_buffer;
 struct pipe_vertex_element;
@@ -256,12 +255,11 @@ struct pipe_context {
     */
    void (*resource_copy_region)(struct pipe_context *pipe,
                                 struct pipe_resource *dst,
-                                struct pipe_subresource subdst,
+                                unsigned dst_level,
                                 unsigned dstx, unsigned dsty, unsigned dstz,
                                 struct pipe_resource *src,
-                                struct pipe_subresource subsrc,
-                                unsigned srcx, unsigned srcy, unsigned srcz,
-                                unsigned width, unsigned height);
+                                unsigned src_level,
+                                const struct pipe_box *src_box);
 
    /**
     * Resolve a multisampled resource into a non-multisampled one.
@@ -269,9 +267,9 @@ struct pipe_context {
     */
    void (*resource_resolve)(struct pipe_context *pipe,
                             struct pipe_resource *dst,
-                            struct pipe_subresource subdst,
+                            unsigned dst_layer,
                             struct pipe_resource *src,
-                            struct pipe_subresource subsrc);
+                            unsigned src_layer);
 
    /*@}*/
 
@@ -328,13 +326,13 @@ struct pipe_context {
     * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
     * \param pipe  context whose unflushed hw commands will be checked.
     * \param texture  texture to check.
-    * \param face  cubemap face. Use 0 for non-cubemap texture.
     * \param level  mipmap level.
+    * \param layer  cubemap face, 2d array or 3d slice, 0 otherwise. Use -1 for any layer.
     * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED
     */
    unsigned int (*is_resource_referenced)(struct pipe_context *pipe,
-                                         struct pipe_resource *texture,
-                                         unsigned face, unsigned level);
+                                          struct pipe_resource *texture,
+                                          unsigned level, int layer);
 
    /**
     * Create a view on a texture to be used by a shader stage.
@@ -347,6 +345,18 @@ struct pipe_context {
                                 struct pipe_sampler_view *view);
 
 
+   /**
+    * Get a surface which is a "view" into a resource, used by
+    * render target / depth stencil stages.
+    * \param usage  bitmaks of PIPE_BIND_* flags
+    */
+   struct pipe_surface *(*create_surface)(struct pipe_context *ctx,
+                                          struct pipe_resource *resource,
+                                          const struct pipe_surface *templat);
+
+   void (*surface_destroy)(struct pipe_context *ctx,
+                           struct pipe_surface *);
+
    /**
     * Get a transfer object for transferring data to/from a texture.
     *
@@ -354,14 +364,14 @@ struct pipe_context {
     * interleaved with
     */
    struct pipe_transfer *(*get_transfer)(struct pipe_context *,
-                                        struct pipe_resource *resource,
-                                        struct pipe_subresource,
-                                        unsigned usage,  /* a combination of PIPE_TRANSFER_x */
-                                        const struct pipe_box *);
+                                         struct pipe_resource *resource,
+                                         unsigned level,
+                                         unsigned usage,  /* a combination of PIPE_TRANSFER_x */
+                                         const struct pipe_box *);
 
    void (*transfer_destroy)(struct pipe_context *,
-                                struct pipe_transfer *);
-   
+                            struct pipe_transfer *);
+
    void *(*transfer_map)( struct pipe_context *,
                           struct pipe_transfer *transfer );
 
@@ -381,13 +391,13 @@ struct pipe_context {
     * pointer.  XXX: strides??
     */
    void (*transfer_inline_write)( struct pipe_context *,
-                                 struct pipe_resource *,
-                                 struct pipe_subresource,
-                                 unsigned usage, /* a combination of PIPE_TRANSFER_x */
-                                 const struct pipe_box *,
-                                 const void *data,
-                                 unsigned stride,
-                                 unsigned slice_stride);
+                                  struct pipe_resource *,
+                                  unsigned level,
+                                  unsigned usage, /* a combination of PIPE_TRANSFER_x */
+                                  const struct pipe_box *,
+                                  const void *data,
+                                  unsigned stride,
+                                  unsigned layer_stride);
 
 };
 
index ef09c3e7bb1e369b6286c394600b4059f0e474c3..7aaf611045669422a89abbb77ac229d5dfc62f78 100644 (file)
@@ -138,12 +138,14 @@ enum pipe_error {
 /** Texture types.
  * See the documentation for info on PIPE_TEXTURE_RECT vs PIPE_TEXTURE_2D */
 enum pipe_texture_target {
-   PIPE_BUFFER       = 0,
-   PIPE_TEXTURE_1D   = 1,
-   PIPE_TEXTURE_2D   = 2,
-   PIPE_TEXTURE_3D   = 3,
-   PIPE_TEXTURE_CUBE = 4,
-   PIPE_TEXTURE_RECT = 5,
+   PIPE_BUFFER           = 0,
+   PIPE_TEXTURE_1D       = 1,
+   PIPE_TEXTURE_2D       = 2,
+   PIPE_TEXTURE_3D       = 3,
+   PIPE_TEXTURE_CUBE     = 4,
+   PIPE_TEXTURE_RECT     = 5,
+   PIPE_TEXTURE_1D_ARRAY = 6,
+   PIPE_TEXTURE_2D_ARRAY = 7,
    PIPE_MAX_TEXTURE_TYPES
 };
 
@@ -178,14 +180,6 @@ enum pipe_texture_target {
 #define PIPE_TEX_COMPARE_NONE          0
 #define PIPE_TEX_COMPARE_R_TO_TEXTURE  1
 
-
-/**
- * Surface layout -- a hint?  Or some driver-internal poking out into
- * the interface?
- */
-#define PIPE_SURFACE_LAYOUT_LINEAR  0
-
-
 /**
  * Clear buffer bits
  */
@@ -281,9 +275,9 @@ enum pipe_transfer_usage {
  * Resource binding flags -- state tracker must specify in advance all
  * the ways a resource might be used.
  */
-#define PIPE_BIND_DEPTH_STENCIL        (1 << 0) /* get_tex_surface */
-#define PIPE_BIND_RENDER_TARGET        (1 << 1) /* get_tex_surface */
-#define PIPE_BIND_SAMPLER_VIEW         (1 << 2) /* get_sampler_view */
+#define PIPE_BIND_DEPTH_STENCIL        (1 << 0) /* create_surface */
+#define PIPE_BIND_RENDER_TARGET        (1 << 1) /* create_surface */
+#define PIPE_BIND_SAMPLER_VIEW         (1 << 2) /* create_sampler_view */
 #define PIPE_BIND_VERTEX_BUFFER        (1 << 3) /* set_vertex_buffers */
 #define PIPE_BIND_INDEX_BUFFER         (1 << 4) /* draw_elements */
 #define PIPE_BIND_CONSTANT_BUFFER      (1 << 5) /* set_constant_buffer */
@@ -461,6 +455,7 @@ enum pipe_cap {
    /** different blend funcs per rendertarget */
    PIPE_CAP_INDEP_BLEND_FUNC,
    PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE,
+   PIPE_CAP_ARRAY_TEXTURES,
    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,
@@ -489,6 +484,7 @@ enum pipe_shader_cap
    PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR,
    PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR,
    PIPE_SHADER_CAP_INDIRECT_CONST_ADDR,
+   PIPE_SHADER_CAP_SUBROUTINES, /* BGNSUB, ENDSUB, CAL, RET */
 };
 
 /**
index 2f22ac22bbf7ca1fd9eee4cadd0d1abf3f022058..ef03ed74a2075c153bbefaf62be6c42784f4c29c 100644 (file)
@@ -122,7 +122,7 @@ struct pipe_screen {
    /**
     * Create a texture from a winsys_handle. The handle is often created in
     * another process by first creating a pipe texture and then calling
-    * texture_get_handle.
+    * resource_get_handle.
     */
    struct pipe_resource * (*resource_from_handle)(struct pipe_screen *,
                                                  const struct pipe_resource *templat,
@@ -141,18 +141,6 @@ struct pipe_screen {
    void (*resource_destroy)(struct pipe_screen *,
                            struct pipe_resource *pt);
 
-   /** Get a 2D surface which is a "view" into a texture
-    * \param usage  bitmaks of PIPE_BIND_* flags
-    */
-   struct pipe_surface *(*get_tex_surface)(struct pipe_screen *,
-                                           struct pipe_resource *resource,
-                                           unsigned face, unsigned level,
-                                           unsigned zslice,
-                                           unsigned usage );
-
-   void (*tex_surface_destroy)(struct pipe_surface *);
-   
-
 
    /**
     * Create a buffer that wraps user-space data.
@@ -187,7 +175,8 @@ struct pipe_screen {
     *                                gets out-of-band
     */
    void (*flush_frontbuffer)( struct pipe_screen *screen,
-                              struct pipe_surface *surf,
+                              struct pipe_resource *resource,
+                              unsigned level, unsigned layer,
                               void *winsys_drawable_handle );
 
 
index fc6dba346daef50e81359cd06e50f2ff0a4ff797..226ae8667b703d17f12cbb920f9fd2914a1ab1c9 100644 (file)
@@ -271,25 +271,33 @@ struct pipe_sampler_state
 
 
 /**
- * 2D surface.  This is basically a view into a memory buffer.
- * May be a renderbuffer, texture mipmap level, etc.
+ * A view into a texture that can be bound to a color render target /
+ * depth stencil attachment point.
  */
 struct pipe_surface
 {
    struct pipe_reference reference;
    struct pipe_resource *texture; /**< resource into which this is a view  */
+   struct pipe_context *context; /**< context this view belongs to */
    enum pipe_format format;
 
+   /* XXX width/height should be removed */
    unsigned width;               /**< logical width in pixels */
    unsigned height;              /**< logical height in pixels */
 
-   unsigned layout;              /**< PIPE_SURFACE_LAYOUT_x */
-   unsigned offset;              /**< offset from start of buffer, in bytes */
    unsigned usage;               /**< bitmask of PIPE_BIND_x */
 
-   unsigned zslice;
-   unsigned face;
-   unsigned level;
+   union {
+      struct {
+         unsigned level;
+         unsigned first_layer:16;
+         unsigned last_layer:16;
+      } tex;
+      struct {
+         unsigned first_element;
+         unsigned last_element;
+      } buf;
+   } u;
 };
 
 
@@ -302,8 +310,18 @@ struct pipe_sampler_view
    enum pipe_format format;      /**< typed PIPE_FORMAT_x */
    struct pipe_resource *texture; /**< texture into which this is a view  */
    struct pipe_context *context; /**< context this view belongs to */
-   unsigned first_level:8;       /**< first mipmap level */
-   unsigned last_level:8;        /**< last mipmap level */
+   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 */
+      } tex;
+      struct {
+         unsigned first_element;
+         unsigned last_element;
+      } buf;
+   } u;
    unsigned swizzle_r:3;         /**< PIPE_SWIZZLE_x for red component */
    unsigned swizzle_g:3;         /**< PIPE_SWIZZLE_x for green component */
    unsigned swizzle_b:3;         /**< PIPE_SWIZZLE_x for blue component */
@@ -338,13 +356,14 @@ struct pipe_resource
    unsigned width0;
    unsigned height0;
    unsigned depth0;
+   unsigned array_size;
 
    unsigned last_level:8;    /**< Index of last mipmap level present/defined */
    unsigned nr_samples:8;    /**< for multisampled surfaces, nr of samples */
    unsigned usage:8;         /**< PIPE_USAGE_x (not a bitmask) */
 
-   unsigned bind;           /**< bitmask of PIPE_BIND_x */
-   unsigned flags;          /**< bitmask of PIPE_RESOURCE_FLAG_x */
+   unsigned bind;            /**< bitmask of PIPE_BIND_x */
+   unsigned flags;           /**< bitmask of PIPE_RESOURCE_FLAG_x */
 };
 
 struct pipe_stream_output_state
@@ -363,15 +382,6 @@ struct pipe_stream_output_state
    unsigned stride;
 };
 
-/**
- * Extra indexing info for (cube) texture resources.
- */
-struct pipe_subresource
-{
-   unsigned face:16;
-   unsigned level:16;
-};
-
 
 /**
  * Transfer object.  For data transfer to/from a resource.
@@ -379,11 +389,11 @@ struct pipe_subresource
 struct pipe_transfer
 {
    struct pipe_resource *resource; /**< resource to transfer to/from  */
-   struct pipe_subresource sr;
+   unsigned level;
    enum pipe_transfer_usage usage;
    struct pipe_box box;
    unsigned stride;
-   unsigned slice_stride;
+   unsigned layer_stride;
    void *data;
 };
 
index 294dc464c36a3f8b9c341d3981d8fa3d5641caa0..2dfdba413ac6d52173fd24d7300a854566f9e127 100644 (file)
@@ -74,6 +74,10 @@ struct pipe_video_context
 
    void (*destroy)(struct pipe_video_context *vpipe);
 
+   struct pipe_surface *(*create_surface)(struct pipe_video_context *vpipe,
+                                          struct pipe_resource *resource,
+                                          const struct pipe_surface *templat);
+
    /**
     * Picture decoding and displaying
     */
@@ -116,7 +120,7 @@ struct pipe_video_context
 
    struct pipe_transfer *(*get_transfer)(struct pipe_video_context *vpipe,
                                          struct pipe_resource *resource,
-                                         struct pipe_subresource subresource,
+                                         unsigned level,
                                          unsigned usage,  /* a combination of PIPE_TRANSFER_x */
                                          const struct pipe_box *box);
 
@@ -135,7 +139,7 @@ struct pipe_video_context
 
    void (*transfer_inline_write)(struct pipe_video_context *vpipe,
                                  struct pipe_resource *resource,
-                                 struct pipe_subresource subresource,
+                                 unsigned level,
                                  unsigned usage, /* a combination of PIPE_TRANSFER_x */
                                  const struct pipe_box *box,
                                  const void *data,
index 565a09614a4479ec5cd4734c1deaac0cb48ebf7d..1c2148b78f23d459960a63e829c5114f70bb6f35 100644 (file)
@@ -164,9 +164,8 @@ struct st_egl_image
    /* this is owned by the caller */
    struct pipe_resource *texture;
 
-   unsigned face;
    unsigned level;
-   unsigned zslice;
+   unsigned layer;
 };
 
 /**
index f22c22bb620216ab15bf11027f719de24231b915..4e7ccc13ac885c7f0196ece41c79538edc72e01f 100644 (file)
@@ -6,7 +6,7 @@
 
 
 struct pipe_screen;
-struct pipe_surface;
+struct pipe_resource;
 
 /* This is what the xlib software winsys expects to find in the
  * "private" field of flush_frontbuffers().
index c246fc5ef7616b0d6d5ed32cb35bf4d4ed79d68e..a54324a04f2eb1e4074fe7b1b91faee461bf2ec0 100644 (file)
@@ -1159,8 +1159,15 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                        unsigned blit_x, blit_y, blit_w, blit_h;
                        float black[4] = {0, 0, 0, 0};
 
-                       if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h)
-                               dst_surface = pipe->screen->get_tex_surface(pipe->screen, dst, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
+                       if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h) {
+                               struct pipe_surface templat;
+                               templat.usage = PIPE_BIND_RENDER_TARGET;
+                               templat.format = dst->format;
+                               templat.u.tex.level = 0;
+                               templat.u.tex.first_layer = 0;
+                               templat.u.tex.last_layer = 0;
+                               dst_surface = pipe->create_surface(pipe, dst, &templat);
+                       }
 
                        if(preserve_aspect_ratio)
                        {
@@ -1199,10 +1206,12 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
 
                        if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
                        {
-                               pipe_subresource sr;
-                               sr.face = 0;
-                               sr.level = 0;
-                               pipe->resource_copy_region(pipe, dst, sr, rect.left, rect.top, 0, src, sr, 0, 0, 0, blit_w, blit_h);
+                               pipe_box box;
+                               box.x = box.y = box.z;
+                               box.width = blit_w;
+                               box.height = blit_h;
+                               box.z = 1;
+                               pipe->resource_copy_region(pipe, dst, 0, rect.left, rect.top, 0, src, 0, &box);
                        }
                        else
                        {
@@ -1218,7 +1227,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                }
 
                if(dst_surface)
-                       pipe->screen->tex_surface_destroy(dst_surface);
+                       pipe->surface_destroy(pipe, dst_surface);
 
                pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0);
 
index 36110595c206fb4288741cb6a180c79def4780d7..e1ba6c184fdc9a939afa19e41f9f00efcf6ef8d9 100644 (file)
@@ -1416,23 +1416,33 @@ changed:
                        *out_predicate_value = render_predicate_value;
        }
 
-       static pipe_subresource d3d11_to_pipe_subresource(struct pipe_resource* resource, unsigned subresource)
+       static unsigned d3d11_subresource_to_level(struct pipe_resource* resource, unsigned subresource)
        {
-               pipe_subresource sr;
                if(subresource <= resource->last_level)
                {
-                       sr.level = subresource;
-                       sr.face = 0;
+                       return subresource;
                }
                else
                {
                        unsigned levels = resource->last_level + 1;
-                       sr.level = subresource % levels;
-                       sr.face = subresource / levels;
+                       return subresource % levels;
                }
-               return sr;
        }
 
+       static unsigned d3d11_subresource_to_face(struct pipe_resource* resource, unsigned subresource)
+       {
+               if(subresource <= resource->last_level)
+               {
+                       return 0;
+               }
+               else
+               {
+                       unsigned levels = resource->last_level + 1;
+                       return subresource / levels;
+               }
+       }
+               
+       
        /* TODO: deferred contexts will need a different implementation of this,
         * because we can't put the transfer info into the resource itself.
         * Also, there are very different restrictions, for obvious reasons.
@@ -1448,8 +1458,10 @@ changed:
                GalliumD3D11Resource<>* resource = (GalliumD3D11Resource<>*)iresource;
                if(resource->transfers.count(subresource))
                        return E_FAIL;
-               pipe_subresource sr = d3d11_to_pipe_subresource(resource->resource, subresource);
-               pipe_box box = d3d11_to_pipe_box(resource->resource, sr.level, 0);
+               unsigned level = d3d11_subresource_to_level(resource->resource, subresource);
+               unsigned face = d3d11_subresource_to_face(resource->resource, subresource);
+               pipe_box box = d3d11_to_pipe_box(resource->resource, level, 0);
+               /* XXX the translation from subresource to level/face(zslice/array layer) isn't quite right */
                unsigned usage = 0;
                if(map_type == D3D11_MAP_READ)
                        usage = PIPE_TRANSFER_READ;
@@ -1465,7 +1477,7 @@ changed:
                        return E_INVALIDARG;
                if(map_type & D3D10_MAP_FLAG_DO_NOT_WAIT)
                        usage |= PIPE_TRANSFER_DONTBLOCK;
-               struct pipe_transfer* transfer = pipe->get_transfer(pipe, resource->resource, sr, usage, &box);
+               struct pipe_transfer* transfer = pipe->get_transfer(pipe, resource->resource, level, usage, &box);
                if(!transfer) {
                        if(map_type & D3D10_MAP_FLAG_DO_NOT_WAIT)
                                return DXGI_ERROR_WAS_STILL_DRAWING;
@@ -1475,7 +1487,7 @@ changed:
                resource->transfers[subresource] = transfer;
                mapped_resource->pData = pipe->transfer_map(pipe, transfer);
                mapped_resource->RowPitch = transfer->stride;
-               mapped_resource->DepthPitch = transfer->slice_stride;
+               mapped_resource->DepthPitch = transfer->layer_stride;
                return S_OK;
        }
 
@@ -1507,15 +1519,16 @@ changed:
                SYNCHRONIZED;
                GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
                GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
-               pipe_subresource subdst = d3d11_to_pipe_subresource(dst->resource, dst_subresource);
-               pipe_subresource subsrc = d3d11_to_pipe_subresource(src->resource, src_subresource);
-               pipe_box box = d3d11_to_pipe_box(src->resource, subsrc.level, src_box);
-               for(unsigned i = 0; i < box.depth; ++i)
+               unsigned dst_level = d3d11_subresource_to_level(dst->resource, dst_subresource);
+               unsigned dst_face = d3d11_subresource_to_face(dst->resource, dst_subresource);
+               unsigned src_level = d3d11_subresource_to_level(src->resource, src_subresource);
+               unsigned src_face = d3d11_subresource_to_face(src->resource, src_subresource);
+               /* XXX the translation from subresource to level/face(zslice/array layer) isn't quite right */
+               pipe_box box = d3d11_to_pipe_box(src->resource, src_level, src_box);
                {
                        pipe->resource_copy_region(pipe,
-                               dst->resource, subdst, dst_x, dst_y, dst_z + i,
-                               src->resource, subsrc, box.x, box.y, box.z + i,
-                               box.width, box.height);
+                               dst->resource, dst_level, dst_x, dst_y, dst_z,
+                               src->resource, src_level, &box);
                }
        }
 
@@ -1526,24 +1539,23 @@ changed:
                SYNCHRONIZED;
                GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
                GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
-               pipe_subresource sr;
-               unsigned faces = dst->resource->target == PIPE_TEXTURE_CUBE ? 6 : 1;
-
-               for(sr.face = 0; sr.face < faces; ++sr.face)
+               unsigned level;
+               for(level = 0; level <= dst->resource->last_level; ++level)
                {
-                       for(sr.level = 0; sr.level <= dst->resource->last_level; ++sr.level)
-                       {
-                               unsigned w = u_minify(dst->resource->width0, sr.level);
-                               unsigned h = u_minify(dst->resource->height0, sr.level);
-                               unsigned d = u_minify(dst->resource->depth0, sr.level);
-                               for(unsigned i = 0; i < d; ++i)
-                               {
-                                       pipe->resource_copy_region(pipe,
-                                                       dst->resource, sr, 0, 0, i,
-                                                       src->resource, sr, 0, 0, i,
-                                                       w, h);
-                               }
-                       }
+                       unsigned layers = 1;
+                       pipe_box box;
+                       if (dst->resource->target == PIPE_TEXTURE_CUBE)
+                               layers = 6;
+                       else if (dst->resource->target == PIPE_TEXTURE_3D)
+                               layers = u_minify(dst->resource->depth0, level);
+                       /* else layers = dst->resource->array_size; */
+                       box.x = box.y = box.z = 0;
+                       box.width = u_minify(dst->resource->width0, level);
+                       box.height = u_minify(dst->resource->height0, level);
+                       box.depth = layers;
+                       pipe->resource_copy_region(pipe,
+                                                  dst->resource, level, 0, 0, 0,
+                                                  src->resource, level, &box);
                }
        }
 
@@ -1557,9 +1569,10 @@ changed:
        {
                SYNCHRONIZED;
                GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
-               pipe_subresource subdst = d3d11_to_pipe_subresource(dst->resource, dst_subresource);
-               pipe_box box = d3d11_to_pipe_box(dst->resource, subdst.level, pDstBox);
-               pipe->transfer_inline_write(pipe, dst->resource, subdst, PIPE_TRANSFER_WRITE, &box, pSrcData, src_row_pitch, src_depth_pitch);
+               unsigned dst_level = d3d11_subresource_to_level(dst->resource, dst_subresource);
+               /* XXX the translation from subresource to level/face(zslice/array layer) isn't quite right */
+               pipe_box box = d3d11_to_pipe_box(dst->resource, dst_level, pDstBox);
+               pipe->transfer_inline_write(pipe, dst->resource, dst_level, PIPE_TRANSFER_WRITE, &box, pSrcData, src_row_pitch, src_depth_pitch);
        }
 
 #if API >= 11
@@ -1714,9 +1727,9 @@ changed:
                SYNCHRONIZED;
                GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
                GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
-               pipe_subresource subdst = d3d11_to_pipe_subresource(dst->resource, dst_subresource);
-               pipe_subresource subsrc = d3d11_to_pipe_subresource(src->resource, src_subresource);
-               pipe->resource_resolve(pipe, dst->resource, subdst, src->resource, subsrc);
+               unsigned dst_layer = d3d11_subresource_to_face(dst->resource, dst_subresource);
+               unsigned src_layer = d3d11_subresource_to_face(src->resource, src_subresource);
+               pipe->resource_resolve(pipe, dst->resource, dst_layer, src->resource, src_layer);
        }
 
 #if API >= 11
index 95ea4e00fc18e5816a5b52ee312edce40d275d6b..9cfdc837d8e361cc12e50db5c4bd8469d0505e5b 100644 (file)
@@ -718,15 +718,13 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
                        {
                                for(unsigned level = 0; level <= templat.last_level; ++level)
                                {
-                                       struct pipe_subresource sr;
-                                       sr.level = level;
-                                       sr.face = slice;
                                        struct pipe_box box;
-                                       box.x = box.y = box.z = 0;
+                                       box.x = box.y = 0;
+                                       box.z = slice;
                                        box.width = u_minify(width, level);
                                        box.height = u_minify(height, level);
-                                       box.depth = u_minify(depth, level);
-                                       immediate_pipe->transfer_inline_write(immediate_pipe, resource, sr, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_UNSYNCHRONIZED, &box, initial_data->pSysMem, initial_data->SysMemPitch, initial_data->SysMemSlicePitch);
+                                       box.depth = 1;
+                                       immediate_pipe->transfer_inline_write(immediate_pipe, resource, level, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_UNSYNCHRONIZED, &box, initial_data->pSysMem, initial_data->SysMemPitch, initial_data->SysMemSlicePitch);
                                        ++initial_data;
                                }
                        }
@@ -978,8 +976,8 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
                case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
                case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
                        /* yes, this works for all of these types (but TODO: texture arrays) */
-                       templat.first_level = desc->Texture1D.MostDetailedMip;
-                       templat.last_level = templat.first_level + desc->Texture1D.MipLevels - 1;
+                       templat.u.tex.first_level = desc->Texture1D.MostDetailedMip;
+                       templat.u.tex.last_level = templat.u.tex.first_level + desc->Texture1D.MipLevels - 1;
                        break;
                case D3D11_SRV_DIMENSION_BUFFER:
                case D3D11_SRV_DIMENSION_TEXTURE2DMS:
@@ -1054,30 +1052,34 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
                        desc = &def_desc;
                }
 
-               unsigned zslice = 0;
-               unsigned face = 0;
-               unsigned level;
-               enum pipe_format format;
+               struct pipe_surface templat;
+               memset(&templat, 0, sizeof(templat));
                if(invalid(desc->format >= DXGI_FORMAT_COUNT))
                        return E_INVALIDARG;
-               format = dxgi_to_pipe_format[desc->Format];
-               if(!format)
+               templat.format = dxgi_to_pipe_format[desc->Format];
+               if(!templat.format)
                        return E_NOTIMPL;
+               templat.usage = PIPE_BIND_RENDER_TARGET;
+               templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
 
                switch(desc->ViewDimension)
                {
                case D3D11_RTV_DIMENSION_TEXTURE1D:
                case D3D11_RTV_DIMENSION_TEXTURE2D:
-                       level = desc->Texture1D.MipSlice;
+                       templat.u.tex.level = desc->Texture1D.MipSlice;
                        break;
                case D3D11_RTV_DIMENSION_TEXTURE3D:
-                       level = desc->Texture3D.MipSlice;
-                       zslice = desc->Texture3D.FirstWSlice;
+                       templat.u.tex.level = desc->Texture3D.MipSlice;
+                       templat.u.tex.first_layer = desc->Texture3D.FirstWSlice;
+                       /* XXX FIXME */
+                       templat.u.tex.last_layer = desc->Texture3D.FirstWSlice;
                        break;
                case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
                case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
-                       level = desc->Texture1DArray.MipSlice;
-                       face = desc->Texture1DArray.FirstArraySlice;
+                       templat.u.tex.level = desc->Texture1DArray.MipSlice;
+                       templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
+                       /* XXX FIXME */
+                       templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice;
                        break;
                case D3D11_RTV_DIMENSION_BUFFER:
                case D3D11_RTV_DIMENSION_TEXTURE2DMS:
@@ -1090,13 +1092,9 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
                if(!out_rtv)
                        return S_FALSE;
 
-               struct pipe_surface* surface = screen->get_tex_surface(screen,
-                               ((GalliumD3D11Resource<>*)iresource)->resource,
-                               face, level, zslice, PIPE_BIND_RENDER_TARGET);
+               struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat);
                if(!surface)
                        return E_FAIL;
-               /* muhahahahaha, let's hope this actually works */
-               surface->format = format;
                *out_rtv = new GalliumD3D11RenderTargetView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc);
                return S_OK;
        }
@@ -1134,26 +1132,28 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
                        desc = &def_desc;
                }
 
-               unsigned zslice = 0;
-               unsigned face = 0;
-               unsigned level;
-               enum pipe_format format;
+               struct pipe_surface templat;
+               memset(&templat, 0, sizeof(templat));
                if(invalid(desc->format >= DXGI_FORMAT_COUNT))
                        return E_INVALIDARG;
-               format = dxgi_to_pipe_format[desc->Format];
-               if(!format)
+               templat.format = dxgi_to_pipe_format[desc->Format];
+               if(!templat.format)
                        return E_NOTIMPL;
+               templat.usage = PIPE_BIND_DEPTH_STENCIL;
+               templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
 
                switch(desc->ViewDimension)
                {
                case D3D11_DSV_DIMENSION_TEXTURE1D:
                case D3D11_DSV_DIMENSION_TEXTURE2D:
-                       level = desc->Texture1D.MipSlice;
+                       templat.u.tex.level = desc->Texture1D.MipSlice;
                        break;
                case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
                case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
-                       level = desc->Texture1DArray.MipSlice;
-                       face = desc->Texture1DArray.FirstArraySlice;
+                       templat.u.tex.level = desc->Texture1DArray.MipSlice;
+                       templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
+                       /* XXX FIXME */
+                       templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice;
                        break;
                case D3D11_DSV_DIMENSION_TEXTURE2DMS:
                case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
@@ -1165,13 +1165,9 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
                if(!out_depth_stencil_view)
                        return S_FALSE;
 
-               struct pipe_surface* surface = screen->get_tex_surface(screen,
-                               ((GalliumD3D11Resource<>*)iresource)->resource,
-                               face, level, zslice, PIPE_BIND_DEPTH_STENCIL);
+               struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat);
                if(!surface)
                        return E_FAIL;
-               /* muhahahahaha, let's hope this actually works */
-               surface->format = format;
                *out_depth_stencil_view = new GalliumD3D11DepthStencilView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc);
                return S_OK;
        }
index 1302e9bc0134799dfc1b4174b799d5ff8904bdb5..f6e22c74b4e68fac3a7174c74c8f93d22241cd79 100644 (file)
@@ -304,9 +304,8 @@ dri_get_egl_image(struct st_manager *smapi,
 
    stimg->texture = NULL;
    pipe_resource_reference(&stimg->texture, img->texture);
-   stimg->face = img->face;
    stimg->level = img->level;
-   stimg->zslice = img->zslice;
+   stimg->layer = img->layer;
 
    return TRUE;
 }
index 0da9b5510fc55ed3568169a4cd13bcd090acfa58..8cb0a102c8d5e09cc3ece5a2ff83d58310fa68f3 100644 (file)
@@ -83,9 +83,8 @@ dri_screen(__DRIscreen * sPriv)
 
 struct __DRIimageRec {
    struct pipe_resource *texture;
-   unsigned face;
    unsigned level;
-   unsigned zslice;
+   unsigned layer;
 
    void *loader_private;
 };
index 3c5b0756174ab431878799fb4c0ce2a103b1ce87..a9d05a80fbd395c24c4b5c9115fe013ba378a299 100644 (file)
@@ -200,6 +200,7 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable,
    templ.width0 = dri_drawable->w;
    templ.height0 = dri_drawable->h;
    templ.depth0 = 1;
+   templ.array_size = 1;
 
    memset(&whandle, 0, sizeof(whandle));
 
@@ -348,6 +349,7 @@ dri2_create_image_from_name(__DRIscreen *_screen,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
 
    memset(&whandle, 0, sizeof(whandle));
    whandle.handle = name;
@@ -360,9 +362,8 @@ dri2_create_image_from_name(__DRIscreen *_screen,
       return NULL;
    }
 
-   img->face = 0;
    img->level = 0;
-   img->zslice = 0;
+   img->layer = 0;
    img->loader_private = loaderPrivate;
 
    return img;
@@ -430,9 +431,8 @@ dri2_create_image(__DRIscreen *_screen,
       return NULL;
    }
 
-   img->face = 0;
    img->level = 0;
-   img->zslice = 0;
+   img->layer = 0;
 
    img->loader_private = loaderPrivate;
    return img;
index c48cc4403674873b1eb68f3847391dc4a71348fc..30088b09685c940b9332029b377be596dd3897eb 100644 (file)
@@ -87,40 +87,17 @@ drisw_put_image(struct dri_drawable *drawable,
    put_image(dPriv, data, width, height);
 }
 
-static struct pipe_surface *
-drisw_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex)
-{
-   struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->base.screen;
-   struct pipe_surface *psurf = drawable->drisw_surface;
-
-   if (!psurf || psurf->texture != ptex) {
-      pipe_surface_reference(&drawable->drisw_surface, NULL);
-
-      drawable->drisw_surface = pipe_screen->get_tex_surface(pipe_screen,
-            ptex, 0, 0, 0, 0/* no bind flag???*/);
-
-      psurf = drawable->drisw_surface;
-   }
-
-   return psurf;
-}
-
 static INLINE void
 drisw_present_texture(__DRIdrawable *dPriv,
                       struct pipe_resource *ptex)
 {
    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct dri_screen *screen = dri_screen(drawable->sPriv);
-   struct pipe_surface *psurf;
 
    if (swrast_no_present)
       return;
 
-   psurf = drisw_get_pipe_surface(drawable, ptex);
-   if (!psurf)
-      return;
-
-   screen->base.screen->flush_frontbuffer(screen->base.screen, psurf, drawable);
+   screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable);
 }
 
 static INLINE void
@@ -220,6 +197,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.last_level = 0;
 
    for (i = 0; i < count; i++) {
index 72c14f0ac497d596e6f48384df26138ddd2a5c84..9873fee6ec28a573eae2aac02659365bc8b54c3b 100644 (file)
@@ -92,9 +92,8 @@ struct egl_g3d_config {
 struct egl_g3d_image {
    _EGLImage base;
    struct pipe_resource *texture;
-   unsigned face;
    unsigned level;
-   unsigned zslice;
+   unsigned layer;
 };
 
 /* standard typecasts */
index fd7dc8f81497f7f91d03d814967b7d0f19603d74..8e53e1dccbaecba3a450471f7b84aee67f0e79b5 100644 (file)
@@ -30,6 +30,7 @@
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
+#include "util/u_box.h"
 
 #include "egl_g3d.h"
 #include "egl_g3d_api.h"
@@ -140,11 +141,22 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
    if (!_eglParseConfigAttribList(&criteria, dpy, attribs))
       return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
 
-   tmp_configs = (_EGLConfig **) _eglFilterArray(dpy->Configs, &tmp_size,
+   /* get the number of matched configs */
+   tmp_size = _eglFilterArray(dpy->Configs, NULL, 0,
          (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
+   if (!tmp_size) {
+      *num_configs = tmp_size;
+      return EGL_TRUE;
+   }
+
+   tmp_configs = MALLOC(sizeof(tmp_configs[0]) * tmp_size);
    if (!tmp_configs)
       return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
 
+   /* get the matched configs */
+   _eglFilterArray(dpy->Configs, (void **) tmp_configs, tmp_size,
+         (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
+
    /* perform sorting of configs */
    if (tmp_configs && tmp_size) {
       _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size,
@@ -154,7 +166,7 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
          configs[i] = _eglGetConfigHandle(tmp_configs[i]);
    }
 
-   free(tmp_configs);
+   FREE(tmp_configs);
 
    *num_configs = size;
 
@@ -665,15 +677,11 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
    ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
    if (ptex) {
       struct pipe_resource *psrc = gsurf->render_texture;
-      struct pipe_subresource subsrc, subdst;
-      subsrc.face = 0;
-      subsrc.level = 0;
-      subdst.face = 0;
-      subdst.level = 0;
-
+      struct pipe_box src_box;
+      u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
       if (psrc) {
-         gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, subdst, 0, 0, 0,
-               gsurf->render_texture, subsrc, 0, 0, 0, ptex->width0, ptex->height0);
+         gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, 0, 0, 0, 0,
+               gsurf->render_texture, 0, &src_box);
          nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
       }
 
index 6a1f8cc697b5144bbe39138672639f73fbb30972..b2d6b433c5e009ce2fb8c3c510e5662dacb812fc 100644 (file)
@@ -173,6 +173,7 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
    templ.width0 = attrs.Width;
    templ.height0 = attrs.Height;
    templ.depth0 = 1;
+   templ.array_size = 1;
 
    memset(&wsh, 0, sizeof(wsh));
    wsh.handle = (unsigned) name;
@@ -191,7 +192,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
 {
    struct pipe_resource *ptex;
    struct egl_g3d_image *gimg;
-   unsigned face = 0, level = 0, zslice = 0;
+   unsigned level = 0, layer = 0;
 
    gimg = CALLOC_STRUCT(egl_g3d_image);
    if (!gimg) {
@@ -231,7 +232,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
       FREE(gimg);
       return NULL;
    }
-   if (zslice > ptex->depth0) {
+   if (layer >= (u_minify(ptex->depth0, level) + ptex->array_size - 1)) {
       _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
       pipe_resource_reference(&gimg->texture, NULL);
       FREE(gimg);
@@ -240,9 +241,8 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
 
    /* transfer the ownership to the image */
    gimg->texture = ptex;
-   gimg->face = face;
    gimg->level = level;
-   gimg->zslice = zslice;
+   gimg->layer = layer;
 
    return &gimg->base;
 }
@@ -288,9 +288,8 @@ egl_g3d_create_drm_image(_EGLDriver *drv, _EGLDisplay *dpy,
 
    /* transfer the ownership to the image */
    gimg->texture = ptex;
-   gimg->face = 0;
    gimg->level = 0;
-   gimg->zslice = 0;
+   gimg->layer = 0;
 
    return &gimg->base;
 }
index 25e2999590c21f1643d762826a2169729b67fd10..2b944b521a495cd12e8efadc1091436036c01463 100644 (file)
@@ -72,9 +72,8 @@ egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
 
    out->texture = NULL;
    pipe_resource_reference(&out->texture, gimg->texture);
-   out->face = gimg->face;
    out->level = gimg->level;
-   out->zslice = gimg->zslice;
+   out->layer = gimg->layer;
 
    _eglUnlockMutex(&gsmapi->display->Mutex);
 
@@ -140,6 +139,7 @@ pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
    templ.width0 = gsurf->base.Width;
    templ.height0 = gsurf->base.Height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.format = gsurf->stvis.color_format;
    templ.bind = PIPE_BIND_RENDER_TARGET;
 
index 7832b2b693f572d904183a8cbe2d2e8ca12be663..0f2d02032b575707d08ce7f587c503fa44030640 100644 (file)
@@ -40,7 +40,6 @@ struct resource_surface {
    uint bind;
 
    struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
-   struct pipe_surface *present_surfaces[NUM_NATIVE_ATTACHMENTS];
    uint resource_mask;
    uint width, height;
 };
@@ -67,8 +66,6 @@ resource_surface_free_resources(struct resource_surface *rsurf)
       int i;
 
       for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
-         if (rsurf->present_surfaces[i])
-            pipe_surface_reference(&rsurf->present_surfaces[i], NULL);
          if (rsurf->resources[i])
             pipe_resource_reference(&rsurf->resources[i], NULL);
       }
@@ -130,6 +127,7 @@ resource_surface_add_resources(struct resource_surface *rsurf,
    templ.width0 = rsurf->width;
    templ.height0 = rsurf->height;
    templ.depth0 = 1;
+   templ.array_size = 1;
 
    for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
       if (resource_mask & (1 <<i)) {
@@ -193,8 +191,6 @@ resource_surface_swap_buffers(struct resource_surface *rsurf,
 
    pointer_swap((const void **) &rsurf->resources[buf1],
                 (const void **) &rsurf->resources[buf2]);
-   pointer_swap((const void **) &rsurf->present_surfaces[buf1],
-                (const void **) &rsurf->present_surfaces[buf2]);
 
    /* swap mask bits */
    mask = rsurf->resource_mask & ~(buf1_bit | buf2_bit);
@@ -212,24 +208,12 @@ resource_surface_present(struct resource_surface *rsurf,
                          void *winsys_drawable_handle)
 {
    struct pipe_resource *pres = rsurf->resources[which];
-   struct pipe_surface *psurf = rsurf->present_surfaces[which];
 
    if (!pres)
       return TRUE;
 
-   if (!psurf) {
-      psurf = rsurf->screen->get_tex_surface(rsurf->screen,
-            pres, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
-      if (!psurf)
-         return FALSE;
-
-      rsurf->present_surfaces[which] = psurf;
-   }
-
-   assert(psurf->texture == pres);
-
    rsurf->screen->flush_frontbuffer(rsurf->screen,
-         psurf, winsys_drawable_handle);
+         pres, 0, 0, winsys_drawable_handle);
 
    return TRUE;
 }
index 3759c2a26dd113cf501113be2e2acc0b676c05b0..2441b43fd8e5269415dd3b4b71d381f448545575 100644 (file)
@@ -34,7 +34,7 @@
 
 /* see get_drm_screen_name */
 #include <radeon_drm.h>
-#include "radeon/drm/radeon_drm.h"
+#include "radeon/drm/radeon_drm_public.h"
 
 static boolean
 drm_display_is_format_supported(struct native_display *ndpy,
index 331a7de432a9714cf36c046672fb359849e53f76..8108ce45865021dfcd6a2554eb6d7d456560b333 100644 (file)
@@ -136,6 +136,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
    templ.width0 = dri2surf->width;
    templ.height0 = dri2surf->height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.format = dri2surf->color_format;
    templ.bind = PIPE_BIND_RENDER_TARGET;
 
index e7466bdbee53376faa8582e36107d4dbe10bab0c..6bfe8b0788c5012713d239fce2a3c7c6a83c6445 100644 (file)
@@ -42,7 +42,7 @@ struct xmesa_st_framebuffer {
    unsigned texture_width, texture_height, texture_mask;
    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
 
-   struct pipe_surface *display_surface;
+   struct pipe_resource *display_resource;
 };
 
 static INLINE struct xmesa_st_framebuffer *
@@ -60,25 +60,19 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
 {
    struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
    struct pipe_resource *ptex = xstfb->textures[statt];
-   struct pipe_surface *psurf;
+   struct pipe_resource *pres;
 
    if (!ptex)
       return TRUE;
 
-   psurf = xstfb->display_surface;
+   pres = xstfb->display_resource;
    /* (re)allocate the surface for the texture to be displayed */
-   if (!psurf || psurf->texture != ptex) {
-      pipe_surface_reference(&xstfb->display_surface, NULL);
-
-      psurf = xstfb->screen->get_tex_surface(xstfb->screen,
-            ptex, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
-      if (!psurf)
-         return FALSE;
-
-      xstfb->display_surface = psurf;
+   if (!pres || pres != ptex) {
+      pipe_resource_reference(&xstfb->display_resource, ptex);
+      pres = xstfb->display_resource;
    }
 
-   xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
+   xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws);
 
    return TRUE;
 }
@@ -96,7 +90,7 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
    struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
    struct pipe_resource *src_ptex = xstfb->textures[src_statt];
    struct pipe_resource *dst_ptex = xstfb->textures[dst_statt];
-   struct pipe_subresource subsrc, subdst;
+   struct pipe_box src_box;
    struct pipe_context *pipe;
 
    if (!src_ptex || !dst_ptex)
@@ -110,14 +104,11 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
       xstfb->display->pipe = pipe;
    }
 
-   subsrc.face = 0;
-   subsrc.level = 0;
-   subdst.face = 0;
-   subdst.level = 0;
+   u_box_2d(x, y, width, height, &src_box);
 
    if (src_ptex && dst_ptex)
-      pipe->resource_copy_region(pipe, dst_ptex, subdst, x, y, 0,
-                                 src_ptex, subsrc, x, y, 0, width, height);
+      pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0,
+                                 src_ptex, 0, &src_box);
 }
 
 /**
@@ -144,6 +135,7 @@ xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.last_level = 0;
 
    for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
@@ -321,7 +313,7 @@ xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
    struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
    int i;
 
-   pipe_surface_reference(&xstfb->display_surface, NULL);
+   pipe_resource_reference(&xstfb->display_resource, NULL);
 
    for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
       pipe_resource_reference(&xstfb->textures[i], NULL);
index 40c4603fb9d90bbe41d56c99e151667ce21abced..5bdeaa8e4ea843b286a7cc1b4539897f0fc6f824 100644 (file)
@@ -132,6 +132,8 @@ struct st_context {
                        enum pipe_format format = PIPE_FORMAT_NONE,
                        unsigned first_level = 0,
                        unsigned last_level = ~0,
+                       unsigned first_layer = 0,
+                       unsigned last_layer = ~0,
                        unsigned swizzle_r = 0,
                        unsigned swizzle_g = 1,
                        unsigned swizzle_b = 2,
@@ -146,9 +148,10 @@ struct st_context {
       } else {
          templat.format = format;
       }
-      templat.last_level = MIN2(last_level, texture->last_level);
-      templat.first_level = first_level;
-      templat.last_level = last_level;
+      templat.u.tex.last_level = MIN2(last_level, texture->last_level);
+      templat.u.tex.first_level = first_level;
+      templat.u.tex.first_layer = first_layer;
+      templat.u.tex.last_layer = last_layer;
       templat.swizzle_r = swizzle_r;
       templat.swizzle_g = swizzle_g;
       templat.swizzle_b = swizzle_b;
@@ -412,17 +415,15 @@ error1:
     */
 
    void resource_copy_region(struct pipe_resource *dst,
-                             struct pipe_subresource subdst,
+                             unsigned dst_level,
                              unsigned dstx, unsigned dsty, unsigned dstz,
                              struct pipe_resource *src,
-                             struct pipe_subresource subsrc,
-                             unsigned srcx, unsigned srcy, unsigned srcz,
-                             unsigned width, unsigned height)
+                             unsigned src_level,
+                             const struct pipe_box *src_box)
    {
       $self->pipe->resource_copy_region($self->pipe,
-                                        dst, subdst, dstx, dsty, dstz,
-                                        src, subsrc, srcx, srcy, srcz,
-                                        width, height);
+                                        dst, dst_level, dstx, dsty, dstz,
+                                        src, src_level, src_box);
    }
 
 
@@ -433,7 +434,7 @@ error1:
    {
       struct pipe_surface *_dst = NULL;
 
-     _dst = st_pipe_surface(dst, PIPE_BIND_RENDER_TARGET);
+     _dst = st_pipe_surface($self->pipe, dst, PIPE_BIND_RENDER_TARGET);
       if(!_dst)
          SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
 
@@ -452,7 +453,7 @@ error1:
    {
       struct pipe_surface *_dst = NULL;
 
-     _dst = st_pipe_surface(dst, PIPE_BIND_DEPTH_STENCIL);
+     _dst = st_pipe_surface($self->pipe, dst, PIPE_BIND_DEPTH_STENCIL);
       if(!_dst)
          SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
 
@@ -482,9 +483,8 @@ error1:
 
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_READ,
                                    x, y, w, h);
       if(transfer) {
@@ -511,9 +511,8 @@ error1:
 
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_WRITE,
                                    x, y, w, h);
       if(!transfer)
@@ -535,9 +534,8 @@ error1:
       struct pipe_transfer *transfer;
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_READ,
                                    x, y, w, h);
       if(transfer) {
@@ -555,9 +553,8 @@ error1:
       struct pipe_transfer *transfer;
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_WRITE,
                                    x, y, w, h);
       if(transfer) {
@@ -597,9 +594,8 @@ error1:
 
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_READ,
                                    x, y, w, h);
       if(transfer) {
@@ -624,9 +620,8 @@ error1:
       struct pipe_transfer *transfer;
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_READ,
                                    x, y, w, h);
       if(transfer) {
@@ -644,9 +639,8 @@ error1:
       struct pipe_transfer *transfer;
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_WRITE,
                                    x, y, w, h);
       if(transfer) {
@@ -681,9 +675,8 @@ error1:
 
       transfer = pipe_get_transfer(pipe,
                                    surface->texture,
-                                   surface->face,
                                    surface->level,
-                                   surface->zslice,
+                                   surface->layer,
                                    PIPE_TRANSFER_READ,
                                    x, y, w, h);
       if(!transfer) {
@@ -715,16 +708,16 @@ error1:
    %cstring_input_binary(const char *STRING, unsigned LENGTH);
    void
    transfer_inline_write(struct pipe_resource *resource,
-                         struct pipe_subresource *sr,
+                         unsigned level,
                          unsigned usage,
                          const struct pipe_box *box,
                          const char *STRING, unsigned LENGTH,
                          unsigned stride,
-                         unsigned slice_stride)
+                         unsigned layer_stride)
    {
       struct pipe_context *pipe = $self->pipe;
 
-      pipe->transfer_inline_write(pipe, resource, *sr, usage, box, STRING, stride, slice_stride);
+      pipe->transfer_inline_write(pipe, resource, level, usage, box, STRING, stride, layer_stride);
    }
 
    %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
index c1e6ea1b43c9d990fa13479bbcce03885ca2858a..0537557661ddc2b94ca51064774bc00678c60d98 100644 (file)
          SWIG_exception(SWIG_ValueError, "index out of bounds");
       
       if(surface) {
-         _surface = st_pipe_surface(surface, PIPE_BIND_RENDER_TARGET);
+         /* XXX need a context here */
+         _surface = st_pipe_surface(NULL, surface, PIPE_BIND_RENDER_TARGET);
          if(!_surface)
             SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing");
       }
       struct pipe_surface *_surface = NULL;
 
       if(surface) {
-         _surface = st_pipe_surface(surface, PIPE_BIND_DEPTH_STENCIL);
+         /* XXX need a context here */
+         _surface = st_pipe_surface(NULL, surface, PIPE_BIND_DEPTH_STENCIL);
          if(!_surface)
             SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing");
       }
index ae506944c4513010e297b61c1581671952db5dcf..1f4b4fd596bf1ca4e6228d1037f0d77885939185 100644 (file)
@@ -42,9 +42,8 @@
 %ignore pipe_resource::screen;
 
 %immutable st_surface::texture;
-%immutable st_surface::face;
 %immutable st_surface::level;
-%immutable st_surface::zslice;
+%immutable st_surface::layer;
 
 %newobject pipe_resource::get_surface;
 
 
    /** Get a surface which is a "view" into a texture */
    struct st_surface *
-   get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0)
+   get_surface(unsigned level=0, unsigned layer=0)
    {
       struct st_surface *surface;
 
-      if(face >= ($self->target == PIPE_TEXTURE_CUBE ? 6U : 1U))
-         SWIG_exception(SWIG_ValueError, "face out of bounds");
       if(level > $self->last_level)
          SWIG_exception(SWIG_ValueError, "level out of bounds");
-      if(zslice >= u_minify($self->depth0, level))
-         SWIG_exception(SWIG_ValueError, "zslice out of bounds");
+      if(layer >= ($self->target == PIPE_TEXTURE_3D ?
+                         u_minify($self->depth0, level) : $self->depth0))
+         SWIG_exception(SWIG_ValueError, "layer out of bounds");
 
       surface = CALLOC_STRUCT(st_surface);
       if(!surface)
          return NULL;
 
       pipe_resource_reference(&surface->texture, $self);
-      surface->face = face;
       surface->level = level;
-      surface->zslice = zslice;
+      surface->layer = layer;
 
       return surface;
 
@@ -113,9 +110,8 @@ struct st_surface
    %immutable;
 
    struct pipe_resource *texture;
-   unsigned face;
    unsigned level;
-   unsigned zslice;
+   unsigned layer;
 
 };
 
index 29813456b5f4bbf9ba44833fc8a0b4d14737fcc8..d0a4295c7a250c97533c51bbfd94374d88dea045 100644 (file)
@@ -240,6 +240,7 @@ st_context_create(struct st_device *st_dev)
       templat.width0 = 1;
       templat.height0 = 1;
       templat.depth0 = 1;
+      templat.array_size = 1;
       templat.last_level = 0;
       templat.bind = PIPE_BIND_SAMPLER_VIEW;
    
@@ -252,7 +253,7 @@ st_context_create(struct st_device *st_dev)
 
         pipe->transfer_inline_write(pipe,
                                     st_ctx->default_texture,
-                                    u_subresource(0,0),
+                                    0,
                                     PIPE_TRANSFER_WRITE,
                                     &box,
                                     &zero,
index 2dca7a1974e38270061413059edffee389c9e098..53e2556cb0dd2edd5d9e6930b9e067ba7c7b91b2 100644 (file)
@@ -41,9 +41,8 @@ struct st_winsys;
 struct st_surface
 {
    struct pipe_resource *texture;
-   unsigned face;
    unsigned level;
-   unsigned zslice;
+   unsigned layer;
 };
 
 
@@ -83,11 +82,17 @@ struct st_device
 
 
 static INLINE struct pipe_surface *
-st_pipe_surface(struct st_surface *surface, unsigned usage) 
+st_pipe_surface(struct pipe_context *pipe, struct st_surface *surface, unsigned usage) 
 {
    struct pipe_resource *texture = surface->texture;
-   struct pipe_screen *screen = texture->screen;
-   return screen->get_tex_surface(screen, texture, surface->face, surface->level, surface->zslice, usage);
+   struct pipe_surface surf_tmpl;
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   surf_tmpl.format = texture->format;
+   surf_tmpl.usage = usage;
+   surf_tmpl.u.tex.level = surface->level;
+   surf_tmpl.u.tex.first_layer = surface->layer;
+   surf_tmpl.u.tex.last_layer = surface->layer;
+   return pipe->create_surface(pipe, texture, &surf_tmpl);
 }
 
 struct st_context *
index 25bfbf1ab73d5991ede74566fa9394ae6025ebcb..cac9a1a6204732f161673f058c34cb9a3cdf187b 100644 (file)
@@ -555,9 +555,8 @@ st_sample_surface(struct pipe_context *pipe,
 
    transfer = pipe_get_transfer(pipe,
                                 surface->texture,
-                                surface->face,
                                 surface->level,
-                                surface->zslice,
+                                surface->layer,
                                 PIPE_TRANSFER_WRITE,
                                 0, 0,
                                 width,
diff --git a/src/gallium/state_trackers/vega/.gitignore b/src/gallium/state_trackers/vega/.gitignore
new file mode 100644 (file)
index 0000000..c452229
--- /dev/null
@@ -0,0 +1 @@
+api_tmp.h
index 0543fac09469a9f64cee27fdc72eaacf8fd29616..7342c124c287469a47de5b7cf2b19b7928373f1a 100644 (file)
@@ -38,7 +38,14 @@ C_SOURCES = \
            renderer.c \
            stroker.c \
            mask.c \
+           text.c \
            shader.c \
            shaders_cache.c
 
+GENERATED_SOURCES := api_tmp.h
+
 include ../../Makefile.template
+
+MAPI := $(TOP)/src/mapi
+api_tmp.h: $(MAPI)/mapi/mapi_abi.py $(MAPI)/vgapi/vgapi.csv
+       $(PYTHON2) $< --printer vgapi --mode app $(MAPI)/vgapi/vgapi.csv > $@
index a62783ab18e53152539019e5dd893bcc0f704803..4900135a1c53d5fdaa9b3ddb07bfd90bd16c6737 100644 (file)
@@ -3,6 +3,8 @@
 
 Import('*')
 
+from sys import executable as python_cmd
+
 env = env.Clone()
 
 env.Append(CPPPATH = [
@@ -40,10 +42,16 @@ vega_sources = [
     'mask.c',
     'shader.c',
     'shaders_cache.c',
+    'text.c',
 ]
 
-# vgapi_header must be generated first
-env.Depends(vega_sources, vgapi_header)
+api_tmp = env.CodeGenerate(
+        target = '#/src/gallium/state_trackers/vega/api_tmp.h',
+        script = '#src/mapi/mapi/mapi_abi.py',
+        source = '#src/mapi/vgapi/vgapi.csv',
+        command = python_cmd + ' $SCRIPT --printer vgapi --mode app $SOURCE > $TARGET'
+)
+env.Depends(vega_sources, api_tmp)
 
 st_vega = env.ConvenienceLibrary(
     target = 'st_vega',
index bf1d37493af7296cd235011e0e889e14afb4ba13..4bf7c71d45346c186fa83b4916b2fd91be5d9241 100644 (file)
 
 #include "mapi/mapi.h"
 
+/* define vega_spec and vega_procs for use with mapi */
+#define API_TMP_DEFINE_SPEC
 #include "api.h"
 
-static const char vega_spec[] =
-   "1"
-#define MAPI_ABI_ENTRY(ret, name, params) \
-   "\0" #name "\0"
-#define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
-   #name "\0"
-#include "vgapi/vgapi_tmp.h"
-   "\0";
-
-static const mapi_proc vega_procs[] = {
-#define MAPI_ABI_ENTRY(ret, name, params) \
-   (mapi_proc) vega ## name,
-#include "vgapi/vgapi_tmp.h"
-};
-
 static void api_init(void)
 {
    static boolean initialized = FALSE;
index 955508dae9a0418eae1183eb917b1c55ae816fe3..459dafb4bb01f76d943a9db77abd4647faa3b228 100644 (file)
 #include "VG/vgext.h"
 #include "vg_manager.h"
 
-/* declare the prototypes */
-#define MAPI_ABI_ENTRY(ret, name, params) \
-   ret VG_API_ENTRY vega ## name params;
-#include "vgapi/vgapi_tmp.h"
+#include "api_tmp.h"
 
 struct mapi_table;
 
index fa1e00d1f88523bd6cdfed0b48a7747d65d44247..724e38241b52232a49459d92dd5268683a3eeaa4 100644 (file)
@@ -31,7 +31,6 @@
 #include "api.h"
 #include "renderer.h"
 #include "shaders_cache.h"
-#include "st_inlines.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
@@ -42,7 +41,6 @@
 #include "util/u_sampler.h"
 #include "util/u_string.h"
 
-
 #include "asm_filters.h"
 
 
@@ -73,6 +71,7 @@ static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx,
    templ.width0 = color_data_len;
    templ.height0 = 1;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.bind = PIPE_BIND_SAMPLER_VIEW;
 
    tex = screen->resource_create(screen, &templ);
@@ -80,9 +79,9 @@ static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx,
    { /* upload color_data */
       struct pipe_transfer *transfer =
          pipe_get_transfer(pipe, tex,
-                               0, 0, 0,
-                               PIPE_TRANSFER_READ_WRITE ,
-                               0, 0, tex->width0, tex->height0);
+                           0, 0,
+                           PIPE_TRANSFER_READ_WRITE ,
+                           0, 0, tex->width0, tex->height0);
       void *map = pipe->transfer_map(pipe, transfer);
       memcpy(map, color_data, sizeof(VGint)*color_data_len);
       pipe->transfer_unmap(pipe, transfer);
@@ -114,153 +113,11 @@ static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context
    return view;
 }
 
-static INLINE struct pipe_surface * setup_framebuffer(struct vg_image *dst)
-{
-   struct vg_context *ctx = vg_current_context();
-   struct pipe_context *pipe = ctx->pipe;
-   struct pipe_framebuffer_state fb;
-   struct pipe_surface *dst_surf = pipe->screen->get_tex_surface(
-      pipe->screen, dst->sampler_view->texture, 0, 0, 0,
-      PIPE_BIND_RENDER_TARGET);
-
-   /* drawing dest */
-   memset(&fb, 0, sizeof(fb));
-   fb.width  = dst->x + dst_surf->width;
-   fb.height = dst->y + dst_surf->height;
-   fb.nr_cbufs = 1;
-   fb.cbufs[0] = dst_surf;
-   {
-      VGint i;
-      for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
-         fb.cbufs[i] = 0;
-   }
-   cso_set_framebuffer(ctx->cso_context, &fb);
-
-   return dst_surf;
-}
-
-static void setup_viewport(struct vg_image *dst)
-{
-   struct vg_context *ctx = vg_current_context();
-   vg_set_viewport(ctx, VEGA_Y0_TOP);
-}
-
-static void setup_blend()
-{
-   struct vg_context *ctx = vg_current_context();
-   struct pipe_blend_state blend;
-   memset(&blend, 0, sizeof(blend));
-   blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   if (ctx->state.vg.filter_channel_mask & VG_RED)
-      blend.rt[0].colormask |= PIPE_MASK_R;
-   if (ctx->state.vg.filter_channel_mask & VG_GREEN)
-      blend.rt[0].colormask |= PIPE_MASK_G;
-   if (ctx->state.vg.filter_channel_mask & VG_BLUE)
-      blend.rt[0].colormask |= PIPE_MASK_B;
-   if (ctx->state.vg.filter_channel_mask & VG_ALPHA)
-      blend.rt[0].colormask |= PIPE_MASK_A;
-   blend.rt[0].blend_enable = 0;
-   cso_set_blend(ctx->cso_context, &blend);
-}
-
-static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
-                                  VGint param_bytes)
-{
-   struct pipe_context *pipe = ctx->pipe;
-   struct pipe_resource **cbuf = &ctx->filter.buffer;
-
-   /* We always need to get a new buffer, to keep the drivers simple and
-    * avoid gratuitous rendering synchronization. */
-   pipe_resource_reference(cbuf, NULL);
-
-   *cbuf = pipe_buffer_create(pipe->screen, 
-                              PIPE_BIND_CONSTANT_BUFFER,
-                              param_bytes);
-
-   if (*cbuf) {
-      st_no_flush_pipe_buffer_write(ctx, *cbuf,
-                                    0, param_bytes, buffer);
-   }
-
-   ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
-}
-
-static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
-{
-   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
-   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
-   struct pipe_sampler_state sampler[3];
-   int num_samplers = 0;
-   int num_textures = 0;
-
-   samplers[0] = NULL;
-   samplers[1] = NULL;
-   samplers[2] = NULL;
-   samplers[3] = NULL;
-   sampler_views[0] = NULL;
-   sampler_views[1] = NULL;
-   sampler_views[2] = NULL;
-   sampler_views[3] = NULL;
-
-   memset(&sampler[0], 0, sizeof(struct pipe_sampler_state));
-   sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler[0].wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler[0].min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
-   sampler[0].mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
-   sampler[0].normalized_coords = 1;
-
-   switch(info->tiling_mode) {
-   case VG_TILE_FILL:
-      sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
-      sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
-      memcpy(sampler[0].border_color,
-             ctx->state.vg.tile_fill_color,
-             sizeof(VGfloat) * 4);
-      break;
-   case VG_TILE_PAD:
-      sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      break;
-   case VG_TILE_REPEAT:
-      sampler[0].wrap_s = PIPE_TEX_WRAP_REPEAT;
-      sampler[0].wrap_t = PIPE_TEX_WRAP_REPEAT;
-      break;
-   case VG_TILE_REFLECT:
-      sampler[0].wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
-      sampler[0].wrap_t = PIPE_TEX_WRAP_MIRROR_REPEAT;
-      break;
-   default:
-      debug_assert(!"Unknown tiling mode");
-   }
-
-   samplers[0] = &sampler[0];
-   sampler_views[0] = info->src->sampler_view;
-   ++num_samplers;
-   ++num_textures;
-
-   if (info->extra_texture_view) {
-      memcpy(&sampler[1], &sampler[0], sizeof(struct pipe_sampler_state));
-      samplers[1] = &sampler[1];
-      sampler_views[1] = info->extra_texture_view;
-      ++num_samplers;
-      ++num_textures;
-   }
-
-
-   cso_set_samplers(ctx->cso_context, num_samplers, (const struct pipe_sampler_state **)samplers);
-   cso_set_fragment_sampler_views(ctx->cso_context, num_textures, sampler_views);
-}
-
 static struct vg_shader * setup_color_matrix(struct vg_context *ctx, void *user_data)
 {
    struct vg_shader *shader =
       shader_create_from_text(ctx->pipe, color_matrix_asm, 200,
          PIPE_SHADER_FRAGMENT);
-   cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
    return shader;
 }
 
@@ -275,7 +132,6 @@ static struct vg_shader * setup_convolution(struct vg_context *ctx, void *user_d
    shader = shader_create_from_text(ctx->pipe, buffer, 200,
                                     PIPE_SHADER_FRAGMENT);
 
-   cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
    return shader;
 }
 
@@ -285,7 +141,6 @@ static struct vg_shader * setup_lookup(struct vg_context *ctx, void *user_data)
       shader_create_from_text(ctx->pipe, lookup_asm,
                               200, PIPE_SHADER_FRAGMENT);
 
-   cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
    return shader;
 }
 
@@ -316,49 +171,68 @@ static struct vg_shader * setup_lookup_single(struct vg_context *ctx, void *user
    shader = shader_create_from_text(ctx->pipe, buffer, 200,
                                     PIPE_SHADER_FRAGMENT);
 
-   cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
    return shader;
 }
 
 static void execute_filter(struct vg_context *ctx,
                            struct filter_info *info)
 {
-   struct pipe_surface *dst_surf;
    struct vg_shader *shader;
+   const struct pipe_sampler_state *samplers[2];
+   struct pipe_sampler_view *views[2];
+   struct pipe_sampler_state sampler;
+   uint tex_wrap;
+
+   memset(&sampler, 0, sizeof(sampler));
+   sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+   sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+   sampler.normalized_coords = 1;
+
+   switch (info->tiling_mode) {
+   case VG_TILE_FILL:
+      tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
+      /* copy border color */
+      memcpy(sampler.border_color, ctx->state.vg.tile_fill_color,
+            sizeof(sampler.border_color));
+      break;
+   case VG_TILE_PAD:
+      tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;;
+      break;
+   case VG_TILE_REPEAT:
+      tex_wrap = PIPE_TEX_WRAP_REPEAT;;
+      break;
+   case VG_TILE_REFLECT:
+      tex_wrap = PIPE_TEX_WRAP_MIRROR_REPEAT;
+      break;
+   default:
+      debug_assert(!"Unknown tiling mode");
+      tex_wrap = 0;
+      break;
+   }
+
+   sampler.wrap_s = tex_wrap;
+   sampler.wrap_t = tex_wrap;
+   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+
+   samplers[0] = samplers[1] = &sampler;
+   views[0] = info->src->sampler_view;
+   views[1] = info->extra_texture_view;
 
-   cso_save_framebuffer(ctx->cso_context);
-   cso_save_fragment_shader(ctx->cso_context);
-   cso_save_viewport(ctx->cso_context);
-   cso_save_blend(ctx->cso_context);
-   cso_save_samplers(ctx->cso_context);
-   cso_save_fragment_sampler_views(ctx->cso_context);
-
-   dst_surf = setup_framebuffer(info->dst);
-   setup_viewport(info->dst);
-   setup_blend();
-   setup_constant_buffer(ctx, info->const_buffer, info->const_buffer_len);
    shader = info->setup_shader(ctx, info->user_data);
-   setup_samplers(ctx, info);
-
-   renderer_draw_texture(ctx->renderer,
-                         info->src->sampler_view->texture,
-                         info->dst->x, info->dst->y,
-                         info->dst->x + info->dst->width,
-                         info->dst->y + info->dst->height,
-                         info->dst->x, info->dst->y,
-                         info->dst->x + info->dst->width,
-                         info->dst->y + info->dst->height);
-
-   cso_restore_framebuffer(ctx->cso_context);
-   cso_restore_fragment_shader(ctx->cso_context);
-   cso_restore_viewport(ctx->cso_context);
-   cso_restore_blend(ctx->cso_context);
-   cso_restore_samplers(ctx->cso_context);
-   cso_restore_fragment_sampler_views(ctx->cso_context);
 
-   vg_shader_destroy(ctx, shader);
+   if (renderer_filter_begin(ctx->renderer,
+            info->dst->sampler_view->texture, VG_TRUE,
+            ctx->state.vg.filter_channel_mask,
+            samplers, views, (info->extra_texture_view) ? 2 : 1,
+            shader->driver, info->const_buffer, info->const_buffer_len)) {
+      renderer_filter(ctx->renderer,
+            info->dst->x, info->dst->y, info->dst->width, info->dst->height,
+            info->src->x, info->src->y, info->src->width, info->src->height);
+      renderer_filter_end(ctx->renderer);
+   }
 
-   pipe_surface_reference(&dst_surf, NULL);
+   vg_shader_destroy(ctx, shader);
 }
 
 void vegaColorMatrix(VGImage dst, VGImage src,
index e9f038c5f9278558f7e1202cbb702d6064994309..ad95409cd00411334554f802511a6dfcc4be1e27 100644 (file)
@@ -303,7 +303,8 @@ void vegaDrawImage(VGImage image)
    }
 
    vg_validate_state(ctx);
-   image_draw((struct vg_image*)image);
+   image_draw((struct vg_image*)image,
+         &ctx->state.vg.image_user_to_surface_matrix);
 }
 
 void vegaSetPixels(VGint dx, VGint dy,
@@ -399,7 +400,6 @@ void vegaReadPixels(void * data, VGint dataStride,
 
    struct st_framebuffer *stfb = ctx->draw_buffer;
    struct st_renderbuffer *strb = stfb->strb;
-   struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
 
    VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
    VGfloat *df = (VGfloat*)temp;
@@ -435,21 +435,21 @@ void vegaReadPixels(void * data, VGint dataStride,
       sy = 0;
    }
 
-   if (sx + width > fb->width || sy + height > fb->height) {
-      width = fb->width - sx;
-      height = fb->height - sy;
+   if (sx + width > stfb->width || sy + height > stfb->height) {
+      width = stfb->width - sx;
+      height = stfb->height - sy;
       /* nothing to read */
       if (width <= 0 || height <= 0)
          return;
    }
 
    {
-      VGint y = (fb->height - sy) - 1, yStep = -1;
+      VGint y = (stfb->height - sy) - 1, yStep = -1;
       struct pipe_transfer *transfer;
 
-      transfer = pipe_get_transfer(pipe, strb->texture,  0, 0, 0,
-                                  PIPE_TRANSFER_READ,
-                                  0, 0, sx + width, fb->height - sy);
+      transfer = pipe_get_transfer(pipe, strb->texture,  0, 0,
+                                   PIPE_TRANSFER_READ,
+                                   0, 0, sx + width, stfb->height - sy);
 
       /* Do a row at a time to flip image data vertically */
       for (i = 0; i < height; i++) {
@@ -472,8 +472,8 @@ void vegaCopyPixels(VGint dx, VGint dy,
                     VGint width, VGint height)
 {
    struct vg_context *ctx = vg_current_context();
-   struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
-   struct st_renderbuffer *strb = ctx->draw_buffer->strb;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+   struct st_renderbuffer *strb = stfb->strb;
 
    if (width <= 0 || height <= 0) {
       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
@@ -481,8 +481,8 @@ void vegaCopyPixels(VGint dx, VGint dy,
    }
 
    /* do nothing if we copy from outside the fb */
-   if (dx >= (VGint)fb->width || dy >= (VGint)fb->height ||
-       sx >= (VGint)fb->width || sy >= (VGint)fb->height)
+   if (dx >= (VGint)stfb->width || dy >= (VGint)stfb->height ||
+       sx >= (VGint)stfb->width || sy >= (VGint)stfb->height)
       return;
 
    vg_validate_state(ctx);
index 189390ec2d38d582813bca4774f1dc36b06cae46..beb15c33a59bada6607f2d58861207c17e648af2 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "mask.h"
 #include "api.h"
+#include "renderer.h"
 
 #include "vg_context.h"
 #include "pipe/p_context.h"
 #include "util/u_pack_color.h"
 #include "util/u_draw_quad.h"
 
-#define DISABLE_1_1_MASKING 1
-
-/**
- * Draw a screen-aligned quadrilateral.
- * Coords are window coords with y=0=bottom.  These coords will be transformed
- * by the vertex shader and viewport transform.
- */
-static void
-draw_clear_quad(struct vg_context *st,
-                float x0, float y0, float x1, float y1, float z,
-                const VGfloat color[4])
-{
-   struct pipe_context *pipe = st->pipe;
-   struct pipe_resource *buf;
-   VGuint i;
-
-   /* positions */
-   st->clear.vertices[0][0][0] = x0;
-   st->clear.vertices[0][0][1] = y0;
-
-   st->clear.vertices[1][0][0] = x1;
-   st->clear.vertices[1][0][1] = y0;
-
-   st->clear.vertices[2][0][0] = x1;
-   st->clear.vertices[2][0][1] = y1;
-
-   st->clear.vertices[3][0][0] = x0;
-   st->clear.vertices[3][0][1] = y1;
-
-   /* same for all verts: */
-   for (i = 0; i < 4; i++) {
-      st->clear.vertices[i][0][2] = z;
-      st->clear.vertices[i][0][3] = 1.0;
-      st->clear.vertices[i][1][0] = color[0];
-      st->clear.vertices[i][1][1] = color[1];
-      st->clear.vertices[i][1][2] = color[2];
-      st->clear.vertices[i][1][3] = color[3];
-   }
-
-
-   /* put vertex data into vbuf */
-   buf =  pipe_user_buffer_create(pipe->screen,
-                                  st->clear.vertices,
-                                  sizeof(st->clear.vertices),
-                                 PIPE_BIND_VERTEX_BUFFER);
-
-
-   /* draw */
-   if (buf) {
-      cso_set_vertex_elements(st->cso_context, 2, st->velems);
-
-      util_draw_vertex_buffer(pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
-
-      pipe_resource_reference(&buf, NULL);
-   }
-}
-
-/**
- * Do vgClear by drawing a quadrilateral.
- */
-static void
-clear_with_quad(struct vg_context *st, float x0, float y0,
-                float width, float height, const VGfloat clear_color[4])
-{
-   VGfloat x1, y1;
-
-   vg_validate_state(st);
-
-   x1 = x0 + width;
-   y1 = y0 + height;
-
-   /*
-     printf("%s %f,%f %f,%f\n", __FUNCTION__,
-     x0, y0,
-     x1, y1);
-   */
-
-   cso_save_blend(st->cso_context);
-   cso_save_rasterizer(st->cso_context);
-   cso_save_fragment_shader(st->cso_context);
-   cso_save_vertex_shader(st->cso_context);
-
-   /* blend state: RGBA masking */
-   {
-      struct pipe_blend_state blend;
-      memset(&blend, 0, sizeof(blend));
-      blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].colormask = PIPE_MASK_RGBA;
-      cso_set_blend(st->cso_context, &blend);
-   }
-
-   cso_set_rasterizer(st->cso_context, &st->clear.raster);
-
-   cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
-   cso_set_vertex_shader_handle(st->cso_context, vg_clear_vs(st));
-
-   /* draw quad matching scissor rect (XXX verify coord round-off) */
-   draw_clear_quad(st, x0, y0, x1, y1, 0, clear_color);
-
-   /* Restore pipe state */
-   cso_restore_blend(st->cso_context);
-   cso_restore_rasterizer(st->cso_context);
-   cso_restore_fragment_shader(st->cso_context);
-   cso_restore_vertex_shader(st->cso_context);
-}
-
-
 void vegaMask(VGHandle mask, VGMaskOperation operation,
               VGint x, VGint y,
               VGint width, VGint height)
@@ -176,12 +64,8 @@ void vegaMask(VGHandle mask, VGMaskOperation operation,
       struct vg_image *image = (struct vg_image *)mask;
       mask_using_image(image, operation, x, y, width, height);
    } else if (vg_object_is_valid((void*)mask, VG_OBJECT_MASK)) {
-#if DISABLE_1_1_MASKING
-      return;
-#else
       struct vg_mask_layer *layer = (struct vg_mask_layer *)mask;
       mask_using_layer(layer, operation, x, y, width, height);
-#endif
    } else {
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    }
@@ -191,7 +75,7 @@ void vegaClear(VGint x, VGint y,
                VGint width, VGint height)
 {
    struct vg_context *ctx = vg_current_context();
-   struct pipe_framebuffer_state *fb;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
 
    if (width <= 0 || height <= 0) {
       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
@@ -208,14 +92,15 @@ void vegaClear(VGint x, VGint y,
                 ctx->state.vg.clear_color[3]);
 #endif
 
-   fb = &ctx->state.g3d.fb;
    /* check for a whole surface clear */
    if (!ctx->state.vg.scissoring &&
-       (x == 0 && y == 0 && width == fb->width && height == fb->height)) {
+       (x == 0 && y == 0 && width == stfb->width && height == stfb->height)) {
       ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
                        ctx->state.vg.clear_color, 1., 0);
-   } else {
-      clear_with_quad(ctx, x, y, width, height, ctx->state.vg.clear_color);
+   } else if (renderer_clear_begin(ctx->renderer)) {
+      /* XXX verify coord round-off */
+      renderer_clear(ctx->renderer, x, y, width, height, ctx->state.vg.clear_color);
+      renderer_clear_end(ctx->renderer);
    }
 }
 
@@ -247,10 +132,6 @@ void vegaRenderToMask(VGPath path,
       return;
    }
 
-#if DISABLE_1_1_MASKING
-   return;
-#endif
-
    vg_validate_state(ctx);
 
    mask_render_to((struct path *)path, paintModes, operation);
@@ -328,9 +209,8 @@ void vegaFillMaskLayer(VGMaskLayer maskLayer,
       return;
    }
 
-#if DISABLE_1_1_MASKING
-   return;
-#endif
+   vg_validate_state(ctx);
+
    mask_layer_fill(mask, x, y, width, height, value);
 }
 
@@ -355,9 +235,7 @@ void vegaCopyMask(VGMaskLayer maskLayer,
       return;
    }
 
-#if DISABLE_1_1_MASKING
-   return;
-#endif
+   vg_validate_state(ctx);
 
    mask = (struct vg_mask_layer*)maskLayer;
    mask_copy(mask, sx, sy, dx, dy, width, height);
index e648549745b941b2813f17dd0473386a218fd481..9e2ab03e01a4ef05d658a0be6837fe319629d304 100644 (file)
@@ -63,8 +63,8 @@ const VGubyte *vegaGetString(VGStringID name)
 {
    struct vg_context *ctx = vg_current_context();
    static const VGubyte *vendor = (VGubyte *)"Tungsten Graphics, Inc";
-   static const VGubyte *renderer = (VGubyte *)"Vega OpenVG 1.0";
-   static const VGubyte *version = (VGubyte *)"1.0";
+   static const VGubyte *renderer = (VGubyte *)"Vega OpenVG 1.1";
+   static const VGubyte *version = (VGubyte *)"1.1";
 
    if (!ctx)
       return NULL;
index a10b009e6314440728ddbdf0b6e6075ffd982db9..a73b6c3effead5f3ea5aea4711f40155379ef7dc 100644 (file)
@@ -30,6 +30,7 @@
 #include "paint.h"
 #include "path.h"
 #include "image.h"
+#include "text.h"
 #include "matrix.h"
 #include "api_consts.h"
 #include "api.h"
@@ -174,6 +175,7 @@ void vegaSeti (VGParamType type, VGint value)
          error = VG_ILLEGAL_ARGUMENT_ERROR;
       else
          state->image_mode = value;
+      break;
 #ifdef OPENVG_VERSION_1_1
    case VG_COLOR_TRANSFORM:
       state->color_transform = value;
@@ -1500,7 +1502,8 @@ VGint vegaGetParameteri(VGHandle object,
 
 #ifdef OPENVG_VERSION_1_1
    case VG_FONT_NUM_GLYPHS: {
-      return 1;
+      struct vg_font *font = (struct vg_font*)object;
+      return font_num_glyphs(font);
    }
       break;
 #endif
index f76adddb5840dd41072610d7ef5add372c61be4e..fe57b7671d95513b8a664ff24eb535abcefed068 100644 (file)
@@ -479,6 +479,7 @@ void vegaDrawPath(VGPath path, VGbitfield paintModes)
 
    if (path_is_empty((struct path*)path))
       return;
-   path_render((struct path*)path, paintModes);
+   path_render((struct path*)path, paintModes,
+         &ctx->state.vg.path_user_to_surface_matrix);
 }
 
index 2a62da0a1de5821991c62bfa871768e009e8a4ef..7c6b479409921154c0e022f5317fa6ea97c86e35 100644 (file)
 #include "VG/openvg.h"
 
 #include "vg_context.h"
+#include "text.h"
+#include "api.h"
 
 #include "util/u_memory.h"
 
 #ifdef OPENVG_VERSION_1_1
 
-struct vg_font {
-   struct vg_object base;
-
-   VGint glyph_indices[200];
-   VGint num_glyphs;
-};
-
 VGFont vegaCreateFont(VGint glyphCapacityHint)
 {
-   struct vg_font *font = 0;
    struct vg_context *ctx = vg_current_context();
 
    if (glyphCapacityHint < 0) {
@@ -49,10 +43,7 @@ VGFont vegaCreateFont(VGint glyphCapacityHint)
       return VG_INVALID_HANDLE;
    }
 
-   font = CALLOC_STRUCT(vg_font);
-   vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
-   vg_context_add_object(ctx, VG_OBJECT_FONT, font);
-   return (VGFont)font;
+   return (VGFont) font_create(glyphCapacityHint);
 }
 
 void vegaDestroyFont(VGFont f)
@@ -64,20 +55,23 @@ void vegaDestroyFont(VGFont f)
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
       return;
    }
+   if (!vg_object_is_valid((void *) font, VG_OBJECT_FONT)) {
+      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
+      return;
+   }
 
-   vg_context_remove_object(ctx, VG_OBJECT_FONT, font);
-   /*free(font);*/
+   font_destroy(font);
 }
 
 void vegaSetGlyphToPath(VGFont font,
                         VGuint glyphIndex,
                         VGPath path,
                         VGboolean isHinted,
-                        VGfloat glyphOrigin [2],
-                        VGfloat escapement[2])
+                        const VGfloat glyphOrigin[2],
+                        const VGfloat escapement[2])
 {
    struct vg_context *ctx = vg_current_context();
-   struct vg_object *pathObj;
+   struct path *pathObj;
    struct vg_font *f;
 
    if (font == VG_INVALID_HANDLE ||
@@ -95,25 +89,22 @@ void vegaSetGlyphToPath(VGFont font,
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
       return;
    }
-   pathObj = (struct vg_object*)path;
-   if (pathObj && pathObj->type != VG_OBJECT_PATH) {
-      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
-      return;
-   }
 
-   f = (struct vg_font*)font;
-   f->glyph_indices[f->num_glyphs] = glyphIndex;
-   ++f->num_glyphs;
+   pathObj = (struct path*) path;
+   f = (struct vg_font*) font;
+
+   font_set_glyph_to_path(f, glyphIndex, pathObj,
+         isHinted, glyphOrigin, escapement);
 }
 
 void vegaSetGlyphToImage(VGFont font,
                          VGuint glyphIndex,
                          VGImage image,
-                         VGfloat glyphOrigin [2],
-                         VGfloat escapement[2])
+                         const VGfloat glyphOrigin[2],
+                         const VGfloat escapement[2])
 {
    struct vg_context *ctx = vg_current_context();
-   struct vg_object *img_obj;
+   struct vg_image *img_obj;
    struct vg_font *f;
 
    if (font == VG_INVALID_HANDLE ||
@@ -131,26 +122,11 @@ void vegaSetGlyphToImage(VGFont font,
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
       return;
    }
-   img_obj = (struct vg_object*)image;
-   if (img_obj && img_obj->type != VG_OBJECT_IMAGE) {
-      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
-      return;
-   }
+
+   img_obj = (struct vg_image*)image;
    f = (struct vg_font*)font;
-   f->glyph_indices[f->num_glyphs] = glyphIndex;
-   ++f->num_glyphs;
-}
 
-static INLINE VGboolean font_contains_glyph(struct vg_font *font,
-                                            VGuint glyph_index)
-{
-   VGint i;
-   for (i = 0; i < font->num_glyphs; ++i) {
-      if (font->glyph_indices[i] == glyph_index) {
-         return VG_TRUE;
-      }
-   }
-   return VG_FALSE;
+   font_set_glyph_to_image(f, glyphIndex, img_obj, glyphOrigin, escapement);
 }
 
 void vegaClearGlyph(VGFont font,
@@ -158,30 +134,15 @@ void vegaClearGlyph(VGFont font,
 {
    struct vg_context *ctx = vg_current_context();
    struct vg_font *f;
-   VGint i;
 
    if (font == VG_INVALID_HANDLE) {
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
       return;
    }
-   if (glyphIndex <= 0) {
-      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
-      return;
-   }
-   f = (struct vg_font*)font;
-   if (!font_contains_glyph(f, glyphIndex)) {
-      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
-      return;
-   }
 
-   for (i = 0; i < f->num_glyphs; ++i) {
-      if (f->glyph_indices[i] == glyphIndex) {
-         /*FIXME*/
-         f->glyph_indices[f->num_glyphs] = 0;
-         --f->num_glyphs;
-         return;
-      }
-   }
+   f = (struct vg_font*) font;
+
+   font_clear_glyph(f, glyphIndex);
 }
 
 void vegaDrawGlyph(VGFont font,
@@ -196,31 +157,24 @@ void vegaDrawGlyph(VGFont font,
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
       return;
    }
-   if (glyphIndex <= 0) {
-      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
-      return;
-   }
    if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
       return;
    }
    f = (struct vg_font*)font;
-   if (!font_contains_glyph(f, glyphIndex)) {
-      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
-      return;
-   }
+
+   font_draw_glyph(f, glyphIndex, paintModes, allowAutoHinting);
 }
 
 void vegaDrawGlyphs(VGFont font,
                     VGint glyphCount,
-                    VGuint *glyphIndices,
-                    VGfloat *adjustments_x,
-                    VGfloat *adjustments_y,
+                    const VGuint *glyphIndices,
+                    const VGfloat *adjustments_x,
+                    const VGfloat *adjustments_y,
                     VGbitfield paintModes,
                     VGboolean allowAutoHinting)
 {
    struct vg_context *ctx = vg_current_context();
-   VGint i;
    struct vg_font *f;
 
    if (font == VG_INVALID_HANDLE) {
@@ -235,8 +189,8 @@ void vegaDrawGlyphs(VGFont font,
       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
       return;
    }
-   if (!adjustments_x || !is_aligned(adjustments_x) ||
-       !adjustments_y || !is_aligned(adjustments_y)) {
+   if ((adjustments_x && !is_aligned(adjustments_x)) ||
+       (adjustments_y && !is_aligned(adjustments_y))) {
       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
       return;
    }
@@ -246,13 +200,9 @@ void vegaDrawGlyphs(VGFont font,
    }
 
    f = (struct vg_font*)font;
-   for (i = 0; i < glyphCount; ++i) {
-      VGuint glyph_index = glyphIndices[i];
-      if (!font_contains_glyph(f, glyph_index)) {
-         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
-         return;
-      }
-   }
+
+   font_draw_glyphs(f, glyphCount, glyphIndices,
+         adjustments_x, adjustments_y, paintModes, allowAutoHinting);
 }
 
-#endif
+#endif /* OPENVG_VERSION_1_1 */
index 27773467fa8090ac18ca49b15e7446d00a02198d..77e6a14fe9973d4cbb357c72366e35839058a3d3 100644 (file)
@@ -44,9 +44,31 @@ solid_fill( struct ureg_program *ureg,
             struct ureg_dst *temp,
             struct ureg_src *constant)
 {
-   ureg_MOV(ureg, *out, constant[0]);
+   ureg_MOV(ureg, *out, constant[2]);
 }
 
+/**
+ * Perform frag-coord-to-paint-coord transform.  The transformation is in
+ * CONST[4..6].
+ */
+#define PAINT_TRANSFORM                                                 \
+   ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]);   \
+   ureg_MOV(ureg,                                                       \
+            ureg_writemask(temp[0], TGSI_WRITEMASK_Z),                  \
+            ureg_scalar(constant[3], TGSI_SWIZZLE_Y));                  \
+   ureg_DP3(ureg, temp[1], constant[4], ureg_src(temp[0]));             \
+   ureg_DP3(ureg, temp[2], constant[5], ureg_src(temp[0]));             \
+   ureg_DP3(ureg, temp[3], constant[6], ureg_src(temp[0]));             \
+   ureg_RCP(ureg, temp[3], ureg_src(temp[3]));                          \
+   ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));       \
+   ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));       \
+   ureg_MOV(ureg,                                                       \
+            ureg_writemask(temp[4], TGSI_WRITEMASK_X),                  \
+            ureg_src(temp[1]));                                         \
+   ureg_MOV(ureg,                                                       \
+            ureg_writemask(temp[4], TGSI_WRITEMASK_Y),                  \
+            ureg_src(temp[2]));
+
 static INLINE void
 linear_grad( struct ureg_program *ureg,
              struct ureg_dst *out,
@@ -55,30 +77,19 @@ linear_grad( struct ureg_program *ureg,
              struct ureg_dst *temp,
              struct ureg_src *constant)
 {
+   PAINT_TRANSFORM
 
-   ureg_MOV(ureg,
-            ureg_writemask(temp[0], TGSI_WRITEMASK_XY),
-            in[0]);
-   ureg_MOV(ureg,
-            ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
-   ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
-   ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
-   ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
-   ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
-   ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
-   ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
-   ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1]));
-   ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+   /* grad = DP2((x, y), CONST[2].xy) * CONST[2].z */
    ureg_MUL(ureg, temp[0],
-            ureg_scalar(constant[0], TGSI_SWIZZLE_Y),
+            ureg_scalar(constant[2], TGSI_SWIZZLE_Y),
             ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y));
    ureg_MAD(ureg, temp[1],
-            ureg_scalar(constant[0], TGSI_SWIZZLE_X),
+            ureg_scalar(constant[2], TGSI_SWIZZLE_X),
             ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X),
             ureg_src(temp[0]));
    ureg_MUL(ureg, temp[2], ureg_src(temp[1]),
-            ureg_scalar(constant[0], TGSI_SWIZZLE_Z));
+            ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
+
    ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
 }
 
@@ -90,52 +101,32 @@ radial_grad( struct ureg_program *ureg,
              struct ureg_dst *temp,
              struct ureg_src *constant)
 {
-
-   ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]);
-   ureg_MOV(ureg,
-            ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
-   ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
-   ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
-   ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
+   PAINT_TRANSFORM
+
+   /*
+    * Calculate (sqrt(B^2 + AC) - B) / A, where
+    *
+    *   A is CONST[2].z,
+    *   B is DP2((x, y), CONST[2].xy), and
+    *   C is DP2((x, y), (x, y)).
+    */
+
+   /* B and C */
+   ureg_DP2(ureg, temp[0], ureg_src(temp[4]), constant[2]);
+   ureg_DP2(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[4]));
+
+   /* the square root */
+   ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[0]));
+   ureg_MAD(ureg, temp[3], ureg_src(temp[1]),
+         ureg_scalar(constant[2], TGSI_SWIZZLE_Z), ureg_src(temp[2]));
+   ureg_RSQ(ureg, temp[3], ureg_src(temp[3]));
    ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
-   ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
-   ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
-   ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_X), ureg_src(temp[1]));
-   ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
-   ureg_MUL(ureg, temp[0], ureg_scalar(constant[0], TGSI_SWIZZLE_Y),
-            ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y));
-   ureg_MAD(ureg, temp[1],
-            ureg_scalar(constant[0], TGSI_SWIZZLE_X),
-            ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X), ureg_src(temp[0]));
-   ureg_ADD(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[1]));
-   ureg_MUL(ureg, temp[3],
-            ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y),
-            ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y));
-   ureg_MAD(ureg, temp[4],
-            ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X),
-            ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X),
-            ureg_src(temp[3]));
-   ureg_MOV(ureg, temp[4], ureg_negate(ureg_src(temp[4])));
-   ureg_MUL(ureg, temp[2],
-            ureg_scalar(constant[0], TGSI_SWIZZLE_Z),
-            ureg_src(temp[4]));
-   ureg_MUL(ureg, temp[0],
-            ureg_scalar(constant[1], TGSI_SWIZZLE_W),
-            ureg_src(temp[2]));
-   ureg_MUL(ureg, temp[3], ureg_src(temp[1]), ureg_src(temp[1]));
-
-   ureg_SUB(ureg, temp[2], ureg_src(temp[3]), ureg_src(temp[0]));
-   ureg_RSQ(ureg, temp[2], ureg_abs(ureg_src(temp[2])));
-   ureg_RCP(ureg, temp[2], ureg_src(temp[2]));
-   ureg_SUB(ureg, temp[1], ureg_src(temp[2]), ureg_src(temp[1]));
-   ureg_ADD(ureg, temp[0],
-            ureg_scalar(constant[0], TGSI_SWIZZLE_Z),
-            ureg_scalar(constant[0], TGSI_SWIZZLE_Z));
-   ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
-   ureg_MUL(ureg, temp[2], ureg_src(temp[1]), ureg_src(temp[0]));
-   ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
 
+   ureg_SUB(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[0]));
+   ureg_RCP(ureg, temp[0], ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
+   ureg_MUL(ureg, temp[0], ureg_src(temp[0]), ureg_src(temp[3]));
+
+   ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[0]), sampler[0]);
 }
 
 
@@ -147,22 +138,11 @@ pattern( struct ureg_program *ureg,
          struct ureg_dst     *temp,
          struct ureg_src     *constant)
 {
-   ureg_MOV(ureg,
-            ureg_writemask(temp[0], TGSI_WRITEMASK_XY),
-            in[0]);
-   ureg_MOV(ureg,
-            ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
-   ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
-   ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
-   ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
-   ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
-   ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
-   ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
-   ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1]));
-   ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+   PAINT_TRANSFORM
+
+   /* (s, t) = (x / tex_width, y / tex_height) */
    ureg_RCP(ureg, temp[0],
-            ureg_swizzle(constant[1],
+            ureg_swizzle(constant[3],
                          TGSI_SWIZZLE_Z,
                          TGSI_SWIZZLE_W,
                          TGSI_SWIZZLE_Z,
@@ -176,22 +156,21 @@ pattern( struct ureg_program *ureg,
             ureg_writemask(temp[1], TGSI_WRITEMASK_Y),
             ureg_src(temp[1]),
             ureg_src(temp[0]));
+
    ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
 }
 
 static INLINE void
-mask( struct ureg_program *ureg,
-      struct ureg_dst *out,
-      struct ureg_src *in,
-      struct ureg_src *sampler,
-      struct ureg_dst *temp,
-      struct ureg_src *constant)
+paint_degenerate( struct ureg_program *ureg,
+                  struct ureg_dst *out,
+                  struct ureg_src *in,
+                  struct ureg_src *sampler,
+                  struct ureg_dst *temp,
+                  struct ureg_src *constant)
 {
-   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
-   ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
-            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+   /* CONST[3].y is 1.0f */
+   ureg_MOV(ureg, temp[1], ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
+   ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[1]), sampler[0]);
 }
 
 static INLINE void
@@ -202,7 +181,9 @@ image_normal( struct ureg_program *ureg,
               struct ureg_dst *temp,
               struct ureg_src *constant)
 {
-   ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, in[1], sampler[3]);
+   /* store and pass image color in TEMP[1] */
+   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
+   ureg_MOV(ureg, *out, ureg_src(temp[1]));
 }
 
 
@@ -214,6 +195,7 @@ image_multiply( struct ureg_program *ureg,
                 struct ureg_dst *temp,
                 struct ureg_src *constant)
 {
+   /* store and pass image color in TEMP[1] */
    ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
    ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
 }
@@ -227,43 +209,279 @@ image_stencil( struct ureg_program *ureg,
                struct ureg_dst *temp,
                struct ureg_src *constant)
 {
+   /* store and pass image color in TEMP[1] */
    ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
-   ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
+   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+}
+
+static INLINE void
+color_transform( struct ureg_program *ureg,
+                 struct ureg_dst *out,
+                 struct ureg_src *in,
+                 struct ureg_src *sampler,
+                 struct ureg_dst *temp,
+                 struct ureg_src *constant)
+{
+   /* note that TEMP[1] may already be used for image color */
+
+   ureg_MAD(ureg, temp[2], ureg_src(temp[0]), constant[0], constant[1]);
+   /* clamp to [0.0f, 1.0f] */
+   ureg_CLAMP(ureg, temp[2],
+              ureg_src(temp[2]),
+              ureg_scalar(constant[3], TGSI_SWIZZLE_X),
+              ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
+   ureg_MOV(ureg, *out, ureg_src(temp[2]));
+}
+
+static INLINE void
+alpha_normal( struct ureg_program *ureg,
+              struct ureg_dst *out,
+              struct ureg_src *in,
+              struct ureg_src *sampler,
+              struct ureg_dst *temp,
+              struct ureg_src *constant)
+{
+   /* save per-channel alpha in TEMP[1] */
+   ureg_MOV(ureg, temp[1], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+
+   ureg_MOV(ureg, *out, ureg_src(temp[0]));
 }
 
-#define EXTENDED_BLENDER_OVER_FUNC                                      \
-   ureg_SUB(ureg, temp[3],                                              \
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y),                   \
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));            \
-   ureg_SUB(ureg, temp[3],                                              \
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y),                   \
-            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));            \
-   ureg_MUL(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[3]));       \
-   ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_src(temp[4]));       \
-   ureg_ADD(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[4]));
+static INLINE void
+alpha_per_channel( struct ureg_program *ureg,
+                   struct ureg_dst *out,
+                   struct ureg_src *in,
+                   struct ureg_src *sampler,
+                   struct ureg_dst *temp,
+                   struct ureg_src *constant)
+{
+   /* save per-channel alpha in TEMP[1] */
+   ureg_MUL(ureg,
+            ureg_writemask(temp[1], TGSI_WRITEMASK_W),
+            ureg_src(temp[0]),
+            ureg_src(temp[1]));
+   ureg_MUL(ureg,
+            ureg_writemask(temp[1], TGSI_WRITEMASK_XYZ),
+            ureg_src(temp[1]),
+            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
 
+   /* update alpha */
+   ureg_MOV(ureg,
+            ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+            ureg_src(temp[1]));
+   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+}
 
+/**
+ * Premultiply src and dst.
+ */
 static INLINE void
-blend_multiply( struct ureg_program *ureg,
+blend_premultiply( struct ureg_program *ureg,
+                   struct ureg_src src,
+                   struct ureg_src src_channel_alpha,
+                   struct ureg_src dst)
+{
+   /* premultiply src */
+   ureg_MUL(ureg,
+            ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
+            src,
+            src_channel_alpha);
+   /* premultiply dst */
+   ureg_MUL(ureg,
+            ureg_writemask(ureg_dst(dst), TGSI_WRITEMASK_XYZ),
+            dst,
+            ureg_scalar(dst, TGSI_SWIZZLE_W));
+}
+
+/**
+ * Unpremultiply src.
+ */
+static INLINE void
+blend_unpremultiply( struct ureg_program *ureg,
+                     struct ureg_src src,
+                     struct ureg_src one,
+                     struct ureg_dst temp[1])
+{
+   /* replace 0.0f by 1.0f before calculating reciprocal */
+   ureg_CMP(ureg,
+            temp[0],
+            ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_W)),
+            ureg_scalar(src, TGSI_SWIZZLE_W),
+            one);
+   ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
+
+   ureg_MUL(ureg,
+            ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
+            src,
+            ureg_src(temp[0]));
+}
+
+/**
+ * Emit instructions for the specified blend mode.  Colors will be
+ * unpremultiplied.  Two temporary registers are required.
+ *
+ * The output is written back to src.
+ */
+static INLINE void
+blend_generic(struct ureg_program *ureg,
+              VGBlendMode mode,
+              struct ureg_src src,
+              struct ureg_src src_channel_alpha,
+              struct ureg_src dst,
+              struct ureg_src one,
+              struct ureg_dst temp[2])
+{
+   struct ureg_dst out;
+
+   blend_premultiply(ureg, src, src_channel_alpha, dst);
+
+   /* blend in-place */
+   out = ureg_dst(src);
+
+   switch (mode) {
+   case VG_BLEND_SRC:
+      ureg_MOV(ureg, out, src);
+      break;
+   case VG_BLEND_SRC_OVER:
+      /* RGBA_out = RGBA_src + (1 - A_src) * RGBA_dst */
+      ureg_SUB(ureg, temp[0], one, src_channel_alpha);
+      ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
+      break;
+   case VG_BLEND_DST_OVER:
+      /* RGBA_out = RGBA_dst + (1 - A_dst) * RGBA_src */
+      ureg_SUB(ureg, temp[0], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
+      ureg_MAD(ureg, out, ureg_src(temp[0]), src, dst);
+      break;
+   case VG_BLEND_SRC_IN:
+      ureg_MUL(ureg, out, src, ureg_scalar(dst, TGSI_SWIZZLE_W));
+      break;
+   case VG_BLEND_DST_IN:
+      ureg_MUL(ureg, out, dst, src_channel_alpha);
+      break;
+   case VG_BLEND_MULTIPLY:
+      /*
+       * RGB_out = (1 - A_dst) * RGB_src + (1 - A_src) * RGB_dst +
+       *           RGB_src * RGB_dst
+       */
+      ureg_MAD(ureg, temp[0],
+            ureg_scalar(dst, TGSI_SWIZZLE_W), ureg_negate(src), src);
+      ureg_MAD(ureg, temp[1],
+            src_channel_alpha, ureg_negate(dst), dst);
+      ureg_MAD(ureg, temp[0], src, dst, ureg_src(temp[0]));
+      ureg_ADD(ureg, out, ureg_src(temp[0]), ureg_src(temp[1]));
+      /* alpha is src over */
+      ureg_ADD(ureg, ureg_writemask(out, TGSI_WRITEMASK_W),
+            src, ureg_src(temp[1]));
+      break;
+   case VG_BLEND_SCREEN:
+      /* RGBA_out = RGBA_src + (1 - RGBA_src) * RGBA_dst */
+      ureg_SUB(ureg, temp[0], one, src);
+      ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
+      break;
+   case VG_BLEND_DARKEN:
+   case VG_BLEND_LIGHTEN:
+      /* src over */
+      ureg_SUB(ureg, temp[0], one, src_channel_alpha);
+      ureg_MAD(ureg, temp[0], ureg_src(temp[0]), dst, src);
+      /* dst over */
+      ureg_SUB(ureg, temp[1], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
+      ureg_MAD(ureg, temp[1], ureg_src(temp[1]), src, dst);
+      /* take min/max for colors */
+      if (mode == VG_BLEND_DARKEN) {
+         ureg_MIN(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
+               ureg_src(temp[0]), ureg_src(temp[1]));
+      }
+      else {
+         ureg_MAX(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
+               ureg_src(temp[0]), ureg_src(temp[1]));
+      }
+      break;
+   case VG_BLEND_ADDITIVE:
+      /* RGBA_out = RGBA_src + RGBA_dst */
+      ureg_ADD(ureg, temp[0], src, dst);
+      ureg_MIN(ureg, out, ureg_src(temp[0]), one);
+      break;
+   default:
+      assert(0);
+      break;
+   }
+
+   blend_unpremultiply(ureg, src, one, temp);
+}
+
+#define BLEND_GENERIC(mode) \
+   do { \
+      ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]);         \
+      blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]),    \
+                    ureg_src(temp[2]),                                     \
+                    ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3);   \
+      ureg_MOV(ureg, *out, ureg_src(temp[0]));                             \
+   } while (0)
+
+static INLINE void
+blend_src( struct ureg_program *ureg,
+           struct ureg_dst *out,
+           struct ureg_src *in,
+           struct ureg_src *sampler,
+           struct ureg_dst *temp,
+           struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_SRC);
+}
+
+static INLINE void
+blend_src_over( struct ureg_program *ureg,
                 struct ureg_dst *out,
                 struct ureg_src *in,
                 struct ureg_src *sampler,
                 struct ureg_dst *temp,
                 struct ureg_src *constant)
 {
-   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
-   EXTENDED_BLENDER_OVER_FUNC
-   ureg_MUL(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[1]));
-   ureg_ADD(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[3]));
+   BLEND_GENERIC(VG_BLEND_SRC_OVER);
+}
 
-   ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
-            ureg_src(temp[3]), ureg_src(temp[2]));
+static INLINE void
+blend_dst_over( struct ureg_program *ureg,
+                struct ureg_dst *out,
+                struct ureg_src *in,
+                struct ureg_src *sampler,
+                struct ureg_dst *temp,
+                struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_DST_OVER);
+}
 
-   ureg_MOV(ureg, *out, ureg_src(temp[1]));
+static INLINE void
+blend_src_in( struct ureg_program *ureg,
+              struct ureg_dst *out,
+              struct ureg_src *in,
+              struct ureg_src *sampler,
+              struct ureg_dst *temp,
+              struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_SRC_IN);
+}
+
+static INLINE void
+blend_dst_in( struct ureg_program *ureg,
+              struct ureg_dst *out,
+              struct ureg_src *in,
+              struct ureg_src *sampler,
+              struct ureg_dst *temp,
+              struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_DST_IN);
+}
+
+static INLINE void
+blend_multiply( struct ureg_program *ureg,
+                struct ureg_dst *out,
+                struct ureg_src *in,
+                struct ureg_src *sampler,
+                struct ureg_dst *temp,
+                struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_MULTIPLY);
 }
 
 static INLINE void
@@ -274,10 +492,7 @@ blend_screen( struct ureg_program *ureg,
               struct ureg_dst     *temp,
               struct ureg_src     *constant)
 {
-   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
-   ureg_ADD(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[1]));
-   ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[1]));
-   ureg_SUB(ureg, *out, ureg_src(temp[3]), ureg_src(temp[2]));
+   BLEND_GENERIC(VG_BLEND_SCREEN);
 }
 
 static INLINE void
@@ -288,23 +503,7 @@ blend_darken( struct ureg_program *ureg,
               struct ureg_dst     *temp,
               struct ureg_src     *constant)
 {
-   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
-   EXTENDED_BLENDER_OVER_FUNC
-   ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
-            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
-   ureg_MIN(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
-   ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
-
-   ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
-            ureg_src(temp[3]), ureg_src(temp[2]));
-
-   ureg_MOV(ureg, *out, ureg_src(temp[1]));
+   BLEND_GENERIC(VG_BLEND_DARKEN);
 }
 
 static INLINE void
@@ -315,23 +514,33 @@ blend_lighten( struct ureg_program *ureg,
                struct ureg_dst *temp,
                struct ureg_src     *constant)
 {
-   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
-   EXTENDED_BLENDER_OVER_FUNC
-   ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
-            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
-   ureg_MAX(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
-   ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
+   BLEND_GENERIC(VG_BLEND_LIGHTEN);
+}
 
-   ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
-            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
-   ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
-            ureg_src(temp[3]), ureg_src(temp[2]));
+static INLINE void
+blend_additive( struct ureg_program *ureg,
+                struct ureg_dst *out,
+                struct ureg_src *in,
+                struct ureg_src *sampler,
+                struct ureg_dst *temp,
+                struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_ADDITIVE);
+}
 
-   ureg_MOV(ureg, *out, ureg_src(temp[1]));
+static INLINE void
+mask( struct ureg_program *ureg,
+      struct ureg_dst *out,
+      struct ureg_src *in,
+      struct ureg_src *sampler,
+      struct ureg_dst *temp,
+      struct ureg_src *constant)
+{
+   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
+   ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+   ureg_MOV(ureg, *out, ureg_src(temp[0]));
 }
 
 static INLINE void
@@ -369,11 +578,11 @@ color_bw( struct ureg_program *ureg,
                 struct ureg_src *constant)
 {
    ureg_ADD(ureg, temp[1],
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+            ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
+            ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
    ureg_RCP(ureg, temp[2], ureg_src(temp[1]));
    ureg_ADD(ureg, temp[1],
-            ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
+            ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
             ureg_src(temp[2]));
    ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
             ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X),
@@ -410,46 +619,75 @@ struct shader_asm_info {
 };
 
 
-static const struct shader_asm_info shaders_asm[] = {
-   /* fills */
+/* paint types */
+static const struct shader_asm_info shaders_paint_asm[] = {
    {VEGA_SOLID_FILL_SHADER, solid_fill,
-    VG_FALSE, 0, 1, 0, 0, 0, 0},
+    VG_FALSE, 2, 1, 0, 0, 0, 0},
    {VEGA_LINEAR_GRADIENT_SHADER, linear_grad,
-    VG_TRUE,  0, 5, 0, 1, 0, 5},
+    VG_TRUE,  2, 5, 0, 1, 0, 5},
    {VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
-    VG_TRUE,  0, 5, 0, 1, 0, 6},
+    VG_TRUE,  2, 5, 0, 1, 0, 5},
    {VEGA_PATTERN_SHADER, pattern,
-    VG_TRUE,  1, 4, 0, 1, 0, 5},
+    VG_TRUE,  3, 4, 0, 1, 0, 5},
+   {VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate,
+    VG_FALSE,  3, 1, 0, 1, 0, 2}
+};
 
-   /* image draw modes */
+/* image draw modes */
+static const struct shader_asm_info shaders_image_asm[] = {
    {VEGA_IMAGE_NORMAL_SHADER, image_normal,
-    VG_TRUE,  0, 0, 3, 1, 0, 0},
+    VG_TRUE,  0, 0, 3, 1, 0, 2},
    {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply,
     VG_TRUE,  0, 0, 3, 1, 0, 2},
    {VEGA_IMAGE_STENCIL_SHADER, image_stencil,
-    VG_TRUE,  0, 0, 3, 1, 0, 2},
+    VG_TRUE,  0, 0, 3, 1, 0, 2}
+};
 
+static const struct shader_asm_info shaders_color_transform_asm[] = {
+   {VEGA_COLOR_TRANSFORM_SHADER, color_transform,
+    VG_FALSE, 0, 4, 0, 0, 0, 3}
+};
+
+static const struct shader_asm_info shaders_alpha_asm[] = {
+   {VEGA_ALPHA_NORMAL_SHADER, alpha_normal,
+    VG_FALSE, 0, 0, 0, 0, 0, 2},
+   {VEGA_ALPHA_PER_CHANNEL_SHADER, alpha_per_channel,
+    VG_FALSE, 0, 0, 0, 0, 0, 2}
+};
+
+/* extra blend modes */
+static const struct shader_asm_info shaders_blend_asm[] = {
+#define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 }
+   BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src),
+   BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over),
+   BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over),
+   BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in),
+   BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in),
+   BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply),
+   BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen),
+   BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken),
+   BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten),
+   BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive)
+#undef BLEND_ASM_INFO
+};
+
+static const struct shader_asm_info shaders_mask_asm[] = {
    {VEGA_MASK_SHADER, mask,
-    VG_TRUE,  0, 0, 1, 1, 0, 2},
-
-   /* extra blend modes */
-   {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply,
-    VG_TRUE,  1, 1, 2, 1, 0, 5},
-   {VEGA_BLEND_SCREEN_SHADER, blend_screen,
-    VG_TRUE,  0, 0, 2, 1, 0, 4},
-   {VEGA_BLEND_DARKEN_SHADER, blend_darken,
-    VG_TRUE,  1, 1, 2, 1, 0, 6},
-   {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten,
-    VG_TRUE,  1, 1, 2, 1, 0, 6},
-
-   /* premultiply */
+    VG_TRUE,  0, 0, 1, 1, 0, 2}
+};
+
+/* premultiply */
+static const struct shader_asm_info shaders_premultiply_asm[] = {
    {VEGA_PREMULTIPLY_SHADER, premultiply,
     VG_FALSE,  0, 0, 0, 0, 0, 1},
    {VEGA_UNPREMULTIPLY_SHADER, unpremultiply,
     VG_FALSE,  0, 0, 0, 0, 0, 1},
+};
 
-   /* color transform to black and white */
+/* color transform to black and white */
+static const struct shader_asm_info shaders_bw_asm[] = {
    {VEGA_BW_SHADER, color_bw,
-    VG_FALSE,  1, 1, 0, 0, 0, 3},
+    VG_FALSE,  3, 1, 0, 0, 0, 3},
 };
+
 #endif
index 903bfc88a4d2fdd39757bc01c3be8ad9fb5c249b..ae1842a62cd74aa991044416e5fd94a44d2ec440 100644 (file)
 #ifndef ASM_UTIL_H
 #define ASM_UTIL_H
 
-
-static const char pass_through_depth_asm[] =
-   "FRAG\n"
-   "DCL IN[0], POSITION, LINEAR\n"
-   "DCL OUT[0].z, POSITION, CONSTANT\n"
-   "0: MOV OUT[0].z, IN[0].zzzz\n"
-   "1: END\n";
-
-
-
 /* μnew = μmask */
 static const char set_mask_asm[] =
    "FRAG\n"
@@ -92,45 +82,4 @@ static const char subtract_mask_asm[] =
    "3: MUL OUT[0], TEMP[2].wwww, TEMP[0].wwww\n"
    "4: END\n";
 
-
-static const char vs_plain_asm[] =
-   "VERT\n"
-   "DCL IN[0]\n"
-   "DCL OUT[0], POSITION\n"
-   "DCL TEMP[0]\n"
-   "DCL CONST[0..1]\n"
-   "0: MUL TEMP[0], IN[0], CONST[0]\n"
-   "1: ADD TEMP[0], TEMP[0], CONST[1]\n"
-   "2: MOV OUT[0], TEMP[0]\n"
-   "3: END\n";
-
-static const char vs_clear_asm[] =
-   "VERT\n"
-   "DCL IN[0]\n"
-   "DCL IN[1]\n"
-   "DCL OUT[0], POSITION\n"
-   "DCL OUT[1], COLOR\n"
-   "DCL TEMP[0]\n"
-   "DCL CONST[0..1]\n"
-   "0: MUL TEMP[0], IN[0], CONST[0]\n"
-   "1: ADD TEMP[0], TEMP[0], CONST[1]\n"
-   "2: MOV OUT[0], TEMP[0]\n"
-   "3: MOV OUT[1], IN[1]\n"
-   "4: END\n";
-
-
-static const char vs_texture_asm[] =
-   "VERT\n"
-   "DCL IN[0]\n"
-   "DCL IN[1]\n"
-   "DCL OUT[0], POSITION\n"
-   "DCL OUT[1], GENERIC\n"
-   "DCL TEMP[0]\n"
-   "DCL CONST[0..1]\n"
-   "0: MUL TEMP[0], IN[0], CONST[0]\n"
-   "1: ADD TEMP[0], TEMP[0], CONST[1]\n"
-   "2: MOV OUT[0], TEMP[0]\n"
-   "3: MOV OUT[1], IN[1]\n"
-   "4: END\n";
-
 #endif
index 28bbe420a21af79c2dbe1d3c6d01e3fd93a15164..318ea94bdfba1b853755433e6ce9f1146e21e2af 100644 (file)
@@ -42,6 +42,7 @@
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "util/u_sampler.h"
+#include "util/u_surface.h"
 
 static enum pipe_format vg_format_to_pipe(VGImageFormat format)
 {
@@ -77,33 +78,23 @@ static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
    dst_loc[3] = src_loc[3];
 }
 
-
-static void vg_copy_texture(struct vg_context *ctx,
-                            struct pipe_resource *dst, VGint dx, VGint dy,
-                            struct pipe_sampler_view *src, VGint sx, VGint sy,
-                            VGint width, VGint height)
+static void vg_get_copy_coords(VGfloat *src_loc,
+                               VGfloat src_width, VGfloat src_height,
+                               VGfloat *dst_loc,
+                               VGfloat dst_width, VGfloat dst_height)
 {
-   VGfloat dst_loc[4], src_loc[4];
    VGfloat dst_bounds[4], src_bounds[4];
    VGfloat src_shift[4], dst_shift[4], shift[4];
 
-   dst_loc[0] = dx;
-   dst_loc[1] = dy;
-   dst_loc[2] = width;
-   dst_loc[3] = height;
    dst_bounds[0] = 0.f;
    dst_bounds[1] = 0.f;
-   dst_bounds[2] = dst->width0;
-   dst_bounds[3] = dst->height0;
+   dst_bounds[2] = dst_width;
+   dst_bounds[3] = dst_height;
 
-   src_loc[0] = sx;
-   src_loc[1] = sy;
-   src_loc[2] = width;
-   src_loc[3] = height;
    src_bounds[0] = 0.f;
    src_bounds[1] = 0.f;
-   src_bounds[2] = src->texture->width0;
-   src_bounds[3] = src->texture->height0;
+   src_bounds[2] = src_width;
+   src_bounds[3] = src_height;
 
    vg_bound_rect(src_loc, src_bounds, src_shift);
    vg_bound_rect(dst_loc, dst_bounds, dst_shift);
@@ -121,22 +112,44 @@ static void vg_copy_texture(struct vg_context *ctx,
       vg_shift_recty(dst_loc, dst_bounds, shift[1]);
 
    vg_sync_size(src_loc, dst_loc);
+}
+
+static void vg_copy_texture(struct vg_context *ctx,
+                            struct pipe_resource *dst, VGint dx, VGint dy,
+                            struct pipe_sampler_view *src, VGint sx, VGint sy,
+                            VGint width, VGint height)
+{
+   VGfloat dst_loc[4], src_loc[4];
+
+   dst_loc[0] = dx;
+   dst_loc[1] = dy;
+   dst_loc[2] = width;
+   dst_loc[3] = height;
+
+   src_loc[0] = sx;
+   src_loc[1] = sy;
+   src_loc[2] = width;
+   src_loc[3] = height;
+
+   vg_get_copy_coords(src_loc, src->texture->width0, src->texture->height0,
+                      dst_loc, dst->width0, dst->height0);
 
    if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
        dst_loc[2] >= 0 && dst_loc[3] >= 0) {
-      renderer_copy_texture(ctx->renderer,
-                            src,
-                            src_loc[0],
-                            src_loc[1] + src_loc[3],
-                            src_loc[0] + src_loc[2],
-                            src_loc[1],
-                            dst,
-                            dst_loc[0],
-                            dst_loc[1] + dst_loc[3],
-                            dst_loc[0] + dst_loc[2],
-                            dst_loc[1]);
-   }
+      struct pipe_surface *surf, surf_tmpl;
+
+      /* get the destination surface */
+      u_surface_default_template(&surf_tmpl, dst, PIPE_BIND_RENDER_TARGET);
+      surf = ctx->pipe->create_surface(ctx->pipe, dst, &surf_tmpl);
+      if (surf && renderer_copy_begin(ctx->renderer, surf, VG_TRUE, src)) {
+         renderer_copy(ctx->renderer,
+               dst_loc[0], dst_loc[1], dst_loc[2], dst_loc[3],
+               src_loc[0], src_loc[1], src_loc[2], src_loc[3]);
+         renderer_copy_end(ctx->renderer);
+      }
 
+      pipe_surface_reference(&surf, NULL);
+   }
 }
 
 void vg_copy_surface(struct vg_context *ctx,
@@ -145,43 +158,19 @@ void vg_copy_surface(struct vg_context *ctx,
                      VGint width, VGint height)
 {
    VGfloat dst_loc[4], src_loc[4];
-   VGfloat dst_bounds[4], src_bounds[4];
-   VGfloat src_shift[4], dst_shift[4], shift[4];
 
    dst_loc[0] = dx;
    dst_loc[1] = dy;
    dst_loc[2] = width;
    dst_loc[3] = height;
-   dst_bounds[0] = 0.f;
-   dst_bounds[1] = 0.f;
-   dst_bounds[2] = dst->width;
-   dst_bounds[3] = dst->height;
 
    src_loc[0] = sx;
    src_loc[1] = sy;
    src_loc[2] = width;
    src_loc[3] = height;
-   src_bounds[0] = 0.f;
-   src_bounds[1] = 0.f;
-   src_bounds[2] = src->width;
-   src_bounds[3] = src->height;
-
-   vg_bound_rect(src_loc, src_bounds, src_shift);
-   vg_bound_rect(dst_loc, dst_bounds, dst_shift);
-   shift[0] = src_shift[0] - dst_shift[0];
-   shift[1] = src_shift[1] - dst_shift[1];
-
-   if (shift[0] < 0)
-      vg_shift_rectx(src_loc, src_bounds, -shift[0]);
-   else
-      vg_shift_rectx(dst_loc, dst_bounds, shift[0]);
-
-   if (shift[1] < 0)
-      vg_shift_recty(src_loc, src_bounds, -shift[1]);
-   else
-      vg_shift_recty(dst_loc, dst_bounds, shift[1]);
 
-   vg_sync_size(src_loc, dst_loc);
+   vg_get_copy_coords(src_loc, src->width, src->height,
+                      dst_loc, dst->width, dst->height);
 
    if (src_loc[2] > 0 && src_loc[3] > 0 &&
        dst_loc[2] > 0 && dst_loc[3] > 0) {
@@ -277,6 +266,7 @@ struct vg_image * image_create(VGImageFormat format,
    pt.width0 = width;
    pt.height0 = height;
    pt.depth0 = 1;
+   pt.array_size = 1;
    pt.bind = PIPE_BIND_SAMPLER_VIEW;
 
    newtex = screen->resource_create(screen, &pt);
@@ -284,6 +274,13 @@ struct vg_image * image_create(VGImageFormat format,
    debug_assert(newtex);
 
    u_sampler_view_default_template(&view_templ, newtex, newtex->format);
+   /* R, G, and B are treated as 1.0 for alpha-only formats in OpenVG */
+   if (newtex->format == PIPE_FORMAT_A8_UNORM) {
+      view_templ.swizzle_r = PIPE_SWIZZLE_ONE;
+      view_templ.swizzle_g = PIPE_SWIZZLE_ONE;
+      view_templ.swizzle_b = PIPE_SWIZZLE_ONE;
+   }
+
    view = pipe->create_sampler_view(pipe, newtex, &view_templ);
    /* want the texture to go away if the view is freed */
    pipe_resource_reference(&newtex, NULL);
@@ -420,7 +417,7 @@ void image_sub_data(struct vg_image *image,
 
    { /* upload color_data */
       struct pipe_transfer *transfer = pipe_get_transfer(
-         pipe, texture, 0, 0, 0,
+         pipe, texture, 0, 0,
          PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0);
       src += (dataStride * yoffset);
       for (i = 0; i < height; i++) {
@@ -451,11 +448,11 @@ void image_get_sub_data(struct vg_image * image,
    {
       struct pipe_transfer *transfer =
          pipe_get_transfer(pipe,
-                                  image->sampler_view->texture,  0, 0, 0,
-                                  PIPE_TRANSFER_READ,
-                                  0, 0,
-                                  image->x + image->width,
-                                  image->y + image->height);
+                           image->sampler_view->texture,  0, 0,
+                           PIPE_TRANSFER_READ,
+                           0, 0,
+                           image->x + image->width,
+                           image->y + image->height);
       /* Do a row at a time to flip image data vertically */
       for (i = 0; i < height; i++) {
 #if 0
@@ -525,14 +522,20 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
                    src->sampler_view, src->x + sx, src->y + sy, width, height);
 }
 
-void image_draw(struct vg_image *img)
+void image_draw(struct vg_image *img, struct matrix *matrix)
 {
    struct vg_context *ctx = vg_current_context();
+   struct matrix paint_matrix;
    VGfloat x1, y1;
    VGfloat x2, y2;
    VGfloat x3, y3;
    VGfloat x4, y4;
-   struct matrix *matrix;
+
+   if (!vg_get_paint_matrix(ctx,
+                            &ctx->state.vg.fill_paint_to_user_matrix,
+                            matrix,
+                            &paint_matrix))
+      return;
 
    x1 = 0;
    y1 = 0;
@@ -543,15 +546,10 @@ void image_draw(struct vg_image *img)
    x4 = 0;
    y4 = img->height;
 
-   matrix = &ctx->state.vg.image_user_to_surface_matrix;
-
-   matrix_map_point(matrix, x1, y1, &x1, &y1);
-   matrix_map_point(matrix, x2, y2, &x2, &y2);
-   matrix_map_point(matrix, x3, y3, &x3, &y3);
-   matrix_map_point(matrix, x4, y4, &x4, &y4);
-
+   shader_set_surface_matrix(ctx->shader, matrix);
    shader_set_drawing_image(ctx->shader, VG_TRUE);
    shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
+   shader_set_paint_matrix(ctx->shader, &paint_matrix);
    shader_set_image(ctx->shader, img);
    shader_bind(ctx->shader);
 
@@ -566,20 +564,21 @@ void image_set_pixels(VGint dx, VGint dy,
 {
    struct vg_context *ctx = vg_current_context();
    struct pipe_context *pipe = ctx->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *surf;
+   struct pipe_surface *surf, surf_tmpl;
    struct st_renderbuffer *strb = ctx->draw_buffer->strb;
 
    /* make sure rendering has completed */
    pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
-   surf = screen->get_tex_surface(screen, image_texture(src),  0, 0, 0,
-                                  0 /* no bind flags as surf isn't actually used??? */);
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, image_texture(src),
+                              0 /* no bind flag - not a surface*/);
+   surf = pipe->create_surface(pipe, image_texture(src), &surf_tmpl);
 
    vg_copy_surface(ctx, strb->surface, dx, dy,
                    surf, sx+src->x, sy+src->y, width, height);
 
-   screen->tex_surface_destroy(surf);
+   pipe->surface_destroy(pipe, surf);
 }
 
 void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
@@ -588,8 +587,7 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
 {
    struct vg_context *ctx = vg_current_context();
    struct pipe_context *pipe = ctx->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *surf;
+   struct pipe_surface *surf, surf_tmpl;
    struct st_renderbuffer *strb = ctx->draw_buffer->strb;
 
    /* flip the y coordinates */
@@ -598,8 +596,10 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
    /* make sure rendering has completed */
    pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
-   surf = screen->get_tex_surface(screen, image_texture(dst),  0, 0, 0,
-                                  0 /* no bind flags as surf isn't actually used??? */);
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, image_texture(dst),
+                              PIPE_BIND_RENDER_TARGET);
+   surf = pipe->create_surface(pipe, image_texture(dst), &surf_tmpl);
 
    vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy,
                    strb->surface, sx, sy, width, height);
index a990c9c58735eb90078bce8452742acc8318c7c7..391c048594843941e82f78fb52e157f1b9a1e339 100644 (file)
@@ -79,7 +79,7 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
                 VGint width, VGint height,
                 VGboolean dither);
 
-void image_draw(struct vg_image *img);
+void image_draw(struct vg_image *img, struct matrix *matrix);
 
 void image_set_pixels(VGint dx, VGint dy,
                       struct vg_image *src, VGint sx, VGint sy,
index ef28ebd740c7919aecf4657e955313b8208e056a..dfd0600e444c2c5d7fdb2eb34f76c86ad777397e 100644 (file)
 #include "shaders_cache.h"
 #include "renderer.h"
 #include "asm_util.h"
-#include "st_inlines.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
 #include "util/u_memory.h"
+#include "util/u_surface.h"
+#include "util/u_sampler.h"
 
 struct vg_mask_layer {
    struct vg_object base;
@@ -48,17 +49,6 @@ struct vg_mask_layer {
    struct pipe_sampler_view *sampler_view;
 };
 
-static INLINE struct pipe_surface *
-alpha_mask_surface(struct vg_context *ctx, int usage)
-{
-   struct pipe_screen *screen = ctx->pipe->screen;
-   struct st_framebuffer *stfb = ctx->draw_buffer;
-   return screen->get_tex_surface(screen,
-                                  stfb->alpha_mask_view->texture,
-                                  0, 0, 0,
-                                  usage);
-}
-
 static INLINE VGboolean
 intersect_rectangles(VGint dwidth, VGint dheight,
                      VGint swidth, VGint sheight,
@@ -110,15 +100,13 @@ static void read_alpha_mask(void * data, VGint dataStride,
 {
    struct vg_context *ctx = vg_current_context();
    struct pipe_context *pipe = ctx->pipe;
-   struct pipe_screen *screen = pipe->screen;
 
    struct st_framebuffer *stfb = ctx->draw_buffer;
    struct st_renderbuffer *strb = stfb->alpha_mask;
-   struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
 
    VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
    VGfloat *df = (VGfloat*)temp;
-   VGint y = (fb->height - sy) - 1, yStep = -1;
+   VGint y = (stfb->height - sy) - 1, yStep = -1;
    VGint i;
    VGubyte *dst = (VGubyte *)data;
    VGint xoffset = 0, yoffset = 0;
@@ -135,15 +123,15 @@ static void read_alpha_mask(void * data, VGint dataStride,
       yoffset = -sy;
       height += sy;
       sy = 0;
-      y = (fb->height - sy) - 1;
+      y = (stfb->height - sy) - 1;
       yoffset *= dataStride;
    }
 
    {
       struct pipe_surface *surf;
 
-      surf = screen->get_tex_surface(screen, strb->texture,  0, 0, 0,
-                                     PIPE_BIND_TRANSFER_READ);
+      surf = pipe->create_surface(pipe, strb->texture,  0, 0, 0,
+                                  PIPE_BIND_TRANSFER_READ);
 
       /* Do a row at a time to flip image data vertically */
       for (i = 0; i < height; i++) {
@@ -164,23 +152,23 @@ static void read_alpha_mask(void * data, VGint dataStride,
 void save_alpha_to_file(const char *filename)
 {
    struct vg_context *ctx = vg_current_context();
-   struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
    VGint *data;
    int i, j;
 
-   data = malloc(sizeof(int) * fb->width * fb->height);
-   read_alpha_mask(data, fb->width * sizeof(int),
+   data = malloc(sizeof(int) * stfb->width * stfb->height);
+   read_alpha_mask(data, stfb->width * sizeof(int),
                    VG_sRGBA_8888,
-                   0, 0, fb->width, fb->height);
+                   0, 0, stfb->width, stfb->height);
    fprintf(stderr, "/*---------- start */\n");
    fprintf(stderr, "const int image_width = %d;\n",
-           fb->width);
+           stfb->width);
    fprintf(stderr, "const int image_height = %d;\n",
-           fb->height);
+           stfb->height);
    fprintf(stderr, "const int image_data = {\n");
-   for (i = 0; i < fb->height; ++i) {
-      for (j = 0; j < fb->width; ++j) {
-         int rgba = data[i * fb->height + j];
+   for (i = 0; i < stfb->height; ++i) {
+      for (j = 0; j < stfb->width; ++j) {
+         int rgba = data[i * stfb->height + j];
          int argb = 0;
          argb = (rgba >> 8);
          argb |= ((rgba & 0xff) << 24);
@@ -193,49 +181,12 @@ void save_alpha_to_file(const char *filename)
 }
 #endif
 
-static void setup_mask_framebuffer(struct pipe_surface *surf,
-                                   VGint surf_width, VGint surf_height)
-{
-   struct vg_context *ctx = vg_current_context();
-   struct pipe_framebuffer_state fb;
-
-   memset(&fb, 0, sizeof(fb));
-   fb.width = surf_width;
-   fb.height = surf_height;
-   fb.nr_cbufs = 1;
-   fb.cbufs[0] = surf;
-   {
-      VGint i;
-      for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
-         fb.cbufs[i] = 0;
-   }
-   cso_set_framebuffer(ctx->cso_context, &fb);
-}
-
-
-/* setup shader constants */
-static void setup_mask_operation(VGMaskOperation operation)
+/* setup mask shader */
+static void *setup_mask_operation(VGMaskOperation operation)
 {
    struct vg_context *ctx = vg_current_context();
-   struct pipe_resource **cbuf = &ctx->mask.cbuf;
-   const VGint param_bytes = 4 * sizeof(VGfloat);
-   const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f};
    void *shader = 0;
 
-   /* We always need to get a new buffer, to keep the drivers simple and
-    * avoid gratuitous rendering synchronization.
-    */
-   pipe_resource_reference(cbuf, NULL);
-
-   *cbuf = pipe_buffer_create(ctx->pipe->screen, 
-                              PIPE_BIND_CONSTANT_BUFFER,
-                              param_bytes);
-   if (*cbuf) {
-      st_no_flush_pipe_buffer_write(ctx, *cbuf,
-                                    0, param_bytes, ones);
-   }
-
-   ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
    switch (operation) {
    case VG_UNION_MASK: {
       if (!ctx->mask.union_fs) {
@@ -281,94 +232,21 @@ static void setup_mask_operation(VGMaskOperation operation)
          assert(0);
       break;
    }
-   cso_set_fragment_shader_handle(ctx->cso_context, shader);
-}
-
-static void setup_mask_samplers(struct pipe_sampler_view *umask)
-{
-   struct vg_context *ctx = vg_current_context();
-   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
-   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
-   struct st_framebuffer *fb_buffers = ctx->draw_buffer;
-   struct pipe_sampler_view *uprev = NULL;
-   struct pipe_sampler_state sampler;
-
-   uprev = fb_buffers->blend_texture_view;
-   sampler = ctx->mask.sampler;
-   sampler.normalized_coords = 1;
-
-   samplers[0] = NULL;
-   samplers[1] = NULL;
-   sampler_views[0] = NULL;
-   sampler_views[1] = NULL;
-
-   samplers[0] = &sampler;
-   samplers[1] = &ctx->mask.sampler;
-
-   sampler_views[0] = umask;
-   sampler_views[1] = uprev;
-
-   cso_set_samplers(ctx->cso_context, 2,
-                    (const struct pipe_sampler_state **)samplers);
-   cso_set_fragment_sampler_views(ctx->cso_context, 2, sampler_views);
-}
-
-
-/* setup shader constants */
-static void setup_mask_fill(const VGfloat color[4])
-{
-   struct vg_context *ctx = vg_current_context();
-   struct pipe_resource **cbuf = &ctx->mask.cbuf;
-   const VGint param_bytes = 4 * sizeof(VGfloat);
-
-   /* We always need to get a new buffer, to keep the drivers simple and
-    * avoid gratuitous rendering synchronization.
-    */
-   pipe_resource_reference(cbuf, NULL);
-
-   *cbuf = pipe_buffer_create(ctx->pipe->screen,
-                              PIPE_BIND_CONSTANT_BUFFER,
-                              param_bytes);
-   if (*cbuf) {
-      st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, color);
-   }
-
-   ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
-   cso_set_fragment_shader_handle(ctx->cso_context,
-                                  shaders_cache_fill(ctx->sc,
-                                                     VEGA_SOLID_FILL_SHADER));
-}
-
-static void setup_mask_viewport()
-{
-   struct vg_context *ctx = vg_current_context();
-   vg_set_viewport(ctx, VEGA_Y0_TOP);
-}
-
-static void setup_mask_blend()
-{
-   struct vg_context *ctx = vg_current_context();
-
-   struct pipe_blend_state blend;
 
-   memset(&blend, 0, sizeof(struct pipe_blend_state));
-   blend.rt[0].blend_enable = 0;
-   blend.rt[0].colormask = PIPE_MASK_RGBA;
-   blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-
-   cso_set_blend(ctx->cso_context, &blend);
+   return shader;
 }
 
-
-static void surface_fill(struct pipe_surface *surf,
-                         int surf_width, int surf_height,
-                         int x, int y, int width, int height,
-                         const VGfloat color[4])
+static void mask_resource_fill(struct pipe_resource *dst,
+                               int x, int y, int width, int height,
+                               VGfloat coverage)
 {
    struct vg_context *ctx = vg_current_context();
+   VGfloat fs_consts[12] = {
+      0.0f, 0.0f, 0.0f, 0.0f, /* not used */
+      0.0f, 0.0f, 0.0f, 0.0f, /* not used */
+      0.0f, 0.0f, 0.0f, coverage /* color */
+   };
+   void *fs;
 
    if (x < 0) {
       width += x;
@@ -379,50 +257,38 @@ static void surface_fill(struct pipe_surface *surf,
       y = 0;
    }
 
-   cso_save_framebuffer(ctx->cso_context);
-   cso_save_blend(ctx->cso_context);
-   cso_save_fragment_shader(ctx->cso_context);
-   cso_save_viewport(ctx->cso_context);
-
-   setup_mask_blend();
-   setup_mask_fill(color);
-   setup_mask_framebuffer(surf, surf_width, surf_height);
-   setup_mask_viewport();
+   fs = shaders_cache_fill(ctx->sc, VEGA_SOLID_FILL_SHADER);
 
-   renderer_draw_quad(ctx->renderer, x, y,
-                      x + width, y + height, 0.0f/*depth should be disabled*/);
-
-
-   /* make sure rendering has completed */
-   ctx->pipe->flush(ctx->pipe,
-                    PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
-                    NULL);
+   if (renderer_filter_begin(ctx->renderer, dst, VG_FALSE, ~0,
+            NULL, NULL, 0, fs, (const void *) fs_consts, sizeof(fs_consts))) {
+      renderer_filter(ctx->renderer, x, y, width, height, 0, 0, 0, 0);
+      renderer_filter_end(ctx->renderer);
+   }
 
 #if DEBUG_MASKS
    save_alpha_to_file(0);
 #endif
-
-   cso_restore_blend(ctx->cso_context);
-   cso_restore_framebuffer(ctx->cso_context);
-   cso_restore_fragment_shader(ctx->cso_context);
-   cso_restore_viewport(ctx->cso_context);
 }
 
 
 static void mask_using_texture(struct pipe_sampler_view *sampler_view,
+                               VGboolean is_layer,
                                VGMaskOperation operation,
                                VGint x, VGint y,
                                VGint width, VGint height)
 {
    struct vg_context *ctx = vg_current_context();
+   struct pipe_sampler_view *dst_view = vg_get_surface_mask(ctx);
+   struct pipe_resource *dst = dst_view->texture;
    struct pipe_resource *texture = sampler_view->texture;
-   struct pipe_surface *surface =
-      alpha_mask_surface(ctx, PIPE_BIND_RENDER_TARGET);
+   const struct pipe_sampler_state *samplers[2];
+   struct pipe_sampler_view *views[2];
+   struct pipe_sampler_state sampler;
    VGint offsets[4], loc[4];
+   const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f};
+   void *fs;
 
-   if (!surface)
-      return;
-   if (!intersect_rectangles(surface->width, surface->height,
+   if (!intersect_rectangles(dst->width0, dst->height0,
                              texture->width0, texture->height0,
                              x, y, width, height,
                              offsets, loc))
@@ -434,38 +300,30 @@ static void mask_using_texture(struct pipe_sampler_view *sampler_view,
                 loc[1], loc[2], loc[3]);
 #endif
 
+
+   sampler = ctx->mask.sampler;
+   sampler.normalized_coords = 1;
+   samplers[0] = &sampler;
+   views[0] = sampler_view;
+
    /* prepare our blend surface */
-   vg_prepare_blend_surface_from_mask(ctx);
-
-   cso_save_samplers(ctx->cso_context);
-   cso_save_fragment_sampler_views(ctx->cso_context);
-   cso_save_framebuffer(ctx->cso_context);
-   cso_save_blend(ctx->cso_context);
-   cso_save_fragment_shader(ctx->cso_context);
-   cso_save_viewport(ctx->cso_context);
-
-   setup_mask_samplers(sampler_view);
-   setup_mask_blend();
-   setup_mask_operation(operation);
-   setup_mask_framebuffer(surface, surface->width, surface->height);
-   setup_mask_viewport();
-
-   /* render the quad to propagate the rendering from stencil */
-   renderer_draw_texture(ctx->renderer, texture,
-                         offsets[0], offsets[1],
-                         offsets[0] + offsets[2], offsets[1] + offsets[3],
-                         loc[0], loc[1], loc[0] + loc[2], loc[1] + loc[3]);
+   samplers[1] = &ctx->mask.sampler;
+   views[1] = vg_prepare_blend_surface_from_mask(ctx);
 
-   /* make sure rendering has completed */
-   ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-   cso_restore_blend(ctx->cso_context);
-   cso_restore_framebuffer(ctx->cso_context);
-   cso_restore_fragment_shader(ctx->cso_context);
-   cso_restore_samplers(ctx->cso_context);
-   cso_restore_fragment_sampler_views(ctx->cso_context);
-   cso_restore_viewport(ctx->cso_context);
-
-   pipe_surface_reference(&surface, NULL);
+   fs = setup_mask_operation(operation);
+
+   if (renderer_filter_begin(ctx->renderer, dst, VG_FALSE,
+            ~0, samplers, views, 2, fs, (const void *) ones, sizeof(ones))) {
+      /* layer should be flipped when used as a texture */
+      if (is_layer) {
+         offsets[1] += offsets[3];
+         offsets[3] = -offsets[3];
+      }
+      renderer_filter(ctx->renderer,
+            loc[0], loc[1], loc[2], loc[3],
+            offsets[0], offsets[1], offsets[2], offsets[3]);
+      renderer_filter_end(ctx->renderer);
+   }
 }
 
 
@@ -496,8 +354,8 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
       pt.width0 = width;
       pt.height0 = height;
       pt.depth0 = 1;
+      pt.array_size = 1;
       pt.bind = PIPE_BIND_SAMPLER_VIEW;
-      pt.compressed = 0;
 
       texture = screen->resource_create(screen, &pt);
 
@@ -519,7 +377,7 @@ void mask_layer_destroy(struct vg_mask_layer *layer)
    struct vg_context *ctx = vg_current_context();
 
    vg_context_remove_object(ctx, VG_OBJECT_MASK, layer);
-   pipe_resource_release(&layer->texture);
+   pipe_sampler_view_reference(&layer->sampler_view, NULL);
    FREE(layer);
 }
 
@@ -528,22 +386,12 @@ void mask_layer_fill(struct vg_mask_layer *layer,
                      VGint width, VGint height,
                      VGfloat value)
 {
-   struct vg_context *ctx = vg_current_context();
    VGfloat alpha_color[4] = {0, 0, 0, 0};
-   struct pipe_surface *surface;
 
    alpha_color[3] = value;
 
-   surface = ctx->pipe->screen->get_tex_surface(
-      ctx->pipe->screen, layer->sampler_view->texture,
-      0, 0, 0,
-      PIPE_BIND_RENDER_TARGET);
-
-   surface_fill(surface,
-                layer->width, layer->height,
-                x, y, width, height, alpha_color);
-
-   ctx->pipe->screen->tex_surface_release(ctx->pipe->screen, &surface);
+   mask_resource_fill(layer->sampler_view->texture,
+                      x, y, width, height, value);
 }
 
 void mask_copy(struct vg_mask_layer *layer,
@@ -551,16 +399,27 @@ void mask_copy(struct vg_mask_layer *layer,
                VGint dx, VGint dy,
                VGint width, VGint height)
 {
-    struct vg_context *ctx = vg_current_context();
-    struct st_framebuffer *fb_buffers = ctx->draw_buffer;
-
-    renderer_copy_texture(ctx->renderer,
-                          layer->sampler_view,
-                          sx, sy,
-                          sx + width, sy + height,
-                          fb_buffers->alpha_mask_view->texture,
-                          dx, dy,
-                          dx + width, dy + height);
+   struct vg_context *ctx = vg_current_context();
+   struct pipe_sampler_view *src = vg_get_surface_mask(ctx);
+   struct pipe_surface *surf, surf_tmpl;
+
+   /* get the destination surface */
+   u_surface_default_template(&surf_tmpl, layer->sampler_view->texture,
+                              PIPE_BIND_RENDER_TARGET);
+   surf = ctx->pipe->create_surface(ctx->pipe, layer->sampler_view->texture,
+                                    &surf_tmpl);
+   if (surf && renderer_copy_begin(ctx->renderer, surf, VG_FALSE, src)) {
+      /* layer should be flipped when used as a texture */
+      sy += height;
+      height = -height;
+
+      renderer_copy(ctx->renderer,
+            dx, dy, width, height,
+            sx, sy, width, height);
+      renderer_copy_end(ctx->renderer);
+   }
+
+   pipe_surface_reference(&surf, NULL);
 }
 
 static void mask_layer_render_to(struct vg_mask_layer *layer,
@@ -568,41 +427,25 @@ static void mask_layer_render_to(struct vg_mask_layer *layer,
                                  VGbitfield paint_modes)
 {
    struct vg_context *ctx = vg_current_context();
-   const VGfloat fill_color[4] = {1.f, 1.f, 1.f, 1.f};
-   struct pipe_screen *screen = ctx->pipe->screen;
-   struct pipe_surface *surface;
-
-   surface = screen->get_tex_surface(screen, layer->sampler_view->texture,  0, 0, 0,
-                                     PIPE_BIND_RENDER_TARGET);
-
-   cso_save_framebuffer(ctx->cso_context);
-   cso_save_fragment_shader(ctx->cso_context);
-   cso_save_viewport(ctx->cso_context);
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_sampler_view *view = vg_get_surface_mask(ctx);
+   struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
+   struct pipe_surface *surf, surf_tmpl;
+   u_surface_default_template(&surf_tmpl, view->texture,
+                              PIPE_BIND_RENDER_TARGET);
+   surf = pipe->create_surface(pipe, view->texture, &surf_tmpl);
 
-   setup_mask_blend();
-   setup_mask_fill(fill_color);
-   setup_mask_framebuffer(surface, layer->width, layer->height);
-   setup_mask_viewport();
+   renderer_validate_for_mask_rendering(ctx->renderer, surf, mat);
 
    if (paint_modes & VG_FILL_PATH) {
-      struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
-      path_fill(path, mat);
+      path_fill(path);
    }
 
    if (paint_modes & VG_STROKE_PATH){
       path_stroke(path);
    }
 
-
-   /* make sure rendering has completed */
-   ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
-   cso_restore_framebuffer(ctx->cso_context);
-   cso_restore_fragment_shader(ctx->cso_context);
-   cso_restore_viewport(ctx->cso_context);
-   ctx->state.dirty |= BLEND_DIRTY;
-
-   screen->tex_surface_release(ctx->pipe->screen, &surface);
+   pipe_surface_reference(&surf, NULL);
 }
 
 void mask_render_to(struct path *path,
@@ -610,19 +453,19 @@ void mask_render_to(struct path *path,
                     VGMaskOperation operation)
 {
    struct vg_context *ctx = vg_current_context();
-   struct st_framebuffer *fb_buffers = ctx->draw_buffer;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
    struct vg_mask_layer *temp_layer;
    VGint width, height;
 
-   width = fb_buffers->alpha_mask_view->texture->width0;
-   height = fb_buffers->alpha_mask_view->texture->width0;
+   width = stfb->width;
+   height = stfb->height;
 
    temp_layer = mask_layer_create(width, height);
+   mask_layer_fill(temp_layer, 0, 0, width, height, 0.0f);
 
    mask_layer_render_to(temp_layer, path, paint_modes);
 
-   mask_using_layer(temp_layer, 0, 0, width, height,
-                    operation);
+   mask_using_layer(temp_layer, operation, 0, 0, width, height);
 
    mask_layer_destroy(temp_layer);
 }
@@ -632,7 +475,7 @@ void mask_using_layer(struct vg_mask_layer *layer,
                       VGint x, VGint y,
                       VGint width, VGint height)
 {
-   mask_using_texture(layer->sampler_view, operation,
+   mask_using_texture(layer->sampler_view, VG_TRUE, operation,
                       x, y, width, height);
 }
 
@@ -654,7 +497,7 @@ void mask_using_image(struct vg_image *image,
                       VGint x, VGint y,
                       VGint width, VGint height)
 {
-   mask_using_texture(image->sampler_view, operation,
+   mask_using_texture(image->sampler_view, VG_FALSE, operation,
                       x, y, width, height);
 }
 
@@ -662,23 +505,15 @@ void mask_fill(VGint x, VGint y, VGint width, VGint height,
                VGfloat value)
 {
    struct vg_context *ctx = vg_current_context();
-   VGfloat alpha_color[4] = {.0f, .0f, .0f, value};
-   struct pipe_surface *surf = alpha_mask_surface(
-      ctx, PIPE_BIND_RENDER_TARGET);
+   struct pipe_sampler_view *view = vg_get_surface_mask(ctx);
 
 #if DEBUG_MASKS
    debug_printf("mask_fill(%d, %d, %d, %d) with  rgba(%f, %f, %f, %f)\n",
                 x, y, width, height,
-                alpha_color[0], alpha_color[1],
-                alpha_color[2], alpha_color[3]);
-   debug_printf("XXX %f  === %f \n",
-                alpha_color[3], value);
+                0.0f, 0.0f, 0.0f, value);
 #endif
 
-   surface_fill(surf, surf->width, surf->height,
-                x, y, width, height, alpha_color);
-
-   pipe_surface_reference(&surf, NULL);
+   mask_resource_fill(view->texture, x, y, width, height, value);
 }
 
 VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
@@ -687,10 +522,8 @@ VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
    struct vg_context *ctx = vg_current_context();
 
    if (ctx->state.vg.masking) {
-      struct st_framebuffer *fb_buffers = ctx->draw_buffer;
-
       samplers[1] = &ctx->mask.sampler;
-      sampler_views[1] = fb_buffers->alpha_mask_view;
+      sampler_views[1] = vg_get_surface_mask(ctx);
       return 1;
    } else
       return 0;
index 4c207f912a8558bad7113ed439ce183e1e2f534c..bed2b3193d02b149e6456258330bb687fb7104c1 100644 (file)
@@ -129,7 +129,7 @@ static INLINE void matrix_make_affine(struct matrix *matrix)
 }
 
 static INLINE void matrix_mult(struct matrix *dst,
-                               struct matrix *src)
+                               const struct matrix *src)
 {
    VGfloat m11 = dst->m[0]*src->m[0] + dst->m[3]*src->m[1] + dst->m[6]*src->m[2];
    VGfloat m12 = dst->m[0]*src->m[3] + dst->m[3]*src->m[4] + dst->m[6]*src->m[5];
index c0c8cddabe94d2edd506a2f7bc93665d3a71143c..2db8cbcf7c89f01305e5527122cd3f89b8578cd1 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "matrix.h"
 #include "image.h"
-#include "st_inlines.h"
 
 #include "pipe/p_compiler.h"
 #include "util/u_inlines.h"
@@ -155,14 +154,15 @@ static INLINE struct pipe_resource *create_gradient_texture(struct vg_paint *p)
    templ.width0 = 1024;
    templ.height0 = 1;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.bind = PIPE_BIND_SAMPLER_VIEW;
 
    tex = screen->resource_create(screen, &templ);
 
    { /* upload color_data */
       struct pipe_transfer *transfer =
-         st_no_flush_get_transfer(p->base.ctx, tex, 0, 0, 0,
-                                      PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
+         pipe_get_transfer(p->base.ctx->pipe, tex, 0, 0,
+                           PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
       void *map = pipe->transfer_map(pipe, transfer);
       memcpy(map, p->gradient.color_data, sizeof(VGint)*1024);
       pipe->transfer_unmap(pipe, transfer);
@@ -261,14 +261,18 @@ static INLINE void paint_color_buffer(struct vg_paint *paint, void *buffer)
    map[7] = 4.f;
 }
 
-static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint,
+                                                const struct matrix *inv,
+                                                void *buffer)
 {
-   struct vg_context *ctx = paint->base.ctx;
    VGfloat *map = (VGfloat*)buffer;
+   VGfloat dd;
 
    map[0] = paint->gradient.linear.coords[2] - paint->gradient.linear.coords[0];
    map[1] = paint->gradient.linear.coords[3] - paint->gradient.linear.coords[1];
-   map[2] = 1.f / (map[0] * map[0] + map[1] * map[1]);
+   dd = (map[0] * map[0] + map[1] * map[1]);
+
+   map[2] = (dd > 0.0f) ? 1.f / dd : 0.f;
    map[3] = 1.f;
 
    map[4] = 0.f;
@@ -277,15 +281,10 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *bu
    map[7] = 4.f;
    {
       struct matrix mat;
-      struct matrix inv;
       matrix_load_identity(&mat);
+      /* VEGA_LINEAR_GRADIENT_SHADER expects the first point to be at (0, 0) */
       matrix_translate(&mat, -paint->gradient.linear.coords[0], -paint->gradient.linear.coords[1]);
-      memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix,
-             sizeof(struct matrix));
-      matrix_invert(&inv);
-      matrix_mult(&inv, &mat);
-      memcpy(&mat, &inv,
-             sizeof(struct matrix));
+      matrix_mult(&mat, inv);
 
       map[8]  = mat.m[0]; map[9]  = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
       map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -298,17 +297,37 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *bu
 }
 
 
-static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
+                                                const struct matrix *inv,
+                                                void *buffer)
 {
-   VGfloat *radialCoords = paint->gradient.radial.vals;
-   struct vg_context *ctx = paint->base.ctx;
-
+   const VGfloat *center = &paint->gradient.radial.vals[0];
+   const VGfloat *focal = &paint->gradient.radial.vals[2];
+   VGfloat rr = paint->gradient.radial.vals[4];
    VGfloat *map = (VGfloat*)buffer;
+   VGfloat dd, new_focal[2];
+
+   rr *= rr;
+
+   map[0] = center[0] - focal[0];
+   map[1] = center[1] - focal[1];
+   dd = map[0] * map[0] + map[1] * map[1];
+
+   /* focal point must lie inside the circle */
+   if (0.998f * rr < dd) {
+      VGfloat scale;
+
+      scale = (dd > 0.0f) ? sqrt(0.998f * rr / dd) : 0.0f;
+      map[0] *= scale;
+      map[1] *= scale;
 
-   map[0] = radialCoords[0] - radialCoords[2];
-   map[1] = radialCoords[1] - radialCoords[3];
-   map[2] = -map[0] * map[0] - map[1] * map[1] +
-            radialCoords[4] * radialCoords[4];
+      new_focal[0] = center[0] - map[0];
+      new_focal[1] = center[1] - map[1];
+      dd = map[0] * map[0] + map[1] * map[1];
+      focal = new_focal;
+   }
+
+   map[2] = (rr > dd) ? rr - dd : 1.0f;
    map[3] = 1.f;
 
    map[4] = 0.f;
@@ -318,15 +337,9 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *bu
 
    {
       struct matrix mat;
-      struct matrix inv;
       matrix_load_identity(&mat);
-      matrix_translate(&mat, -radialCoords[2], -radialCoords[3]);
-      memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix,
-             sizeof(struct matrix));
-      matrix_invert(&inv);
-      matrix_mult(&inv, &mat);
-      memcpy(&mat, &inv,
-             sizeof(struct matrix));
+      matrix_translate(&mat, -focal[0], -focal[1]);
+      matrix_mult(&mat, inv);
 
       map[8]  = mat.m[0]; map[9]  = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
       map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -340,10 +353,10 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *bu
 }
 
 
-static INLINE void  paint_pattern_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void  paint_pattern_buffer(struct vg_paint *paint,
+                                         const struct matrix *inv,
+                                         void *buffer)
 {
-   struct vg_context *ctx = paint->base.ctx;
-
    VGfloat *map = (VGfloat *)buffer;
    memcpy(map, paint->solid.color, 4 * sizeof(VGfloat));
 
@@ -353,17 +366,8 @@ static INLINE void  paint_pattern_buffer(struct vg_paint *paint, void *buffer)
    map[7] = paint->pattern.sampler_view->texture->height0;
    {
       struct matrix mat;
-      memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
-             sizeof(struct matrix));
-      matrix_invert(&mat);
-      {
-         struct matrix pm;
-         memcpy(&pm, &ctx->state.vg.path_user_to_surface_matrix,
-                sizeof(struct matrix));
-         matrix_invert(&pm);
-         matrix_mult(&pm, &mat);
-         memcpy(&mat, &pm, sizeof(struct matrix));
-      }
+
+      memcpy(&mat, inv, sizeof(*inv));
 
       map[8]  = mat.m[0]; map[9]  = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
       map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -672,6 +676,34 @@ void paint_resolve_type(struct vg_paint *paint)
    }
 }
 
+VGboolean paint_is_degenerate(struct vg_paint *paint)
+{
+   VGboolean degen;
+   VGfloat *vals;
+
+
+   switch (paint->type) {
+   case VG_PAINT_TYPE_LINEAR_GRADIENT:
+      vals = paint->gradient.linear.coords;
+      /* two points are coincident */
+      degen = (floatsEqual(vals[0], vals[2]) &&
+               floatsEqual(vals[1], vals[3]));
+      break;
+   case VG_PAINT_TYPE_RADIAL_GRADIENT:
+      vals = paint->gradient.radial.vals;
+      /* radius <= 0 */
+      degen = (vals[4] <= 0.0f);
+      break;
+   case VG_PAINT_TYPE_COLOR:
+   case VG_PAINT_TYPE_PATTERN:
+   default:
+      degen = VG_FALSE;
+      break;
+   }
+
+   return degen;
+}
+
 VGint paint_constant_buffer_size(struct vg_paint *paint)
 {
    switch(paint->type) {
@@ -695,6 +727,7 @@ VGint paint_constant_buffer_size(struct vg_paint *paint)
 }
 
 void paint_fill_constant_buffer(struct vg_paint *paint,
+                                const struct matrix *mat,
                                 void *buffer)
 {
    switch(paint->type) {
@@ -702,13 +735,13 @@ void paint_fill_constant_buffer(struct vg_paint *paint,
       paint_color_buffer(paint, buffer);
       break;
    case VG_PAINT_TYPE_LINEAR_GRADIENT:
-      paint_linear_gradient_buffer(paint, buffer);
+      paint_linear_gradient_buffer(paint, mat, buffer);
       break;
    case VG_PAINT_TYPE_RADIAL_GRADIENT:
-      paint_radial_gradient_buffer(paint, buffer);
+      paint_radial_gradient_buffer(paint, mat, buffer);
       break;
    case VG_PAINT_TYPE_PATTERN:
-      paint_pattern_buffer(paint, buffer);
+      paint_pattern_buffer(paint, mat, buffer);
       break;
 
    default:
index 012cd3e561896f67a0df4be761468c5ab19be84e..3de3bbe12eda91fc9c00fd03df54ecdab09a5359 100644 (file)
@@ -110,8 +110,12 @@ VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
 VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
                           struct pipe_sampler_view **sampler_views);
 
+VGboolean paint_is_degenerate(struct vg_paint *paint);
+
 VGint paint_constant_buffer_size(struct vg_paint *paint);
+
 void paint_fill_constant_buffer(struct vg_paint *paint,
+                                const struct matrix *mat,
                                 void *buffer);
 
 
index 05f8b0d9979ed181c9319c8369592f1e068eb318..d7253befd035049d0ea1a107876f3091fed79413 100644 (file)
@@ -207,13 +207,29 @@ struct path * path_create(VGPathDatatype dt, VGfloat scale, VGfloat bias,
    return path;
 }
 
+static void polygon_array_cleanup(struct polygon_array *polyarray)
+{
+   if (polyarray->array) {
+      VGint i;
+
+      for (i = 0; i < polyarray->array->num_elements; i++) {
+         struct polygon *p = ((struct polygon **) polyarray->array->data)[i];
+         polygon_destroy(p);
+      }
+
+      array_destroy(polyarray->array);
+      polyarray->array = NULL;
+   }
+}
+
 void path_destroy(struct path *p)
 {
    vg_context_remove_object(vg_current_context(), VG_OBJECT_PATH, p);
 
    array_destroy(p->segments);
    array_destroy(p->control_points);
-   array_destroy(p->fill_polys.polygon_array.array);
+
+   polygon_array_cleanup(&p->fill_polys.polygon_array);
 
    if (p->stroked.path)
       path_destroy(p->stroked.path);
@@ -302,7 +318,6 @@ static void convert_path(struct path *p,
    }
 }
 
-
 static void polygon_array_calculate_bounds( struct polygon_array *polyarray )
 {
    struct array *polys = polyarray->array;
@@ -312,7 +327,15 @@ static void polygon_array_calculate_bounds( struct polygon_array *polyarray )
    unsigned i;
 
    assert(polys);
-   assert(polys->num_elements);
+
+   if (!polys->num_elements) {
+      polyarray->min_x = 0.0f;
+      polyarray->min_y = 0.0f;
+      polyarray->max_x = 0.0f;
+      polyarray->max_y = 0.0f;
+      return;
+   }
+
    polygon_bounding_rect((((struct polygon**)polys->data)[0]), bounds);
    min_x = bounds[0];
    min_y = bounds[1];
@@ -353,16 +376,17 @@ static struct polygon_array * path_get_fill_polygons(struct path *p, struct matr
          return &p->fill_polys.polygon_array;
       }
       else {
-         array_destroy( p->fill_polys.polygon_array.array );
-         p->fill_polys.polygon_array.array = NULL;
+         polygon_array_cleanup(&p->fill_polys.polygon_array);
       }
    }
 
-   array = array_create(sizeof(struct array*));
+   /* an array of pointers to polygons */
+   array = array_create(sizeof(struct polygon *));
 
    sx = sy = px = py = ox = oy = 0.f;
 
-   current = polygon_create(32);
+   if (p->num_segments)
+      current = polygon_create(32);
 
    for (i = 0; i < p->num_segments; ++i) {
       VGubyte segment = ((VGubyte*)(p->segments->data))[i];
@@ -1519,10 +1543,11 @@ struct path * path_create_stroke(struct path *p,
    return stroker.base.path;
 }
 
-void path_render(struct path *p, VGbitfield paintModes)
+void path_render(struct path *p, VGbitfield paintModes,
+                 struct matrix *mat)
 {
    struct vg_context *ctx = vg_current_context();
-   struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
+   struct matrix paint_matrix;
 
    vg_validate_state(ctx);
 
@@ -1534,29 +1559,45 @@ void path_render(struct path *p, VGbitfield paintModes)
            mat->m[3], mat->m[4], mat->m[5],
            mat->m[6], mat->m[7], mat->m[8]);
 #endif
-   if (paintModes & VG_FILL_PATH) {
+   if ((paintModes & VG_FILL_PATH) &&
+       vg_get_paint_matrix(ctx,
+                           &ctx->state.vg.fill_paint_to_user_matrix,
+                           mat,
+                           &paint_matrix)) {
       /* First the fill */
+      shader_set_surface_matrix(ctx->shader, mat);
       shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
+      shader_set_paint_matrix(ctx->shader, &paint_matrix);
       shader_bind(ctx->shader);
-      path_fill(p, mat);
+      path_fill(p);
    }
 
-   if (paintModes & VG_STROKE_PATH){
+   if ((paintModes & VG_STROKE_PATH) &&
+       vg_get_paint_matrix(ctx,
+                           &ctx->state.vg.stroke_paint_to_user_matrix,
+                           mat,
+                           &paint_matrix)) {
       /* 8.7.5: "line width less than or equal to 0 prevents stroking from
        *  taking place."*/
       if (ctx->state.vg.stroke.line_width.f <= 0)
          return;
+      shader_set_surface_matrix(ctx->shader, mat);
       shader_set_paint(ctx->shader, ctx->state.vg.stroke_paint);
+      shader_set_paint_matrix(ctx->shader, &paint_matrix);
       shader_bind(ctx->shader);
       path_stroke(p);
    }
 }
 
-void path_fill(struct path *p, struct matrix *mat)
+void path_fill(struct path *p)
 {
    struct vg_context *ctx = vg_current_context();
+   struct matrix identity;
+
+   matrix_load_identity(&identity);
+
    {
-      struct polygon_array *polygon_array = path_get_fill_polygons(p, mat);
+      struct polygon_array *polygon_array = path_get_fill_polygons(p, &identity);
       struct array *polys = polygon_array->array;
 
       if (!polygon_array || !polys || !polys->num_elements) {
@@ -1569,7 +1610,6 @@ void path_fill(struct path *p, struct matrix *mat)
 void path_stroke(struct path *p)
 {
    struct vg_context *ctx = vg_current_context();
-   struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
    VGFillRule old_fill = ctx->state.vg.fill_rule;
    struct matrix identity;
    struct path *stroke;
@@ -1579,7 +1619,7 @@ void path_stroke(struct path *p)
    if (stroke && !path_is_empty(stroke)) {
       ctx->state.vg.fill_rule = VG_NON_ZERO;
 
-      path_fill(stroke, mat);
+      path_fill(stroke);
 
       ctx->state.vg.fill_rule = old_fill;
    }
index e34538b73681de2835e83ae7ef784dd8935a7653..d84b1f083cee32d7d4c3cd8b591037e6cb46a993 100644 (file)
@@ -104,8 +104,8 @@ VGboolean path_interpolate(struct path *dst,
                            VGfloat amount);
 
 void path_clear(struct path *p, VGbitfield capabilities);
-void path_render(struct path *p, VGbitfield paintModes);
-void path_fill(struct path *p, struct matrix *mat);
+void path_render(struct path *p, VGbitfield paintModes, struct matrix *mat);
+void path_fill(struct path *p);
 void path_stroke(struct path *p);
 
 void path_move_to(struct path *p, float x, float y);
index ca8831064c919ed6db9554754ed667e8455aaaac..a491de27fa675613c9197f6263a3ab389eece1cc 100644 (file)
@@ -244,24 +244,11 @@ VGboolean polygon_is_closed(struct polygon *p)
    return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]);
 }
 
-static void set_blend_for_fill(struct pipe_blend_state *blend)
-{
-   memset(blend, 0, sizeof(struct pipe_blend_state));
-   blend->rt[0].colormask = 0; /*disable colorwrites*/
-
-   blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
-   blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
-}
-
-static void draw_polygon(struct vg_context *ctx,
-                         struct polygon *poly)
+static void polygon_prepare_buffer(struct vg_context *ctx,
+                                   struct polygon *poly)
 {
    int vert_size;
    struct pipe_context *pipe;
-   struct pipe_vertex_buffer vbuffer;
-   struct pipe_vertex_element velement;
 
    vert_size = poly->num_verts * COMPONENTS * sizeof(float);
 
@@ -281,35 +268,15 @@ static void draw_polygon(struct vg_context *ctx,
                                          PIPE_BIND_VERTEX_BUFFER);
       poly->dirty = VG_FALSE;
    }
-
-
-   /* tell pipe about the vertex buffer */
-   memset(&vbuffer, 0, sizeof(vbuffer));
-   vbuffer.buffer = poly->vbuf;
-   vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
-   vbuffer.buffer_offset = 0;
-   vbuffer.max_index = poly->num_verts - 1;
-   pipe->set_vertex_buffers(pipe, 1, &vbuffer);
-
-   /* tell pipe about the vertex attributes */
-   memset(&velement, 0, sizeof(velement));
-   velement.src_offset = 0;
-   velement.instance_divisor = 0;
-   velement.vertex_buffer_index = 0;
-   velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
-   cso_set_vertex_elements(ctx->cso_context, 1, &velement);
-
-   /* draw */
-   util_draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, (uint) poly->num_verts);
 }
 
 void polygon_fill(struct polygon *poly, struct vg_context *ctx)
 {
-   struct pipe_depth_stencil_alpha_state dsa;
-   struct pipe_stencil_ref sr;
-   struct pipe_blend_state blend;
+   struct pipe_vertex_element velement;
+   struct pipe_vertex_buffer vbuffer;
    VGfloat bounds[4];
    VGfloat min_x, min_y, max_x, max_y;
+
    assert(poly);
    polygon_bounding_rect(poly, bounds);
    min_x = bounds[0];
@@ -322,113 +289,42 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx)
                 min_x, min_y, max_x, max_y);
 #endif
 
-   set_blend_for_fill(&blend);
-
-   memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
-   memset(&sr, 0, sizeof(struct pipe_stencil_ref));
-   /* only need a fixed 0. Rely on default or move it out at least? */
-   cso_set_stencil_ref(ctx->cso_context, &sr);
-
-   cso_save_blend(ctx->cso_context);
-   cso_save_depth_stencil_alpha(ctx->cso_context);
-
-   dsa.stencil[0].enabled = 1;
-   if (ctx->state.vg.fill_rule == VG_EVEN_ODD) {
-      dsa.stencil[0].writemask = 1;
-      dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-      dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-      dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
-      dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-      dsa.stencil[0].valuemask = ~0;
-
-      cso_set_blend(ctx->cso_context, &blend);
-      cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-      draw_polygon(ctx, poly);
-   } else if (ctx->state.vg.fill_rule == VG_NON_ZERO) {
-      struct pipe_screen *screen = ctx->pipe->screen;
-
-      if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
-         /* front */
-         dsa.stencil[0].writemask = ~0;
-         dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-         dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].valuemask = ~0;
-
-         /* back */
-         dsa.stencil[1].enabled = 1;
-         dsa.stencil[1].writemask = ~0;
-         dsa.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
-         dsa.stencil[1].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[1].valuemask = ~0;
-
-         cso_set_blend(ctx->cso_context, &blend);
-         cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-         draw_polygon(ctx, poly);
-      } else {
-         struct pipe_rasterizer_state raster;
-
-         memcpy(&raster, &ctx->state.g3d.rasterizer, sizeof(struct pipe_rasterizer_state));
-
-         cso_save_rasterizer(ctx->cso_context);
-         dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].valuemask = ~0;
-
-         raster.cull_face = PIPE_FACE_BACK;
-         dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-
-         cso_set_blend(ctx->cso_context, &blend);
-         cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-         cso_set_rasterizer(ctx->cso_context, &raster);
-         draw_polygon(ctx, poly);
-
-         raster.cull_face = PIPE_FACE_FRONT;
-         dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
-         cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-         cso_set_rasterizer(ctx->cso_context, &raster);
-         draw_polygon(ctx, poly);
-
-         cso_restore_rasterizer(ctx->cso_context);
-      }
-   }
+   polygon_prepare_buffer(ctx, poly);
+
+   /* tell renderer about the vertex attributes */
+   memset(&velement, 0, sizeof(velement));
+   velement.src_offset = 0;
+   velement.instance_divisor = 0;
+   velement.vertex_buffer_index = 0;
+   velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+   /* tell renderer about the vertex buffer */
+   memset(&vbuffer, 0, sizeof(vbuffer));
+   vbuffer.buffer = poly->vbuf;
+   vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
+   vbuffer.buffer_offset = 0;
+   vbuffer.max_index = poly->num_verts - 1;
+
+   renderer_polygon_stencil_begin(ctx->renderer,
+         &velement, ctx->state.vg.fill_rule, VG_FALSE);
+   renderer_polygon_stencil(ctx->renderer, &vbuffer,
+         PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
+   renderer_polygon_stencil_end(ctx->renderer);
 
-   /* restore color writes */
-   cso_restore_blend(ctx->cso_context);
-   /* setup stencil ops */
-   dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
-   dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].valuemask = dsa.stencil[0].writemask;
-   dsa.stencil[1].enabled = 0;
-   memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth,
-          sizeof(struct pipe_depth_state));
-   cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-
-   /* render the quad to propagate the rendering from stencil */
-   renderer_draw_quad(ctx->renderer, min_x, min_y,
-                      max_x, max_y, 0.0f/*depth should be disabled*/);
-
-   cso_restore_depth_stencil_alpha(ctx->cso_context);
+   renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
+   renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
+   renderer_polygon_fill_end(ctx->renderer);
 }
 
 void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
 {
    struct array *polys = polyarray->array;
-   struct pipe_depth_stencil_alpha_state dsa;
-   struct pipe_stencil_ref sr;
-   struct pipe_blend_state blend;
    VGfloat min_x = polyarray->min_x;
    VGfloat min_y = polyarray->min_y;
    VGfloat max_x = polyarray->max_x;
    VGfloat max_y = polyarray->max_y;
+   struct pipe_vertex_element velement;
+   struct pipe_vertex_buffer vbuffer;
    VGint i;
 
 
@@ -438,111 +334,35 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
                 min_x, min_y, max_x, max_y);
 #endif
 
-   set_blend_for_fill(&blend);
-
-   memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
-   memset(&sr, 0, sizeof(struct pipe_stencil_ref));
-   /* only need a fixed 0. Rely on default or move it out at least? */
-   cso_set_stencil_ref(ctx->cso_context, &sr);
-
-   cso_save_blend(ctx->cso_context);
-   cso_save_depth_stencil_alpha(ctx->cso_context);
-
-   dsa.stencil[0].enabled = 1;
-   if (ctx->state.vg.fill_rule == VG_EVEN_ODD) {
-      dsa.stencil[0].writemask = 1;
-      dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-      dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-      dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
-      dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-      dsa.stencil[0].valuemask = ~0;
-
-      cso_set_blend(ctx->cso_context, &blend);
-      cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-      for (i = 0; i < polys->num_elements; ++i) {
-         struct polygon *poly = (((struct polygon**)polys->data)[i]);
-         draw_polygon(ctx, poly);
-      }
-   } else if (ctx->state.vg.fill_rule == VG_NON_ZERO) {
-      struct pipe_screen *screen = ctx->pipe->screen;
-
-      if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
-         /* front */
-         dsa.stencil[0].writemask = ~0;
-         dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-         dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].valuemask = ~0;
-
-         /* back */
-         dsa.stencil[1].enabled = 1;
-         dsa.stencil[1].writemask = ~0;
-         dsa.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
-         dsa.stencil[1].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[1].valuemask = ~0;
-
-         cso_set_blend(ctx->cso_context, &blend);
-         cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-         for (i = 0; i < polys->num_elements; ++i) {
-            struct polygon *poly = (((struct polygon**)polys->data)[i]);
-            draw_polygon(ctx, poly);
-         }
-      } else {
-         struct pipe_rasterizer_state raster;
-
-         memcpy(&raster, &ctx->state.g3d.rasterizer, sizeof(struct pipe_rasterizer_state));
-
-         cso_save_rasterizer(ctx->cso_context);
-         dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].valuemask = ~0;
-
-         raster.cull_face = PIPE_FACE_BACK;
-         dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-
-         cso_set_blend(ctx->cso_context, &blend);
-         cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-         cso_set_rasterizer(ctx->cso_context, &raster);
-         for (i = 0; i < polys->num_elements; ++i) {
-            struct polygon *poly = (((struct polygon**)polys->data)[i]);
-            draw_polygon(ctx, poly);
-         }
-
-         raster.cull_face = PIPE_FACE_FRONT;
-         dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
-         dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
-         cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-         cso_set_rasterizer(ctx->cso_context, &raster);
-         for (i = 0; i < polys->num_elements; ++i) {
-            struct polygon *poly = (((struct polygon**)polys->data)[i]);
-            draw_polygon(ctx, poly);
-         }
-
-         cso_restore_rasterizer(ctx->cso_context);
-      }
+   /* tell renderer about the vertex attributes */
+   memset(&velement, 0, sizeof(velement));
+   velement.src_offset = 0;
+   velement.instance_divisor = 0;
+   velement.vertex_buffer_index = 0;
+   velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+   /* tell renderer about the vertex buffer */
+   memset(&vbuffer, 0, sizeof(vbuffer));
+   vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
+   vbuffer.buffer_offset = 0;
+
+   /* prepare the stencil buffer */
+   renderer_polygon_stencil_begin(ctx->renderer,
+         &velement, ctx->state.vg.fill_rule, VG_FALSE);
+   for (i = 0; i < polys->num_elements; ++i) {
+      struct polygon *poly = (((struct polygon**)polys->data)[i]);
+
+      polygon_prepare_buffer(ctx, poly);
+      vbuffer.buffer = poly->vbuf;
+      vbuffer.max_index = poly->num_verts - 1;
+
+      renderer_polygon_stencil(ctx->renderer, &vbuffer,
+            PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
    }
+   renderer_polygon_stencil_end(ctx->renderer);
 
-   /* restore color writes */
-   cso_restore_blend(ctx->cso_context);
-   /* setup stencil ops */
-   dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
-   dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].valuemask = dsa.stencil[0].writemask;
-   dsa.stencil[1].enabled = 0;
-   memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth,
-          sizeof(struct pipe_depth_state));
-   cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-
-   /* render the quad to propagate the rendering from stencil */
-   renderer_draw_quad(ctx->renderer, min_x, min_y,
-                      max_x, max_y, 0.0f/*depth should be disabled*/);
-
-   cso_restore_depth_stencil_alpha(ctx->cso_context);
+   /* fill it */
+   renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
+   renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
+   renderer_polygon_fill_end(ctx->renderer);
 }
index c6f5f7a05b8c5cf7275754a60ec2b2cfa5fa8cb5..7871c516c41081e6fa2be40e384f64803f4d90fe 100644 (file)
@@ -1,6 +1,7 @@
 /**************************************************************************
  *
  * Copyright 2009 VMware, Inc.  All Rights Reserved.
+ * 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
@@ -27,6 +28,7 @@
 #include "renderer.h"
 
 #include "vg_context.h"
+#include "image.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_simple_shaders.h"
 #include "util/u_memory.h"
 #include "util/u_sampler.h"
+#include "util/u_surface.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
 
 #include "cso_cache/cso_context.h"
+#include "tgsi/tgsi_ureg.h"
+
+typedef enum {
+   RENDERER_STATE_INIT,
+   RENDERER_STATE_COPY,
+   RENDERER_STATE_DRAWTEX,
+   RENDERER_STATE_SCISSOR,
+   RENDERER_STATE_CLEAR,
+   RENDERER_STATE_FILTER,
+   RENDERER_STATE_POLYGON_STENCIL,
+   RENDERER_STATE_POLYGON_FILL,
+   NUM_RENDERER_STATES
+} RendererState;
+
+typedef enum {
+   RENDERER_VS_PLAIN,
+   RENDERER_VS_COLOR,
+   RENDERER_VS_TEXTURE,
+   NUM_RENDERER_VS
+} RendererVs;
+
+typedef enum {
+   RENDERER_FS_COLOR,
+   RENDERER_FS_TEXTURE,
+   RENDERER_FS_SCISSOR,
+   RENDERER_FS_WHITE,
+   NUM_RENDERER_FS
+} RendererFs;
 
 struct renderer {
    struct pipe_context *pipe;
-   struct vg_context *owner;
-
    struct cso_context *cso;
 
-   void *fs;
+   VGbitfield dirty;
+   struct {
+      struct pipe_rasterizer_state rasterizer;
+      struct pipe_depth_stencil_alpha_state dsa;
+      struct pipe_framebuffer_state fb;
+   } g3d;
+   struct matrix projection;
+
+   struct matrix mvp;
+   struct pipe_resource *vs_cbuf;
+
+   struct pipe_resource *fs_cbuf;
+   VGfloat fs_cbuf_data[32];
+   VGint fs_cbuf_len;
 
+   struct pipe_vertex_element velems[2];
    VGfloat vertices[4][2][4];
+
+   void *cached_vs[NUM_RENDERER_VS];
+   void *cached_fs[NUM_RENDERER_FS];
+
+   RendererState state;
+
+   /* state data */
+   union {
+      struct {
+         VGint tex_width;
+         VGint tex_height;
+      } copy;
+
+      struct {
+         VGint tex_width;
+         VGint tex_height;
+      } drawtex;
+
+      struct {
+         VGboolean restore_dsa;
+      } scissor;
+
+      struct {
+         VGboolean use_sampler;
+         VGint tex_width, tex_height;
+      } filter;
+
+      struct {
+         struct pipe_depth_stencil_alpha_state dsa;
+         VGboolean manual_two_sides;
+         VGboolean restore_dsa;
+      } polygon_stencil;
+   } u;
 };
 
-static void setup_shaders(struct renderer *ctx)
+/**
+ * Return VG_TRUE if the renderer can use the resource as the asked bindings.
+ */
+static VGboolean renderer_can_support(struct renderer *renderer,
+                                      struct pipe_resource *res,
+                                      unsigned bindings)
 {
-   struct pipe_context *pipe = ctx->pipe;
-   /* fragment shader */
-   ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
-                                           TGSI_INTERPOLATE_LINEAR);
-}
-
-static struct pipe_resource *
-setup_vertex_data(struct renderer *ctx,
-                  float x0, float y0, float x1, float y1, float z)
-{
-   ctx->vertices[0][0][0] = x0;
-   ctx->vertices[0][0][1] = y0;
-   ctx->vertices[0][0][2] = z;
-   ctx->vertices[0][1][0] = 0.0f; /*s*/
-   ctx->vertices[0][1][1] = 0.0f; /*t*/
-
-   ctx->vertices[1][0][0] = x1;
-   ctx->vertices[1][0][1] = y0;
-   ctx->vertices[1][0][2] = z;
-   ctx->vertices[1][1][0] = 1.0f; /*s*/
-   ctx->vertices[1][1][1] = 0.0f; /*t*/
-
-   ctx->vertices[2][0][0] = x1;
-   ctx->vertices[2][0][1] = y1;
-   ctx->vertices[2][0][2] = z;
-   ctx->vertices[2][1][0] = 1.0f;
-   ctx->vertices[2][1][1] = 1.0f;
-
-   ctx->vertices[3][0][0] = x0;
-   ctx->vertices[3][0][1] = y1;
-   ctx->vertices[3][0][2] = z;
-   ctx->vertices[3][1][0] = 0.0f;
-   ctx->vertices[3][1][1] = 1.0f;
-
-   return pipe_user_buffer_create( ctx->pipe->screen,
-                                   ctx->vertices,
-                                   sizeof(ctx->vertices),
-                                  PIPE_BIND_VERTEX_BUFFER);
-}
-
-static struct pipe_resource *
-setup_vertex_data_tex(struct renderer *ctx,
-                      float x0, float y0, float x1, float y1,
-                      float s0, float t0, float s1, float t1,
-                      float z)
-{
-   ctx->vertices[0][0][0] = x0;
-   ctx->vertices[0][0][1] = y0;
-   ctx->vertices[0][0][2] = z;
-   ctx->vertices[0][1][0] = s0; /*s*/
-   ctx->vertices[0][1][1] = t0; /*t*/
-
-   ctx->vertices[1][0][0] = x1;
-   ctx->vertices[1][0][1] = y0;
-   ctx->vertices[1][0][2] = z;
-   ctx->vertices[1][1][0] = s1; /*s*/
-   ctx->vertices[1][1][1] = t0; /*t*/
-
-   ctx->vertices[2][0][0] = x1;
-   ctx->vertices[2][0][1] = y1;
-   ctx->vertices[2][0][2] = z;
-   ctx->vertices[2][1][0] = s1;
-   ctx->vertices[2][1][1] = t1;
-
-   ctx->vertices[3][0][0] = x0;
-   ctx->vertices[3][0][1] = y1;
-   ctx->vertices[3][0][2] = z;
-   ctx->vertices[3][1][0] = s0;
-   ctx->vertices[3][1][1] = t1;
-
-   return pipe_user_buffer_create( ctx->pipe->screen,
-                                   ctx->vertices,
-                                   sizeof(ctx->vertices),
-                                  PIPE_BIND_VERTEX_BUFFER);
-}
-
-
-static struct pipe_resource *
-setup_vertex_data_qtex(struct renderer *ctx,
-                       float x0, float y0, float x1, float y1,
-                       float x2, float y2, float x3, float y3,
-                       float s0, float t0, float s1, float t1,
-                       float z)
-{
-   ctx->vertices[0][0][0] = x0;
-   ctx->vertices[0][0][1] = y0;
-   ctx->vertices[0][0][2] = z;
-   ctx->vertices[0][1][0] = s0; /*s*/
-   ctx->vertices[0][1][1] = t0; /*t*/
-
-   ctx->vertices[1][0][0] = x1;
-   ctx->vertices[1][0][1] = y1;
-   ctx->vertices[1][0][2] = z;
-   ctx->vertices[1][1][0] = s1; /*s*/
-   ctx->vertices[1][1][1] = t0; /*t*/
-
-   ctx->vertices[2][0][0] = x2;
-   ctx->vertices[2][0][1] = y2;
-   ctx->vertices[2][0][2] = z;
-   ctx->vertices[2][1][0] = s1;
-   ctx->vertices[2][1][1] = t1;
-
-   ctx->vertices[3][0][0] = x3;
-   ctx->vertices[3][0][1] = y3;
-   ctx->vertices[3][0][2] = z;
-   ctx->vertices[3][1][0] = s0;
-   ctx->vertices[3][1][1] = t1;
-
-   return pipe_user_buffer_create( ctx->pipe->screen,
-                                   ctx->vertices,
-                                   sizeof(ctx->vertices),
-                                  PIPE_BIND_VERTEX_BUFFER);
+   struct pipe_screen *screen = renderer->pipe->screen;
+
+   return screen->is_format_supported(screen,
+         res->format, res->target, 0, bindings, 0);
 }
 
-struct renderer * renderer_create(struct vg_context *owner)
+/**
+ * Set the model-view-projection matrix used by vertex shaders.
+ */
+static void renderer_set_mvp(struct renderer *renderer,
+                             const struct matrix *mvp)
 {
+   struct matrix *cur = &renderer->mvp;
+   struct pipe_resource *cbuf;
+   VGfloat consts[3][4];
    VGint i;
-   struct renderer *renderer = CALLOC_STRUCT(renderer);
 
-   if (!renderer)
+   /* projection only */
+   if (!mvp)
+      mvp = &renderer->projection;
+
+   /* re-upload only if necessary */
+   if (memcmp(cur, mvp, sizeof(*mvp)) == 0)
+      return;
+
+   /* 3x3 matrix to 3 constant vectors (no Z) */
+   for (i = 0; i < 3; i++) {
+      consts[i][0] = mvp->m[i + 0];
+      consts[i][1] = mvp->m[i + 3];
+      consts[i][2] = 0.0f;
+      consts[i][3] = mvp->m[i + 6];
+   }
+
+   cbuf = renderer->vs_cbuf;
+   pipe_resource_reference(&cbuf, NULL);
+   cbuf = pipe_buffer_create(renderer->pipe->screen,
+                             PIPE_BIND_CONSTANT_BUFFER,
+                             sizeof(consts));
+   if (cbuf) {
+      pipe_buffer_write(renderer->pipe, cbuf,
+            0, sizeof(consts), consts);
+   }
+   renderer->pipe->set_constant_buffer(renderer->pipe,
+         PIPE_SHADER_VERTEX, 0, cbuf);
+
+   memcpy(cur, mvp, sizeof(*mvp));
+   renderer->vs_cbuf = cbuf;
+}
+
+/**
+ * Create a simple vertex shader that passes through position and the given
+ * attribute.
+ */
+static void *create_passthrough_vs(struct pipe_context *pipe, int semantic_name)
+{
+   struct ureg_program *ureg;
+   struct ureg_src src[2], constants[3];
+   struct ureg_dst dst[2], tmp;
+   int i;
+
+   ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
+   if (!ureg)
       return NULL;
 
-   renderer->owner = owner;
-   renderer->pipe = owner->pipe;
-   renderer->cso = owner->cso_context;
+   /* position is in user coordinates */
+   src[0] = ureg_DECL_vs_input(ureg, 0);
+   dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+   tmp = ureg_DECL_temporary(ureg);
+   for (i = 0; i < Elements(constants); i++)
+      constants[i] = ureg_DECL_constant(ureg, i);
+
+   /* transform to clipped coordinates */
+   ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), src[0], constants[0]);
+   ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), src[0], constants[1]);
+   ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), src[0]);
+   ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), src[0], constants[2]);
+   ureg_MOV(ureg, dst[0], ureg_src(tmp));
+
+   if (semantic_name >= 0) {
+      src[1] = ureg_DECL_vs_input(ureg, 1);
+      dst[1] = ureg_DECL_output(ureg, semantic_name, 0);
+      ureg_MOV(ureg, dst[1], src[1]);
+   }
 
-   setup_shaders(renderer);
+   ureg_END(ureg);
 
-   /* init vertex data that doesn't change */
-   for (i = 0; i < 4; i++) {
-      renderer->vertices[i][0][3] = 1.0f; /* w */
-      renderer->vertices[i][1][2] = 0.0f; /* r */
-      renderer->vertices[i][1][3] = 1.0f; /* q */
+   return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
+ * Set renderer vertex shader.
+ *
+ * This function modifies vertex_shader state.
+ */
+static void renderer_set_vs(struct renderer *r, RendererVs id)
+{
+   /* create as needed */
+   if (!r->cached_vs[id]) {
+      int semantic_name = -1;
+
+      switch (id) {
+      case RENDERER_VS_PLAIN:
+         break;
+      case RENDERER_VS_COLOR:
+         semantic_name = TGSI_SEMANTIC_COLOR;
+         break;
+      case RENDERER_VS_TEXTURE:
+         semantic_name = TGSI_SEMANTIC_GENERIC;
+         break;
+      default:
+         assert(!"Unknown renderer vs id");
+         break;
+      }
+
+      r->cached_vs[id] = create_passthrough_vs(r->pipe, semantic_name);
    }
 
-   return renderer;
+   cso_set_vertex_shader_handle(r->cso, r->cached_vs[id]);
 }
 
-void renderer_destroy(struct renderer *ctx)
+/**
+ * Create a simple fragment shader that sets the depth to 0.0f.
+ */
+static void *create_scissor_fs(struct pipe_context *pipe)
+{
+   struct ureg_program *ureg;
+   struct ureg_dst out;
+   struct ureg_src imm;
+
+   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+   imm = ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f);
+
+   ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_Z), imm);
+   ureg_END(ureg);
+
+   return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
+ * Create a simple fragment shader that sets the color to white.
+ */
+static void *create_white_fs(struct pipe_context *pipe)
+{
+   struct ureg_program *ureg;
+   struct ureg_dst out;
+   struct ureg_src imm;
+
+   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
+   imm = ureg_imm4f(ureg, 1.0f, 1.0f, 1.0f, 1.0f);
+
+   ureg_MOV(ureg, out, imm);
+   ureg_END(ureg);
+
+   return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
+ * Set renderer fragment shader.
+ *
+ * This function modifies fragment_shader state.
+ */
+static void renderer_set_fs(struct renderer *r, RendererFs id)
 {
-#if 0
-   if (ctx->fs) {
-      cso_delete_fragment_shader(ctx->cso, ctx->fs);
-      ctx->fs = NULL;
+   /* create as needed */
+   if (!r->cached_fs[id]) {
+      void *fs = NULL;
+
+      switch (id) {
+      case RENDERER_FS_COLOR:
+         fs = util_make_fragment_passthrough_shader(r->pipe);
+         break;
+      case RENDERER_FS_TEXTURE:
+         fs = util_make_fragment_tex_shader(r->pipe,
+               TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
+         break;
+      case RENDERER_FS_SCISSOR:
+         fs = create_scissor_fs(r->pipe);
+         break;
+      case RENDERER_FS_WHITE:
+         fs = create_white_fs(r->pipe);
+         break;
+      default:
+         assert(!"Unknown renderer fs id");
+         break;
+      }
+
+      r->cached_fs[id] = fs;
    }
-#endif
-   FREE(ctx);
+
+   cso_set_fragment_shader_handle(r->cso, r->cached_fs[id]);
 }
 
-void renderer_draw_quad(struct renderer *r,
-                        VGfloat x1, VGfloat y1,
-                        VGfloat x2, VGfloat y2,
-                        VGfloat depth)
+typedef enum {
+   VEGA_Y0_TOP,
+   VEGA_Y0_BOTTOM
+} VegaOrientation;
+
+static void vg_set_viewport(struct renderer *r,
+                            VegaOrientation orientation)
 {
-   struct pipe_resource *buf;
+   const struct pipe_framebuffer_state *fb = &r->g3d.fb;
+   struct pipe_viewport_state viewport;
+   VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f;
+
+   viewport.scale[0] =  fb->width / 2.f;
+   viewport.scale[1] =  fb->height / y_scale;
+   viewport.scale[2] =  1.0;
+   viewport.scale[3] =  1.0;
+   viewport.translate[0] = fb->width / 2.f;
+   viewport.translate[1] = fb->height / 2.f;
+   viewport.translate[2] = 0.0;
+   viewport.translate[3] = 0.0;
+
+   cso_set_viewport(r->cso, &viewport);
+}
+
+/**
+ * Set renderer target.
+ *
+ * This function modifies framebuffer and viewport states.
+ */
+static void renderer_set_target(struct renderer *r,
+                                struct pipe_surface *cbuf,
+                                struct pipe_surface *zsbuf,
+                                VGboolean y0_top)
+{
+   struct pipe_framebuffer_state fb;
+
+   memset(&fb, 0, sizeof(fb));
+   fb.width = cbuf->width;
+   fb.height = cbuf->height;
+   fb.cbufs[0] = cbuf;
+   fb.nr_cbufs = 1;
+   fb.zsbuf = zsbuf;
+   cso_set_framebuffer(r->cso, &fb);
+
+   vg_set_viewport(r, (y0_top) ? VEGA_Y0_TOP : VEGA_Y0_BOTTOM);
+}
+
+/**
+ * Set renderer blend state.  Blending is disabled.
+ *
+ * This function modifies blend state.
+ */
+static void renderer_set_blend(struct renderer *r,
+                               VGbitfield channel_mask)
+{
+   struct pipe_blend_state blend;
+
+   memset(&blend, 0, sizeof(blend));
+
+   blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+   blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+
+   if (channel_mask & VG_RED)
+      blend.rt[0].colormask |= PIPE_MASK_R;
+   if (channel_mask & VG_GREEN)
+      blend.rt[0].colormask |= PIPE_MASK_G;
+   if (channel_mask & VG_BLUE)
+      blend.rt[0].colormask |= PIPE_MASK_B;
+   if (channel_mask & VG_ALPHA)
+      blend.rt[0].colormask |= PIPE_MASK_A;
+
+   cso_set_blend(r->cso, &blend);
+}
+
+/**
+ * Set renderer sampler and view states.
+ *
+ * This function modifies samplers and fragment_sampler_views states.
+ */
+static void renderer_set_samplers(struct renderer *r,
+                                  uint num_views,
+                                  struct pipe_sampler_view **views)
+{
+   struct pipe_sampler_state sampler;
+   unsigned tex_filter = PIPE_TEX_FILTER_NEAREST;
+   unsigned tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   uint i;
+
+   memset(&sampler, 0, sizeof(sampler));
+
+   sampler.min_img_filter = tex_filter;
+   sampler.mag_img_filter = tex_filter;
+   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+
+   sampler.wrap_s = tex_wrap;
+   sampler.wrap_t = tex_wrap;
+   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+
+   sampler.normalized_coords = 1;
+
+   /* set samplers */
+   for (i = 0; i < num_views; i++)
+      cso_single_sampler(r->cso, i, &sampler);
+   cso_single_sampler_done(r->cso);
+
+   /* set views */
+   cso_set_fragment_sampler_views(r->cso, num_views, views);
+}
+
+/**
+ * Set custom renderer fragment shader, and optionally set samplers and views
+ * and upload the fragment constant buffer.
+ *
+ * This function modifies fragment_shader, samplers and fragment_sampler_views
+ * states.
+ */
+static void renderer_set_custom_fs(struct renderer *renderer,
+                                   void *fs,
+                                   const struct pipe_sampler_state **samplers,
+                                   struct pipe_sampler_view **views,
+                                   VGint num_samplers,
+                                   const void *const_buffer,
+                                   VGint const_buffer_len)
+{
+   cso_set_fragment_shader_handle(renderer->cso, fs);
+
+   /* set samplers and views */
+   if (num_samplers) {
+      cso_set_samplers(renderer->cso, num_samplers, samplers);
+      cso_set_fragment_sampler_views(renderer->cso, num_samplers, views);
+   }
+
+   /* upload fs constant buffer */
+   if (const_buffer_len) {
+      struct pipe_resource *cbuf = renderer->fs_cbuf;
+
+      if (!cbuf || renderer->fs_cbuf_len != const_buffer_len ||
+          memcmp(renderer->fs_cbuf_data, const_buffer, const_buffer_len)) {
+         pipe_resource_reference(&cbuf, NULL);
+
+         cbuf = pipe_buffer_create(renderer->pipe->screen,
+               PIPE_BIND_CONSTANT_BUFFER, const_buffer_len);
+         pipe_buffer_write(renderer->pipe, cbuf, 0,
+               const_buffer_len, const_buffer);
+         renderer->pipe->set_constant_buffer(renderer->pipe,
+               PIPE_SHADER_FRAGMENT, 0, cbuf);
+
+         renderer->fs_cbuf = cbuf;
+         if (const_buffer_len <= sizeof(renderer->fs_cbuf_data)) {
+            memcpy(renderer->fs_cbuf_data, const_buffer, const_buffer_len);
+            renderer->fs_cbuf_len = const_buffer_len;
+         }
+         else {
+            renderer->fs_cbuf_len = 0;
+         }
+      }
+   }
+}
+
+/**
+ * Setup renderer quad position.
+ */
+static void renderer_quad_pos(struct renderer *r,
+                              VGfloat x0, VGfloat y0,
+                              VGfloat x1, VGfloat y1,
+                              VGboolean scissor)
+{
+   VGfloat z;
+
+   /* the depth test is used for scissoring */
+   z = (scissor) ? 0.0f : 1.0f;
+
+   /* positions */
+   r->vertices[0][0][0] = x0;
+   r->vertices[0][0][1] = y0;
+   r->vertices[0][0][2] = z;
 
-   buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
+   r->vertices[1][0][0] = x1;
+   r->vertices[1][0][1] = y0;
+   r->vertices[1][0][2] = z;
 
+   r->vertices[2][0][0] = x1;
+   r->vertices[2][0][1] = y1;
+   r->vertices[2][0][2] = z;
+
+   r->vertices[3][0][0] = x0;
+   r->vertices[3][0][1] = y1;
+   r->vertices[3][0][2] = z;
+}
+
+/**
+ * Setup renderer quad texture coordinates.
+ */
+static void renderer_quad_texcoord(struct renderer *r,
+                                   VGfloat x0, VGfloat y0,
+                                   VGfloat x1, VGfloat y1,
+                                   VGint tex_width, VGint tex_height)
+{
+   VGfloat s0, t0, s1, t1, r0, q0;
+   VGint i;
+
+   s0 = x0 / tex_width;
+   s1 = x1 / tex_width;
+   t0 = y0 / tex_height;
+   t1 = y1 / tex_height;
+   r0 = 0.0f;
+   q0 = 1.0f;
+
+   /* texcoords */
+   r->vertices[0][1][0] = s0;
+   r->vertices[0][1][1] = t0;
+
+   r->vertices[1][1][0] = s1;
+   r->vertices[1][1][1] = t0;
+
+   r->vertices[2][1][0] = s1;
+   r->vertices[2][1][1] = t1;
+
+   r->vertices[3][1][0] = s0;
+   r->vertices[3][1][1] = t1;
+
+   for (i = 0; i < 4; i++) {
+      r->vertices[i][1][2] = r0;
+      r->vertices[i][1][3] = q0;
+   }
+}
+
+/**
+ * Draw renderer quad.
+ */
+static void renderer_quad_draw(struct renderer *r)
+{
+   struct pipe_resource *buf;
+
+   buf = pipe_user_buffer_create(r->pipe->screen,
+                                 r->vertices,
+                                 sizeof(r->vertices),
+                                 PIPE_BIND_VERTEX_BUFFER);
    if (buf) {
-      cso_set_vertex_elements(r->cso, 2, r->owner->velems);
       util_draw_vertex_buffer(r->pipe, buf, 0,
                               PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
+                              Elements(r->vertices),     /* verts */
+                              Elements(r->vertices[0])); /* attribs/vert */
 
-      pipe_resource_reference( &buf,
-                             NULL );
+      pipe_resource_reference(&buf, NULL);
    }
 }
 
-void renderer_draw_texture(struct renderer *r,
-                           struct pipe_resource *tex,
-                           VGfloat x1offset, VGfloat y1offset,
-                           VGfloat x2offset, VGfloat y2offset,
-                           VGfloat x1, VGfloat y1,
-                           VGfloat x2, VGfloat y2)
+/**
+ * Prepare the renderer for copying.
+ */
+VGboolean renderer_copy_begin(struct renderer *renderer,
+                              struct pipe_surface *dst,
+                              VGboolean y0_top,
+                              struct pipe_sampler_view *src)
 {
-   struct pipe_context *pipe = r->pipe;
-   struct pipe_resource *buf;
-   VGfloat s0, t0, s1, t1;
+   assert(renderer->state == RENDERER_STATE_INIT);
 
-   assert(tex->width0 != 0);
-   assert(tex->height0 != 0);
+   /* sanity check */
+   if (!renderer_can_support(renderer,
+            dst->texture, PIPE_BIND_RENDER_TARGET) ||
+       !renderer_can_support(renderer,
+          src->texture, PIPE_BIND_SAMPLER_VIEW))
+      return VG_FALSE;
 
-   s0 = x1offset / tex->width0;
-   s1 = x2offset / tex->width0;
-   t0 = y1offset / tex->height0;
-   t1 = y2offset / tex->height0;
+   cso_save_framebuffer(renderer->cso);
+   cso_save_viewport(renderer->cso);
+   cso_save_blend(renderer->cso);
+   cso_save_samplers(renderer->cso);
+   cso_save_fragment_sampler_views(renderer->cso);
+   cso_save_fragment_shader(renderer->cso);
+   cso_save_vertex_shader(renderer->cso);
 
-   cso_save_vertex_shader(r->cso);
-   /* shaders */
-   cso_set_vertex_shader_handle(r->cso, vg_texture_vs(r->owner));
+   renderer_set_target(renderer, dst, NULL, y0_top);
 
-   /* draw quad */
-   buf = setup_vertex_data_tex(r, x1, y1, x2, y2,
-                               s0, t0, s1, t1, 0.0f);
+   renderer_set_blend(renderer, ~0);
+   renderer_set_samplers(renderer, 1, &src);
 
-   if (buf) {
-      cso_set_vertex_elements(r->cso, 2, r->owner->velems);
-      util_draw_vertex_buffer(pipe, buf, 0,
-                           PIPE_PRIM_TRIANGLE_FAN,
-                           4,  /* verts */
-                           2); /* attribs/vert */
-
-      pipe_resource_reference( &buf,
-                             NULL );
+   renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
+   renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
+
+   renderer_set_mvp(renderer, NULL);
+
+   /* remember the texture size */
+   renderer->u.copy.tex_width = src->texture->width0;
+   renderer->u.copy.tex_height = src->texture->height0;
+   renderer->state = RENDERER_STATE_COPY;
+
+   return VG_TRUE;
+}
+
+/**
+ * Draw into the destination rectangle given by (x, y, w, h).  The texture is
+ * sampled from within the rectangle given by (sx, sy, sw, sh).
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_copy(struct renderer *renderer,
+                   VGint x, VGint y, VGint w, VGint h,
+                   VGint sx, VGint sy, VGint sw, VGint sh)
+{
+   assert(renderer->state == RENDERER_STATE_COPY);
+
+   /* there is no depth buffer for scissoring anyway */
+   renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
+   renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
+         renderer->u.copy.tex_width,
+         renderer->u.copy.tex_height);
+
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End copying and restore the states.
+ */
+void renderer_copy_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_COPY);
+
+   cso_restore_framebuffer(renderer->cso);
+   cso_restore_viewport(renderer->cso);
+   cso_restore_blend(renderer->cso);
+   cso_restore_samplers(renderer->cso);
+   cso_restore_fragment_sampler_views(renderer->cso);
+   cso_restore_fragment_shader(renderer->cso);
+   cso_restore_vertex_shader(renderer->cso);
+
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for textured drawing.
+ */
+VGboolean renderer_drawtex_begin(struct renderer *renderer,
+                                 struct pipe_sampler_view *src)
+{
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   if (!renderer_can_support(renderer, src->texture, PIPE_BIND_SAMPLER_VIEW))
+      return VG_FALSE;
+
+   cso_save_blend(renderer->cso);
+   cso_save_samplers(renderer->cso);
+   cso_save_fragment_sampler_views(renderer->cso);
+   cso_save_fragment_shader(renderer->cso);
+   cso_save_vertex_shader(renderer->cso);
+
+   renderer_set_blend(renderer, ~0);
+
+   renderer_set_samplers(renderer, 1, &src);
+
+   renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
+   renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
+
+   renderer_set_mvp(renderer, NULL);
+
+   /* remember the texture size */
+   renderer->u.drawtex.tex_width = src->texture->width0;
+   renderer->u.drawtex.tex_height = src->texture->height0;
+   renderer->state = RENDERER_STATE_DRAWTEX;
+
+   return VG_TRUE;
+}
+
+/**
+ * Draw into the destination rectangle given by (x, y, w, h).  The texture is
+ * sampled from within the rectangle given by (sx, sy, sw, sh).
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_drawtex(struct renderer *renderer,
+                      VGint x, VGint y, VGint w, VGint h,
+                      VGint sx, VGint sy, VGint sw, VGint sh)
+{
+   assert(renderer->state == RENDERER_STATE_DRAWTEX);
+
+   /* with scissoring */
+   renderer_quad_pos(renderer, x, y, x + w, y + h, VG_TRUE);
+   renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
+         renderer->u.drawtex.tex_width,
+         renderer->u.drawtex.tex_height);
+
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End textured drawing and restore the states.
+ */
+void renderer_drawtex_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_DRAWTEX);
+
+   cso_restore_blend(renderer->cso);
+   cso_restore_samplers(renderer->cso);
+   cso_restore_fragment_sampler_views(renderer->cso);
+   cso_restore_fragment_shader(renderer->cso);
+   cso_restore_vertex_shader(renderer->cso);
+
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for scissor update.  This will reset the depth buffer
+ * to 1.0f.
+ */
+VGboolean renderer_scissor_begin(struct renderer *renderer,
+                                 VGboolean restore_dsa)
+{
+   struct pipe_depth_stencil_alpha_state dsa;
+
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   if (restore_dsa)
+      cso_save_depth_stencil_alpha(renderer->cso);
+   cso_save_blend(renderer->cso);
+   cso_save_fragment_shader(renderer->cso);
+
+   /* enable depth writes */
+   memset(&dsa, 0, sizeof(dsa));
+   dsa.depth.enabled = 1;
+   dsa.depth.writemask = 1;
+   dsa.depth.func = PIPE_FUNC_ALWAYS;
+   cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+
+   /* disable color writes */
+   renderer_set_blend(renderer, 0);
+   renderer_set_fs(renderer, RENDERER_FS_SCISSOR);
+
+   renderer_set_mvp(renderer, NULL);
+
+   renderer->u.scissor.restore_dsa = restore_dsa;
+   renderer->state = RENDERER_STATE_SCISSOR;
+
+   /* clear the depth buffer to 1.0f */
+   renderer->pipe->clear(renderer->pipe,
+         PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0f, 0);
+
+   return VG_TRUE;
+}
+
+/**
+ * Add a scissor rectangle.  Depth values inside the rectangle will be set to
+ * 0.0f.
+ */
+void renderer_scissor(struct renderer *renderer,
+                      VGint x, VGint y, VGint width, VGint height)
+{
+   assert(renderer->state == RENDERER_STATE_SCISSOR);
+
+   renderer_quad_pos(renderer, x, y, x + width, y + height, VG_FALSE);
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End scissor update and restore the states.
+ */
+void renderer_scissor_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_SCISSOR);
+
+   if (renderer->u.scissor.restore_dsa)
+      cso_restore_depth_stencil_alpha(renderer->cso);
+   cso_restore_blend(renderer->cso);
+   cso_restore_fragment_shader(renderer->cso);
+
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for clearing.
+ */
+VGboolean renderer_clear_begin(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   cso_save_blend(renderer->cso);
+   cso_save_fragment_shader(renderer->cso);
+   cso_save_vertex_shader(renderer->cso);
+
+   renderer_set_blend(renderer, ~0);
+   renderer_set_fs(renderer, RENDERER_FS_COLOR);
+   renderer_set_vs(renderer, RENDERER_VS_COLOR);
+
+   renderer_set_mvp(renderer, NULL);
+
+   renderer->state = RENDERER_STATE_CLEAR;
+
+   return VG_TRUE;
+}
+
+/**
+ * Clear the framebuffer with the specified region and color.
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_clear(struct renderer *renderer,
+                    VGint x, VGint y, VGint width, VGint height,
+                    const VGfloat color[4])
+{
+   VGuint i;
+
+   assert(renderer->state == RENDERER_STATE_CLEAR);
+
+   renderer_quad_pos(renderer, x, y, x + width, y + height, VG_TRUE);
+   for (i = 0; i < 4; i++)
+      memcpy(renderer->vertices[i][1], color, sizeof(VGfloat) * 4);
+
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End clearing and retore the states.
+ */
+void renderer_clear_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_CLEAR);
+
+   cso_restore_blend(renderer->cso);
+   cso_restore_fragment_shader(renderer->cso);
+   cso_restore_vertex_shader(renderer->cso);
+
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for image filtering.
+ */
+VGboolean renderer_filter_begin(struct renderer *renderer,
+                                struct pipe_resource *dst,
+                                VGboolean y0_top,
+                                VGbitfield channel_mask,
+                                const struct pipe_sampler_state **samplers,
+                                struct pipe_sampler_view **views,
+                                VGint num_samplers,
+                                void *fs,
+                                const void *const_buffer,
+                                VGint const_buffer_len)
+{
+   struct pipe_surface *surf, surf_tmpl;
+
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   if (!fs)
+      return VG_FALSE;
+   if (!renderer_can_support(renderer, dst, PIPE_BIND_RENDER_TARGET))
+      return VG_FALSE;
+
+   u_surface_default_template(&surf_tmpl, dst,
+                              PIPE_BIND_RENDER_TARGET);
+   surf = renderer->pipe->create_surface(renderer->pipe, dst, &surf_tmpl);
+   if (!surf)
+      return VG_FALSE;
+
+   cso_save_framebuffer(renderer->cso);
+   cso_save_viewport(renderer->cso);
+   cso_save_blend(renderer->cso);
+
+   /* set the image as the target */
+   renderer_set_target(renderer, surf, NULL, y0_top);
+   pipe_surface_reference(&surf, NULL);
+
+   renderer_set_blend(renderer, channel_mask);
+
+   if (num_samplers) {
+      struct pipe_resource *tex;
+
+      cso_save_samplers(renderer->cso);
+      cso_save_fragment_sampler_views(renderer->cso);
+      cso_save_fragment_shader(renderer->cso);
+      cso_save_vertex_shader(renderer->cso);
+
+      renderer_set_custom_fs(renderer, fs,
+                             samplers, views, num_samplers,
+                             const_buffer, const_buffer_len);
+      renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
+
+      tex = views[0]->texture;
+      renderer->u.filter.tex_width = tex->width0;
+      renderer->u.filter.tex_height = tex->height0;
+      renderer->u.filter.use_sampler = VG_TRUE;
    }
+   else {
+      cso_save_fragment_shader(renderer->cso);
 
-   cso_restore_vertex_shader(r->cso);
+      renderer_set_custom_fs(renderer, fs, NULL, NULL, 0,
+                             const_buffer, const_buffer_len);
+
+      renderer->u.filter.use_sampler = VG_FALSE;
+   }
+
+   renderer_set_mvp(renderer, NULL);
+
+   renderer->state = RENDERER_STATE_FILTER;
+
+   return VG_TRUE;
 }
 
-void renderer_copy_texture(struct renderer *ctx,
-                           struct pipe_sampler_view *src,
-                           VGfloat sx1, VGfloat sy1,
-                           VGfloat sx2, VGfloat sy2,
-                           struct pipe_resource *dst,
-                           VGfloat dx1, VGfloat dy1,
-                           VGfloat dx2, VGfloat dy2)
+/**
+ * Draw into a rectangle of the destination with the specified region of the
+ * texture(s).
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_filter(struct renderer *renderer,
+                    VGint x, VGint y, VGint w, VGint h,
+                    VGint sx, VGint sy, VGint sw, VGint sh)
 {
-   struct pipe_context *pipe = ctx->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_resource *tex = src->texture;
-   struct pipe_resource *buf;
-   struct pipe_surface *dst_surf = screen->get_tex_surface(
-      screen, dst, 0, 0, 0,
-      PIPE_BIND_RENDER_TARGET);
-   struct pipe_framebuffer_state fb;
-   float s0, t0, s1, t1;
+   assert(renderer->state == RENDERER_STATE_FILTER);
 
-   assert(tex->width0 != 0);
-   assert(tex->height0 != 0);
-   assert(dst->width0 != 0);
-   assert(dst->height0 != 0);
-
-#if 0
-   debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n",
-                sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
-#endif
-
-#if 1
-   s0 = sx1 / tex->width0;
-   s1 = sx2 / tex->width0;
-   t0 = sy1 / tex->height0;
-   t1 = sy2 / tex->height0;
-#else
-   s0 = 0;
-   s1 = 1;
-   t0 = 0;
-   t1 = 1;
-#endif
-
-   assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D,
-                                      0, PIPE_BIND_RENDER_TARGET, 0));
+   renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
+   if (renderer->u.filter.use_sampler) {
+      renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
+            renderer->u.filter.tex_width,
+            renderer->u.filter.tex_height);
+   }
 
-   /* save state (restored below) */
-   cso_save_blend(ctx->cso);
-   cso_save_samplers(ctx->cso);
-   cso_save_fragment_sampler_views(ctx->cso);
-   cso_save_framebuffer(ctx->cso);
-   cso_save_fragment_shader(ctx->cso);
-   cso_save_vertex_shader(ctx->cso);
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End image filtering and restore the states.
+ */
+void renderer_filter_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_FILTER);
 
-   cso_save_viewport(ctx->cso);
+   if (renderer->u.filter.use_sampler) {
+      cso_restore_samplers(renderer->cso);
+      cso_restore_fragment_sampler_views(renderer->cso);
+      cso_restore_vertex_shader(renderer->cso);
+   }
 
+   cso_restore_framebuffer(renderer->cso);
+   cso_restore_viewport(renderer->cso);
+   cso_restore_blend(renderer->cso);
+   cso_restore_fragment_shader(renderer->cso);
 
-   /* set misc state we care about */
-   {
-      struct pipe_blend_state blend;
-      memset(&blend, 0, sizeof(blend));
-      blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].colormask = PIPE_MASK_RGBA;
-      cso_set_blend(ctx->cso, &blend);
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for polygon silhouette rendering.
+ */
+VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
+                                         struct pipe_vertex_element *velem,
+                                         VGFillRule rule,
+                                         VGboolean restore_dsa)
+{
+   struct pipe_depth_stencil_alpha_state *dsa;
+   VGboolean manual_two_sides;
+
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   cso_save_vertex_elements(renderer->cso);
+   cso_save_blend(renderer->cso);
+   cso_save_depth_stencil_alpha(renderer->cso);
+
+   cso_set_vertex_elements(renderer->cso, 1, velem);
+
+   /* disable color writes */
+   renderer_set_blend(renderer, 0);
+
+   manual_two_sides = VG_FALSE;
+   dsa = &renderer->u.polygon_stencil.dsa;
+   memset(dsa, 0, sizeof(*dsa));
+   if (rule == VG_EVEN_ODD) {
+      dsa->stencil[0].enabled = 1;
+      dsa->stencil[0].writemask = 1;
+      dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
+      dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+      dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
+      dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
+      dsa->stencil[0].valuemask = ~0;
    }
+   else {
+      assert(rule == VG_NON_ZERO);
+
+      /* front face */
+      dsa->stencil[0].enabled = 1;
+      dsa->stencil[0].writemask = ~0;
+      dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
+      dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+      dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
+      dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
+      dsa->stencil[0].valuemask = ~0;
+
+      if (renderer->pipe->screen->get_param(renderer->pipe->screen,
+                                            PIPE_CAP_TWO_SIDED_STENCIL)) {
+         /* back face */
+         dsa->stencil[1] = dsa->stencil[0];
+         dsa->stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
+      }
+      else {
+         manual_two_sides = VG_TRUE;
+      }
+   }
+   cso_set_depth_stencil_alpha(renderer->cso, dsa);
+
+   if (manual_two_sides)
+      cso_save_rasterizer(renderer->cso);
 
-   /* sampler */
-   {
-      struct pipe_sampler_state sampler;
-      memset(&sampler, 0, sizeof(sampler));
-      sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
-      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
-      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
-      sampler.normalized_coords = 1;
-      cso_single_sampler(ctx->cso, 0, &sampler);
-      cso_single_sampler_done(ctx->cso);
+   renderer->u.polygon_stencil.manual_two_sides = manual_two_sides;
+   renderer->u.polygon_stencil.restore_dsa = restore_dsa;
+   renderer->state = RENDERER_STATE_POLYGON_STENCIL;
+
+   return VG_TRUE;
+}
+
+/**
+ * Render a polygon silhouette to stencil buffer.
+ */
+void renderer_polygon_stencil(struct renderer *renderer,
+                              struct pipe_vertex_buffer *vbuf,
+                              VGuint mode, VGuint start, VGuint count)
+{
+   assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
+
+   renderer->pipe->set_vertex_buffers(renderer->pipe, 1, vbuf);
+
+   if (!renderer->u.polygon_stencil.manual_two_sides) {
+      util_draw_arrays(renderer->pipe, mode, start, count);
    }
+   else {
+      struct pipe_rasterizer_state raster;
+      struct pipe_depth_stencil_alpha_state dsa;
 
-   vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
+      raster = renderer->g3d.rasterizer;
+      dsa = renderer->u.polygon_stencil.dsa;
 
-   /* texture */
-   cso_set_fragment_sampler_views(ctx->cso, 1, &src);
+      /* front */
+      raster.cull_face = PIPE_FACE_BACK;
+      dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
 
-   /* shaders */
-   cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+      cso_set_rasterizer(renderer->cso, &raster);
+      cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+      util_draw_arrays(renderer->pipe, mode, start, count);
 
-   /* drawing dest */
-   memset(&fb, 0, sizeof(fb));
-   fb.width = dst_surf->width;
-   fb.height = dst_surf->height;
-   fb.nr_cbufs = 1;
-   fb.cbufs[0] = dst_surf;
-   {
-      VGint i;
-      for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
-         fb.cbufs[i] = 0;
+      /* back */
+      raster.cull_face = PIPE_FACE_FRONT;
+      dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
+
+      cso_set_rasterizer(renderer->cso, &raster);
+      cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+      util_draw_arrays(renderer->pipe, mode, start, count);
    }
-   cso_set_framebuffer(ctx->cso, &fb);
+}
+
+/**
+ * End polygon silhouette rendering.
+ */
+void renderer_polygon_stencil_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
 
-   /* draw quad */
-   buf = setup_vertex_data_tex(ctx,
-                         dx1, dy1,
-                         dx2, dy2,
-                         s0, t0, s1, t1,
-                         0.0f);
+   if (renderer->u.polygon_stencil.manual_two_sides)
+      cso_restore_rasterizer(renderer->cso);
 
-   if (buf) {
-      cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
-      util_draw_vertex_buffer(ctx->pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
+   cso_restore_vertex_elements(renderer->cso);
+
+   /* restore color writes */
+   cso_restore_blend(renderer->cso);
+
+   if (renderer->u.polygon_stencil.restore_dsa)
+      cso_restore_depth_stencil_alpha(renderer->cso);
+
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for polygon filling.
+ */
+VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
+                                      VGboolean save_dsa)
+{
+   struct pipe_depth_stencil_alpha_state dsa;
+
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   if (save_dsa)
+      cso_save_depth_stencil_alpha(renderer->cso);
+
+   /* setup stencil ops */
+   memset(&dsa, 0, sizeof(dsa));
+   dsa.stencil[0].enabled = 1;
+   dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
+   dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].valuemask = ~0;
+   dsa.stencil[0].writemask = ~0;
+   dsa.depth = renderer->g3d.dsa.depth;
+   cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+
+   renderer->state = RENDERER_STATE_POLYGON_FILL;
+
+   return VG_TRUE;
+}
+
+/**
+ * Fill a polygon.
+ */
+void renderer_polygon_fill(struct renderer *renderer,
+                           VGfloat min_x, VGfloat min_y,
+                           VGfloat max_x, VGfloat max_y)
+{
+   assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
+
+   renderer_quad_pos(renderer, min_x, min_y, max_x, max_y, VG_TRUE);
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End polygon filling.
+ */
+void renderer_polygon_fill_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
+
+   cso_restore_depth_stencil_alpha(renderer->cso);
 
-      pipe_resource_reference( &buf,
-                             NULL );
+   renderer->state = RENDERER_STATE_INIT;
+}
+
+struct renderer * renderer_create(struct vg_context *owner)
+{
+   struct renderer *renderer;
+   struct pipe_rasterizer_state *raster;
+   struct pipe_stencil_ref sr;
+   VGint i;
+
+   renderer = CALLOC_STRUCT(renderer);
+   if (!renderer)
+      return NULL;
+
+   renderer->pipe = owner->pipe;
+   renderer->cso = owner->cso_context;
+
+   /* init vertex data that doesn't change */
+   for (i = 0; i < 4; i++)
+      renderer->vertices[i][0][3] = 1.0f; /* w */
+
+   for (i = 0; i < 2; i++) {
+      renderer->velems[i].src_offset = i * 4 * sizeof(float);
+      renderer->velems[i].instance_divisor = 0;
+      renderer->velems[i].vertex_buffer_index = 0;
+      renderer->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   }
+   cso_set_vertex_elements(renderer->cso, 2, renderer->velems);
+
+   /* GL rasterization rules */
+   raster = &renderer->g3d.rasterizer;
+   memset(raster, 0, sizeof(*raster));
+   raster->gl_rasterization_rules = 1;
+   cso_set_rasterizer(renderer->cso, raster);
+
+   /* fixed at 0 */
+   memset(&sr, 0, sizeof(sr));
+   cso_set_stencil_ref(renderer->cso, &sr);
+
+   renderer_set_vs(renderer, RENDERER_VS_PLAIN);
+
+   renderer->state = RENDERER_STATE_INIT;
+
+   return renderer;
+}
+
+void renderer_destroy(struct renderer *ctx)
+{
+   int i;
+
+   for (i = 0; i < NUM_RENDERER_VS; i++) {
+      if (ctx->cached_vs[i])
+         cso_delete_vertex_shader(ctx->cso, ctx->cached_vs[i]);
+   }
+   for (i = 0; i < NUM_RENDERER_FS; i++) {
+      if (ctx->cached_fs[i])
+         cso_delete_fragment_shader(ctx->cso, ctx->cached_fs[i]);
+   }
+
+   pipe_resource_reference(&ctx->vs_cbuf, NULL);
+   pipe_resource_reference(&ctx->fs_cbuf, NULL);
+
+   FREE(ctx);
+}
+
+static void update_clip_state(struct renderer *renderer,
+                              const struct vg_state *state)
+{
+   struct pipe_depth_stencil_alpha_state *dsa = &renderer->g3d.dsa;
+
+   memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
+
+   if (state->scissoring) {
+      struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
+      int i;
+
+      renderer_scissor_begin(renderer, VG_FALSE);
+
+      for (i = 0; i < state->scissor_rects_num; ++i) {
+         const float x      = state->scissor_rects[i * 4 + 0].f;
+         const float y      = state->scissor_rects[i * 4 + 1].f;
+         const float width  = state->scissor_rects[i * 4 + 2].f;
+         const float height = state->scissor_rects[i * 4 + 3].f;
+         VGint x0, y0, x1, y1, iw, ih;
+
+         x0 = (VGint) x;
+         y0 = (VGint) y;
+         if (x0 < 0)
+            x0 = 0;
+         if (y0 < 0)
+            y0 = 0;
+
+         /* note that x1 and y1 are exclusive */
+         x1 = (VGint) ceilf(x + width);
+         y1 = (VGint) ceilf(y + height);
+         if (x1 > fb->width)
+            x1 = fb->width;
+         if (y1 > fb->height)
+            y1 = fb->height;
+
+         iw = x1 - x0;
+         ih = y1 - y0;
+         if (iw > 0 && ih> 0 )
+            renderer_scissor(renderer, x0, y0, iw, ih);
+      }
+
+      renderer_scissor_end(renderer);
+
+      dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
+      dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
+      dsa->depth.func = PIPE_FUNC_GEQUAL;
    }
+}
+
+static void renderer_validate_blend(struct renderer *renderer,
+                                     const struct vg_state *state,
+                                     enum pipe_format fb_format)
+{
+   struct pipe_blend_state blend;
+
+   memset(&blend, 0, sizeof(blend));
+   blend.rt[0].colormask = PIPE_MASK_RGBA;
+   blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
+   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+   blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
+   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
 
-   /* restore state we changed */
-   cso_restore_blend(ctx->cso);
-   cso_restore_samplers(ctx->cso);
-   cso_restore_fragment_sampler_views(ctx->cso);
-   cso_restore_framebuffer(ctx->cso);
-   cso_restore_vertex_shader(ctx->cso);
-   cso_restore_fragment_shader(ctx->cso);
-   cso_restore_viewport(ctx->cso);
+   /* TODO alpha masking happens after blending? */
+
+   switch (state->blend_mode) {
+   case VG_BLEND_SRC:
+      blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
+      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+      blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
+      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+      break;
+   case VG_BLEND_SRC_OVER:
+      if (!util_format_has_alpha(fb_format)) {
+         blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
+         blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+         blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+         blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+         blend.rt[0].blend_enable = 1;
+      }
+      break;
+   case VG_BLEND_SRC_IN:
+      blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
+      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+      blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
+      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+      blend.rt[0].blend_enable = 1;
+      break;
+   case VG_BLEND_DST_IN:
+      blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ZERO;
+      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+      blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ONE;
+      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+      blend.rt[0].blend_enable = 1;
+      break;
+   case VG_BLEND_DST_OVER:
+   case VG_BLEND_MULTIPLY:
+   case VG_BLEND_SCREEN:
+   case VG_BLEND_DARKEN:
+   case VG_BLEND_LIGHTEN:
+   case VG_BLEND_ADDITIVE:
+      /* need a shader */
+      break;
+   default:
+      assert(!"not implemented blend mode");
+      break;
+   }
 
-   pipe_surface_reference(&dst_surf, NULL);
+   cso_set_blend(renderer->cso, &blend);
+}
+
+/**
+ * Propogate OpenVG state changes to the renderer.  Only framebuffer, blending
+ * and scissoring states are relevant here.
+ */
+void renderer_validate(struct renderer *renderer,
+                       VGbitfield dirty,
+                       const struct st_framebuffer *stfb,
+                       const struct vg_state *state)
+{
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   dirty |= renderer->dirty;
+   renderer->dirty = 0;
+
+   if (dirty & FRAMEBUFFER_DIRTY) {
+      struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
+      struct matrix *proj = &renderer->projection;
+
+      memset(fb, 0, sizeof(struct pipe_framebuffer_state));
+      fb->width  = stfb->width;
+      fb->height = stfb->height;
+      fb->nr_cbufs = 1;
+      fb->cbufs[0] = stfb->strb->surface;
+      fb->zsbuf = stfb->dsrb->surface;
+
+      cso_set_framebuffer(renderer->cso, fb);
+      vg_set_viewport(renderer, VEGA_Y0_BOTTOM);
+
+      matrix_load_identity(proj);
+      matrix_translate(proj, -1.0f, -1.0f);
+      matrix_scale(proj, 2.0f / fb->width, 2.0f / fb->height);
+
+      /* we also got a new depth buffer */
+      if (dirty & DEPTH_STENCIL_DIRTY) {
+         renderer->pipe->clear(renderer->pipe,
+               PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
+      }
+   }
+
+   /* must be last because it renders to the depth buffer*/
+   if (dirty & DEPTH_STENCIL_DIRTY) {
+      update_clip_state(renderer, state);
+      cso_set_depth_stencil_alpha(renderer->cso, &renderer->g3d.dsa);
+   }
+
+   if (dirty & BLEND_DIRTY)
+      renderer_validate_blend(renderer, state, stfb->strb->format);
+}
+
+/**
+ * Prepare the renderer for OpenVG pipeline.
+ */
+void renderer_validate_for_shader(struct renderer *renderer,
+                                  const struct pipe_sampler_state **samplers,
+                                  struct pipe_sampler_view **views,
+                                  VGint num_samplers,
+                                  const struct matrix *modelview,
+                                  void *fs,
+                                  const void *const_buffer,
+                                  VGint const_buffer_len)
+{
+   struct matrix mvp = renderer->projection;
+
+   /* will be used in POLYGON_STENCIL and POLYGON_FILL */
+   matrix_mult(&mvp, modelview);
+   renderer_set_mvp(renderer, &mvp);
+
+   renderer_set_custom_fs(renderer, fs,
+                          samplers, views, num_samplers,
+                          const_buffer, const_buffer_len);
+}
+
+void renderer_validate_for_mask_rendering(struct renderer *renderer,
+                                          struct pipe_surface *dst,
+                                          const struct matrix *modelview)
+{
+   struct matrix mvp = renderer->projection;
+
+   /* will be used in POLYGON_STENCIL and POLYGON_FILL */
+   matrix_mult(&mvp, modelview);
+   renderer_set_mvp(renderer, &mvp);
+
+   renderer_set_target(renderer, dst, renderer->g3d.fb.zsbuf, VG_FALSE);
+   renderer_set_blend(renderer, ~0);
+   renderer_set_fs(renderer, RENDERER_FS_WHITE);
+
+   /* set internal dirty flags (hacky!) */
+   renderer->dirty = FRAMEBUFFER_DIRTY | BLEND_DIRTY;
 }
 
 void renderer_copy_surface(struct renderer *ctx,
@@ -409,13 +1429,11 @@ void renderer_copy_surface(struct renderer *ctx,
 {
    struct pipe_context *pipe = ctx->pipe;
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_resource *buf;
    struct pipe_sampler_view view_templ;
    struct pipe_sampler_view *view;
+   struct pipe_box src_box;
    struct pipe_resource texTemp, *tex;
-   struct pipe_subresource subsrc, subdst;
-   struct pipe_framebuffer_state fb;
-   struct st_framebuffer *stfb = ctx->owner->draw_buffer;
+   const struct pipe_framebuffer_state *fb = &ctx->g3d.fb;
    const int srcW = abs(srcX1 - srcX0);
    const int srcH = abs(srcY1 - srcY0);
    const int srcLeft = MIN2(srcX0, srcX1);
@@ -458,6 +1476,7 @@ void renderer_copy_surface(struct renderer *ctx,
    texTemp.width0 = srcW;
    texTemp.height0 = srcH;
    texTemp.depth0 = 1;
+   texTemp.array_size = 1;
    texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
 
    tex = screen->resource_create(screen, &texTemp);
@@ -470,100 +1489,35 @@ void renderer_copy_surface(struct renderer *ctx,
    if (!view)
       return;
 
-   subdst.face = 0;
-   subdst.level = 0;
-   subsrc.face = src->face;
-   subsrc.level = src->level;
+   u_box_2d_zslice(srcLeft, srcTop, src->u.tex.first_layer, srcW, srcH, &src_box);
 
    pipe->resource_copy_region(pipe,
-                              tex, subdst, 0, 0, 0,  /* dest */
-                              src->texture, subsrc, srcLeft, srcTop, src->zslice, /* src */
-                              srcW, srcH);     /* size */
-
-   /* save state (restored below) */
-   cso_save_blend(ctx->cso);
-   cso_save_samplers(ctx->cso);
-   cso_save_fragment_sampler_views(ctx->cso);
-   cso_save_framebuffer(ctx->cso);
-   cso_save_fragment_shader(ctx->cso);
-   cso_save_vertex_shader(ctx->cso);
-   cso_save_viewport(ctx->cso);
-
-   /* set misc state we care about */
-   {
-      struct pipe_blend_state blend;
-      memset(&blend, 0, sizeof(blend));
-      blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].colormask = PIPE_MASK_RGBA;
-      cso_set_blend(ctx->cso, &blend);
+                              tex, 0, 0, 0, 0,  /* dest */
+                              src->texture, 0, &src_box);
+
+   assert(floatsEqual(z, 0.0f));
+
+   /* draw */
+   if (fb->cbufs[0] == dst) {
+      /* transform back to surface coordinates */
+      dstY0 = dst->height - dstY0;
+      dstY1 = dst->height - dstY1;
+
+      if (renderer_drawtex_begin(ctx, view)) {
+         renderer_drawtex(ctx,
+               dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
+               0, 0, view->texture->width0, view->texture->height0);
+         renderer_drawtex_end(ctx);
+      }
    }
-
-   vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
-
-   /* sampler */
-   {
-      struct pipe_sampler_state sampler;
-      memset(&sampler, 0, sizeof(sampler));
-      sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
-      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
-      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
-      sampler.normalized_coords = 1;
-      cso_single_sampler(ctx->cso, 0, &sampler);
-      cso_single_sampler_done(ctx->cso);
-   }
-
-   /* texture */
-   cso_set_fragment_sampler_views(ctx->cso, 1, &view);
-
-   /* shaders */
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
-   cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
-
-   /* drawing dest */
-   if (stfb->strb->surface != dst) {
-      memset(&fb, 0, sizeof(fb));
-      fb.width = dst->width;
-      fb.height = dst->height;
-      fb.nr_cbufs = 1;
-      fb.cbufs[0] = dst;
-      fb.zsbuf = stfb->dsrb->surface;
-      cso_set_framebuffer(ctx->cso, &fb);
+   else {
+      if (renderer_copy_begin(ctx, dst, VG_TRUE, view)) {
+         renderer_copy(ctx,
+               dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
+               0, 0, view->texture->width0, view->texture->height0);
+         renderer_copy_end(ctx);
+      }
    }
-
-   /* draw quad */
-   buf = setup_vertex_data(ctx,
-                           (float) dstX0, (float) dstY0,
-                           (float) dstX1, (float) dstY1, z);
-
-   if (buf) {
-      cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
-      util_draw_vertex_buffer(ctx->pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
-
-      pipe_resource_reference( &buf,
-                             NULL );
-   }
-
-
-   /* restore state we changed */
-   cso_restore_blend(ctx->cso);
-   cso_restore_samplers(ctx->cso);
-   cso_restore_fragment_sampler_views(ctx->cso);
-   cso_restore_framebuffer(ctx->cso);
-   cso_restore_fragment_shader(ctx->cso);
-   cso_restore_vertex_shader(ctx->cso);
-   cso_restore_viewport(ctx->cso);
-
-   pipe_resource_reference(&tex, NULL);
-   pipe_sampler_view_reference(&view, NULL);
 }
 
 void renderer_texture_quad(struct renderer *r,
@@ -575,36 +1529,38 @@ void renderer_texture_quad(struct renderer *r,
                            VGfloat x3, VGfloat y3,
                            VGfloat x4, VGfloat y4)
 {
-   struct pipe_context *pipe = r->pipe;
-   struct pipe_resource *buf;
-   VGfloat s0, t0, s1, t1;
+   const VGfloat z = 0.0f;
 
+   assert(r->state == RENDERER_STATE_INIT);
    assert(tex->width0 != 0);
    assert(tex->height0 != 0);
 
-   s0 = x1offset / tex->width0;
-   s1 = x2offset / tex->width0;
-   t0 = y1offset / tex->height0;
-   t1 = y2offset / tex->height0;
-
    cso_save_vertex_shader(r->cso);
-   /* shaders */
-   cso_set_vertex_shader_handle(r->cso, vg_texture_vs(r->owner));
 
-   /* draw quad */
-   buf = setup_vertex_data_qtex(r, x1, y1, x2, y2, x3, y3, x4, y4,
-                          s0, t0, s1, t1, 0.0f);
+   renderer_set_vs(r, RENDERER_VS_TEXTURE);
 
-   if (buf) {
-      cso_set_vertex_elements(r->cso, 2, r->owner->velems);
-      util_draw_vertex_buffer(pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
+   /* manually set up positions */
+   r->vertices[0][0][0] = x1;
+   r->vertices[0][0][1] = y1;
+   r->vertices[0][0][2] = z;
 
-      pipe_resource_reference(&buf,
-                            NULL);
-   }
+   r->vertices[1][0][0] = x2;
+   r->vertices[1][0][1] = y2;
+   r->vertices[1][0][2] = z;
+
+   r->vertices[2][0][0] = x3;
+   r->vertices[2][0][1] = y3;
+   r->vertices[2][0][2] = z;
+
+   r->vertices[3][0][0] = x4;
+   r->vertices[3][0][1] = y4;
+   r->vertices[3][0][2] = z;
+
+   /* texcoords */
+   renderer_quad_texcoord(r, x1offset, y1offset,
+         x2offset, y2offset, tex->width0, tex->height0);
+
+   renderer_quad_draw(r);
 
    cso_restore_vertex_shader(r->cso);
 }
index b1a9fb58be6564f39842c90f6de9cb18540883ac..fe7199365804f9a3e04477f6f9dee3064f46a34c 100644 (file)
@@ -1,6 +1,7 @@
 /**************************************************************************
  *
  * Copyright 2009 VMware, Inc.  All Rights Reserved.
+ * 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
 struct renderer;
 
 struct vg_context;
+struct vg_state;
+struct st_framebuffer;
 struct pipe_resource;
+struct pipe_sampler_state;
 struct pipe_sampler_view;
 struct pipe_surface;
+struct pipe_vertex_element;
+struct pipe_vertex_buffer;
+struct matrix;
 
 struct renderer *renderer_create(struct vg_context *owner);
 void renderer_destroy(struct renderer *);
 
-void renderer_draw_quad(struct renderer *,
-                        VGfloat x1, VGfloat y1,
-                        VGfloat x2, VGfloat y2,
-                        VGfloat depth);
-void renderer_draw_texture(struct renderer *,
-                           struct pipe_resource *texture,
-                           VGfloat x1offset, VGfloat y1offset,
-                           VGfloat x2offset, VGfloat y2offset,
-                           VGfloat x1, VGfloat y1,
-                           VGfloat x2, VGfloat y2);
+void renderer_validate(struct renderer *renderer,
+                       VGbitfield dirty,
+                       const struct st_framebuffer *stfb,
+                       const struct vg_state *state);
+
+void renderer_validate_for_shader(struct renderer *renderer,
+                                  const struct pipe_sampler_state **samplers,
+                                  struct pipe_sampler_view **views,
+                                  VGint num_samplers,
+                                  const struct matrix *modelview,
+                                  void *fs,
+                                  const void *const_buffer,
+                                  VGint const_buffer_len);
+
+void renderer_validate_for_mask_rendering(struct renderer *renderer,
+                                          struct pipe_surface *dst,
+                                          const struct matrix *modelview);
+
+VGboolean renderer_copy_begin(struct renderer *renderer,
+                              struct pipe_surface *dst,
+                              VGboolean y0_top,
+                              struct pipe_sampler_view *src);
+
+void renderer_copy(struct renderer *renderer,
+                   VGint x, VGint y, VGint w, VGint h,
+                   VGint sx, VGint sy, VGint sw, VGint sh);
+
+void renderer_copy_end(struct renderer *renderer);
+
+VGboolean renderer_drawtex_begin(struct renderer *renderer,
+                                 struct pipe_sampler_view *src);
+
+void renderer_drawtex(struct renderer *renderer,
+                      VGint x, VGint y, VGint w, VGint h,
+                      VGint sx, VGint sy, VGint sw, VGint sh);
+
+void renderer_drawtex_end(struct renderer *renderer);
+
+VGboolean renderer_scissor_begin(struct renderer *renderer,
+                                 VGboolean restore_dsa);
+
+void renderer_scissor(struct renderer *renderer,
+                      VGint x, VGint y, VGint width, VGint height);
+
+void renderer_scissor_end(struct renderer *renderer);
+
+VGboolean renderer_clear_begin(struct renderer *renderer);
+
+void renderer_clear(struct renderer *renderer,
+                    VGint x, VGint y, VGint width, VGint height,
+                    const VGfloat color[4]);
+
+void renderer_clear_end(struct renderer *renderer);
+
+VGboolean renderer_filter_begin(struct renderer *renderer,
+                                struct pipe_resource *dst,
+                                VGboolean y0_top,
+                                VGbitfield channel_mask,
+                                const struct pipe_sampler_state **samplers,
+                                struct pipe_sampler_view **views,
+                                VGint num_samplers,
+                                void *fs,
+                                const void *const_buffer,
+                                VGint const_buffer_len);
+
+void renderer_filter(struct renderer *renderer,
+                     VGint x, VGint y, VGint w, VGint h,
+                     VGint sx, VGint sy, VGint sw, VGint sh);
+
+void renderer_filter_end(struct renderer *renderer);
+
+VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
+                                         struct pipe_vertex_element *velem,
+                                         VGFillRule rule,
+                                         VGboolean restore_dsa);
+
+void renderer_polygon_stencil(struct renderer *renderer,
+                              struct pipe_vertex_buffer *vbuf,
+                              VGuint mode, VGuint start, VGuint count);
+
+void renderer_polygon_stencil_end(struct renderer *renderer);
+
+VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
+                                      VGboolean save_dsa);
+
+void renderer_polygon_fill(struct renderer *renderer,
+                           VGfloat min_x, VGfloat min_y,
+                           VGfloat max_x, VGfloat max_y);
+
+void renderer_polygon_fill_end(struct renderer *renderer);
+
 void renderer_texture_quad(struct renderer *,
                            struct pipe_resource *texture,
                            VGfloat x1offset, VGfloat y1offset,
@@ -57,13 +145,7 @@ void renderer_texture_quad(struct renderer *,
                            VGfloat x2, VGfloat y2,
                            VGfloat x3, VGfloat y3,
                            VGfloat x4, VGfloat y4);
-void renderer_copy_texture(struct renderer *r,
-                           struct pipe_sampler_view *src,
-                           VGfloat sx1, VGfloat sy1,
-                           VGfloat sx2, VGfloat sy2,
-                           struct pipe_resource *dst,
-                           VGfloat dx1, VGfloat dy1,
-                           VGfloat dx2, VGfloat dy2);
+
 void renderer_copy_surface(struct renderer *r,
                            struct pipe_surface *src,
                            int sx1, int sy1,
index eab1349639c2881f41c651864ffd5b81c2b0736e..0ed721376cfd5ed097cfd16d62a772a0f6b2dfd1 100644 (file)
 #include "paint.h"
 #include "mask.h"
 #include "image.h"
+#include "renderer.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
 
-#define MAX_CONSTANTS 20
+#define MAX_CONSTANTS 28
 
 struct shader {
    struct vg_context *context;
 
+   VGboolean color_transform;
    VGboolean masking;
    struct vg_paint *paint;
    struct vg_image *image;
 
+   struct matrix modelview;
+   struct matrix paint_matrix;
+
    VGboolean drawing_image;
    VGImageMode image_mode;
 
@@ -71,6 +78,11 @@ void shader_destroy(struct shader *shader)
    FREE(shader);
 }
 
+void shader_set_color_transform(struct shader *shader, VGboolean set)
+{
+   shader->color_transform = set;
+}
+
 void shader_set_masking(struct shader *shader, VGboolean set)
 {
    shader->masking = set;
@@ -91,49 +103,64 @@ struct vg_paint * shader_paint(struct shader *shader)
    return shader->paint;
 }
 
-
-static void setup_constant_buffer(struct shader *shader)
+static VGint setup_constant_buffer(struct shader *shader)
 {
-   struct vg_context *ctx = shader->context;
-   struct pipe_context *pipe = shader->context->pipe;
-   struct pipe_resource **cbuf = &shader->cbuf;
+   const struct vg_state *state = &shader->context->state.vg;
    VGint param_bytes = paint_constant_buffer_size(shader->paint);
-   float temp_buf[MAX_CONSTANTS];
+   VGint i;
+
+   param_bytes += sizeof(VGfloat) * 8;
+   assert(param_bytes <= sizeof(shader->constants));
+
+   if (state->color_transform) {
+      for (i = 0; i < 8; i++) {
+         VGfloat val = (i < 4) ? 127.0f : 1.0f;
+         shader->constants[i] =
+            CLAMP(state->color_transform_values[i], -val, val);
+      }
+   }
+   else {
+      memset(shader->constants, 0, sizeof(VGfloat) * 8);
+   }
 
-   assert(param_bytes <= sizeof(temp_buf));
-   paint_fill_constant_buffer(shader->paint, temp_buf);
+   paint_fill_constant_buffer(shader->paint,
+         &shader->paint_matrix, shader->constants + 8);
 
-   if (*cbuf == NULL ||
-       memcmp(temp_buf, shader->constants, param_bytes) != 0)
-   {
-      pipe_resource_reference(cbuf, NULL);
+   return param_bytes;
+}
+
+static VGboolean blend_use_shader(struct vg_context *ctx)
+{
+   VGboolean advanced_blending;
 
-      memcpy(shader->constants, temp_buf, param_bytes);
-      *cbuf = pipe_user_buffer_create(pipe->screen,
-                                      &shader->constants,
-                                      sizeof(shader->constants),
-                                     PIPE_BIND_VERTEX_BUFFER);
+   switch (ctx->state.vg.blend_mode) {
+   case VG_BLEND_SRC_OVER:
+      advanced_blending =
+         util_format_has_alpha(ctx->draw_buffer->strb->format);
+      break;
+   case VG_BLEND_DST_OVER:
+   case VG_BLEND_MULTIPLY:
+   case VG_BLEND_SCREEN:
+   case VG_BLEND_DARKEN:
+   case VG_BLEND_LIGHTEN:
+   case VG_BLEND_ADDITIVE:
+      advanced_blending = VG_TRUE;
+      break;
+   default:
+      advanced_blending = VG_FALSE;
+      break;
    }
 
-   ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
+   return advanced_blending;
 }
 
 static VGint blend_bind_samplers(struct vg_context *ctx,
                                  struct pipe_sampler_state **samplers,
                                  struct pipe_sampler_view **sampler_views)
 {
-   VGBlendMode bmode = ctx->state.vg.blend_mode;
-
-   if (bmode == VG_BLEND_MULTIPLY ||
-       bmode == VG_BLEND_SCREEN ||
-       bmode == VG_BLEND_DARKEN ||
-       bmode == VG_BLEND_LIGHTEN) {
-      struct st_framebuffer *stfb = ctx->draw_buffer;
-
-      vg_prepare_blend_surface(ctx);
-
+   if (blend_use_shader(ctx)) {
       samplers[2] = &ctx->blend_sampler;
-      sampler_views[2] = stfb->blend_texture_view;
+      sampler_views[2] = vg_prepare_blend_surface(ctx);
 
       if (!samplers[0] || !sampler_views[0]) {
          samplers[0] = samplers[2];
@@ -149,10 +176,10 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
    return 0;
 }
 
-static void setup_samplers(struct shader *shader)
+static VGint setup_samplers(struct shader *shader,
+                            struct pipe_sampler_state **samplers,
+                            struct pipe_sampler_view **sampler_views)
 {
-   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
-   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
    struct vg_context *ctx = shader->context;
    /* a little wonky: we use the num as a boolean that just says
     * whether any sampler/textures have been set. the actual numbering
@@ -179,10 +206,7 @@ static void setup_samplers(struct shader *shader)
    if (shader->drawing_image && shader->image)
       num += image_bind_samplers(shader->image, samplers, sampler_views);
 
-   if (num) {
-      cso_set_samplers(ctx->cso_context, 4, (const struct pipe_sampler_state **)samplers);
-      cso_set_fragment_sampler_views(ctx->cso_context, 4, sampler_views);
-   }
+   return (num) ? 4 : 0;
 }
 
 static INLINE VGboolean is_format_bw(struct shader *shader)
@@ -227,6 +251,9 @@ static void setup_shader_program(struct shader *shader)
       default:
          abort();
       }
+
+      if (paint_is_degenerate(shader->paint))
+         shader_id = VEGA_PAINT_DEGENERATE_SHADER;
    }
 
    /* second stage image */
@@ -246,43 +273,86 @@ static void setup_shader_program(struct shader *shader)
       }
    }
 
-   if (shader->masking)
-      shader_id |= VEGA_MASK_SHADER;
+   if (shader->color_transform)
+      shader_id |= VEGA_COLOR_TRANSFORM_SHADER;
 
-   switch(blend_mode) {
-   case VG_BLEND_MULTIPLY:
-      shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
-      break;
-   case VG_BLEND_SCREEN:
-      shader_id |= VEGA_BLEND_SCREEN_SHADER;
-      break;
-   case VG_BLEND_DARKEN:
-      shader_id |= VEGA_BLEND_DARKEN_SHADER;
-      break;
-   case VG_BLEND_LIGHTEN:
-      shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
-      break;
-   default:
-      /* handled by pipe_blend_state */
-      break;
+   if (blend_use_shader(ctx)) {
+      if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
+         shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
+      else
+         shader_id |= VEGA_ALPHA_NORMAL_SHADER;
+
+      switch(blend_mode) {
+      case VG_BLEND_SRC:
+         shader_id |= VEGA_BLEND_SRC_SHADER;
+         break;
+      case VG_BLEND_SRC_OVER:
+         shader_id |= VEGA_BLEND_SRC_OVER_SHADER;
+         break;
+      case VG_BLEND_DST_OVER:
+         shader_id |= VEGA_BLEND_DST_OVER_SHADER;
+         break;
+      case VG_BLEND_SRC_IN:
+         shader_id |= VEGA_BLEND_SRC_IN_SHADER;
+         break;
+      case VG_BLEND_DST_IN:
+         shader_id |= VEGA_BLEND_DST_IN_SHADER;
+         break;
+      case VG_BLEND_MULTIPLY:
+         shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
+         break;
+      case VG_BLEND_SCREEN:
+         shader_id |= VEGA_BLEND_SCREEN_SHADER;
+         break;
+      case VG_BLEND_DARKEN:
+         shader_id |= VEGA_BLEND_DARKEN_SHADER;
+         break;
+      case VG_BLEND_LIGHTEN:
+         shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
+         break;
+      case VG_BLEND_ADDITIVE:
+         shader_id |= VEGA_BLEND_ADDITIVE_SHADER;
+         break;
+      default:
+         assert(0);
+         break;
+      }
+   }
+   else {
+      /* update alpha of the source */
+      if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
+         shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
    }
 
+   if (shader->masking)
+      shader_id |= VEGA_MASK_SHADER;
+
    if (black_white)
       shader_id |= VEGA_BW_SHADER;
 
    shader->fs = shaders_cache_fill(ctx->sc, shader_id);
-   cso_set_fragment_shader_handle(ctx->cso_context, shader->fs);
 }
 
 
 void shader_bind(struct shader *shader)
 {
+   struct vg_context *ctx = shader->context;
+   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+   VGint num_samplers, param_bytes;
+
    /* first resolve the real paint type */
    paint_resolve_type(shader->paint);
 
-   setup_constant_buffer(shader);
-   setup_samplers(shader);
+   num_samplers = setup_samplers(shader, samplers, sampler_views);
+   param_bytes = setup_constant_buffer(shader);
    setup_shader_program(shader);
+
+   renderer_validate_for_shader(ctx->renderer,
+         (const struct pipe_sampler_state **) samplers,
+         sampler_views, num_samplers,
+         &shader->modelview,
+         shader->fs, (const void *) shader->constants, param_bytes);
 }
 
 void shader_set_image_mode(struct shader *shader, VGImageMode image_mode)
@@ -309,3 +379,28 @@ void shader_set_image(struct shader *shader, struct vg_image *img)
 {
    shader->image = img;
 }
+
+/**
+ * Set the transformation to map a vertex to the surface coordinates.
+ */
+void shader_set_surface_matrix(struct shader *shader,
+                               const struct matrix *mat)
+{
+   shader->modelview = *mat;
+}
+
+/**
+ * Set the transformation to map a pixel to the paint coordinates.
+ */
+void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat)
+{
+   const struct st_framebuffer *stfb = shader->context->draw_buffer;
+   const VGfloat px_center_offset = 0.5f;
+
+   memcpy(&shader->paint_matrix, mat, sizeof(*mat));
+
+   /* make it window-to-paint for the shaders */
+   matrix_translate(&shader->paint_matrix, px_center_offset,
+         stfb->height - 1.0f + px_center_offset);
+   matrix_scale(&shader->paint_matrix, 1.0f, -1.0f);
+}
index 847eee6a31039e401479d447ea0b80845341d49e..8b97e537efed09398e5a2b73a3c4647cb87ab32f 100644 (file)
@@ -33,10 +33,13 @@ struct shader;
 struct vg_paint;
 struct vg_context;
 struct vg_image;
+struct matrix;
 
 struct shader *shader_create(struct vg_context *context);
 void shader_destroy(struct shader *shader);
 
+void shader_set_color_transform(struct shader *shader, VGboolean set);
+
 void shader_set_masking(struct shader *shader, VGboolean set);
 VGboolean shader_is_masking(struct shader *shader);
 
@@ -51,6 +54,10 @@ VGboolean shader_drawing_image(struct shader *shader);
 
 void shader_set_image(struct shader *shader, struct vg_image *img);
 
+void shader_set_surface_matrix(struct shader *shader,
+                               const struct matrix *mat);
+void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat);
+
 void shader_bind(struct shader *shader);
 
 #endif
index e002a7ed42899dbf5c8667d37b49168ca43e1467..023996ce2d8c848ea84dc265b6e5ec5826ec2776 100644 (file)
 
 /* Essentially we construct an ubber-shader based on the state
  * of the pipeline. The stages are:
- * 1) Fill (mandatory, solid color/gradient/pattern/image draw)
- * 2) Image composition (image mode multiply and stencil)
- * 3) Mask
- * 4) Extended blend (multiply/screen/darken/lighten)
- * 5) Premultiply/Unpremultiply
- * 6) Color transform (to black and white)
+ * 1) Paint generation (color/gradient/pattern)
+ * 2) Image composition (normal/multiply/stencil)
+ * 3) Color transform
+ * 4) Per-channel alpha generation
+ * 5) Extended blend (multiply/screen/darken/lighten)
+ * 6) Mask
+ * 7) Premultiply/Unpremultiply
+ * 8) Color transform (to black and white)
  */
-#define SHADER_STAGES 6
+#define SHADER_STAGES 8
 
 struct cached_shader {
    void *driver_shader;
@@ -86,13 +88,6 @@ static INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_t
    return tokens;
 }
 
-#define ALL_FILLS (VEGA_SOLID_FILL_SHADER | \
-   VEGA_LINEAR_GRADIENT_SHADER | \
-   VEGA_RADIAL_GRADIENT_SHADER | \
-   VEGA_PATTERN_SHADER         | \
-   VEGA_IMAGE_NORMAL_SHADER)
-
-
 /*
 static const char max_shader_preamble[] =
    "FRAG\n"
@@ -257,98 +252,126 @@ create_shader(struct pipe_context *pipe,
               int id,
               struct pipe_shader_state *shader)
 {
-   int idx = 0;
+   int idx = 0, sh;
    const struct shader_asm_info * shaders[SHADER_STAGES];
 
-   /* the shader has to have a fill */
-   debug_assert(id & ALL_FILLS);
-
    /* first stage */
-   if (id & VEGA_SOLID_FILL_SHADER) {
-      debug_assert(idx == 0);
-      shaders[idx] = &shaders_asm[0];
-      debug_assert(shaders_asm[0].id == VEGA_SOLID_FILL_SHADER);
-      ++idx;
-   }
-   if ((id & VEGA_LINEAR_GRADIENT_SHADER)) {
-      debug_assert(idx == 0);
-      shaders[idx] = &shaders_asm[1];
-      debug_assert(shaders_asm[1].id == VEGA_LINEAR_GRADIENT_SHADER);
-      ++idx;
-   }
-   if ((id & VEGA_RADIAL_GRADIENT_SHADER)) {
-      debug_assert(idx == 0);
-      shaders[idx] = &shaders_asm[2];
-      debug_assert(shaders_asm[2].id == VEGA_RADIAL_GRADIENT_SHADER);
-      ++idx;
-   }
-   if ((id & VEGA_PATTERN_SHADER)) {
-      debug_assert(idx == 0);
-      debug_assert(shaders_asm[3].id == VEGA_PATTERN_SHADER);
-      shaders[idx] = &shaders_asm[3];
-      ++idx;
-   }
-   if ((id & VEGA_IMAGE_NORMAL_SHADER)) {
-      debug_assert(idx == 0);
-      debug_assert(shaders_asm[4].id == VEGA_IMAGE_NORMAL_SHADER);
-      shaders[idx] = &shaders_asm[4];
-      ++idx;
+   sh = SHADERS_GET_PAINT_SHADER(id);
+   switch (sh << SHADERS_PAINT_SHIFT) {
+   case VEGA_SOLID_FILL_SHADER:
+   case VEGA_LINEAR_GRADIENT_SHADER:
+   case VEGA_RADIAL_GRADIENT_SHADER:
+   case VEGA_PATTERN_SHADER:
+   case VEGA_PAINT_DEGENERATE_SHADER:
+      shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
    }
 
    /* second stage */
-   if ((id & VEGA_IMAGE_MULTIPLY_SHADER)) {
-      debug_assert(shaders_asm[5].id == VEGA_IMAGE_MULTIPLY_SHADER);
-      shaders[idx] = &shaders_asm[5];
-      ++idx;
-   } else if ((id & VEGA_IMAGE_STENCIL_SHADER)) {
-      debug_assert(shaders_asm[6].id == VEGA_IMAGE_STENCIL_SHADER);
-      shaders[idx] = &shaders_asm[6];
-      ++idx;
+   sh = SHADERS_GET_IMAGE_SHADER(id);
+   switch (sh) {
+   case VEGA_IMAGE_NORMAL_SHADER:
+   case VEGA_IMAGE_MULTIPLY_SHADER:
+   case VEGA_IMAGE_STENCIL_SHADER:
+      shaders[idx] = &shaders_image_asm[(sh >> SHADERS_IMAGE_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
    }
 
+   /* sanity check */
+   assert(idx == ((!sh || sh == VEGA_IMAGE_NORMAL_SHADER) ? 1 : 2));
+
    /* third stage */
-   if ((id & VEGA_MASK_SHADER)) {
-      debug_assert(idx == 1);
-      debug_assert(shaders_asm[7].id == VEGA_MASK_SHADER);
-      shaders[idx] = &shaders_asm[7];
-      ++idx;
+   sh = SHADERS_GET_COLOR_TRANSFORM_SHADER(id);
+   switch (sh) {
+   case VEGA_COLOR_TRANSFORM_SHADER:
+      shaders[idx] = &shaders_color_transform_asm[
+         (sh >> SHADERS_COLOR_TRANSFORM_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
    }
 
    /* fourth stage */
-   if ((id & VEGA_BLEND_MULTIPLY_SHADER)) {
-      debug_assert(shaders_asm[8].id == VEGA_BLEND_MULTIPLY_SHADER);
-      shaders[idx] = &shaders_asm[8];
-      ++idx;
-   } else if ((id & VEGA_BLEND_SCREEN_SHADER)) {
-      debug_assert(shaders_asm[9].id == VEGA_BLEND_SCREEN_SHADER);
-      shaders[idx] = &shaders_asm[9];
-      ++idx;
-   } else if ((id & VEGA_BLEND_DARKEN_SHADER)) {
-      debug_assert(shaders_asm[10].id == VEGA_BLEND_DARKEN_SHADER);
-      shaders[idx] = &shaders_asm[10];
-      ++idx;
-   } else if ((id & VEGA_BLEND_LIGHTEN_SHADER)) {
-      debug_assert(shaders_asm[11].id == VEGA_BLEND_LIGHTEN_SHADER);
-      shaders[idx] = &shaders_asm[11];
-      ++idx;
+   sh = SHADERS_GET_ALPHA_SHADER(id);
+   switch (sh) {
+   case VEGA_ALPHA_NORMAL_SHADER:
+   case VEGA_ALPHA_PER_CHANNEL_SHADER:
+      shaders[idx] = &shaders_alpha_asm[
+         (sh >> SHADERS_ALPHA_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
    }
 
    /* fifth stage */
-   if ((id & VEGA_PREMULTIPLY_SHADER)) {
-      debug_assert(shaders_asm[12].id == VEGA_PREMULTIPLY_SHADER);
-      shaders[idx] = &shaders_asm[12];
-      ++idx;
-   } else if ((id & VEGA_UNPREMULTIPLY_SHADER)) {
-      debug_assert(shaders_asm[13].id == VEGA_UNPREMULTIPLY_SHADER);
-      shaders[idx] = &shaders_asm[13];
-      ++idx;
+   sh = SHADERS_GET_BLEND_SHADER(id);
+   switch (sh) {
+   case VEGA_BLEND_SRC_SHADER:
+   case VEGA_BLEND_SRC_OVER_SHADER:
+   case VEGA_BLEND_DST_OVER_SHADER:
+   case VEGA_BLEND_SRC_IN_SHADER:
+   case VEGA_BLEND_DST_IN_SHADER:
+   case VEGA_BLEND_MULTIPLY_SHADER:
+   case VEGA_BLEND_SCREEN_SHADER:
+   case VEGA_BLEND_DARKEN_SHADER:
+   case VEGA_BLEND_LIGHTEN_SHADER:
+   case VEGA_BLEND_ADDITIVE_SHADER:
+      shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
    }
 
    /* sixth stage */
-   if ((id & VEGA_BW_SHADER)) {
-      debug_assert(shaders_asm[14].id == VEGA_BW_SHADER);
-      shaders[idx] = &shaders_asm[14];
-      ++idx;
+   sh = SHADERS_GET_MASK_SHADER(id);
+   switch (sh) {
+   case VEGA_MASK_SHADER:
+      shaders[idx] = &shaders_mask_asm[(sh >> SHADERS_MASK_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
+   }
+
+   /* seventh stage */
+   sh = SHADERS_GET_PREMULTIPLY_SHADER(id);
+   switch (sh) {
+   case VEGA_PREMULTIPLY_SHADER:
+   case VEGA_UNPREMULTIPLY_SHADER:
+      shaders[idx] = &shaders_premultiply_asm[
+         (sh >> SHADERS_PREMULTIPLY_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
+   }
+
+   /* eighth stage */
+   sh = SHADERS_GET_BW_SHADER(id);
+   switch (sh) {
+   case VEGA_BW_SHADER:
+      shaders[idx] = &shaders_bw_asm[(sh >> SHADERS_BW_SHIFT) - 1];
+      assert(shaders[idx]->id == sh);
+      idx++;
+      break;
+   default:
+      break;
    }
 
    return combine_shaders(shaders, idx, pipe, shader);
index feca58b61a9dd412ac3493a15ad586647132941c..05014f25dccedb4669f319ab9df48d991fdfb943 100644 (file)
@@ -33,26 +33,69 @@ struct pipe_context;
 struct tgsi_token;
 struct shaders_cache;
 
+#define _SHADERS_PAINT_BITS            3
+#define _SHADERS_IMAGE_BITS            2
+#define _SHADERS_COLOR_TRANSFORM_BITS  1
+#define _SHADERS_ALPHA_BITS            2
+#define _SHADERS_BLEND_BITS            4
+#define _SHADERS_MASK_BITS             1
+#define _SHADERS_PREMULTIPLY_BITS      2
+#define _SHADERS_BW_BITS               1
+
+#define SHADERS_PAINT_SHIFT           (0)
+#define SHADERS_IMAGE_SHIFT           (SHADERS_PAINT_SHIFT + _SHADERS_PAINT_BITS)
+#define SHADERS_COLOR_TRANSFORM_SHIFT (SHADERS_IMAGE_SHIFT + _SHADERS_IMAGE_BITS)
+#define SHADERS_ALPHA_SHIFT           (SHADERS_COLOR_TRANSFORM_SHIFT + _SHADERS_COLOR_TRANSFORM_BITS)
+#define SHADERS_BLEND_SHIFT           (SHADERS_ALPHA_SHIFT + _SHADERS_ALPHA_BITS)
+#define SHADERS_MASK_SHIFT            (SHADERS_BLEND_SHIFT + _SHADERS_BLEND_BITS)
+#define SHADERS_PREMULTIPLY_SHIFT     (SHADERS_MASK_SHIFT + _SHADERS_MASK_BITS)
+#define SHADERS_BW_SHIFT              (SHADERS_PREMULTIPLY_SHIFT + _SHADERS_PREMULTIPLY_BITS)
+
+#define _SHADERS_GET_STAGE(stage, id) \
+   ((id) & (((1 << _SHADERS_ ## stage ## _BITS) - 1) << SHADERS_ ## stage ## _SHIFT))
+
+#define SHADERS_GET_PAINT_SHADER(id)           _SHADERS_GET_STAGE(PAINT, id)
+#define SHADERS_GET_IMAGE_SHADER(id)           _SHADERS_GET_STAGE(IMAGE, id)
+#define SHADERS_GET_COLOR_TRANSFORM_SHADER(id) _SHADERS_GET_STAGE(COLOR_TRANSFORM, id)
+#define SHADERS_GET_ALPHA_SHADER(id)           _SHADERS_GET_STAGE(ALPHA, id)
+#define SHADERS_GET_BLEND_SHADER(id)           _SHADERS_GET_STAGE(BLEND, id)
+#define SHADERS_GET_MASK_SHADER(id)            _SHADERS_GET_STAGE(MASK, id)
+#define SHADERS_GET_PREMULTIPLY_SHADER(id)     _SHADERS_GET_STAGE(PREMULTIPLY, id)
+#define SHADERS_GET_BW_SHADER(id)              _SHADERS_GET_STAGE(BW, id)
+
 enum VegaShaderType {
-   VEGA_SOLID_FILL_SHADER         = 1 <<  0,
-   VEGA_LINEAR_GRADIENT_SHADER    = 1 <<  1,
-   VEGA_RADIAL_GRADIENT_SHADER    = 1 <<  2,
-   VEGA_PATTERN_SHADER            = 1 <<  3,
-   VEGA_IMAGE_NORMAL_SHADER       = 1 <<  4,
-   VEGA_IMAGE_MULTIPLY_SHADER     = 1 <<  5,
-   VEGA_IMAGE_STENCIL_SHADER      = 1 <<  6,
+   VEGA_SOLID_FILL_SHADER         = 1 << SHADERS_PAINT_SHIFT,
+   VEGA_LINEAR_GRADIENT_SHADER    = 2 << SHADERS_PAINT_SHIFT,
+   VEGA_RADIAL_GRADIENT_SHADER    = 3 << SHADERS_PAINT_SHIFT,
+   VEGA_PATTERN_SHADER            = 4 << SHADERS_PAINT_SHIFT,
+   VEGA_PAINT_DEGENERATE_SHADER   = 5 << SHADERS_PAINT_SHIFT,
+
+   VEGA_IMAGE_NORMAL_SHADER       = 1 << SHADERS_IMAGE_SHIFT,
+   VEGA_IMAGE_MULTIPLY_SHADER     = 2 << SHADERS_IMAGE_SHIFT,
+   VEGA_IMAGE_STENCIL_SHADER      = 3 << SHADERS_IMAGE_SHIFT,
+
+   VEGA_COLOR_TRANSFORM_SHADER    = 1 <<  SHADERS_COLOR_TRANSFORM_SHIFT,
+
+   VEGA_ALPHA_NORMAL_SHADER       = 1 <<  SHADERS_ALPHA_SHIFT,
+   VEGA_ALPHA_PER_CHANNEL_SHADER  = 2 <<  SHADERS_ALPHA_SHIFT,
 
-   VEGA_MASK_SHADER               = 1 <<  7,
+   VEGA_BLEND_SRC_SHADER          = 1 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SRC_OVER_SHADER     = 2 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_DST_OVER_SHADER     = 3 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SRC_IN_SHADER       = 4 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_DST_IN_SHADER       = 5 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_MULTIPLY_SHADER     = 6 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SCREEN_SHADER       = 7 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_DARKEN_SHADER       = 8 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_LIGHTEN_SHADER      = 9 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_ADDITIVE_SHADER     = 10<< SHADERS_BLEND_SHIFT,
 
-   VEGA_BLEND_MULTIPLY_SHADER     = 1 <<  8,
-   VEGA_BLEND_SCREEN_SHADER       = 1 <<  9,
-   VEGA_BLEND_DARKEN_SHADER       = 1 << 10,
-   VEGA_BLEND_LIGHTEN_SHADER      = 1 << 11,
+   VEGA_MASK_SHADER               = 1 << SHADERS_MASK_SHIFT,
 
-   VEGA_PREMULTIPLY_SHADER        = 1 << 12,
-   VEGA_UNPREMULTIPLY_SHADER      = 1 << 13,
+   VEGA_PREMULTIPLY_SHADER        = 1 << SHADERS_PREMULTIPLY_SHIFT,
+   VEGA_UNPREMULTIPLY_SHADER      = 2 << SHADERS_PREMULTIPLY_SHIFT,
 
-   VEGA_BW_SHADER                 = 1 << 14
+   VEGA_BW_SHADER                 = 1 << SHADERS_BW_SHIFT
 };
 
 struct vg_shader {
diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h
deleted file mode 100644 (file)
index 7eaa67c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * Functions for checking if buffers/textures are referenced when we need
- * to read/write from/to them.  Flush when needed.
- */
-
-#ifndef ST_INLINES_H
-#define ST_INLINES_H
-
-#include "vg_context.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "pipe/p_state.h"
-
-static INLINE struct pipe_transfer *
-st_cond_flush_get_transfer(struct vg_context *st,
-                              struct pipe_resource *pt,
-                              unsigned int face,
-                              unsigned int level,
-                              unsigned int zslice,
-                              enum pipe_transfer_usage usage,
-                              unsigned int x, unsigned int y,
-                              unsigned int w, unsigned int h)
-{
-   struct pipe_context *pipe = st->pipe;
-
-   return pipe_get_transfer(pipe, pt, face, level, zslice, usage,
-                           x, y, w, h);
-}
-
-static INLINE struct pipe_transfer *
-st_no_flush_get_transfer(struct vg_context *st,
-                            struct pipe_resource *pt,
-                            unsigned int face,
-                            unsigned int level,
-                            unsigned int zslice,
-                            enum pipe_transfer_usage usage,
-                            unsigned int x, unsigned int y,
-                            unsigned int w, unsigned int h)
-{
-   struct pipe_context *pipe = st->pipe;
-
-   return pipe_get_transfer(pipe, pt, face, level,
-                           zslice, usage, x, y, w, h);
-}
-
-
-static INLINE void
-st_cond_flush_pipe_buffer_write(struct vg_context *st,
-                               struct pipe_resource *buf,
-                               unsigned int offset,
-                               unsigned int size,
-                               const void * data)
-{
-   struct pipe_context *pipe = st->pipe;
-
-   pipe_buffer_write(pipe, buf, offset, size, data);
-}
-
-static INLINE void
-st_no_flush_pipe_buffer_write(struct vg_context *st,
-                             struct pipe_resource *buf,
-                             unsigned int offset,
-                             unsigned int size,
-                             const void * data)
-{
-   pipe_buffer_write(st->pipe, buf, offset, size, data);
-}
-
-static INLINE void
-st_cond_flush_pipe_buffer_read(struct vg_context *st,
-                              struct pipe_resource *buf,
-                              unsigned int offset,
-                              unsigned int size,
-                              void * data)
-{
-   struct pipe_context *pipe = st->pipe;
-
-   pipe_buffer_read(pipe, buf, offset, size, data);
-}
-
-static INLINE void
-st_no_flush_pipe_buffer_read(struct vg_context *st,
-                            struct pipe_resource *buf,
-                            unsigned int offset,
-                            unsigned int size,
-                            void * data)
-{
-   pipe_buffer_read(st->pipe, buf, offset, size, data);
-}
-
-#endif
-
diff --git a/src/gallium/state_trackers/vega/text.c b/src/gallium/state_trackers/vega/text.c
new file mode 100644 (file)
index 0000000..01ff602
--- /dev/null
@@ -0,0 +1,250 @@
+/**************************************************************************
+ *
+ * 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_memory.h"
+#include "cso_cache/cso_hash.h"
+
+#include "text.h"
+#include "image.h"
+#include "path.h"
+#include "api.h"
+
+#ifdef OPENVG_VERSION_1_1
+
+struct vg_font {
+   struct vg_object base;
+   struct cso_hash *glyphs;
+};
+
+struct vg_glyph {
+   struct vg_object *object; /* it could be NULL */
+   VGboolean is_hinted;
+   VGfloat glyph_origin[2];
+   VGfloat escapement[2];
+};
+
+static VGboolean del_glyph(struct vg_font *font,
+                           VGuint glyphIndex)
+{
+   struct vg_glyph *glyph;
+
+   glyph = (struct vg_glyph *)
+      cso_hash_take(font->glyphs, (unsigned) glyphIndex);
+   if (glyph)
+      FREE(glyph);
+
+   return (glyph != NULL);
+}
+
+static void add_glyph(struct vg_font *font,
+                      VGuint glyphIndex,
+                      struct vg_object *obj,
+                      VGboolean isHinted,
+                      const VGfloat glyphOrigin[2],
+                      const VGfloat escapement[2])
+{
+   struct vg_glyph *glyph;
+
+   /* remove the existing one */
+   del_glyph(font, glyphIndex);
+
+   glyph = CALLOC_STRUCT(vg_glyph);
+   glyph->object = obj;
+   glyph->is_hinted = isHinted;
+   memcpy(glyph->glyph_origin, glyphOrigin, sizeof(glyphOrigin));
+   memcpy(glyph->escapement, escapement, sizeof(escapement));
+
+   cso_hash_insert(font->glyphs, (unsigned) glyphIndex, glyph);
+}
+
+static struct vg_glyph *get_glyph(struct vg_font *font,
+                                  VGuint glyphIndex)
+{
+   struct cso_hash_iter iter;
+
+   iter = cso_hash_find(font->glyphs, (unsigned) glyphIndex);
+   return (struct vg_glyph *) cso_hash_iter_data(iter);
+}
+
+static void vg_render_glyph(struct vg_context *ctx,
+                            struct vg_glyph *glyph,
+                            VGbitfield paintModes,
+                            VGboolean allowAutoHinting)
+{
+   if (glyph->object && paintModes) {
+      struct vg_state *state = &ctx->state.vg;
+      struct matrix m;
+
+      m = state->glyph_user_to_surface_matrix;
+      matrix_translate(&m,
+            state->glyph_origin[0].f - glyph->glyph_origin[0],
+            state->glyph_origin[1].f - glyph->glyph_origin[1]);
+
+      if (glyph->object->type == VG_OBJECT_PATH) {
+         path_render((struct path *) glyph->object, paintModes, &m);
+      }
+      else {
+         assert(glyph->object->type == VG_OBJECT_IMAGE);
+         image_draw((struct vg_image *) glyph->object, &m);
+      }
+   }
+}
+
+static void vg_advance_glyph(struct vg_context *ctx,
+                             struct vg_glyph *glyph,
+                             VGfloat adjustment_x,
+                             VGfloat adjustment_y,
+                             VGboolean last)
+{
+   struct vg_value *glyph_origin = ctx->state.vg.glyph_origin;
+
+   glyph_origin[0].f += glyph->escapement[0] + adjustment_x;
+   glyph_origin[1].f += glyph->escapement[1] + adjustment_y;
+
+   if (last) {
+      glyph_origin[0].i = float_to_int_floor(glyph_origin[0].f);
+      glyph_origin[1].i = float_to_int_floor(glyph_origin[1].f);
+   }
+}
+
+struct vg_font *font_create(VGint glyphCapacityHint)
+{
+   struct vg_context *ctx = vg_current_context();
+   struct vg_font *font;
+
+   font = CALLOC_STRUCT(vg_font);
+   vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
+   font->glyphs = cso_hash_create();
+
+   vg_context_add_object(ctx, VG_OBJECT_FONT, font);
+
+   return font;
+}
+
+void font_destroy(struct vg_font *font)
+{
+   struct vg_context *ctx = vg_current_context();
+   struct cso_hash_iter iter;
+
+   vg_context_remove_object(ctx, VG_OBJECT_FONT, font);
+
+   iter = cso_hash_first_node(font->glyphs);
+   while (!cso_hash_iter_is_null(iter)) {
+      struct vg_glyph *glyph = (struct vg_glyph *) cso_hash_iter_data(iter);
+      FREE(glyph);
+      iter = cso_hash_iter_next(iter);
+   }
+   cso_hash_delete(font->glyphs);
+
+   FREE(font);
+}
+
+void font_set_glyph_to_path(struct vg_font *font,
+                            VGuint glyphIndex,
+                            struct path *path,
+                            VGboolean isHinted,
+                            const VGfloat glyphOrigin[2],
+                            const VGfloat escapement[2])
+{
+   add_glyph(font, glyphIndex, (struct vg_object *) path,
+         isHinted, glyphOrigin, escapement);
+}
+
+void font_set_glyph_to_image(struct vg_font *font,
+                             VGuint glyphIndex,
+                             struct vg_image *image,
+                             const VGfloat glyphOrigin[2],
+                             const VGfloat escapement[2])
+{
+   add_glyph(font, glyphIndex, (struct vg_object *) image,
+         VG_TRUE, glyphOrigin, escapement);
+}
+
+void font_clear_glyph(struct vg_font *font,
+                      VGuint glyphIndex)
+{
+   if (!del_glyph(font, glyphIndex)) {
+      struct vg_context *ctx = vg_current_context();
+      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
+   }
+}
+
+void font_draw_glyph(struct vg_font *font,
+                     VGuint glyphIndex,
+                     VGbitfield paintModes,
+                     VGboolean allowAutoHinting)
+{
+   struct vg_context *ctx = vg_current_context();
+   struct vg_glyph *glyph;
+
+   glyph = get_glyph(font, glyphIndex);
+   if (!glyph) {
+      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
+      return;
+   }
+
+   vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
+   vg_advance_glyph(ctx, glyph, 0.0f, 0.0f, VG_TRUE);
+}
+
+void font_draw_glyphs(struct vg_font *font,
+                      VGint glyphCount,
+                      const VGuint *glyphIndices,
+                      const VGfloat *adjustments_x,
+                      const VGfloat *adjustments_y,
+                      VGbitfield paintModes,
+                      VGboolean allowAutoHinting)
+{
+   struct vg_context *ctx = vg_current_context();
+   VGint i;
+
+   for (i = 0; i < glyphCount; ++i) {
+      if (!get_glyph(font, glyphIndices[i])) {
+         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
+         return;
+      }
+   }
+
+   for (i = 0; i < glyphCount; ++i) {
+      struct vg_glyph *glyph;
+      VGfloat adj_x, adj_y;
+
+      glyph = get_glyph(font, glyphIndices[i]);
+
+      vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
+
+      adj_x = (adjustments_x) ? adjustments_x[i] : 0.0f;
+      adj_y = (adjustments_y) ? adjustments_y[i] : 0.0f;
+      vg_advance_glyph(ctx, glyph, adj_x, adj_y, (i == glyphCount - 1));
+   }
+}
+
+VGint font_num_glyphs(struct vg_font *font)
+{
+   return cso_hash_size(font->glyphs);
+}
+
+#endif /* OPENVG_VERSION_1_1 */
diff --git a/src/gallium/state_trackers/vega/text.h b/src/gallium/state_trackers/vega/text.h
new file mode 100644 (file)
index 0000000..6b3fa73
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+ *
+ * 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef _TEXT_H
+#define _TEXT_H
+
+#include "vg_context.h"
+#include "cso_cache/cso_hash.h"
+
+struct vg_font;
+struct vg_image;
+struct path;
+
+struct vg_font *font_create(VGint glyphCapacityHint);
+void font_destroy(struct vg_font *font);
+
+void font_set_glyph_to_path(struct vg_font *font,
+                            VGuint glyphIndex,
+                            struct path *path,
+                            VGboolean isHinted,
+                            const VGfloat glyphOrigin[2],
+                            const VGfloat escapement[2]);
+
+void font_set_glyph_to_image(struct vg_font *font,
+                             VGuint glyphIndex,
+                             struct vg_image *image,
+                             const VGfloat glyphOrigin[2],
+                             const VGfloat escapement[2]);
+
+void font_clear_glyph(struct vg_font *font,
+                      VGuint glyphIndex);
+
+void font_draw_glyph(struct vg_font *font,
+                     VGuint glyphIndex,
+                     VGbitfield paintModes,
+                     VGboolean allowAutoHinting);
+
+void font_draw_glyphs(struct vg_font *font,
+                      VGint glyphCount,
+                      const VGuint *glyphIndices,
+                      const VGfloat *adjustments_x,
+                      const VGfloat *adjustments_y,
+                      VGbitfield paintModes,
+                      VGboolean allowAutoHinting);
+
+VGint font_num_glyphs(struct vg_font *font);
+
+#endif /* _TEXT_H */
index 99e444affdffe955faec64216143b6359a2ddcd0..0844012cc3b45908722169b37809a5017ad88860 100644 (file)
@@ -31,9 +31,9 @@
 #include "shaders_cache.h"
 #include "shader.h"
 #include "asm_util.h"
-#include "st_inlines.h"
 #include "vg_manager.h"
 #include "api.h"
+#include "mask.h"
 
 #include "pipe/p_context.h"
 #include "util/u_inlines.h"
@@ -44,6 +44,8 @@
 #include "util/u_memory.h"
 #include "util/u_blit.h"
 #include "util/u_sampler.h"
+#include "util/u_surface.h"
+#include "util/u_format.h"
 
 struct vg_context *_vg_context = 0;
 
@@ -52,19 +54,6 @@ struct vg_context * vg_current_context(void)
    return _vg_context;
 }
 
-static void init_clear(struct vg_context *st)
-{
-   struct pipe_context *pipe = st->pipe;
-
-   /* rasterizer state: bypass clipping */
-   memset(&st->clear.raster, 0, sizeof(st->clear.raster));
-   st->clear.raster.gl_rasterization_rules = 1;
-
-   /* fragment shader state: color pass-through program */
-   st->clear.fs =
-      util_make_fragment_passthrough_shader(pipe);
-}
-
 /**
  * A depth/stencil rb will be needed regardless of what the visual says.
  */
@@ -101,7 +90,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
                                       struct vg_context *share)
 {
    struct vg_context *ctx;
-   unsigned i;
 
    ctx = CALLOC_STRUCT(vg_context);
 
@@ -118,8 +106,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
 
    ctx->cso_context = cso_create_context(pipe);
 
-   init_clear(ctx);
-
    ctx->default_paint = paint_create(ctx);
    ctx->state.vg.stroke_paint = ctx->default_paint;
    ctx->state.vg.fill_paint = ctx->default_paint;
@@ -141,13 +127,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
    ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
    ctx->blend_sampler.normalized_coords = 0;
 
-   for (i = 0; i < 2; i++) {
-      ctx->velems[i].src_offset = i * 4 * sizeof(float);
-      ctx->velems[i].instance_divisor = 0;
-      ctx->velems[i].vertex_buffer_index = 0;
-      ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-   }
-
    vg_set_error(ctx, VG_NO_ERROR);
 
    ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
@@ -168,7 +147,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
 void vg_destroy_context(struct vg_context *ctx)
 {
    struct pipe_resource **cbuf = &ctx->mask.cbuf;
-   struct pipe_resource **vsbuf = &ctx->vs_const_buffer;
 
    util_destroy_blit(ctx->blit);
    renderer_destroy(ctx->renderer);
@@ -179,29 +157,6 @@ void vg_destroy_context(struct vg_context *ctx)
    if (*cbuf)
       pipe_resource_reference(cbuf, NULL);
 
-   if (*vsbuf)
-      pipe_resource_reference(vsbuf, NULL);
-
-   if (ctx->clear.fs) {
-      cso_delete_fragment_shader(ctx->cso_context, ctx->clear.fs);
-      ctx->clear.fs = NULL;
-   }
-
-   if (ctx->plain_vs) {
-      vg_shader_destroy(ctx, ctx->plain_vs);
-      ctx->plain_vs = NULL;
-   }
-   if (ctx->clear_vs) {
-      vg_shader_destroy(ctx, ctx->clear_vs);
-      ctx->clear_vs = NULL;
-   }
-   if (ctx->texture_vs) {
-      vg_shader_destroy(ctx, ctx->texture_vs);
-      ctx->texture_vs = NULL;
-   }
-
-   if (ctx->pass_through_depth_fs)
-      vg_shader_destroy(ctx, ctx->pass_through_depth_fs);
    if (ctx->mask.union_fs)
       vg_shader_destroy(ctx, ctx->mask.union_fs);
    if (ctx->mask.intersect_fs)
@@ -268,186 +223,195 @@ void vg_context_remove_object(struct vg_context *ctx,
    }
 }
 
-static void update_clip_state(struct vg_context *ctx)
+static struct pipe_resource *
+create_texture(struct pipe_context *pipe, enum pipe_format format,
+                    VGint width, VGint height)
 {
-   struct pipe_depth_stencil_alpha_state *dsa = &ctx->state.g3d.dsa;
-   struct vg_state *state =  &ctx->state.vg;
-
-   memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
-
-   if (state->scissoring) {
-      struct pipe_blend_state *blend = &ctx->state.g3d.blend;
-      struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
-      int i;
-
-      dsa->depth.writemask = 1;/*glDepthMask(TRUE);*/
-      dsa->depth.func = PIPE_FUNC_ALWAYS;
-      dsa->depth.enabled = 1;
-
-      cso_save_blend(ctx->cso_context);
-      cso_save_fragment_shader(ctx->cso_context);
-      /* set a passthrough shader */
-      if (!ctx->pass_through_depth_fs)
-         ctx->pass_through_depth_fs = shader_create_from_text(ctx->pipe,
-                                                              pass_through_depth_asm,
-                                                              40,
-                                                              PIPE_SHADER_FRAGMENT);
-      cso_set_fragment_shader_handle(ctx->cso_context,
-                                     ctx->pass_through_depth_fs->driver);
-      cso_set_depth_stencil_alpha(ctx->cso_context, dsa);
-
-      ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);
-
-      /* disable color writes */
-      blend->rt[0].colormask = 0; /*disable colorwrites*/
-      cso_set_blend(ctx->cso_context, blend);
-
-      /* enable scissoring */
-      for (i = 0; i < state->scissor_rects_num; ++i) {
-         const float x      = state->scissor_rects[i * 4 + 0].f;
-         const float y      = state->scissor_rects[i * 4 + 1].f;
-         const float width  = state->scissor_rects[i * 4 + 2].f;
-         const float height = state->scissor_rects[i * 4 + 3].f;
-         VGfloat minx, miny, maxx, maxy;
-
-         minx = 0;
-         miny = 0;
-         maxx = fb->width;
-         maxy = fb->height;
-
-         if (x > minx)
-            minx = x;
-         if (y > miny)
-            miny = y;
-
-         if (x + width < maxx)
-            maxx = x + width;
-         if (y + height < maxy)
-            maxy = y + height;
-
-         /* check for null space */
-         if (minx >= maxx || miny >= maxy)
-            minx = miny = maxx = maxy = 0;
-
-         /*glClear(GL_DEPTH_BUFFER_BIT);*/
-         renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f);
-      }
-
-      cso_restore_blend(ctx->cso_context);
-      cso_restore_fragment_shader(ctx->cso_context);
-
-      dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
-      dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
-      dsa->depth.func = PIPE_FUNC_GEQUAL;
+   struct pipe_resource templ;
+
+   memset(&templ, 0, sizeof(templ));
+
+   if (format != PIPE_FORMAT_NONE) {
+      templ.format = format;
+   }
+   else {
+      templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+   }
+
+   templ.target = PIPE_TEXTURE_2D;
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
+   templ.array_size = 1;
+   templ.last_level = 0;
+
+   if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
+      templ.bind = PIPE_BIND_DEPTH_STENCIL;
+   } else {
+      templ.bind = (PIPE_BIND_DISPLAY_TARGET |
+                    PIPE_BIND_RENDER_TARGET |
+                    PIPE_BIND_SAMPLER_VIEW);
    }
+
+   return pipe->screen->resource_create(pipe->screen, &templ);
 }
 
-void vg_validate_state(struct vg_context *ctx)
+static struct pipe_sampler_view *
+create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
+                    VGint width, VGint height)
 {
-   vg_manager_validate_framebuffer(ctx);
+   struct pipe_resource *texture;
+   struct pipe_sampler_view view_templ;
+   struct pipe_sampler_view *view;
 
-   if ((ctx->state.dirty & BLEND_DIRTY)) {
-      struct pipe_blend_state *blend = &ctx->state.g3d.blend;
-      memset(blend, 0, sizeof(struct pipe_blend_state));
-      blend->rt[0].blend_enable = 1;
-      blend->rt[0].colormask = PIPE_MASK_RGBA;
-
-      switch (ctx->state.vg.blend_mode) {
-      case VG_BLEND_SRC:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].blend_enable = 0;
-         break;
-      case VG_BLEND_SRC_OVER:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
-         break;
-      case VG_BLEND_DST_OVER:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_INV_DST_ALPHA;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_DST_ALPHA;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
-         break;
-      case VG_BLEND_SRC_IN:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_DST_ALPHA;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-         break;
-      case VG_BLEND_DST_IN:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
-         break;
-      case VG_BLEND_MULTIPLY:
-      case VG_BLEND_SCREEN:
-      case VG_BLEND_DARKEN:
-      case VG_BLEND_LIGHTEN:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-         blend->rt[0].blend_enable = 0;
-         break;
-      case VG_BLEND_ADDITIVE:
-         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ONE;
-         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
-         break;
-      default:
-         assert(!"not implemented blend mode");
-      }
-      cso_set_blend(ctx->cso_context, &ctx->state.g3d.blend);
-   }
-   if ((ctx->state.dirty & RASTERIZER_DIRTY)) {
-      struct pipe_rasterizer_state *raster = &ctx->state.g3d.rasterizer;
-      memset(raster, 0, sizeof(struct pipe_rasterizer_state));
-      raster->gl_rasterization_rules = 1;
-      cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer);
-   }
-   if ((ctx->state.dirty & VIEWPORT_DIRTY)) {
-      struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
-      const VGint param_bytes = 8 * sizeof(VGfloat);
-      VGfloat vs_consts[8] = {
-         2.f/fb->width, 2.f/fb->height, 1, 1,
-         -1, -1, 0, 0
-      };
-      struct pipe_resource **cbuf = &ctx->vs_const_buffer;
+   texture = create_texture(pipe, format, width, height);
 
-      vg_set_viewport(ctx, VEGA_Y0_BOTTOM);
+   if (!texture)
+      return NULL;
 
-      pipe_resource_reference(cbuf, NULL);
-      *cbuf = pipe_buffer_create(ctx->pipe->screen, 
-                                PIPE_BIND_CONSTANT_BUFFER,
-                                param_bytes);
-
-      if (*cbuf) {
-         st_no_flush_pipe_buffer_write(ctx, *cbuf,
-                                       0, param_bytes, vs_consts);
-      }
-      ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf);
+   u_sampler_view_default_template(&view_templ, texture, texture->format);
+   view = pipe->create_sampler_view(pipe, texture, &view_templ);
+   /* want the texture to go away if the view is freed */
+   pipe_resource_reference(&texture, NULL);
+
+   return view;
+}
+
+static void
+vg_context_update_surface_mask_view(struct vg_context *ctx,
+                                    uint width, uint height)
+{
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+   struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view;
+   struct pipe_context *pipe = ctx->pipe;
+
+   if (old_sampler_view &&
+       old_sampler_view->texture->width0 == width &&
+       old_sampler_view->texture->height0 == height)
+      return;
+
+   /*
+     we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
+     this texture and use it as a sampler, so while this wastes some
+     space it makes both of those a lot simpler
+   */
+   stfb->surface_mask_view = create_tex_and_view(pipe,
+         PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+
+   if (!stfb->surface_mask_view) {
+      if (old_sampler_view)
+         pipe_sampler_view_reference(&old_sampler_view, NULL);
+      return;
    }
-   if ((ctx->state.dirty & VS_DIRTY)) {
-      cso_set_vertex_shader_handle(ctx->cso_context,
-                                   vg_plain_vs(ctx));
+
+   /* XXX could this call be avoided? */
+   vg_validate_state(ctx);
+
+   /* alpha mask starts with 1.f alpha */
+   mask_fill(0, 0, width, height, 1.f);
+
+   /* if we had an old surface copy it over */
+   if (old_sampler_view) {
+      struct pipe_box src_box;
+      u_box_origin_2d(MIN2(old_sampler_view->texture->width0,
+                           stfb->surface_mask_view->texture->width0),
+                      MIN2(old_sampler_view->texture->height0,
+                           stfb->surface_mask_view->texture->height0),
+                      &src_box);
+
+      pipe->resource_copy_region(pipe,
+                                 stfb->surface_mask_view->texture,
+                                 0, 0, 0, 0,
+                                 old_sampler_view->texture,
+                                 0, &src_box);
    }
 
-   /* must be last because it renders to the depth buffer*/
-   if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) {
-      update_clip_state(ctx);
-      cso_set_depth_stencil_alpha(ctx->cso_context, &ctx->state.g3d.dsa);
+   /* Free the old texture
+    */
+   if (old_sampler_view)
+      pipe_sampler_view_reference(&old_sampler_view, NULL);
+}
+
+static void
+vg_context_update_blend_texture_view(struct vg_context *ctx,
+                                     uint width, uint height)
+{
+   struct pipe_context *pipe = ctx->pipe;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+   struct pipe_sampler_view *old = stfb->blend_texture_view;
+
+   if (old &&
+       old->texture->width0 == width &&
+       old->texture->height0 == height)
+      return;
+
+   stfb->blend_texture_view = create_tex_and_view(pipe,
+         PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+
+   pipe_sampler_view_reference(&old, NULL);
+}
+
+static boolean
+vg_context_update_depth_stencil_rb(struct vg_context * ctx,
+                                   uint width, uint height)
+{
+   struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_surface surf_tmpl;
+
+   if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
+      return FALSE;
+
+   /* unreference existing ones */
+   pipe_surface_reference(&dsrb->surface, NULL);
+   pipe_resource_reference(&dsrb->texture, NULL);
+   dsrb->width = dsrb->height = 0;
+
+   dsrb->texture = create_texture(pipe, dsrb->format, width, height);
+   if (!dsrb->texture)
+      return TRUE;
+
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, dsrb->texture,
+                              PIPE_BIND_DEPTH_STENCIL);
+   dsrb->surface = pipe->create_surface(pipe,
+                                        dsrb->texture,
+                                        &surf_tmpl);
+   if (!dsrb->surface) {
+      pipe_resource_reference(&dsrb->texture, NULL);
+      return TRUE;
    }
 
+   dsrb->width = width;
+   dsrb->height = height;
+
+   assert(dsrb->surface->width == width);
+   assert(dsrb->surface->height == height);
+
+   return TRUE;
+}
+
+void vg_validate_state(struct vg_context *ctx)
+{
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+
+   vg_manager_validate_framebuffer(ctx);
+
+   if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height))
+      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
+
+   /* blend state depends on fb format */
+   if (ctx->state.dirty & FRAMEBUFFER_DIRTY)
+      ctx->state.dirty |= BLEND_DIRTY;
+
+   renderer_validate(ctx->renderer, ctx->state.dirty,
+         ctx->draw_buffer, &ctx->state.vg);
+
+   ctx->state.dirty = 0;
+
    shader_set_masking(ctx->shader, ctx->state.vg.masking);
    shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode);
-
-   ctx->state.dirty = NONE_DIRTY;
+   shader_set_color_transform(ctx->shader, ctx->state.vg.color_transform);
 }
 
 VGboolean vg_object_is_valid(void *ptr, enum vg_object_type type)
@@ -470,130 +434,94 @@ void vg_set_error(struct vg_context *ctx,
       ctx->_error = code;
 }
 
-void vg_prepare_blend_surface(struct vg_context *ctx)
+static void vg_prepare_blend_texture(struct vg_context *ctx,
+                                     struct pipe_sampler_view *src)
+{
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+   struct pipe_surface *surf;
+   struct pipe_surface surf_tmpl;
+
+   vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
+
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, stfb->blend_texture_view->texture,
+                              PIPE_BIND_RENDER_TARGET);
+   surf = ctx->pipe->create_surface(ctx->pipe,
+                                    stfb->blend_texture_view->texture,
+                                    &surf_tmpl);
+   if (surf) {
+      util_blit_pixels_tex(ctx->blit,
+                           src, 0, 0, stfb->width, stfb->height,
+                           surf, 0, 0, stfb->width, stfb->height,
+                           0.0, PIPE_TEX_MIPFILTER_NEAREST);
+
+      pipe_surface_reference(&surf, NULL);
+   }
+}
+
+struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx)
 {
-   struct pipe_surface *dest_surface = NULL;
    struct pipe_context *pipe = ctx->pipe;
    struct pipe_sampler_view *view;
    struct pipe_sampler_view view_templ;
    struct st_framebuffer *stfb = ctx->draw_buffer;
    struct st_renderbuffer *strb = stfb->strb;
 
-   /* first finish all pending rendering */
-   vgFinish();
+   vg_validate_state(ctx);
 
    u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format);
    view = pipe->create_sampler_view(pipe, strb->texture, &view_templ);
 
-   dest_surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                stfb->blend_texture_view->texture,
-                                                0, 0, 0,
-                                                PIPE_BIND_RENDER_TARGET);
-   /* flip it, because we want to use it as a sampler */
-   util_blit_pixels_tex(ctx->blit,
-                        view,
-                        0, strb->height,
-                        strb->width, 0,
-                        dest_surface,
-                        0, 0,
-                        strb->width, strb->height,
-                        0.0, PIPE_TEX_MIPFILTER_NEAREST);
-
-   if (dest_surface)
-      pipe_surface_reference(&dest_surface, NULL);
-
-   /* make sure it's complete */
-   vgFinish();
+   vg_prepare_blend_texture(ctx, view);
 
    pipe_sampler_view_reference(&view, NULL);
+
+   return stfb->blend_texture_view;
 }
 
 
-void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
+struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
 {
-   struct pipe_surface *dest_surface = NULL;
-   struct pipe_context *pipe = ctx->pipe;
    struct st_framebuffer *stfb = ctx->draw_buffer;
-   struct st_renderbuffer *strb = stfb->strb;
 
    vg_validate_state(ctx);
 
-   /* first finish all pending rendering */
-   vgFinish();
-
-   dest_surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                stfb->blend_texture_view->texture,
-                                                0, 0, 0,
-                                                PIPE_BIND_RENDER_TARGET);
-
-   /* flip it, because we want to use it as a sampler */
-   util_blit_pixels_tex(ctx->blit,
-                        stfb->alpha_mask_view,
-                        0, strb->height,
-                        strb->width, 0,
-                        dest_surface,
-                        0, 0,
-                        strb->width, strb->height,
-                        0.0, PIPE_TEX_MIPFILTER_NEAREST);
-
-   /* make sure it's complete */
-   vgFinish();
-
-   if (dest_surface)
-      pipe_surface_reference(&dest_surface, NULL);
+   vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
+   vg_prepare_blend_texture(ctx, stfb->surface_mask_view);
+
+   return stfb->blend_texture_view;
 }
 
-void * vg_plain_vs(struct vg_context *ctx)
+struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx)
 {
-   if (!ctx->plain_vs) {
-      ctx->plain_vs = shader_create_from_text(ctx->pipe,
-                                              vs_plain_asm,
-                                              200,
-                                              PIPE_SHADER_VERTEX);
-   }
+   struct st_framebuffer *stfb = ctx->draw_buffer;
 
-   return ctx->plain_vs->driver;
-}
+   vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
 
+   return stfb->surface_mask_view;
+}
 
-void * vg_clear_vs(struct vg_context *ctx)
+/**
+ * A transformation from window coordinates to paint coordinates.
+ */
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+                              const struct matrix *paint_to_user,
+                              const struct matrix *user_to_surface,
+                              struct matrix *mat)
 {
-   if (!ctx->clear_vs) {
-      ctx->clear_vs = shader_create_from_text(ctx->pipe,
-                                              vs_clear_asm,
-                                              200,
-                                              PIPE_SHADER_VERTEX);
-   }
+   struct matrix tmp;
 
-   return ctx->clear_vs->driver;
-}
+   /* get user-to-paint matrix */
+   memcpy(mat, paint_to_user, sizeof(*paint_to_user));
+   if (!matrix_invert(mat))
+      return VG_FALSE;
 
-void * vg_texture_vs(struct vg_context *ctx)
-{
-   if (!ctx->texture_vs) {
-      ctx->texture_vs = shader_create_from_text(ctx->pipe,
-                                                vs_texture_asm,
-                                                200,
-                                                PIPE_SHADER_VERTEX);
-   }
+   /* get surface-to-user matrix */
+   memcpy(&tmp, user_to_surface, sizeof(*user_to_surface));
+   if (!matrix_invert(&tmp))
+      return VG_FALSE;
 
-   return ctx->texture_vs->driver;
-}
+   matrix_mult(mat, &tmp);
 
-void vg_set_viewport(struct vg_context *ctx, VegaOrientation orientation)
-{
-   struct pipe_viewport_state viewport;
-   struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
-   VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f;
-
-   viewport.scale[0] =  fb->width / 2.f;
-   viewport.scale[1] =  fb->height / y_scale;
-   viewport.scale[2] =  1.0;
-   viewport.scale[3] =  1.0;
-   viewport.translate[0] = fb->width / 2.f;
-   viewport.translate[1] = fb->height / 2.f;
-   viewport.translate[2] = 0.0;
-   viewport.translate[3] = 0.0;
-
-   cso_set_viewport(ctx->cso_context, &viewport);
+   return VG_TRUE;
 }
index 80a6c07c693eb28c5667f4071325bcfd367c5f4d..d616a20a3d9aa532c9108e3161e130132bb6749e 100644 (file)
@@ -56,7 +56,7 @@ struct st_framebuffer {
    struct st_renderbuffer *strb;
    struct st_renderbuffer *dsrb;
 
-   struct pipe_sampler_view *alpha_mask_view;
+   struct pipe_sampler_view *surface_mask_view;
 
    struct pipe_sampler_view *blend_texture_view;
 
@@ -78,14 +78,13 @@ enum vg_object_type {
    VG_OBJECT_LAST
 };
 enum dirty_state {
-   NONE_DIRTY          = 0<<0,
-   BLEND_DIRTY         = 1<<1,
-   RASTERIZER_DIRTY    = 1<<2,
-   VIEWPORT_DIRTY      = 1<<3,
-   VS_DIRTY            = 1<<4,
-   DEPTH_STENCIL_DIRTY = 1<<5,
-   ALL_DIRTY           = BLEND_DIRTY | RASTERIZER_DIRTY |
-   VIEWPORT_DIRTY | VS_DIRTY | DEPTH_STENCIL_DIRTY
+   BLEND_DIRTY         = 1 << 0,
+   FRAMEBUFFER_DIRTY   = 1 << 1,
+   DEPTH_STENCIL_DIRTY = 1 << 2,
+
+   ALL_DIRTY           = BLEND_DIRTY |
+                         FRAMEBUFFER_DIRTY |
+                         DEPTH_STENCIL_DIRTY
 };
 
 struct vg_context
@@ -98,13 +97,6 @@ struct vg_context
 
    struct {
       struct vg_state vg;
-      struct {
-         struct pipe_blend_state blend;
-         struct pipe_rasterizer_state rasterizer;
-         struct pipe_shader_state vs_state;
-         struct pipe_depth_stencil_alpha_state dsa;
-         struct pipe_framebuffer_state fb;
-      } g3d;
       VGbitfield dirty;
    } state;
 
@@ -115,14 +107,6 @@ struct vg_context
 
    struct cso_hash *owned_objects[VG_OBJECT_LAST];
 
-   struct {
-      struct pipe_shader_state vert_shader;
-      struct pipe_shader_state frag_shader;
-      struct pipe_rasterizer_state raster;
-      void *fs;
-      float vertices[4][2][4];  /**< vertex pos + color */
-   } clear;
-
    struct {
       struct pipe_resource *cbuf;
       struct pipe_sampler_state sampler;
@@ -133,31 +117,16 @@ struct vg_context
       struct vg_shader *set_fs;
    } mask;
 
-   struct vg_shader *pass_through_depth_fs;
-
    struct cso_context *cso_context;
 
-   struct pipe_resource *stencil_quad;
-   VGfloat stencil_vertices[4][2][4];
-
    struct renderer *renderer;
    struct shaders_cache *sc;
    struct shader *shader;
 
    struct pipe_sampler_state blend_sampler;
-   struct {
-      struct pipe_resource *buffer;
-      void *color_matrix_fs;
-   } filter;
    struct vg_paint *default_paint;
 
    struct blit_state *blit;
-
-   struct vg_shader *plain_vs;
-   struct vg_shader *clear_vs;
-   struct vg_shader *texture_vs;
-   struct pipe_resource *vs_const_buffer;
-   struct pipe_vertex_element velems[2];
 };
 
 struct vg_object {
@@ -189,9 +158,15 @@ void vg_validate_state(struct vg_context *ctx);
 void vg_set_error(struct vg_context *ctx,
                   VGErrorCode code);
 
-void vg_prepare_blend_surface(struct vg_context *ctx);
-void vg_prepare_blend_surface_from_mask(struct vg_context *ctx);
+struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx);
+struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx);
 
+struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx);
+
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+                              const struct matrix *paint_to_user,
+                              const struct matrix *user_to_surface,
+                              struct matrix *mat);
 
 static INLINE VGboolean is_aligned_to(const void *ptr, VGbyte alignment)
 {
@@ -292,13 +267,4 @@ static INLINE void vg_bound_rect(VGfloat coords[4],
    }
 }
 
-void *vg_plain_vs(struct vg_context *ctx);
-void *vg_clear_vs(struct vg_context *ctx);
-void *vg_texture_vs(struct vg_context *ctx);
-typedef enum {
-   VEGA_Y0_TOP,
-   VEGA_Y0_BOTTOM
-} VegaOrientation;
-void vg_set_viewport(struct vg_context *ctx, VegaOrientation orientation);
-
 #endif
index bb15ec024f2e495de77636f14e3e064d105e36ba..de935768b22cfb8111ab970788d2ddcf58b208af 100644 (file)
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
-#include "util/u_format.h"
 #include "util/u_sampler.h"
+#include "util/u_box.h"
+#include "util/u_surface.h"
 
 #include "vg_api.h"
 #include "vg_manager.h"
 #include "vg_context.h"
 #include "image.h"
-#include "mask.h"
 #include "api.h"
 
-static struct pipe_resource *
-create_texture(struct pipe_context *pipe, enum pipe_format format,
-                    VGint width, VGint height)
-{
-   struct pipe_resource templ;
-
-   memset(&templ, 0, sizeof(templ));
-
-   if (format != PIPE_FORMAT_NONE) {
-      templ.format = format;
-   }
-   else {
-      templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
-   }
-
-   templ.target = PIPE_TEXTURE_2D;
-   templ.width0 = width;
-   templ.height0 = height;
-   templ.depth0 = 1;
-   templ.last_level = 0;
-
-   if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
-      templ.bind = PIPE_BIND_DEPTH_STENCIL;
-   } else {
-      templ.bind = (PIPE_BIND_DISPLAY_TARGET |
-                    PIPE_BIND_RENDER_TARGET |
-                    PIPE_BIND_SAMPLER_VIEW);
-   }
-
-   return pipe->screen->resource_create(pipe->screen, &templ);
-}
-
-static struct pipe_sampler_view *
-create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
-                    VGint width, VGint height)
-{
-   struct pipe_resource *texture;
-   struct pipe_sampler_view view_templ;
-   struct pipe_sampler_view *view;
-
-   texture = create_texture(pipe, format, width, height);
-
-   if (!texture)
-      return NULL;
-
-   u_sampler_view_default_template(&view_templ, texture, texture->format);
-   view = pipe->create_sampler_view(pipe, texture, &view_templ);
-   /* want the texture to go away if the view is freed */
-   pipe_resource_reference(&texture, NULL);
-
-   return view;
-}
-
-static void
-setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb)
-{
-   struct pipe_context *pipe = ctx->pipe;
-   struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
-
-   /*
-     we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
-     this texture and use it as a sampler, so while this wastes some
-     space it makes both of those a lot simpler
-   */
-   stfb->alpha_mask_view = create_tex_and_view(pipe,
-         PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height);
-
-   if (!stfb->alpha_mask_view) {
-      if (old_sampler_view)
-         pipe_sampler_view_reference(&old_sampler_view, NULL);
-      return;
-   }
-
-   /* XXX could this call be avoided? */
-   vg_validate_state(ctx);
-
-   /* alpha mask starts with 1.f alpha */
-   mask_fill(0, 0, stfb->width, stfb->height, 1.f);
-
-   /* if we had an old surface copy it over */
-   if (old_sampler_view) {
-      struct pipe_subresource subsurf, subold_surf;
-      subsurf.face = 0;
-      subsurf.level = 0;
-      subold_surf.face = 0;
-      subold_surf.level = 0;
-      pipe->resource_copy_region(pipe,
-                                 stfb->alpha_mask_view->texture,
-                                 subsurf,
-                                 0, 0, 0,
-                                 old_sampler_view->texture,
-                                 subold_surf,
-                                 0, 0, 0,
-                                 MIN2(old_sampler_view->texture->width0,
-                                      stfb->alpha_mask_view->texture->width0),
-                                 MIN2(old_sampler_view->texture->height0,
-                                      stfb->alpha_mask_view->texture->height0));
-   }
-
-   /* Free the old texture
-    */
-   if (old_sampler_view)
-      pipe_sampler_view_reference(&old_sampler_view, NULL);
-}
-
-static boolean
-vg_context_update_depth_stencil_rb(struct vg_context * ctx,
-                                   uint width, uint height)
-{
-   struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
-   struct pipe_context *pipe = ctx->pipe;
-   unsigned surface_usage;
-
-   if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
-      return FALSE;
-
-   /* unreference existing ones */
-   pipe_surface_reference(&dsrb->surface, NULL);
-   pipe_resource_reference(&dsrb->texture, NULL);
-   dsrb->width = dsrb->height = 0;
-
-   /* Probably need dedicated flags for surface usage too:
-    */
-   surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */
-
-   dsrb->texture = create_texture(pipe, dsrb->format, width, height);
-   if (!dsrb->texture)
-      return TRUE;
-
-   dsrb->surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                 dsrb->texture,
-                                                 0, 0, 0,
-                                                 surface_usage);
-   if (!dsrb->surface) {
-      pipe_resource_reference(&dsrb->texture, NULL);
-      return TRUE;
-   }
-
-   dsrb->width = width;
-   dsrb->height = height;
-
-   assert(dsrb->surface->width == width);
-   assert(dsrb->surface->height == height);
-
-   return TRUE;
-}
-
 static boolean
 vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
 {
    struct st_renderbuffer *strb = ctx->draw_buffer->strb;
-   struct pipe_screen *screen = ctx->pipe->screen;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_surface surf_tmpl;
 
    if (strb->texture == pt) {
       pipe_resource_reference(&pt, NULL);
@@ -207,8 +61,12 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
    strb->width = strb->height = 0;
 
    strb->texture = pt;
-   strb->surface = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
-                                           PIPE_BIND_RENDER_TARGET);
+
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, strb->texture,
+                              PIPE_BIND_RENDER_TARGET);
+   strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
+
    if (!strb->surface) {
       pipe_resource_reference(&strb->texture, NULL);
       return TRUE;
@@ -220,49 +78,6 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
    return TRUE;
 }
 
-static void
-vg_context_update_draw_buffer(struct vg_context *ctx, struct pipe_resource *pt)
-{
-   struct st_framebuffer *stfb = ctx->draw_buffer;
-   boolean new_cbuf, new_zsbuf, new_size;
-
-   new_cbuf = vg_context_update_color_rb(ctx, pt);
-   new_zsbuf =
-      vg_context_update_depth_stencil_rb(ctx, pt->width0, pt->height0);
-
-   new_size = (stfb->width != pt->width0 || stfb->height != pt->height0);
-   stfb->width = pt->width0;
-   stfb->height = pt->height0;
-
-   if (new_cbuf || new_zsbuf || new_size) {
-      struct pipe_framebuffer_state *state = &ctx->state.g3d.fb;
-
-      memset(state, 0, sizeof(struct pipe_framebuffer_state));
-      state->width  = stfb->width;
-      state->height = stfb->height;
-      state->nr_cbufs = 1;
-      state->cbufs[0] = stfb->strb->surface;
-      state->zsbuf = stfb->dsrb->surface;
-
-      cso_set_framebuffer(ctx->cso_context, state);
-   }
-
-   if (new_zsbuf || new_size) {
-      ctx->state.dirty |= VIEWPORT_DIRTY;
-      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;/*to reset the scissors*/
-
-      ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
-
-      /* we need all the other state already set */
-
-      setup_new_alpha_mask(ctx, stfb);
-
-      pipe_sampler_view_reference( &stfb->blend_texture_view, NULL);
-      stfb->blend_texture_view = create_tex_and_view(ctx->pipe,
-            PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height);
-   }
-}
-
 /**
  * Flush the front buffer if the current context renders to the front buffer.
  */
@@ -304,15 +119,16 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
    if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
       return;
 
-   /*
-    * unset draw_buffer_invalid first because vg_context_update_draw_buffer
-    * will cause the framebuffer to be validated again because of a call to
-    * vg_validate_state
-    */
    p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
-   vg_context_update_draw_buffer(ctx, pt);
-}
 
+   if (vg_context_update_color_rb(ctx, pt) ||
+       stfb->width != pt->width0 ||
+       stfb->height != pt->height0)
+      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
+
+   stfb->width = pt->width0;
+   stfb->height = pt->height0;
+}
 
 static void
 vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
@@ -336,7 +152,10 @@ static void
 vg_context_destroy(struct st_context_iface *stctxi)
 {
    struct vg_context *ctx = (struct vg_context *) stctxi;
+   struct pipe_context *pipe = ctx->pipe;
+
    vg_destroy_context(ctx);
+   pipe->destroy(pipe);
 }
 
 static struct st_context_iface *
index ec55f042f909f5a02a55bc0e02b60af27906e23e..1b7597de44056d3ae8b4253468ccafe457e24506 100644 (file)
@@ -13,7 +13,6 @@ env.Append(CPPPATH = [
 env.AppendUnique(CPPDEFINES = [
     '_GDI32_', # prevent wgl* being declared __declspec(dllimport)
     'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers 
-    'WIN32_THREADS', # use Win32 thread API
     'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx
 ])
 
@@ -22,6 +21,7 @@ sources = [
     'stw_device.c',
     'stw_ext_extensionsstring.c',
     'stw_ext_gallium.c',
+    'stw_ext_pbuffer.c',
     'stw_ext_pixelformat.c',
     'stw_ext_swapinterval.c',
     'stw_framebuffer.c',
index 86c0a28e8da75122cfa59aa62d279872e8f02ce6..cd4f3c8b3e28a8ba4a701b65c770aadd32a7e6e1 100644 (file)
@@ -264,75 +264,82 @@ stw_make_current(
    struct stw_context *curctx = NULL;
    struct stw_context *ctx = NULL;
    struct stw_framebuffer *fb = NULL;
+   BOOL ret = FALSE;
 
    if (!stw_dev)
-      goto fail;
+      return FALSE;
 
    curctx = stw_current_context();
    if (curctx != NULL) {
-      if (curctx->dhglrc != dhglrc)
+      if (curctx->dhglrc == dhglrc) {
+         if (curctx->hdc == hdc) {
+            /* Return if already current. */
+            return TRUE;
+         }
+      } else {
          curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-      
-      /* Return if already current. */
-      if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
-         ctx = curctx;
-         fb = stw_framebuffer_from_hdc( hdc );
-         goto success;
       }
-
-      stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
    }
 
-   if (hdc == NULL || dhglrc == 0) {
-      return stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
-   }
-
-   pipe_mutex_lock( stw_dev->ctx_mutex ); 
-   ctx = stw_lookup_context_locked( dhglrc );
-   pipe_mutex_unlock( stw_dev->ctx_mutex ); 
-   if(!ctx)
-      goto fail;
-
-   fb = stw_framebuffer_from_hdc( hdc );
-   if (fb) {
-      stw_framebuffer_update(fb);
-   }
-   else {
-      /* Applications should call SetPixelFormat before creating a context,
-       * but not all do, and the opengl32 runtime seems to use a default pixel
-       * format in some cases, so we must create a framebuffer for those here
-       */
-      int iPixelFormat = GetPixelFormat(hdc);
-      if(iPixelFormat)
-         fb = stw_framebuffer_create( hdc, iPixelFormat );
-      if(!fb) 
+   if (dhglrc) {
+      pipe_mutex_lock( stw_dev->ctx_mutex );
+      ctx = stw_lookup_context_locked( dhglrc );
+      pipe_mutex_unlock( stw_dev->ctx_mutex );
+      if (!ctx) {
          goto fail;
-   }
-   
-   if(fb->iPixelFormat != ctx->iPixelFormat)
-      goto fail;
+      }
 
-   /* Bind the new framebuffer */
-   ctx->hdc = hdc;
+      fb = stw_framebuffer_from_hdc( hdc );
+      if (fb) {
+         stw_framebuffer_update(fb);
+      }
+      else {
+         /* Applications should call SetPixelFormat before creating a context,
+          * but not all do, and the opengl32 runtime seems to use a default pixel
+          * format in some cases, so we must create a framebuffer for those here
+          */
+         int iPixelFormat = GetPixelFormat(hdc);
+         if (iPixelFormat)
+            fb = stw_framebuffer_create( hdc, iPixelFormat );
+         if (!fb)
+            goto fail;
+      }
    
-   if (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb))
-      goto fail;
+      if (fb->iPixelFormat != ctx->iPixelFormat) {
+         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+         goto fail;
+      }
 
-   stw_framebuffer_reference(&ctx->current_framebuffer, fb);
+      /* Bind the new framebuffer */
+      ctx->hdc = hdc;
 
-success:
-   assert(fb);
-   if(fb) {
-      stw_framebuffer_release(fb);
+      ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb);
+      stw_framebuffer_reference(&ctx->current_framebuffer, fb);
+   } else {
+      ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    }
    
-   return TRUE;
-
 fail:
-   if(fb)
+
+   if (fb) {
       stw_framebuffer_release(fb);
-   stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
-   return FALSE;
+   }
+
+   /* On failure, make the thread's current rendering context not current
+    * before returning */
+   if (!ret) {
+      stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
+      ctx = NULL;
+   }
+
+   /* Unreference the previous framebuffer if any. It must be done after
+    * make_current, as it can be referenced inside.
+    */
+   if (curctx && curctx != ctx) {
+      stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
+   }
+
+   return ret;
 }
 
 /**
index 37809d084ce4c4ee4c826416c26b1aecdde58b0c..c4822d4d8aa9943919abebc277cd79c27d9b5880 100644 (file)
@@ -41,9 +41,7 @@
 #include "stw_framebuffer.h"
 #include "stw_st.h"
 
-#ifdef WIN32_THREADS
 extern _glthread_Mutex OneTimeLock;
-#endif
 
 
 struct stw_device *stw_dev = NULL;
@@ -76,9 +74,7 @@ stw_init(const struct stw_winsys *stw_winsys)
    
    stw_dev->stw_winsys = stw_winsys;
 
-#ifdef WIN32_THREADS
    _glthread_INIT_MUTEX(OneTimeLock);
-#endif
 
    stw_dev->stapi = stw_st_create_api();
    stw_dev->smapi = CALLOC_STRUCT(st_manager);
@@ -96,6 +92,10 @@ stw_init(const struct stw_winsys *stw_winsys)
    stw_dev->smapi->get_param = stw_get_param;
    stw_dev->screen = screen;
 
+   stw_dev->max_2d_levels =
+         screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+   stw_dev->max_2d_length = 1 << (stw_dev->max_2d_levels - 1);
+
    pipe_mutex_init( stw_dev->ctx_mutex );
    pipe_mutex_init( stw_dev->fb_mutex );
 
@@ -168,11 +168,9 @@ stw_cleanup(void)
 
    stw_dev->screen->destroy(stw_dev->screen);
 
-#ifdef WIN32_THREADS
    _glthread_DESTROY_MUTEX(OneTimeLock);
 
    _glapi_destroy_multithread();
-#endif
 
 #ifdef DEBUG
    debug_memory_end(stw_dev->memdbg_no);
index 1b836960d0d48c0e997eba775faa608147f8f9e1..3c2b6d9c076d3ff8cdefe81613ef4c400a2d7ee0 100644 (file)
@@ -50,6 +50,10 @@ struct stw_device
    
    struct pipe_screen *screen;
    
+   /* Cache some PIPE_CAP_* */
+   unsigned max_2d_levels;
+   unsigned max_2d_length;
+
    struct st_api *stapi;
    struct st_manager *smapi;
 
index 62c859e1f92cc0601d707e66b0d6086686ec8788..ecb326f1cf6c9dcb6ef6660ba0a909cebb1184bf 100644 (file)
@@ -37,6 +37,7 @@
 static const char *stw_extension_string = 
    "WGL_ARB_extensions_string "
    "WGL_ARB_multisample "
+   "WGL_ARB_pbuffer "
    "WGL_ARB_pixel_format "
 /*   "WGL_EXT_swap_interval " */
    "WGL_EXT_extensions_string";
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
new file mode 100644 (file)
index 0000000..32636c6
--- /dev/null
@@ -0,0 +1,212 @@
+/**************************************************************************
+ * 
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include <windows.h>
+
+#define WGL_WGLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
+#include "stw_device.h"
+#include "stw_pixelformat.h"
+#include "stw_framebuffer.h"
+
+
+HPBUFFERARB WINAPI
+wglCreatePbufferARB(HDC _hDC,
+                    int iPixelFormat,
+                    int iWidth,
+                    int iHeight,
+                    const int *piAttribList)
+{
+   static boolean first = TRUE;
+   const int *piAttrib;
+   int useLargest = 0;
+   const struct stw_pixelformat_info *info;
+   struct stw_framebuffer *fb;
+   HWND hWnd;
+   HDC hDC;
+
+   info = stw_pixelformat_get_info(iPixelFormat);
+   if (!info) {
+      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+      return 0;
+   }
+
+   if (iWidth <= 0 || iHeight <= 0) {
+      SetLastError(ERROR_INVALID_DATA);
+      return 0;
+   }
+
+   for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
+      switch (*piAttrib) {
+      case WGL_PBUFFER_LARGEST_ARB:
+         piAttrib++;
+         useLargest = *piAttrib;
+         break;
+      default:
+         SetLastError(ERROR_INVALID_DATA);
+         return 0;
+      }
+   }
+
+   if (iWidth > stw_dev->max_2d_length) {
+      if (useLargest) {
+         iWidth = stw_dev->max_2d_length;
+      } else {
+         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+         return 0;
+      }
+   }
+
+   if (iHeight > stw_dev->max_2d_length) {
+      if (useLargest) {
+         iHeight = stw_dev->max_2d_length;
+      } else {
+         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+         return 0;
+      }
+   }
+
+   /*
+    * Implement pbuffers through invisible windows
+    */
+
+   if (first) {
+      WNDCLASS wc;
+      memset(&wc, 0, sizeof wc);
+      wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
+      wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+      wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+      wc.lpfnWndProc = DefWindowProc;
+      wc.lpszClassName = "wglpbuffer";
+      wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+      RegisterClass(&wc);
+      first = FALSE;
+   }
+
+   hWnd = CreateWindowEx(0,
+                         "wglpbuffer", /* wc.lpszClassName */
+                         "wglpbuffer",
+#if 0 /* Useful for debugging what the application is drawing */
+                         WS_VISIBLE |
+#endif
+                         WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+                         CW_USEDEFAULT, CW_USEDEFAULT, /* x, y */
+                         iWidth, iHeight,
+                         NULL,
+                         NULL,
+                         NULL,
+                         NULL);
+   if (!hWnd) {
+      return 0;
+   }
+
+   hDC = GetDC(hWnd);
+   if (!hDC) {
+      return 0;
+   }
+
+   SetPixelFormat(hDC, iPixelFormat, &info->pfd);
+
+   fb = stw_framebuffer_create(hDC, iPixelFormat);
+   if (!fb) {
+      SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+   }
+
+   return (HPBUFFERARB)fb;
+}
+
+
+HDC WINAPI
+wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
+{
+   struct stw_framebuffer *fb;
+   HDC hDC;
+
+   fb = (struct stw_framebuffer *)hPbuffer;
+
+   hDC = GetDC(fb->hWnd);
+   SetPixelFormat(hDC, fb->iPixelFormat, &fb->pfi->pfd);
+
+   return hDC;
+}
+
+
+int WINAPI
+wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
+                       HDC hDC)
+{
+   struct stw_framebuffer *fb;
+
+   fb = (struct stw_framebuffer *)hPbuffer;
+
+   return ReleaseDC(fb->hWnd, hDC);
+}
+
+
+BOOL WINAPI
+wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
+{
+   struct stw_framebuffer *fb;
+
+   fb = (struct stw_framebuffer *)hPbuffer;
+
+   /* This will destroy all our data */
+   return DestroyWindow(fb->hWnd);
+}
+
+
+BOOL WINAPI
+wglQueryPbufferARB(HPBUFFERARB hPbuffer,
+                   int iAttribute,
+                   int *piValue)
+{
+   struct stw_framebuffer *fb;
+
+   fb = (struct stw_framebuffer *)hPbuffer;
+
+   switch (iAttribute) {
+   case WGL_PBUFFER_WIDTH_ARB:
+      *piValue = fb->width;
+      return TRUE;
+   case WGL_PBUFFER_HEIGHT_ARB:
+      *piValue = fb->width;
+      return TRUE;
+   case WGL_PBUFFER_LOST_ARB:
+      /* We assume that no content is ever lost due to display mode change */
+      *piValue = FALSE;
+      return TRUE;
+   default:
+      SetLastError(ERROR_INVALID_DATA);
+      return FALSE;
+   }
+}
index ab56800e28ddb3243e70ae580d1d3185ca2ac6ea..d0a95863bb412969cf5b8249f21509f9ad82f0c9 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "pipe/p_compiler.h"
 #include "util/u_memory.h"
+#include "stw_device.h"
 #include "stw_pixelformat.h"
 
 
@@ -234,6 +235,23 @@ stw_query_attrib(
       *pvalue = pfi->stvis.samples;
       break;
 
+
+   /* WGL_ARB_pbuffer */
+
+   case WGL_MAX_PBUFFER_WIDTH_ARB:
+   case WGL_MAX_PBUFFER_HEIGHT_ARB:
+      *pvalue = stw_dev->max_2d_length;
+      break;
+
+   case WGL_MAX_PBUFFER_PIXELS_ARB:
+      *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
+      break;
+
+   case WGL_DRAW_TO_PBUFFER_ARB:
+      *pvalue = 1;
+      break;
+
+
    default:
       return FALSE;
    }
index 259b22f22c73a1a13ab435fd31cd45428ede5f12..733222aa21c828662b7b2058119f08bd578de241 100644 (file)
@@ -469,7 +469,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
 {
    struct stw_framebuffer *fb;
    struct pipe_screen *screen;
-   struct pipe_surface *surface;
+   struct pipe_resource *res;
 
    if (!stw_dev)
       return FALSE;
@@ -480,7 +480,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
 
    screen = stw_dev->screen;
 
-   surface = (struct pipe_surface *)data->pPrivateData;
+   res = (struct pipe_resource *)data->pPrivateData;
 
    if(data->hSharedSurface != fb->hSharedSurface) {
       if(fb->shared_surface) {
@@ -498,13 +498,13 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
 
    if(fb->shared_surface) {
       stw_dev->stw_winsys->compose(screen,
-                                   surface,
+                                   res,
                                    fb->shared_surface,
                                    &fb->client_rect,
                                    data->PresentHistoryToken);
    }
    else {
-      stw_dev->stw_winsys->present( screen, surface, hdc );
+      stw_dev->stw_winsys->present( screen, res, hdc );
    }
 
    stw_framebuffer_update(fb);
@@ -524,7 +524,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
 BOOL
 stw_framebuffer_present_locked(HDC hdc,
                                struct stw_framebuffer *fb,
-                               struct pipe_surface *surface)
+                               struct pipe_resource *res)
 {
    if(stw_dev->callbacks.wglCbPresentBuffers &&
       stw_dev->stw_winsys->compose) {
@@ -535,7 +535,7 @@ stw_framebuffer_present_locked(HDC hdc,
       data.magic2 = 0;
       data.AdapterLuid = stw_dev->AdapterLuid;
       data.rect = fb->client_rect;
-      data.pPrivateData = (void *)surface;
+      data.pPrivateData = (void *)res;
 
       stw_notify_current_locked(fb);
       stw_framebuffer_release(fb);
@@ -545,7 +545,7 @@ stw_framebuffer_present_locked(HDC hdc,
    else {
       struct pipe_screen *screen = stw_dev->screen;
 
-      stw_dev->stw_winsys->present( screen, surface, hdc );
+      stw_dev->stw_winsys->present( screen, res, hdc );
 
       stw_framebuffer_update(fb);
       stw_notify_current_locked(fb);
index 89d12300e67c2386410072ae292274244bc95577..6604e545cbc67a34865606b2d0b80846e236a574 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "os/os_thread.h"
 
-struct pipe_surface;
+struct pipe_resource;
 struct st_framebuffer_iface;
 struct stw_pixelformat_info;
 
@@ -143,7 +143,7 @@ stw_framebuffer_from_hdc(
 BOOL
 stw_framebuffer_present_locked(HDC hdc,
                                struct stw_framebuffer *fb,
-                               struct pipe_surface *surface);
+                               struct pipe_resource *res);
 
 void
 stw_framebuffer_update(
index d43a55fa9e603ed45859eab9dc5943a0bb88a05c..b0aef943d30b03e5fd39d6facd57ed58ea8f60e4 100644 (file)
@@ -50,6 +50,13 @@ static const struct stw_extension_entry stw_extension_entries[] = {
    /* WGL_ARB_extensions_string */
    STW_EXTENSION_ENTRY( wglGetExtensionsStringARB ),
 
+   /* WGL_ARB_pbuffer */
+   STW_EXTENSION_ENTRY( wglCreatePbufferARB ),
+   STW_EXTENSION_ENTRY( wglGetPbufferDCARB ),
+   STW_EXTENSION_ENTRY( wglReleasePbufferDCARB ),
+   STW_EXTENSION_ENTRY( wglDestroyPbufferARB ),
+   STW_EXTENSION_ENTRY( wglQueryPbufferARB ),
+
    /* WGL_ARB_pixel_format */
    STW_EXTENSION_ENTRY( wglChoosePixelFormatARB ),
    STW_EXTENSION_ENTRY( wglGetPixelFormatAttribfvARB ),
index 18ac48236965ad00de6f5cb7f3aea9dda44d2070..5ede1d43220f9a4287f0812c3677686c46bfe2c0 100644 (file)
@@ -185,7 +185,7 @@ stw_pixelformat_add(
     */
    pfi->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
    if (doublebuffer)
-      pfi->stvis.buffer_mask = ST_ATTACHMENT_BACK_LEFT_MASK;
+      pfi->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
 
    pfi->stvis.color_format = color->format;
    pfi->stvis.depth_stencil_format = depth->format;
index bcdd82e4f66e3f2934175deb214cfbfad995325b..b58d91673b7867dfe483e961cd2a1508122c8494 100644 (file)
@@ -43,8 +43,6 @@ struct stw_st_framebuffer {
    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
    unsigned texture_width, texture_height;
    unsigned texture_mask;
-
-   struct pipe_surface *front_surface, *back_surface;
 };
 
 static INLINE struct stw_st_framebuffer *
@@ -65,10 +63,6 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
    struct pipe_resource templ;
    unsigned i;
 
-   /* remove outdated surface */
-   pipe_surface_reference(&stwfb->front_surface, NULL);
-   pipe_surface_reference(&stwfb->back_surface, NULL);
-
    /* remove outdated textures */
    if (stwfb->texture_width != width || stwfb->texture_height != height) {
       for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
@@ -80,6 +74,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.last_level = 0;
 
    for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
@@ -155,45 +150,6 @@ stw_st_framebuffer_validate(struct st_framebuffer_iface *stfb,
    return TRUE;
 }
 
-static struct pipe_surface *
-get_present_surface_locked(struct st_framebuffer_iface *stfb,
-                           enum st_attachment_type statt)
-{
-   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
-   struct pipe_resource *ptex;
-   struct pipe_surface *psurf, **cache;
-   
-   ptex = stwfb->textures[statt];
-   if (!ptex)
-      return NULL;
-
-   psurf = NULL;
-
-   switch (statt) {
-   case ST_ATTACHMENT_FRONT_LEFT:
-      cache = &stwfb->front_surface;
-      break;
-   case ST_ATTACHMENT_BACK_LEFT:
-      cache = &stwfb->back_surface;
-      break;
-   default:
-      cache = &psurf;
-      break;
-   }
-
-   if (!*cache) {
-      *cache = stw_dev->screen->get_tex_surface(stw_dev->screen,
-            ptex, 0, 0, 0,
-            PIPE_BIND_DISPLAY_TARGET |
-            PIPE_BIND_RENDER_TARGET);
-   }
-
-   if (psurf != *cache)
-      pipe_surface_reference(&psurf, *cache);
-
-   return psurf;
-}
-
 /**
  * Present an attachment of the framebuffer.
  */
@@ -202,12 +158,11 @@ stw_st_framebuffer_present_locked(struct st_framebuffer_iface *stfb,
                                   enum st_attachment_type statt)
 {
    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
-   struct pipe_surface *psurf;
-   
-   psurf = get_present_surface_locked(&stwfb->base, statt);
-   if (psurf) {
-      stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, psurf);
-      pipe_surface_reference(&psurf, NULL);
+   struct pipe_resource *resource;
+
+   resource = stwfb->textures[statt];
+   if (resource) {
+      stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, resource);
    }
 
    return TRUE;
@@ -255,9 +210,6 @@ stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb)
    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
    int i;
 
-   pipe_surface_reference(&stwfb->front_surface, NULL);
-   pipe_surface_reference(&stwfb->back_surface, NULL);
-
    for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
       pipe_resource_reference(&stwfb->textures[i], NULL);
 
@@ -273,7 +225,6 @@ stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
    unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT;
    struct pipe_resource *ptex;
-   struct pipe_surface *psurf;
    unsigned mask;
 
    /* swap the textures */
@@ -281,11 +232,6 @@ stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
    stwfb->textures[front] = stwfb->textures[back];
    stwfb->textures[back] = ptex;
 
-   /* swap the surfaces */
-   psurf = stwfb->front_surface;
-   stwfb->front_surface = stwfb->back_surface;
-   stwfb->back_surface = psurf;
-
    /* convert to mask */
    front = 1 << front;
    back = 1 << back;
index 270fad56a19dd28fd5f87853815a630b60f35f5a..397065fc15905c447e8db84ebb063ea9fa69e2ae 100644 (file)
@@ -34,7 +34,7 @@
 
 struct pipe_screen;
 struct pipe_context;
-struct pipe_surface;
+struct pipe_resource;
 
 struct stw_shared_surface;
 
@@ -43,12 +43,13 @@ struct stw_winsys
    struct pipe_screen *
    (*create_screen)( void );
 
+   /* XXX is it actually possible to have non-zero level/layer ??? */
    /**
     * Present the color buffer to the window associated with the device context.
     */
    void
    (*present)( struct pipe_screen *screen,
-               struct pipe_surface *surf,
+               struct pipe_resource *res,
                HDC hDC );
 
    /**
@@ -85,7 +86,7 @@ struct stw_winsys
     */
    void
    (*compose)( struct pipe_screen *screen,
-               struct pipe_surface *src,
+               struct pipe_resource *res,
                struct stw_shared_surface *dest,
                LPCRECT pRect,
                ULONGLONG PresentHistoryToken );
index 4ff48026e50a73a79ada4b3492ea8262a6741772..d4dc84a122b1a6bfa16bef5cb2b2f45127addde9 100644 (file)
@@ -473,7 +473,7 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
                                   struct exa_pixmap_priv *pMask,
                                   struct exa_pixmap_priv *pDst)
 {
-   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
+   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst);
 
    renderer_bind_destination(exa->renderer, dst_surf,
                              pDst->width,
@@ -529,7 +529,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
                               struct exa_pixmap_priv *pixmap,
                               Pixel fg)
 {
-   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap);
+   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
    unsigned vs_traits, fs_traits;
    struct xorg_shader shader;
 
index 80af82d97b23eaf62ed24db23e9096492d774f6f..28e30e09ff3a6137f92ac18e1ccb68c4fd9fca19 100644 (file)
@@ -210,6 +210,7 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
        templat.target = PIPE_TEXTURE_2D;
        templat.last_level = 0;
        templat.depth0 = 1;
+       templat.array_size = 1;
        templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
        templat.width0 = 64;
        templat.height0 = 64;
@@ -225,9 +226,9 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
     }
 
     transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex,
-                                         0, 0, 0,
-                                         PIPE_TRANSFER_WRITE,
-                                         0, 0, 64, 64);
+                                 0, 0,
+                                 PIPE_TRANSFER_WRITE,
+                                 0, 0, 64, 64);
     ptr = ms->ctx->transfer_map(ms->ctx, transfer);
     util_copy_rect(ptr, crtcp->cursor_tex->format,
                   transfer->stride, 0, 0,
index b723a8e9cb0cdcc5d917b121f6e7ac89031dedea..17c34b7eac851c55af0a4ca37051b20b4d7f7d96 100644 (file)
@@ -129,6 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
            template.width0 = pDraw->width;
            template.height0 = pDraw->height;
            template.depth0 = 1;
+           template.array_size = 1;
            template.last_level = 0;
            template.bind = PIPE_BIND_DEPTH_STENCIL |
                PIPE_BIND_SHARED;
index 1ee79ae177e72bd9e73f6075ad63c3ebdad1039f..66685ecec646649313f617518c0bb9e8b7780899 100644 (file)
@@ -538,44 +538,37 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
     return TRUE;
 }
 
-static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
-                              pointer pReadmask)
+void xorg_flush(ScreenPtr pScreen)
 {
-    ScreenPtr pScreen = screenInfo.screens[i];
     modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
 
-    pScreen->BlockHandler = ms->blockHandler;
-    pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
-    pScreen->BlockHandler = drv_block_handler;
-
     if (ms->ctx) {
-       int j;
+       int j;
 
-       ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
-                     ms->dirtyThrottling ?
-                     &ms->fence[XORG_NR_FENCES-1] :
-                     NULL);
+       ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
+                      ms->dirtyThrottling ?
+                      &ms->fence[XORG_NR_FENCES-1] :
+                      NULL);
        
-       if (ms->dirtyThrottling) {
-          if (ms->fence[0])
-              ms->ctx->screen->fence_finish(ms->ctx->screen,
-                                            ms->fence[0], 0);
+       if (ms->dirtyThrottling) {
+           if (ms->fence[0])
+               ms->ctx->screen->fence_finish(ms->ctx->screen,
+                                             ms->fence[0], 0);
   
-          /* The amount of rendering generated by a block handler can be
-           * quite small.  Let us get a fair way ahead of hardware before
-           * throttling.
-           */
-          for (j = 0; j < XORG_NR_FENCES - 1; j++)
-              ms->screen->fence_reference(ms->screen,
-                                          &ms->fence[j],
-                                          ms->fence[j+1]);
-
-          ms->screen->fence_reference(ms->screen,
-                                      &ms->fence[XORG_NR_FENCES-1],
-                                      NULL);
-       }
+           /* The amount of rendering generated by a block handler can be
+            * quite small.  Let us get a fair way ahead of hardware before
+            * throttling.
+            */
+           for (j = 0; j < XORG_NR_FENCES - 1; j++)
+               ms->screen->fence_reference(ms->screen,
+                                           &ms->fence[j],
+                                           ms->fence[j+1]);
+
+           ms->screen->fence_reference(ms->screen,
+                                       &ms->fence[XORG_NR_FENCES-1],
+                                       NULL);
+       }
     }
-        
 
 #ifdef DRM_MODE_FEATURE_DIRTYFB
     {
@@ -608,6 +601,19 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
 #endif
 }
 
+static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
+                              pointer pReadmask)
+{
+    ScreenPtr pScreen = screenInfo.screens[i];
+    modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
+
+    pScreen->BlockHandler = ms->blockHandler;
+    pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+    pScreen->BlockHandler = drv_block_handler;
+
+    xorg_flush(pScreen);
+}
+
 static Bool
 drv_create_screen_resources(ScreenPtr pScreen)
 {
index 4b1c02bad42e323175185837ac1a4b573f08d7b9..718a3453939d3452f45e8dbff772e246359f6246 100644 (file)
@@ -46,6 +46,8 @@
 #include "util/u_math.h"
 #include "util/u_debug.h"
 #include "util/u_format.h"
+#include "util/u_box.h"
+#include "util/u_surface.h"
 
 #define DEBUG_PRINT 0
 #define ROUND_UP_TEXTURES 1
@@ -188,8 +190,8 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x,  int y, int w,  int h, char *dst,
     if (!priv || !priv->tex)
        return FALSE;
 
-    transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0, 0,
-                                          PIPE_TRANSFER_READ, x, y, w, h);
+    transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
+                                 PIPE_TRANSFER_READ, x, y, w, h);
     if (!transfer)
        return FALSE;
 
@@ -222,8 +224,8 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
     if (!priv || !priv->tex)
        return FALSE;
 
-    transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0, 0,
-                                          PIPE_TRANSFER_WRITE, x, y, w, h);
+    transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
+                                 PIPE_TRANSFER_WRITE, x, y, w, h);
     if (!transfer)
        return FALSE;
 
@@ -265,7 +267,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
         assert(pPix->drawable.height <= priv->tex->height0);
 
        priv->map_transfer =
-          pipe_get_transfer(exa->pipe, priv->tex, 0, 0, 0,
+          pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
 #ifdef EXA_MIXED_PIXMAPS
                                        PIPE_TRANSFER_MAP_DIRECTLY |
 #endif
@@ -449,6 +451,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
        exa->copy.use_surface_copy = TRUE;
     }
     else {
+       struct pipe_surface surf_tmpl;
        exa->copy.use_surface_copy = FALSE;
 
        if (exa->copy.dst == exa->copy.src)
@@ -458,11 +461,13 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
           pipe_resource_reference(&exa->copy.src_texture,
                                  exa->copy.src->tex);
 
+       memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+       u_surface_default_template(&surf_tmpl, exa->copy.dst->tex,
+                                  PIPE_BIND_RENDER_TARGET);
        exa->copy.dst_surface =
-          exa->scrn->get_tex_surface(exa->scrn,
-                                     exa->copy.dst->tex,
-                                     0, 0, 0,
-                                     PIPE_BIND_RENDER_TARGET);
+          exa->pipe->create_surface(exa->pipe,
+                                    exa->copy.dst->tex,
+                                    &surf_tmpl);
 
 
        renderer_copy_prepare(exa->renderer, 
@@ -492,19 +497,14 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
    (void) priv;
 
    if (exa->copy.use_surface_copy) {
-      struct pipe_subresource subdst, subsrc;
-      subdst.face = 0;
-      subdst.level = 0;
-      subsrc.face = 0;
-      subsrc.level = 0;
+      struct pipe_box src_box;
+      u_box_2d(srcX, srcY, width, height, &src_box);
       exa->pipe->resource_copy_region( exa->pipe,
                                        exa->copy.dst->tex,
-                                       subdst,
+                                       0,
                                        dstX, dstY, 0,
                                        exa->copy.src->tex,
-                                       subsrc,
-                                       srcX, srcY, 0,
-                                       width, height );
+                                       0, &src_box);
    }
    else {
       renderer_copy_pixmap(exa->renderer, 
@@ -874,24 +874,21 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
         }
 
        template.depth0 = 1;
+       template.array_size = 1;
        template.last_level = 0;
        template.bind = PIPE_BIND_RENDER_TARGET | priv->flags;
        priv->tex_flags = priv->flags;
        texture = exa->scrn->resource_create(exa->scrn, &template);
 
        if (priv->tex) {
-           struct pipe_subresource subdst, subsrc;
-
-           subdst.face = 0;
-           subdst.level = 0;
-           subsrc.face = 0;
-           subsrc.level = 0;
+            struct pipe_box src_box;
+            u_box_origin_2d(min(width, texture->width0),
+                            min(height, texture->height0),
+                            &src_box);
             exa->pipe->resource_copy_region(exa->pipe, texture,
-                                            subdst, 0, 0, 0,
+                                            0, 0, 0, 0,
                                             priv->tex,
-                                            subsrc, 0, 0, 0,
-                                            min(width, texture->width0),
-                                            min(height, texture->height0));
+                                            0, &src_box);
        }
 
        pipe_resource_reference(&priv->tex, texture);
@@ -947,6 +944,7 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
     template.width0 = width;
     template.height0 = height;
     template.depth0 = 1;
+    template.array_size = 1;
     template.last_level = 0;
     template.bind |= PIPE_BIND_RENDER_TARGET;
     template.bind |= PIPE_BIND_SCANOUT;
@@ -1063,10 +1061,14 @@ out_err:
 }
 
 struct pipe_surface *
-xorg_gpu_surface(struct pipe_screen *scrn, struct exa_pixmap_priv *priv)
+xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv)
 {
-   return scrn->get_tex_surface(scrn, priv->tex, 0, 0, 0,
-                                PIPE_BIND_RENDER_TARGET);
+   struct pipe_surface surf_tmpl;
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   u_surface_default_template(&surf_tmpl, priv->tex,
+                              PIPE_BIND_RENDER_TARGET);
+
+   return pipe->create_surface(pipe, priv->tex, &surf_tmpl);
 
 }
 
index 86a1afc06e660cac1750744899a77b69459e8d32..1f78f60be743f8f6237359d4e3d98715acd36603 100644 (file)
@@ -72,7 +72,7 @@ do {                                                          \
 } while(0)
 
 struct pipe_surface *
-xorg_gpu_surface(struct pipe_screen *scrn, struct exa_pixmap_priv *priv);
+xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv);
 
 void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
                     struct pipe_fence_handle **fence);
index 92f1cc50653bf0ffec05b934a2b8eb2349b1ca7d..a3d7c5a70e21d4af59dee3e7c705c5bd49f33d6a 100644 (file)
@@ -10,6 +10,7 @@
 #include "util/u_sampler.h"
 
 #include "util/u_inlines.h"
+#include "util/u_box.h"
 
 #include <math.h>
 
@@ -535,6 +536,7 @@ renderer_clone_texture(struct xorg_renderer *r,
    templ.width0 = src->width0;
    templ.height0 = src->height0;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.bind = PIPE_BIND_SAMPLER_VIEW;
 
    pt = screen->resource_create(screen, &templ);
@@ -546,19 +548,15 @@ renderer_clone_texture(struct xorg_renderer *r,
 
    {
       /* copy source framebuffer surface into texture */
-      struct pipe_subresource subsrc, subdst;
-      subsrc.face = 0;
-      subsrc.level = 0;
-      subdst.face = 0;
-      subdst.level = 0;
+      struct pipe_box src_box;
+      u_box_origin_2d(src->width0, src->height0, &src_box);
+
       pipe->resource_copy_region(pipe,
                                  pt, /* dest */
-                                 subdst,
+                                 0, /* dest_level */
                                  0, 0, 0, /* destx/y/z */
                                  src,
-                                 subsrc,
-                                 0, 0, 0,
-                                 src->width0, src->height0);
+                                 0, &src_box);
    }
 
    return pt;
index a3fb5e5dad0551402147dbc218fd55d84f91ac60..56397b8fea8c331652c77ec6bb9026fc5b8ccda6 100644 (file)
@@ -156,6 +156,7 @@ CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn);
 
 Bool xorg_has_gallium(ScrnInfoPtr pScrn);
 
+void xorg_flush(ScreenPtr pScreen);
 /***********************************************************************
  * xorg_exa.c
  */
index f64959f00e914620bc8ec84cc3358e9a2124ae04..c72ba9ef8dbd67b1346d055db988a6e56c0a1acb 100644 (file)
@@ -171,6 +171,7 @@ create_component_texture(struct pipe_context *pipe,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.bind = PIPE_BIND_SAMPLER_VIEW;
 
    tex = screen->resource_create(screen, &templ);
@@ -312,17 +313,17 @@ copy_packed_data(ScrnInfoPtr pScrn,
    int y_array_size = w * h;
 
    ytrans = pipe_get_transfer(pipe, dst[0],
-                                   0, 0, 0,
-                                   PIPE_TRANSFER_WRITE,
-                                   left, top, w, h);
+                              0, 0,
+                              PIPE_TRANSFER_WRITE,
+                              left, top, w, h);
    utrans = pipe_get_transfer(pipe, dst[1],
-                                   0, 0, 0,
-                                   PIPE_TRANSFER_WRITE,
-                                   left, top, w, h);
+                              0, 0,
+                              PIPE_TRANSFER_WRITE,
+                              left, top, w, h);
    vtrans = pipe_get_transfer(pipe, dst[2],
-                                   0, 0, 0,
-                                   PIPE_TRANSFER_WRITE,
-                                   left, top, w, h);
+                              0, 0,
+                              PIPE_TRANSFER_WRITE,
+                              left, top, w, h);
 
    ymap = (char*)pipe->transfer_map(pipe, ytrans);
    umap = (char*)pipe->transfer_map(pipe, utrans);
@@ -533,7 +534,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
    if (!dst || !dst->tex)
       XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex");
 
-   dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
+   dst_surf = xorg_gpu_surface(pPriv->r->pipe, dst);
    hdtv = ((src_w >= RES_720P_X) && (src_h >= RES_720P_Y));
 
 #ifdef COMPOSITE
index e0c9e303817a6b7a4891fc5a6ca15fd7fa5fb6e3..1c70d1deb66808a903a7e68ce957460dcfc97d13 100644 (file)
@@ -135,6 +135,7 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *
    struct pipe_video_context *vpipe;
    struct pipe_resource template;
    struct pipe_resource *tex;
+   struct pipe_surface surf_template;
    Status ret;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Creating subpicture %p.\n", subpicture);
@@ -181,8 +182,11 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *
 
    subpicture_priv->context = context;
    tex = vpipe->screen->resource_create(vpipe->screen, &template);
-   subpicture_priv->sfc = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
-                                                         PIPE_BIND_SAMPLER_VIEW);
+
+   memset(&surf_template, 0, sizeof(surf_template));
+   surf_template.format = tex->format;
+   surf_template.usage = PIPE_BIND_SAMPLER_VIEW;
+   subpicture_priv->sfc = vpipe->create_surface(vpipe, tex, &surf_template);
    pipe_resource_reference(&tex, NULL);
    if (!subpicture_priv->sfc) {
       FREE(subpicture_priv);
@@ -239,7 +243,6 @@ Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage
    unsigned char *src, *dst, *dst_line;
    unsigned x, y;
    struct pipe_box dst_box = {dstx, dsty, 0, width, height, 1};
-   struct pipe_subresource sr = {0, 0};
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Compositing subpicture %p.\n", subpicture);
 
@@ -264,7 +267,7 @@ Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage
    /* TODO: Assert rects are within bounds? Or clip? */
 
    xfer = vpipe->get_transfer(vpipe, subpicture_priv->sfc->texture,
-                              sr, PIPE_TRANSFER_WRITE, &dst_box);
+                              0, PIPE_TRANSFER_WRITE, &dst_box);
    if (!xfer)
       return BadAlloc;
 
index 209dffd2c58e7dfd439113130681789a35c56285..d7285a478fb4e473663cb0060e4b52dadf76d6b6 100644 (file)
@@ -203,6 +203,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
    XvMCSurfacePrivate *surface_priv;
    struct pipe_resource template;
    struct pipe_resource *vsfc_tex;
+   struct pipe_surface surf_template;
    struct pipe_surface *vsfc;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
@@ -248,8 +249,10 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
       return BadAlloc;
    }
 
-   vsfc = vpipe->screen->get_tex_surface(vpipe->screen, vsfc_tex, 0, 0, 0,
-                                         PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+   memset(&surf_template, 0, sizeof(surf_template));
+   surf_template.format = vsfc_tex->format;
+   surf_template.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+   vsfc = vpipe->create_surface(vpipe, vsfc_tex, &surf_template);
    pipe_resource_reference(&vsfc_tex, NULL);
    if (!vsfc) {
       FREE(surface_priv);
@@ -396,7 +399,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    context = surface_priv->context;
    context_priv = context->privData;
 
-   drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable);
+   drawable_surface = vl_drawable_surface_get(context_priv->vctx, drawable);
    if (!drawable_surface)
       return BadDrawable;
 
@@ -448,7 +451,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    vpipe->screen->flush_frontbuffer
    (
       vpipe->screen,
-      drawable_surface,
+      drawable_surface->texture,
+      0, 0,
       vl_contextprivate_get(context_priv->vctx, drawable_surface)
    );
 
index 786d5d1105e783b2b9299fd1ee35abfb0a636344..bb182ba9845d5d70ba4234a7e60c8bb80ac0e3ac 100644 (file)
@@ -100,9 +100,14 @@ load_st_module(struct st_module *stmod,
 {
    struct st_api *(*create_api)(void);
 
-   _eglLog(_EGL_DEBUG, "searching for st module %s", name);
+   if (name) {
+      _eglLog(_EGL_DEBUG, "searching for st module %s", name);
+      stmod->name = loader_strdup(name);
+   }
+   else {
+      stmod->name = NULL;
+   }
 
-   stmod->name = loader_strdup(name);
    if (stmod->name)
       _eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod);
    else
@@ -232,6 +237,21 @@ get_st_api_full(enum st_api_type api, enum st_profile_type profile)
          break;
    }
 
+   /* try again with libGL.so loaded */
+   if (!stmod->stapi && api == ST_API_OPENGL) {
+      struct util_dl_library *glapi = util_dl_open("libGL" UTIL_DL_EXT);
+
+      if (glapi) {
+         _eglLog(_EGL_DEBUG, "retry with libGL" UTIL_DL_EXT " loaded");
+         /* skip the last name (which is NULL) */
+         for (i = 0; i < count - 1; i++) {
+            if (load_st_module(stmod, names[i], symbol))
+               break;
+         }
+         util_dl_close(glapi);
+      }
+   }
+
    if (!stmod->stapi) {
       EGLint level = (egl_g3d_loader.profile_masks[api]) ?
          _EGL_WARNING : _EGL_DEBUG;
index 1d6e664eabd6557c3b3d49566bae5f6ef07f5a49..112904ab5fe88e6a690e31564808d34d9d9216dd 100644 (file)
@@ -100,7 +100,7 @@ no_winsys:
 
 static void
 gdi_present(struct pipe_screen *screen,
-            struct pipe_surface *surface,
+            struct pipe_resource *res,
             HDC hDC)
 {
    /* This will fail if any interposing layer (trace, debug, etc) has
@@ -119,14 +119,14 @@ gdi_present(struct pipe_screen *screen,
 #ifdef HAVE_LLVMPIPE
    if (use_llvmpipe) {
       winsys = llvmpipe_screen(screen)->winsys;
-      dt = llvmpipe_resource(surface->texture)->dt;
+      dt = llvmpipe_resource(res)->dt;
       gdi_sw_display(winsys, dt, hDC);
       return;
    }
 #endif
 
    winsys = softpipe_screen(screen)->winsys,
-   dt = softpipe_resource(surface->texture)->dt,
+   dt = softpipe_resource(res)->dt,
    gdi_sw_display(winsys, dt, hDC);
 }
 
index 94465e520439daf78b7f127a6d5f3946ae227ba2..7979209993dbc96ad3b5ed544adcc348eecd8562 100644 (file)
@@ -362,8 +362,10 @@ vmw_video_close(struct vmw_customizer *vmw)
        /* make sure the port is stoped as well */
        vmw_xv_stop_video(pScrn, &video->port[i], TRUE);
        vmw_ioctl_unref_stream(vmw, video->port[i].streamId);
+       REGION_UNINIT(pScreen, &video->port[i].clipBoxes);
     }
 
+
     /* XXX: I'm sure this function is missing code for turning off Xv */
 
     free(vmw->video_priv);
@@ -448,7 +450,16 @@ vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw)
     vmw->video_priv = video;
 
     adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
-    adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+
+    /**
+     * Note: CLIP_TO_VIEWPORT was removed from the flags, since with the
+     * crtc/output based modesetting, the viewport is not updated on
+     * RandR modeswitches. Hence the video may incorrectly be clipped away.
+     * The correct approach, (if needed) would be to clip against the
+     * scanout area union of all active crtcs. Revisit if needed.
+     */
+
+    adaptor->flags = VIDEO_OVERLAID_IMAGES;
     adaptor->name = "VMware Video Engine";
     adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
     adaptor->pEncodings = vmwareVideoEncodings;
@@ -463,6 +474,7 @@ vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw)
         video->port[i].flags = SVGA_VIDEO_FLAG_COLORKEY;
         video->port[i].colorKey = VMWARE_VIDEO_COLORKEY;
         video->port[i].isAutoPaintColorkey = TRUE;
+        REGION_NULL(pScrn->pScreen, &video->port[i].clipBoxes);
         adaptor->pPortPrivates[i].ptr = &video->port[i];
     }
 
@@ -554,7 +566,9 @@ vmw_video_port_init(ScrnInfoPtr pScrn, struct vmw_video_port *port,
     REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes);
 
     if (port->isAutoPaintColorkey)
-        xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes);
+       xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes);
+
+    xorg_flush(pScrn->pScreen);
 
     return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h,
                       drw_w, drw_h, format, buf, width, height, clipBoxes);
@@ -641,11 +655,12 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
      */
     if (!REGION_EQUAL(pScrn->pScreen, &port->clipBoxes, clipBoxes)) {
         REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes);
-        if (port->isAutoPaintColorkey) {
+        if (port->isAutoPaintColorkey)
             xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes);
-        }
     }
 
+    xorg_flush(pScrn->pScreen);
+
     ret = drmCommandWrite(vmw->fd, DRM_VMW_CONTROL_STREAM, &arg, sizeof(arg));
     if (ret) {
        vmw_video_port_cleanup(pScrn, port);
@@ -865,6 +880,8 @@ vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
     if (!vmw->video_priv)
         return;
 
+    REGION_EMPTY(pScrn->pScreen, &port->clipBoxes);
+
     if (!cleanup)
         return;
 
index ee4581ef1eda6f00a8600eb53af66bca8e565fc9..1ff80cadeec3f534e571b143d49aa38127dfe542 100644 (file)
@@ -20,6 +20,7 @@ static const int HEIGHT = 300;
 struct pipe_screen *screen;
 struct pipe_context *ctx;
 struct pipe_surface *surf;
+struct pipe_resource *tex;
 static void *window = NULL;
 
 static void draw( void )
@@ -31,13 +32,14 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, tex, 0, 0, window);
 }
 
 static void init( void )
 {
    struct pipe_framebuffer_state fb;
-   struct pipe_resource *tex, templat;
+   struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -66,6 +68,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -76,9 +79,12 @@ static void init( void )
    if (tex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, tex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index 19af83fda8885b936103c0a05d58cdd49f7f3213..37be2d0830c74d8b54f5c84ba177cc8bee756e4f 100644 (file)
@@ -119,6 +119,7 @@ static void init_fs_constbuf( void )
    templat.width0 = sizeof(constants1);
    templat.height0 = 1;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_CONSTANT_BUFFER;
@@ -139,7 +140,7 @@ static void init_fs_constbuf( void )
 
       ctx->transfer_inline_write(ctx,
                                  constbuf1,
-                                 u_subresource(0,0),
+                                 0,
                                  PIPE_TRANSFER_WRITE,
                                  &box,
                                  constants1,
@@ -156,7 +157,7 @@ static void init_fs_constbuf( void )
 
       ctx->transfer_inline_write(ctx,
                                  constbuf2,
-                                 u_subresource(0,0),
+                                 0,
                                  PIPE_TRANSFER_WRITE,
                                  &box,
                                  constants2,
@@ -280,7 +281,7 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
 }
 
 #define SIZE 16
@@ -340,6 +341,7 @@ static void init_tex( void )
    templat.width0 = SIZE;
    templat.height0 = SIZE;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -354,7 +356,7 @@ static void init_tex( void )
 
    ctx->transfer_inline_write(ctx,
                               samptex,
-                              u_subresource(0,0),
+                              0,
                               PIPE_TRANSFER_WRITE,
                               &box,
                               tex2d,
@@ -368,7 +370,7 @@ static void init_tex( void )
       struct pipe_transfer *t;
       uint32_t *ptr;
       t = pipe_get_transfer(ctx, samptex,
-                            0, 0, 0, /* face, level, zslice */
+                            0, 0, /* level, layer */
                             PIPE_TRANSFER_READ,
                             0, 0, SIZE, SIZE); /* x, y, width, height */
 
@@ -387,8 +389,6 @@ static void init_tex( void )
    memset(&sv_template, 0, sizeof sv_template);
    sv_template.format = samptex->format;
    sv_template.texture = samptex;
-   sv_template.first_level = 0;
-   sv_template.last_level = 0;
    sv_template.swizzle_r = 0;
    sv_template.swizzle_g = 1;
    sv_template.swizzle_b = 2;
@@ -424,6 +424,7 @@ static void init( void )
 {
    struct pipe_framebuffer_state fb;
    struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -450,6 +451,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -460,9 +462,12 @@ static void init( void )
    if (rttex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, rttex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index ef29f134980daa2ec859122c3590f4d5312b5482..812666a8c84a09cca0efe6ba047d14247fdb3d8a 100644 (file)
@@ -156,6 +156,7 @@ static void init_fs_constbuf( void )
    templat.width0 = sizeof(constants1);
    templat.height0 = 1;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_CONSTANT_BUFFER;
@@ -172,7 +173,7 @@ static void init_fs_constbuf( void )
 
       ctx->transfer_inline_write(ctx,
                                  constbuf1,
-                                 u_subresource(0,0),
+                                 0,
                                  PIPE_TRANSFER_WRITE,
                                  &box,
                                  constants1,
@@ -189,7 +190,7 @@ static void init_fs_constbuf( void )
 
       ctx->transfer_inline_write(ctx,
                                  constbuf2,
-                                 u_subresource(0,0),
+                                 0,
                                  PIPE_TRANSFER_WRITE,
                                  &box,
                                  constants2,
@@ -344,7 +345,7 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
 }
 
 #define SIZE 16
@@ -404,6 +405,7 @@ static void init_tex( void )
    templat.width0 = SIZE;
    templat.height0 = SIZE;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -418,7 +420,7 @@ static void init_tex( void )
 
    ctx->transfer_inline_write(ctx,
                               samptex,
-                              u_subresource(0,0),
+                              0,
                               PIPE_TRANSFER_WRITE,
                               &box,
                               tex2d,
@@ -432,7 +434,7 @@ static void init_tex( void )
       struct pipe_transfer *t;
       uint32_t *ptr;
       t = pipe_get_transfer(ctx, samptex,
-                            0, 0, 0, /* face, level, zslice */
+                            0, 0, /* level, layer */
                             PIPE_TRANSFER_READ,
                             0, 0, SIZE, SIZE); /* x, y, width, height */
 
@@ -451,8 +453,6 @@ static void init_tex( void )
    memset(&sv_template, 0, sizeof sv_template);
    sv_template.format = samptex->format;
    sv_template.texture = samptex;
-   sv_template.first_level = 0;
-   sv_template.last_level = 0;
    sv_template.swizzle_r = 0;
    sv_template.swizzle_g = 1;
    sv_template.swizzle_b = 2;
@@ -488,6 +488,7 @@ static void init( void )
 {
    struct pipe_framebuffer_state fb;
    struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -514,6 +515,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -524,9 +526,12 @@ static void init( void )
    if (rttex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, rttex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index 35eade939e6bf869ac0b242c45259713882035cd..952131d765bde0abdc0882353d4b8a51a698a42e 100644 (file)
@@ -151,7 +151,7 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
 }
 
 #define SIZE 16
@@ -211,6 +211,7 @@ static void init_tex( void )
    templat.width0 = SIZE;
    templat.height0 = SIZE;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -225,7 +226,7 @@ static void init_tex( void )
 
    ctx->transfer_inline_write(ctx,
                               samptex,
-                              u_subresource(0,0),
+                              0,
                               PIPE_TRANSFER_WRITE,
                               &box,
                               tex2d,
@@ -239,7 +240,7 @@ static void init_tex( void )
       struct pipe_transfer *t;
       uint32_t *ptr;
       t = pipe_get_transfer(ctx, samptex,
-                            0, 0, 0, /* face, level, zslice */
+                            0, 0, /* level, layer */
                             PIPE_TRANSFER_READ,
                             0, 0, SIZE, SIZE); /* x, y, width, height */
 
@@ -258,8 +259,6 @@ static void init_tex( void )
    memset(&sv_template, 0, sizeof sv_template);
    sv_template.format = samptex->format;
    sv_template.texture = samptex;
-   sv_template.first_level = 0;
-   sv_template.last_level = 0;
    sv_template.swizzle_r = 0;
    sv_template.swizzle_g = 1;
    sv_template.swizzle_b = 2;
@@ -295,6 +294,7 @@ static void init( void )
 {
    struct pipe_framebuffer_state fb;
    struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -321,6 +321,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -331,9 +332,12 @@ static void init( void )
    if (rttex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, rttex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index 0a6c362d17245852b1fe71c891b3b29b6b1b4a20..b53f0a046ca8c1750a368e824eada7039c2da337 100644 (file)
@@ -28,6 +28,7 @@ static const int HEIGHT = 300;
 static struct pipe_screen *screen = NULL;
 static struct pipe_context *ctx = NULL;
 static struct pipe_surface *surf = NULL;
+static struct pipe_resource *tex = NULL;
 static void *window = NULL;
 
 struct vertex {
@@ -155,7 +156,7 @@ static void draw( void )
       ctx->delete_fs_state(ctx, fs);
    }
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, tex, 0, 0, window);
    ctx->destroy(ctx);
 
    exit(0);
@@ -165,7 +166,8 @@ static void draw( void )
 static void init( void )
 {
    struct pipe_framebuffer_state fb;
-   struct pipe_resource *tex, templat;
+   struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -203,11 +205,16 @@ static void init( void )
       exit(4);
    }
 
-   surf = screen->get_tex_surface(screen, tex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
-   if (surf == NULL)
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
+   if (surf == NULL) {
+      fprintf(stderr, "Unable to create tex surface!\n");
       exit(5);
+   }
 
    memset(&fb, 0, sizeof fb);
    fb.nr_cbufs = 1;
index 731c4e10cfdc9c4eb5f45563bc8a3b8cb03d6644..84ff3e6773528b702bc0a7b208b61cea65fdcc71 100644 (file)
@@ -23,6 +23,7 @@ static const int HEIGHT = 300;
 static struct pipe_screen *screen = NULL;
 static struct pipe_context *ctx = NULL;
 static struct pipe_surface *surf = NULL;
+static struct pipe_resource *tex = NULL;
 static void *window = NULL;
 
 struct vertex {
@@ -164,14 +165,15 @@ static void draw( void )
    util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
    ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, tex, 0, 0, window);
 }
 
 
 static void init( void )
 {
    struct pipe_framebuffer_state fb;
-   struct pipe_resource *tex, templat;
+   struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -198,6 +200,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -208,9 +211,12 @@ static void init( void )
    if (tex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, tex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index 76443811629ed7668273654bdc9a64709d7463d0..f33c061b22b861c72c2d49578f2f70aa6a7194ae 100644 (file)
@@ -27,6 +27,7 @@ static const int HEIGHT = 300;
 static struct pipe_screen *screen = NULL;
 static struct pipe_context *ctx = NULL;
 static struct pipe_surface *surf = NULL;
+static struct pipe_resource *tex = NULL;
 static void *window = NULL;
 
 struct vertex {
@@ -216,14 +217,15 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, tex, 0, 0, window);
 }
 
 
 static void init( void )
 {
    struct pipe_framebuffer_state fb;
-   struct pipe_resource *tex, templat;
+   struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -250,6 +252,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -260,9 +263,12 @@ static void init( void )
    if (tex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, tex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index 025a1470dc906473bfee5561ecd3570c3496f842..2742c7c99e051162f480af0c5397316026f2580f 100644 (file)
@@ -25,6 +25,7 @@ static const int HEIGHT = 300;
 static struct pipe_screen *screen = NULL;
 static struct pipe_context *ctx = NULL;
 static struct pipe_surface *surf = NULL;
+static struct pipe_resource *tex = NULL;
 static void *window = NULL;
 
 struct vertex {
@@ -144,14 +145,15 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, tex, 0, 0, window);
 }
 
 
 static void init( void )
 {
    struct pipe_framebuffer_state fb;
-   struct pipe_resource *tex, templat;
+   struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -180,6 +182,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -192,11 +195,14 @@ static void init( void )
       exit(4);
    }
 
-   surf = screen->get_tex_surface(screen, tex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
    if (surf == NULL) {
-      fprintf(stderr, "Unable to get tex surface!\n");
+      fprintf(stderr, "Unable to create tex surface!\n");
       exit(5);
    }
 
index 440c40bdcdab9bfb0917345cb3ce7b68f83a5f67..58908f38a23ed06485fb3a96e7015398e25100e1 100644 (file)
@@ -87,6 +87,7 @@ static void init_fs_constbuf( void )
    templat.width0 = sizeof(constants);
    templat.height0 = 1;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_CONSTANT_BUFFER;
@@ -101,7 +102,7 @@ static void init_fs_constbuf( void )
 
    ctx->transfer_inline_write(ctx,
                               constbuf,
-                              u_subresource(0,0),
+                              0,
                               PIPE_TRANSFER_WRITE,
                               &box,
                               constants,
@@ -231,7 +232,7 @@ static void draw( void )
 
    graw_save_surface_to_file(ctx, surf, NULL);
 
-   screen->flush_frontbuffer(screen, surf, window);
+   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
 }
 
 #define SIZE 16
@@ -291,6 +292,7 @@ static void init_tex( void )
    templat.width0 = SIZE;
    templat.height0 = SIZE;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -305,7 +307,7 @@ static void init_tex( void )
 
    ctx->transfer_inline_write(ctx,
                               samptex,
-                              u_subresource(0,0),
+                              0,
                               PIPE_TRANSFER_WRITE,
                               &box,
                               tex2d,
@@ -319,7 +321,7 @@ static void init_tex( void )
       struct pipe_transfer *t;
       uint32_t *ptr;
       t = pipe_get_transfer(ctx, samptex,
-                            0, 0, 0, /* face, level, zslice */
+                            0, 0, /* level, layer */
                             PIPE_TRANSFER_READ,
                             0, 0, SIZE, SIZE); /* x, y, width, height */
 
@@ -338,8 +340,6 @@ static void init_tex( void )
    memset(&sv_template, 0, sizeof sv_template);
    sv_template.format = samptex->format;
    sv_template.texture = samptex;
-   sv_template.first_level = 0;
-   sv_template.last_level = 0;
    sv_template.swizzle_r = 0;
    sv_template.swizzle_g = 1;
    sv_template.swizzle_b = 2;
@@ -375,6 +375,7 @@ static void init( void )
 {
    struct pipe_framebuffer_state fb;
    struct pipe_resource templat;
+   struct pipe_surface surf_tmpl;
    int i;
 
    /* It's hard to say whether window or screen should be created
@@ -401,6 +402,7 @@ static void init( void )
    templat.width0 = WIDTH;
    templat.height0 = HEIGHT;
    templat.depth0 = 1;
+   templat.array_size = 1;
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
@@ -411,9 +413,12 @@ static void init( void )
    if (rttex == NULL)
       exit(4);
 
-   surf = screen->get_tex_surface(screen, rttex, 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET |
-                                  PIPE_BIND_DISPLAY_TARGET);
+   surf_tmpl.format = templat.format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = 0;
+   surf_tmpl.u.tex.first_layer = 0;
+   surf_tmpl.u.tex.last_layer = 0;
+   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
    if (surf == NULL)
       exit(5);
 
index 954a701a53f9af8d918bb72cbcd177e9a840e126..84371223f66177ff238a6031bf468ef8bcff4931 100755 (executable)
@@ -251,14 +251,6 @@ class Screen(Object):
     def texture_release(self, surface):
         pass
 
-    def get_tex_surface(self, texture, face, level, zslice, usage):
-        if texture is None:
-            return None
-        return texture.get_surface(face, level, zslice)
-    
-    def tex_surface_destroy(self, surface):
-        self.interpreter.unregister_object(surface)
-
     def tex_surface_release(self, surface):
         pass
 
@@ -282,7 +274,7 @@ class Screen(Object):
     def fence_reference(self, dst, src):
         pass
     
-    def flush_frontbuffer(self, surface):
+    def flush_frontbuffer(self, resource):
         pass
 
 
@@ -581,7 +573,7 @@ class Context(Object):
         if transfer and usage & gallium.PIPE_TRANSFER_READ:
             if self.interpreter.options.all:
                 surface = texture.get_surface(sr.face, sr.level, box.z)
-                self.interpreter.present(self.real, transfer.surface, 'transf_read', box.x, box.y, box.w, box.h)
+                self.interpreter.present(self.real, transfer.surface, 'transf_read', box.x, box.y, box.width, box.height)
         return transfer
     
     def tex_transfer_destroy(self, transfer):
@@ -589,6 +581,10 @@ class Context(Object):
 
     def transfer_inline_write(self, resource, sr, usage, box, stride, slice_stride, data):
         self.real.transfer_inline_write(resource, sr, usage, box, data, stride, slice_stride)
+        if self.interpreter.options.all:
+            for z in range(box.z, box.z + box.depth):
+                surface = resource.get_surface(sr.face, sr.level, box.z)
+                self.interpreter.present(self.real, surface, 'transf_inline_write%u' % z, box.x, box.y, box.width, box.height)
 
     def _set_dirty(self):
         if self.interpreter.options.step:
@@ -627,7 +623,13 @@ class Context(Object):
         if self.zsbuf:
             if self.interpreter.options.all:
                 self.interpreter.present(self.real, self.zsbuf, "zsbuf")
-    
+    def create_surface(self, texture, level, layer, usage):
+        if texture is None:
+            return None
+        return texture.get_surface(level, layer)
+
+    def surface_destroy(self, surface):
+        self.interpreter.unregister_object(surface)
 
 class Interpreter(parser.TraceDumper):
     
index cf88edcdc56f91322ea3be2bad43c4570fe24e78..92c5b4dbb183f3ac5111ae6b9551d98a1d8b7511 100644 (file)
@@ -92,6 +92,7 @@ struct program
 
 static void init_prog(struct program *p)
 {
+       struct pipe_surface surf_tmpl;
        /* create the software rasterizer */
        p->screen = sw_screen_create(null_sw_create());
        /* wrap the screen with any debugger */
@@ -141,6 +142,7 @@ static void init_prog(struct program *p)
                tmplt.width0 = WIDTH;
                tmplt.height0 = HEIGHT;
                tmplt.depth0 = 1;
+               tmplt.array_size = 1;
                tmplt.last_level = 0;
                tmplt.bind = PIPE_BIND_RENDER_TARGET;
 
@@ -153,7 +155,6 @@ static void init_prog(struct program *p)
                struct pipe_transfer *t;
                struct pipe_resource t_tmplt;
                struct pipe_sampler_view v_tmplt;
-               struct pipe_subresource sub;
                struct pipe_box box;
 
                memset(&t_tmplt, 0, sizeof(t_tmplt));
@@ -162,17 +163,17 @@ static void init_prog(struct program *p)
                t_tmplt.width0 = 2;
                t_tmplt.height0 = 2;
                t_tmplt.depth0 = 1;
+               t_tmplt.array_size = 1;
                t_tmplt.last_level = 0;
                t_tmplt.bind = PIPE_BIND_RENDER_TARGET;
 
                p->tex = p->screen->resource_create(p->screen, &t_tmplt);
 
-               memset(&sub, 0, sizeof(sub));
                memset(&box, 0, sizeof(box));
                box.width = 2;
                box.height = 2;
 
-               t = p->pipe->get_transfer(p->pipe, p->tex, sub, PIPE_TRANSFER_WRITE, &box);
+               t = p->pipe->get_transfer(p->pipe, p->tex, 0, PIPE_TRANSFER_WRITE, &box);
 
                ptr = p->pipe->transfer_map(p->pipe, t);
                ptr[0] = 0xffff0000;
@@ -210,12 +211,17 @@ static void init_prog(struct program *p)
        p->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
        p->sampler.normalized_coords = 1;
 
+       surf_tmpl.format = templat.format;
+       surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+       surf_tmpl.u.tex.level = 0;
+       surf_tmpl.u.tex.first_layer = 0;
+       surf_tmpl.u.tex.last_layer = 0;
        /* drawing destination */
        memset(&p->framebuffer, 0, sizeof(p->framebuffer));
        p->framebuffer.width = WIDTH;
        p->framebuffer.height = HEIGHT;
        p->framebuffer.nr_cbufs = 1;
-       p->framebuffer.cbufs[0] = p->screen->get_tex_surface(p->screen, p->target, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
+       p->framebuffer.cbufs[0] = p->pipe->create_surface(p->pipe, p->target, &surf_tmpl);
 
        /* viewport, depth isn't really needed */
        {
index 667a27b28ab87363e55ecca72be4459b7c9ae4f8..37c1573051f1da16ee2b18dc612d1539008acda9 100644 (file)
@@ -87,6 +87,7 @@ struct program
 
 static void init_prog(struct program *p)
 {
+       struct pipe_surface surf_tmpl;
        /* create the software rasterizer */
        p->screen = sw_screen_create(null_sw_create());
        /* wrap the screen with any debugger */
@@ -132,6 +133,7 @@ static void init_prog(struct program *p)
                tmplt.width0 = WIDTH;
                tmplt.height0 = HEIGHT;
                tmplt.depth0 = 1;
+               tmplt.array_size = 1;
                tmplt.last_level = 0;
                tmplt.bind = PIPE_BIND_RENDER_TARGET;
 
@@ -150,12 +152,17 @@ static void init_prog(struct program *p)
        p->rasterizer.cull_face = PIPE_FACE_NONE;
        p->rasterizer.gl_rasterization_rules = 1;
 
+       surf_tmpl.format = templat.format;
+       surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+       surf_tmpl.u.tex.level = 0;
+       surf_tmpl.u.tex.first_layer = 0;
+       surf_tmpl.u.tex.last_layer = 0;
        /* drawing destination */
        memset(&p->framebuffer, 0, sizeof(p->framebuffer));
        p->framebuffer.width = WIDTH;
        p->framebuffer.height = HEIGHT;
        p->framebuffer.nr_cbufs = 1;
-       p->framebuffer.cbufs[0] = p->screen->get_tex_surface(p->screen, p->target, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
+       p->framebuffer.cbufs[0] = p->pipe->create_surface(p->pipe, p->target, &surf_tmpl);
 
        /* viewport, depth isn't really needed */
        {
index 4d10e27c5806d34b1f0cd204f9dbff989214b6ec..8588ddd17cbb3649c1c25cebf3e98f132b7f2657 100644 (file)
@@ -50,7 +50,7 @@ struct vl_dri_context
 };
 
 static struct pipe_surface*
-vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
+vl_dri2_get_front(struct vl_context *vctx, Drawable drawable)
 {
    int w, h;
    unsigned int attachments[1] = {DRI_BUFFER_FRONT_LEFT};
@@ -59,6 +59,9 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
    struct pipe_resource *front_tex;
    struct pipe_surface *front_surf = NULL;
 
+   assert(vctx);
+
+   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vctx->vscreen;
    assert(vl_dri_scrn);
 
    dri2_front = DRI2GetBuffers(vl_dri_scrn->dri_screen->display,
@@ -74,6 +77,7 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
          .stride = dri2_front->pitch
       };
       struct pipe_resource template;
+      struct pipe_surface surf_template;
 
       memset(&template, 0, sizeof(struct pipe_resource));
       template.target = PIPE_TEXTURE_2D;
@@ -87,10 +91,12 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
       template.flags = 0;
 
       front_tex = vl_dri_scrn->base.pscreen->resource_from_handle(vl_dri_scrn->base.pscreen, &template, &dri2_front_handle);
-      if (front_tex)
-         front_surf = vl_dri_scrn->base.pscreen->get_tex_surface(vl_dri_scrn->base.pscreen,
-                                                                 front_tex, 0, 0, 0,
-                                                                 PIPE_BIND_RENDER_TARGET);
+      if (front_tex) {
+         memset(&surf_template, 0, sizeof(surf_template));
+         surf_template.format = front_tex->format;
+         surf_template.usage = PIPE_BIND_RENDER_TARGET;
+         front_surf = vctx->vpipe->create_surface(vctx->vpipe, front_tex, &surf_template);
+      }
       pipe_resource_reference(&front_tex, NULL);
       Xfree(dri2_front);
    }
@@ -100,13 +106,15 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
 
 static void
 vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
-                          struct pipe_surface *surf, void *context_private)
+                          struct pipe_resource *resource,
+                          unsigned level, unsigned layer,
+                          void *context_private)
 {
    struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private;
    struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
 
    assert(screen);
-   assert(surf);
+   assert(resource);
    assert(context_private);
 
    dri2CopyDrawable(vl_dri_scrn->dri_screen, vl_dri_scrn->last_seen_drawable,
@@ -114,11 +122,12 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
 }
 
 struct pipe_surface*
-vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
+vl_drawable_surface_get(struct vl_context *vctx, Drawable drawable)
 {
-   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
+   assert(vctx);
 
-   assert(vscreen);
+   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vctx->vscreen;
+   assert(vl_dri_scrn);
 
    if (vl_dri_scrn->last_seen_drawable != drawable) {
       /* Hash table business depends on this equality */
@@ -131,7 +140,7 @@ vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
       vl_dri_scrn->last_seen_drawable = drawable;
    }
 
-   return vl_dri2_get_front(vl_dri_scrn, drawable);
+   return vl_dri2_get_front(vctx, drawable);
 }
 
 void*
index 381478637a8fa06f25be68641fcad0ccb5152c2f..58f548849f6dd6e38b93befd6482b88c832cd520 100644 (file)
@@ -61,7 +61,7 @@ vl_video_create(struct vl_screen *vscreen,
 void vl_video_destroy(struct vl_context *vctx);
 
 struct pipe_surface*
-vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable);
+vl_drawable_surface_get(struct vl_context *vctx, Drawable drawable);
 
 void*
 vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface);
index c6daa52a379e0bad756aae8ab2d109f619778853..ebe86dcf196d0a2b39da746724219bb4bea10e25 100644 (file)
@@ -14,9 +14,6 @@
 #define INTEL_BATCH_CLIPRECTS    0x2
 
 #undef INTEL_RUN_SYNC
-#undef INTEL_MAP_BATCHBUFFER
-#undef INTEL_MAP_GTT
-#define INTEL_ALWAYS_FLUSH
 
 struct i915_drm_batchbuffer
 {
@@ -72,11 +69,7 @@ i915_drm_batchbuffer_create(struct i915_winsys *iws)
 
    batch->actual_size = idws->max_batch_size;
 
-#ifdef INTEL_MAP_BATCHBUFFER
-   batch->base.map = NULL;
-#else
    batch->base.map = MALLOC(batch->actual_size);
-#endif
    batch->base.ptr = NULL;
    batch->base.size = 0;
 
@@ -94,7 +87,7 @@ static int
 i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
                             struct i915_winsys_buffer *buffer,
                             enum i915_winsys_buffer_usage usage,
-                            unsigned pre_add)
+                            unsigned pre_add, bool fenced)
 {
    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
    unsigned write_domain = 0;
@@ -104,37 +97,44 @@ i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
 
    assert(batch->base.relocs < batch->base.max_relocs);
 
-   if (usage == I915_USAGE_SAMPLER) {
+   switch (usage) {
+   case I915_USAGE_SAMPLER:
       write_domain = 0;
       read_domain = I915_GEM_DOMAIN_SAMPLER;
-
-   } else if (usage == I915_USAGE_RENDER) {
+      break;
+   case I915_USAGE_RENDER:
       write_domain = I915_GEM_DOMAIN_RENDER;
       read_domain = I915_GEM_DOMAIN_RENDER;
-
-   } else if (usage == I915_USAGE_2D_TARGET) {
+      break;
+   case I915_USAGE_2D_TARGET:
       write_domain = I915_GEM_DOMAIN_RENDER;
       read_domain = I915_GEM_DOMAIN_RENDER;
-
-   } else if (usage == I915_USAGE_2D_SOURCE) {
+      break;
+   case I915_USAGE_2D_SOURCE:
       write_domain = 0;
       read_domain = I915_GEM_DOMAIN_RENDER;
-
-   } else if (usage == I915_USAGE_VERTEX) {
+      break;
+   case I915_USAGE_VERTEX:
       write_domain = 0;
       read_domain = I915_GEM_DOMAIN_VERTEX;
-
-   } else {
+      break;
+   default:
       assert(0);
       return -1;
    }
 
    offset = (unsigned)(batch->base.ptr - batch->base.map);
 
-   ret = drm_intel_bo_emit_reloc(batch->bo, offset,
-                                 intel_bo(buffer), pre_add,
-                                 read_domain,
-                                 write_domain);
+   if (fenced)
+      ret = drm_intel_bo_emit_reloc_fence(batch->bo, offset,
+                                   intel_bo(buffer), pre_add,
+                                   read_domain,
+                                   write_domain);
+   else
+      ret = drm_intel_bo_emit_reloc(batch->bo, offset,
+                                   intel_bo(buffer), pre_add,
+                                   read_domain,
+                                   write_domain);
 
    ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
    batch->base.ptr += 4;
@@ -150,70 +150,32 @@ i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
                             struct pipe_fence_handle **fence)
 {
    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
-   unsigned used = 0;
-   int ret = 0;
+   unsigned used;
+   int ret;
 
-   assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
+   /* MI_BATCH_BUFFER_END */
+   i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
 
    used = batch->base.ptr - batch->base.map;
-   assert((used & 3) == 0);
-
-
-#ifdef INTEL_ALWAYS_FLUSH
-   /* MI_FLUSH | FLUSH_MAP_CACHE */
-   i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
-   used += 4;
-#endif
-
-   if ((used & 4) == 0) {
+   if (used & 4) {
       /* MI_NOOP */
-      i915_winsys_batchbuffer_dword(ibatch, 0);
+      i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
+      used += 4;
    }
-   /* MI_BATCH_BUFFER_END */
-   i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
-
-   used = batch->base.ptr - batch->base.map;
-   assert((used & 4) == 0);
-
-#ifdef INTEL_MAP_BATCHBUFFER
-#ifdef INTEL_MAP_GTT
-   drm_intel_gem_bo_unmap_gtt(batch->bo);
-#else
-   drm_intel_bo_unmap(batch->bo);
-#endif
-#else
-   drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
-#endif
 
    /* Do the sending to HW */
-   if (i915_drm_winsys(ibatch->iws)->send_cmd)
+   ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
+   if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd)
       ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
-   else
-      ret = 0;
 
    if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) {
-#ifdef INTEL_MAP_BATCHBUFFER
-#ifdef INTEL_MAP_GTT
-      drm_intel_gem_bo_map_gtt(batch->bo);
-#else
-      drm_intel_bo_map(batch->bo, 0);
-#endif
-#endif
       i915_dump_batchbuffer(ibatch);
       assert(ret == 0);
-#ifdef INTEL_MAP_BATCHBUFFER
-#ifdef INTEL_MAP_GTT
-   drm_intel_gem_bo_unmap_gtt(batch->bo);
-#else
-   drm_intel_bo_unmap(batch->bo);
-#endif
-#endif
-   } else {
+   }
+
 #ifdef INTEL_RUN_SYNC
-      drm_intel_bo_map(batch->bo, FALSE);
-      drm_intel_bo_unmap(batch->bo);
+   drm_intel_bo_wait_rendering(batch->bo);
 #endif
-   }
 
    if (fence) {
       ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
@@ -237,9 +199,7 @@ i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
    if (batch->bo)
       drm_intel_bo_unreference(batch->bo);
 
-#ifndef INTEL_MAP_BATCHBUFFER
    FREE(batch->base.map);
-#endif
    FREE(batch);
 }
 
index 15ec4487457795a72c1ee11ac430c9979fe934c2..01dd4bf062f943079441bacd9e2b3b2fdd5b07fc 100644 (file)
@@ -5,14 +5,31 @@
 
 #include "i915_drm.h"
 
+static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type)
+{
+   char *name;
+
+   if (type == I915_NEW_TEXTURE) {
+      name = "gallium3d_texture";
+   } else if (type == I915_NEW_VERTEX) {
+      name = "gallium3d_vertex";
+   } else if (type == I915_NEW_SCANOUT) {
+      name = "gallium3d_scanout";
+   } else {
+      assert(0);
+      name = "gallium3d_unknown";
+   }
+
+   return name;
+}
+
 static struct i915_winsys_buffer *
 i915_drm_buffer_create(struct i915_winsys *iws,
-                        unsigned size, unsigned alignment,
+                        unsigned size,
                         enum i915_winsys_buffer_type type)
 {
    struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
-   char *name;
 
    if (!buf)
       return NULL;
@@ -21,22 +38,48 @@ i915_drm_buffer_create(struct i915_winsys *iws,
    buf->flinked = FALSE;
    buf->flink = 0;
 
-   if (type == I915_NEW_TEXTURE) {
-      name = "gallium3d_texture";
-   } else if (type == I915_NEW_VERTEX) {
-      name = "gallium3d_vertex";
-   } else if (type == I915_NEW_SCANOUT) {
-      name = "gallium3d_scanout";
-   } else {
-      assert(0);
-      name = "gallium3d_unknown";
-   }
+   buf->bo = drm_intel_bo_alloc(idws->gem_manager,
+                                i915_drm_type_to_name(type), size, 0);
 
-   buf->bo = drm_intel_bo_alloc(idws->gem_manager, name, size, alignment);
+   if (!buf->bo)
+      goto err;
+
+   return (struct i915_winsys_buffer *)buf;
+
+err:
+   assert(0);
+   FREE(buf);
+   return NULL;
+}
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_create_tiled(struct i915_winsys *iws,
+                             unsigned *stride, unsigned height, 
+                             enum i915_winsys_buffer_tile *tiling,
+                             enum i915_winsys_buffer_type type)
+{
+   struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+   struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+   unsigned long pitch = 0;
+   uint32_t tiling_mode = *tiling;
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->flinked = FALSE;
+   buf->flink = 0;
+
+   buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager,
+                                      i915_drm_type_to_name(type),
+                                     *stride, height, 1,
+                                      &tiling_mode, &pitch, 0);
 
    if (!buf->bo)
       goto err;
 
+   *stride = pitch;
+   *tiling = tiling_mode;
    return (struct i915_winsys_buffer *)buf;
 
 err:
@@ -47,8 +90,9 @@ err:
 
 static struct i915_winsys_buffer *
 i915_drm_buffer_from_handle(struct i915_winsys *iws,
-                             struct winsys_handle *whandle,
-                             unsigned *stride)
+                            struct winsys_handle *whandle,
+                            enum i915_winsys_buffer_tile *tiling,
+                            unsigned *stride)
 {
    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
    struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
@@ -68,6 +112,7 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws,
    drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
 
    *stride = whandle->stride;
+   *tiling = tile;
 
    return (struct i915_winsys_buffer *)buf;
 
@@ -103,24 +148,6 @@ i915_drm_buffer_get_handle(struct i915_winsys *iws,
    return TRUE;
 }
 
-static int
-i915_drm_buffer_set_fence_reg(struct i915_winsys *iws,
-                               struct i915_winsys_buffer *buffer,
-                               unsigned stride,
-                               enum i915_winsys_buffer_tile tile)
-{
-   struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
-   assert(I915_TILING_NONE == I915_TILE_NONE);
-   assert(I915_TILING_X == I915_TILE_X);
-   assert(I915_TILING_Y == I915_TILE_Y);
-
-   if (tile != I915_TILE_NONE) {
-      assert(buf->map_count == 0);
-   }
-
-   return drm_intel_bo_set_tiling(buf->bo, &tile, stride);
-}
-
 static void *
 i915_drm_buffer_map(struct i915_winsys *iws,
                      struct i915_winsys_buffer *buffer,
@@ -190,9 +217,9 @@ void
 i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
 {
    idws->base.buffer_create = i915_drm_buffer_create;
+   idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled;
    idws->base.buffer_from_handle = i915_drm_buffer_from_handle;
    idws->base.buffer_get_handle = i915_drm_buffer_get_handle;
-   idws->base.buffer_set_fence_reg = i915_drm_buffer_set_fence_reg;
    idws->base.buffer_map = i915_drm_buffer_map;
    idws->base.buffer_unmap = i915_drm_buffer_unmap;
    idws->base.buffer_write = i915_drm_buffer_write;
index cc0b6a99577220e49e9b0485f290dfc6c7caba50..2288b48b2bde84cf557e565129afead87ba69889 100644 (file)
@@ -69,6 +69,7 @@ i915_drm_winsys_create(int drmFD)
 
    idws->gem_manager = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
    drm_intel_bufmgr_gem_enable_reuse(idws->gem_manager);
+   drm_intel_bufmgr_gem_enable_fenced_relocs(idws->gem_manager);
 
    idws->dump_cmd = debug_get_bool_option("I915_DUMP_CMD", FALSE);
    idws->send_cmd = !debug_get_bool_option("I915_NO_HW", FALSE);
index a480cfed57bf4b7e585f4a0083a39af4203635c8..44773ae30e7492bd368683593267af9f73128286 100644 (file)
@@ -61,7 +61,7 @@ static int
 i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
                           struct i915_winsys_buffer *buffer,
                           enum i915_winsys_buffer_usage usage,
-                          unsigned pre_add)
+                          unsigned pre_add, bool fenced)
 {
    struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
    int ret = 0;
index df175688861579fd04a74ff36f24096a4131ecb9..834805e621df2ab1c7000e6bb9fb7f8d54115c1c 100644 (file)
@@ -4,28 +4,15 @@
 
 static struct i915_winsys_buffer *
 i915_sw_buffer_create(struct i915_winsys *iws,
-                      unsigned size, unsigned alignment,
+                      unsigned size,
                       enum i915_winsys_buffer_type type)
 {
    struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer);
-   char *name;
 
    if (!buf)
       return NULL;
 
-   if (type == I915_NEW_TEXTURE) {
-      name = "gallium3d_texture";
-   } else if (type == I915_NEW_VERTEX) {
-      name = "gallium3d_vertex";
-   } else if (type == I915_NEW_SCANOUT) {
-      name = "gallium3d_scanout";
-   } else {
-      assert(0);
-      name = "gallium3d_unknown";
-   }
-
    buf->magic = 0xDEAD1337;
-   buf->name = name;
    buf->type = type;
    buf->ptr = CALLOC(size, 1);
 
@@ -40,21 +27,32 @@ err:
    return NULL;
 }
 
-static int
-i915_sw_buffer_set_fence_reg(struct i915_winsys *iws,
-                               struct i915_winsys_buffer *buffer,
-                               unsigned stride,
-                               enum i915_winsys_buffer_tile tile)
+static struct i915_winsys_buffer *
+i915_sw_buffer_create_tiled(struct i915_winsys *iws,
+                      unsigned *stride, unsigned height, 
+                      enum i915_winsys_buffer_tile *tiling,
+                      enum i915_winsys_buffer_type type)
 {
-   struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+   struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer);
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->type = type;
+   buf->ptr = CALLOC(*stride * height, 1);
+   buf->tiling = *tiling;
+   buf->stride = *stride;
 
-   if (tile != I915_TILE_NONE) {
-      assert(buf->map_count == 0);
-   }
+   if (!buf->ptr)
+      goto err;
 
-   buf->tile = tile;
+   return (struct i915_winsys_buffer *)buf;
 
-   return 0;
+err:
+   assert(0);
+   FREE(buf);
+   return NULL;
 }
 
 static void *
@@ -108,7 +106,7 @@ void
 i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *isws)
 {
    isws->base.buffer_create = i915_sw_buffer_create;
-   isws->base.buffer_set_fence_reg = i915_sw_buffer_set_fence_reg;
+   isws->base.buffer_create_tiled = i915_sw_buffer_create_tiled;
    isws->base.buffer_map = i915_sw_buffer_map;
    isws->base.buffer_unmap = i915_sw_buffer_unmap;
    isws->base.buffer_write = i915_sw_buffer_write;
index b7b43669f30674a5b4dfe8ba2c53c3f38d2af9d6..3af2548419e4343ccc85f7b3b114f2b0391349c5 100644 (file)
@@ -43,8 +43,8 @@ struct i915_sw_buffer {
    void *ptr;
    unsigned map_count;
    enum i915_winsys_buffer_type type;
-   enum i915_winsys_buffer_tile tile;
-   const char *name;
+   enum i915_winsys_buffer_tile tiling;
+   unsigned stride;
 };
 
 static INLINE struct i915_sw_buffer *
index baadd6e89cad70b906483649a02cc81cb2206107..c22df6643aab03fd50312fb476b95f840240939d 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "i965/brw_winsys.h"
 #include "i965/brw_screen.h"
+#include "i965/brw_resource.h"
 #include "i965/brw_reg.h"
 #include "i965/brw_structs_dump.h"
 
@@ -421,25 +422,28 @@ xlib_create_brw_winsys_screen( void )
 
 static void
 xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
-                          struct pipe_surface *surf)
+                          struct pipe_resource *resource,
+                          unsigned level, unsigned layer)
 {
-   struct brw_surface *surface = brw_surface(surf);
-   struct xlib_brw_buffer *bo = xlib_brw_buffer(surface->bo);
-
+   struct brw_texture *tex = brw_texture(resource);
+   struct xlib_brw_buffer *bo = xlib_brw_buffer(tex->bo);
+   /* not sure if the resource is really useful here but
+      since it was never implemented anyway... */
    if (BRW_DEBUG & DEBUG_WINSYS)
-      debug_printf("%s offset %x+%x sz %dx%d\n", __FUNCTION__, 
+      debug_printf("%s level %u layer %u offset %x base sz %dx%d\n", __FUNCTION__,
+                   level, layer,
                    bo->offset,
-                   surface->draw_offset,
-                   surf->width,
-                   surf->height);
+                   resource->width0,
+                   resource->height0);
 }
 
 static void
 xlib_i965_flush_frontbuffer(struct pipe_screen *screen,
-                           struct pipe_surface *surf,
-                           void *context_private)
+                            struct pipe_resource *resource,
+                            unsigned level, unsigned layer,
+                            void *context_private)
 {
-   xlib_i965_display_surface(NULL, surf);
+   xlib_i965_display_surface(NULL, resource, level, layer);
 }
 
 
index a396205f897530de518543f7b463a7131fd5798b..91c65012c835c8a5b5ddbe270418a880e245e46b 100644 (file)
@@ -8,12 +8,12 @@ C_SOURCES = \
        bof.c \
        evergreen_hw_context.c \
        radeon_bo.c \
-       radeon_bo_pb.c \
        radeon_pciid.c \
        r600.c \
        r600_bo.c \
        r600_drm.c \
-       r600_hw_context.c
+       r600_hw_context.c \
+       r600_bomgr.c
 
 LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r600 \
                   $(shell pkg-config libdrm --cflags-only-I)
index cc053c06dd0e4ab105d14ab285d820c52d84ac53..dac0097f14436308b56634bcf19af4c7138cd8bb 100644 (file)
@@ -6,12 +6,12 @@ r600_sources = [
     'bof.c',
     'evergreen_hw_context.c',
     'radeon_bo.c',
-    'radeon_bo_pb.c',
     'radeon_pciid.c',
     'r600.c',
     'r600_bo.c',
     'r600_drm.c',
     'r600_hw_context.c',
+    'r600_bomgr.c',
 ]
 
 env.ParseConfig('pkg-config --cflags libdrm_radeon')
index b93cc650272e67851245c6f60e2f9ea9c7a9aab1..2175d578ec770fedd255243a0b05345395e049f4 100644 (file)
@@ -36,7 +36,6 @@
 #include "pipe/p_compiler.h"
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
-#include <pipebuffer/pb_bufmgr.h>
 #include "r600_priv.h"
 
 #define GROUP_FORCE_NEW_BLOCK  0
@@ -855,7 +854,7 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
                ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
        }
        ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0);
-       ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT;
+       ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
 
        /* flush color buffer */
        for (int i = 0; i < 12; i++) {
index 0a4d2e791db60eebf2179d977688a7e576a6b473..b88733f80f140602f4ed048d1b98b4e16e488fef 100644 (file)
@@ -27,7 +27,6 @@
 #include "radeon_drm.h"
 #include "pipe/p_compiler.h"
 #include "util/u_inlines.h"
-#include <pipebuffer/pb_bufmgr.h>
 #include "r600_priv.h"
 
 enum radeon_family r600_get_family(struct radeon *r600)
@@ -93,6 +92,12 @@ struct radeon *r600_new(int fd, unsigned device)
        case CHIP_RV730:
        case CHIP_RV710:
        case CHIP_RV740:
+       case CHIP_CEDAR:
+       case CHIP_REDWOOD:
+       case CHIP_JUNIPER:
+       case CHIP_CYPRESS:
+       case CHIP_HEMLOCK:
+       case CHIP_PALM:
                break;
        case CHIP_R100:
        case CHIP_RV100:
@@ -121,11 +126,6 @@ struct radeon *r600_new(int fd, unsigned device)
        case CHIP_RV560:
        case CHIP_RV570:
        case CHIP_R580:
-       case CHIP_CEDAR:
-       case CHIP_REDWOOD:
-       case CHIP_JUNIPER:
-       case CHIP_CYPRESS:
-       case CHIP_HEMLOCK:
        default:
                R600_ERR("unknown or unsupported chipset 0x%04X\n", r600->device);
                break;
@@ -154,6 +154,7 @@ struct radeon *r600_new(int fd, unsigned device)
        case CHIP_JUNIPER:
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
+       case CHIP_PALM:
                r600->chip_class = EVERGREEN;
                break;
        default:
index 251f009a6b05b93d9e20b4bbe0f5ae3c737ae162..6a3737f0a4a8c6030784a5de0f58d76478622d3a 100644 (file)
@@ -36,142 +36,153 @@ struct r600_bo *r600_bo(struct radeon *radeon,
                        unsigned size, unsigned alignment,
                        unsigned binding, unsigned usage)
 {
-       struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo));
-       struct pb_desc desc;
-       struct pb_manager *man;
+       struct r600_bo *bo;
+       struct radeon_bo *rbo;
 
-       desc.alignment = alignment;
-       desc.usage = (PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_READ_WRITE);
-       ws_bo->size = size;
+       if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
+               bo = r600_bomgr_bo_create(radeon->bomgr, size, alignment, *radeon->cfence);
+               if (bo) {
+                       return bo;
+               }
+       }
 
-       if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
-               man = radeon->cman;
-       else
-               man = radeon->kman;
+       rbo = radeon_bo(radeon, 0, size, alignment);
+       if (rbo == NULL) {
+               return NULL;
+       }
+
+       bo = calloc(1, sizeof(struct r600_bo));
+       bo->size = size;
+       bo->alignment = alignment;
+       bo->bo = rbo;
+       if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
+               r600_bomgr_bo_init(radeon->bomgr, bo);
+       }
 
        /* Staging resources particpate in transfers and blits only
         * and are used for uploads and downloads from regular
         * resources.  We generate them internally for some transfers.
         */
        if (usage == PIPE_USAGE_STAGING)
-                ws_bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
-        else
-                ws_bo->domains = (RADEON_GEM_DOMAIN_CPU |
-                                  RADEON_GEM_DOMAIN_GTT |
-                                  RADEON_GEM_DOMAIN_VRAM);
-
-
-       ws_bo->pb = man->create_buffer(man, size, &desc);
-       if (ws_bo->pb == NULL) {
-               free(ws_bo);
-               return NULL;
-       }
+               bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
+       else
+               bo->domains = (RADEON_GEM_DOMAIN_CPU |
+                               RADEON_GEM_DOMAIN_GTT |
+                               RADEON_GEM_DOMAIN_VRAM);
 
-       pipe_reference_init(&ws_bo->reference, 1);
-       return ws_bo;
+       pipe_reference_init(&bo->reference, 1);
+       return bo;
 }
 
 struct r600_bo *r600_bo_handle(struct radeon *radeon,
                               unsigned handle, unsigned *array_mode)
 {
-       struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo));
-       struct radeon_bo *bo;
+       struct r600_bo *bo = calloc(1, sizeof(struct r600_bo));
+       struct radeon_bo *rbo;
 
-       ws_bo->pb = radeon_bo_pb_create_buffer_from_handle(radeon->kman, handle);
-       if (!ws_bo->pb) {
-               free(ws_bo);
+       rbo = bo->bo = radeon_bo(radeon, handle, 0, 0);
+       if (rbo == NULL) {
+               free(bo);
                return NULL;
        }
-       bo = radeon_bo_pb_get_bo(ws_bo->pb);
-       ws_bo->size = bo->size;
-       ws_bo->domains = (RADEON_GEM_DOMAIN_CPU |
-                         RADEON_GEM_DOMAIN_GTT |
-                         RADEON_GEM_DOMAIN_VRAM);
+       bo->size = rbo->size;
+       bo->domains = (RADEON_GEM_DOMAIN_CPU |
+                       RADEON_GEM_DOMAIN_GTT |
+                       RADEON_GEM_DOMAIN_VRAM);
 
-       pipe_reference_init(&ws_bo->reference, 1);
+       pipe_reference_init(&bo->reference, 1);
 
-       radeon_bo_get_tiling_flags(radeon, bo, &ws_bo->tiling_flags,
-                                  &ws_bo->kernel_pitch);
+       radeon_bo_get_tiling_flags(radeon, rbo, &bo->tiling_flags, &bo->kernel_pitch);
        if (array_mode) {
-               if (ws_bo->tiling_flags) {
-                       if (ws_bo->tiling_flags & RADEON_TILING_MICRO)
+               if (bo->tiling_flags) {
+                       if (bo->tiling_flags & RADEON_TILING_MICRO)
                                *array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
-                       if ((ws_bo->tiling_flags & (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) ==
+                       if ((bo->tiling_flags & (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) ==
                            (RADEON_TILING_MICRO | RADEON_TILING_MACRO))
                                *array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
                } else {
                        *array_mode = 0;
                }
        }
-       return ws_bo;
+       return bo;
 }
 
 void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx)
 {
-       return pb_map(bo->pb, usage, ctx);
+       struct pipe_context *pctx = ctx;
+
+       if (usage & PB_USAGE_UNSYNCHRONIZED) {
+               radeon_bo_map(radeon, bo->bo);
+               return (uint8_t *) bo->bo->data + bo->offset;
+       }
+
+       if (p_atomic_read(&bo->bo->reference.count) > 1) {
+               if (usage & PB_USAGE_DONTBLOCK) {
+                       return NULL;
+               }
+               if (ctx) {
+                       pctx->flush(pctx, 0, NULL);
+               }
+       }
+
+       if (usage & PB_USAGE_DONTBLOCK) {
+               uint32_t domain;
+
+               if (radeon_bo_busy(radeon, bo->bo, &domain))
+                       return NULL;
+               if (radeon_bo_map(radeon, bo->bo)) {
+                       return NULL;
+               }
+               goto out;
+       }
+
+       radeon_bo_map(radeon, bo->bo);
+       if (radeon_bo_wait(radeon, bo->bo)) {
+               radeon_bo_unmap(radeon, bo->bo);
+               return NULL;
+       }
+
+out:
+       return (uint8_t *) bo->bo->data + bo->offset;
 }
 
 void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo)
 {
-       pb_unmap(bo->pb);
+       radeon_bo_unmap(radeon, bo->bo);
 }
 
-static void r600_bo_destroy(struct radeon *radeon, struct r600_bo *bo)
+void r600_bo_destroy(struct radeon *radeon, struct r600_bo *bo)
 {
-       if (bo->pb)
-               pb_reference(&bo->pb, NULL);
+       if (bo->manager_id) {
+               if (!r600_bomgr_bo_destroy(radeon->bomgr, bo)) {
+                       /* destroy is delayed by buffer manager */
+                       return;
+               }
+       }
+       radeon_bo_reference(radeon, &bo->bo, NULL);
        free(bo);
 }
 
-void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst,
-                           struct r600_bo *src)
+void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, struct r600_bo *src)
 {
        struct r600_bo *old = *dst;
-               
+
        if (pipe_reference(&(*dst)->reference, &src->reference)) {
                r600_bo_destroy(radeon, old);
        }
        *dst = src;
 }
 
-unsigned r600_bo_get_handle(struct r600_bo *pb_bo)
-{
-       struct radeon_bo *bo;
-
-       bo = radeon_bo_pb_get_bo(pb_bo->pb);
-       if (!bo)
-               return 0;
-
-       return bo->handle;
-}
-
-unsigned r600_bo_get_size(struct r600_bo *pb_bo)
-{
-       struct radeon_bo *bo;
-
-       bo = radeon_bo_pb_get_bo(pb_bo->pb);
-       if (!bo)
-               return 0;
-
-       return bo->size;
-}
-
-boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo,
+boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *bo,
                                unsigned stride, struct winsys_handle *whandle)
 {
-       struct radeon_bo *bo;
-
-       bo = radeon_bo_pb_get_bo(pb_bo->pb);
-       if (!bo)
-               return FALSE;
-
        whandle->stride = stride;
        switch(whandle->type) {
        case DRM_API_HANDLE_TYPE_KMS:
-               whandle->handle = r600_bo_get_handle(pb_bo);
+               whandle->handle = r600_bo_get_handle(bo);
                break;
        case DRM_API_HANDLE_TYPE_SHARED:
-               if (radeon_bo_get_name(radeon, bo, &whandle->handle))
+               if (radeon_bo_get_name(radeon, bo->bo, &whandle->handle))
                        return FALSE;
                break;
        default:
diff --git a/src/gallium/winsys/r600/drm/r600_bomgr.c b/src/gallium/winsys/r600/drm/r600_bomgr.c
new file mode 100644 (file)
index 0000000..446ef0f
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2010 VMWare.
+ * Copyright 2010 Red Hat 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:
+ *      Jose Fonseca <jrfonseca-at-vmware-dot-com>
+ *      Thomas Hellström <thomas-at-vmware-dot-com>
+ *      Jerome Glisse <jglisse@redhat.com>
+ */
+#include <util/u_memory.h>
+#include <util/u_double_list.h>
+#include <util/u_time.h>
+#include <pipebuffer/pb_bufmgr.h>
+#include "r600_priv.h"
+
+static void r600_bomgr_timeout_flush(struct r600_bomgr *mgr)
+{
+       struct r600_bo *bo, *tmp;
+       int64_t now;
+
+       now = os_time_get();
+       LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &mgr->delayed, list) {
+               if(!os_time_timeout(bo->start, bo->end, now))
+                       break;
+
+               mgr->num_delayed--;
+               bo->manager_id = 0;
+               LIST_DEL(&bo->list);
+               r600_bo_destroy(mgr->radeon, bo);
+       }
+}
+
+static INLINE int r600_bo_is_compat(struct r600_bomgr *mgr,
+                                       struct r600_bo *bo,
+                                       unsigned size,
+                                       unsigned alignment,
+                                       unsigned cfence)
+{
+       if(bo->size < size) {
+               return 0;
+       }
+
+       /* be lenient with size */
+       if(bo->size >= 2*size) {
+               return 0;
+       }
+
+       if(!pb_check_alignment(alignment, bo->alignment)) {
+               return 0;
+       }
+
+       if (!fence_is_after(cfence, bo->fence)) {
+               return 0;
+       }
+
+       return 1;
+}
+
+struct r600_bo *r600_bomgr_bo_create(struct r600_bomgr *mgr,
+                                       unsigned size,
+                                       unsigned alignment,
+                                       unsigned cfence)
+{
+       struct r600_bo *bo, *tmp;
+       int64_t now;
+
+
+       pipe_mutex_lock(mgr->mutex);
+
+       now = os_time_get();
+       LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &mgr->delayed, list) {
+               if(r600_bo_is_compat(mgr, bo, size, alignment, cfence)) {
+                       LIST_DEL(&bo->list);
+                       --mgr->num_delayed;
+                       r600_bomgr_timeout_flush(mgr);
+                       pipe_mutex_unlock(mgr->mutex);
+                       LIST_INITHEAD(&bo->list);
+                       pipe_reference_init(&bo->reference, 1);
+                       return bo;
+               }
+
+               if(os_time_timeout(bo->start, bo->end, now)) {
+                       mgr->num_delayed--;
+                       bo->manager_id = 0;
+                       LIST_DEL(&bo->list);
+                       r600_bo_destroy(mgr->radeon, bo);
+               }
+       }
+
+       pipe_mutex_unlock(mgr->mutex);
+       return NULL;
+}
+
+void r600_bomgr_bo_init(struct r600_bomgr *mgr, struct r600_bo *bo)
+{
+       LIST_INITHEAD(&bo->list);
+       bo->manager_id = 1;
+}
+
+bool r600_bomgr_bo_destroy(struct r600_bomgr *mgr, struct r600_bo *bo)
+{
+       bo->start = os_time_get();
+       bo->end = bo->start + mgr->usecs;
+       pipe_mutex_lock(mgr->mutex);
+       LIST_ADDTAIL(&bo->list, &mgr->delayed);
+       ++mgr->num_delayed;
+       pipe_mutex_unlock(mgr->mutex);
+       return FALSE;
+}
+
+void r600_bomgr_destroy(struct r600_bomgr *mgr)
+{
+       struct r600_bo *bo, *tmp;
+
+       pipe_mutex_lock(mgr->mutex);
+       LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &mgr->delayed, list) {
+               mgr->num_delayed--;
+               bo->manager_id = 0;
+               LIST_DEL(&bo->list);
+               r600_bo_destroy(mgr->radeon, bo);
+       }
+       pipe_mutex_unlock(mgr->mutex);
+
+       FREE(mgr);
+}
+
+struct r600_bomgr *r600_bomgr_create(struct radeon *radeon, unsigned usecs)
+{
+       struct r600_bomgr *mgr;
+
+       mgr = CALLOC_STRUCT(r600_bomgr);
+       if (mgr == NULL)
+               return NULL;
+
+       mgr->radeon = radeon;
+       mgr->usecs = usecs;
+       LIST_INITHEAD(&mgr->delayed);
+       mgr->num_delayed = 0;
+       pipe_mutex_init(mgr->mutex);
+
+       return mgr;
+}
index 6742993ef3e9ae3190b45e251c132c18bb6136a9..3cbbf91878d670cb03119d1175c531ca6453ac54 100644 (file)
@@ -30,7 +30,6 @@
 #include <sys/ioctl.h>
 #include "util/u_inlines.h"
 #include "util/u_debug.h"
-#include <pipebuffer/pb_bufmgr.h>
 #include "r600.h"
 #include "r600_priv.h"
 #include "r600_drm_public.h"
@@ -40,6 +39,9 @@
 #ifndef RADEON_INFO_TILING_CONFIG
 #define RADEON_INFO_TILING_CONFIG 0x6
 #endif
+
+static struct radeon *radeon_new(int fd, unsigned device);
+
 static int radeon_get_device(struct radeon *radeon)
 {
        struct drm_radeon_info info;
@@ -108,7 +110,7 @@ static int radeon_drm_get_tiling(struct radeon *radeon)
        return 0;
 }
 
-struct radeon *radeon_new(int fd, unsigned device)
+static struct radeon *radeon_new(int fd, unsigned device)
 {
        struct radeon *radeon;
        int r;
@@ -150,6 +152,7 @@ struct radeon *radeon_new(int fd, unsigned device)
        case CHIP_JUNIPER:
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
+       case CHIP_PALM:
                break;
        case CHIP_R100:
        case CHIP_RV100:
@@ -211,6 +214,7 @@ struct radeon *radeon_new(int fd, unsigned device)
        case CHIP_JUNIPER:
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
+       case CHIP_PALM:
                radeon->chip_class = EVERGREEN;
                /* set default group bytes, overridden by tiling info ioctl */
                radeon->tiling_info.group_bytes = 512;
@@ -225,12 +229,10 @@ struct radeon *radeon_new(int fd, unsigned device)
                if (radeon_drm_get_tiling(radeon))
                        return NULL;
        }
-       radeon->kman = radeon_bo_pbmgr_create(radeon);
-       if (!radeon->kman)
-               return NULL;
-       radeon->cman = pb_cache_manager_create(radeon->kman, 100000);
-       if (!radeon->cman)
+       radeon->bomgr = r600_bomgr_create(radeon, 1000000);
+       if (radeon->bomgr == NULL) {
                return NULL;
+       }
        return radeon;
 }
 
@@ -247,14 +249,11 @@ struct radeon *radeon_decref(struct radeon *radeon)
                return NULL;
        }
 
-        if (radeon->cman)
-           radeon->cman->destroy(radeon->cman);
-
-        if (radeon->kman)
-           radeon->kman->destroy(radeon->kman);
+       if (radeon->bomgr)
+               r600_bomgr_destroy(radeon->bomgr);
 
-        if (radeon->fd >= 0)
-           drmClose(radeon->fd);
+       if (radeon->fd >= 0)
+               drmClose(radeon->fd);
 
        free(radeon);
        return NULL;
index de228918953590f91722ee2358ee027252b0dc29..d01ec3ee9b0cce262eaa2d7d49c323cfff8c0d9a 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <pipe/p_compiler.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include <pipebuffer/pb_bufmgr.h>
 #include "xf86drm.h"
-#include "r600.h"
-#include "r600d.h"
 #include "radeon_drm.h"
-#include "bof.h"
-#include "pipe/p_compiler.h"
-#include "util/u_inlines.h"
-#include "util/u_memory.h"
-#include <pipebuffer/pb_bufmgr.h>
 #include "r600_priv.h"
+#include "bof.h"
+#include "r600d.h"
 
 #define GROUP_FORCE_NEW_BLOCK  0
 
@@ -50,6 +49,7 @@ int r600_context_init_fence(struct r600_context *ctx)
        }
        ctx->cfence = r600_bo_map(ctx->radeon, ctx->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL);
        *ctx->cfence = 0;
+       ctx->radeon->cfence = ctx->cfence;
        LIST_INITHEAD(&ctx->fenced_bo);
        return 0;
 }
@@ -618,6 +618,9 @@ void r600_context_fini(struct r600_context *ctx)
                                        range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
                                        range->blocks[CTX_BLOCK_ID(ctx, offset)] = NULL;
                                }
+                               for (int k = 1; k <= block->nbo; k++) {
+                                       r600_bo_reference(ctx->radeon, &block->reloc[k].bo, NULL);
+                               }
                                free(block);
                        }
                }
@@ -811,6 +814,7 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *r
        ctx->reloc[ctx->creloc].write_domain = rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM);
        ctx->reloc[ctx->creloc].flags = 0;
        radeon_bo_reference(ctx->radeon, &ctx->bo[ctx->creloc], bo);
+       rbo->fence = ctx->fence;
        ctx->creloc++;
        /* set PKT3 to point to proper reloc */
        *pm4 = bo->reloc_id;
@@ -833,6 +837,7 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat
                        /* find relocation */
                        id = block->pm4_bo_index[id];
                        r600_bo_reference(ctx->radeon, &block->reloc[id].bo, state->regs[i].bo);
+                       state->regs[i].bo->fence = ctx->fence;
                }
                if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
                        block->status |= R600_BLOCK_STATUS_ENABLED;
@@ -872,10 +877,13 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx
                 */
                r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[0].bo);
                r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[0].bo);
+               state->regs[0].bo->fence = ctx->fence;
        } else {
                /* TEXTURE RESOURCE */
                r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo);
                r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[3].bo);
+               state->regs[2].bo->fence = ctx->fence;
+               state->regs[3].bo->fence = ctx->fence;
        }
        if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
@@ -1108,9 +1116,9 @@ void r600_context_flush(struct r600_context *ctx)
        /* suspend queries */
        r600_context_queries_suspend(ctx);
 
-       radeon_bo_pbmgr_flush_maps(ctx->radeon->kman);
-
        /* emit fence */
+       ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0);
+       ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
        ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4);
        ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
        ctx->pm4[ctx->pm4_cdwords++] = 0;
index 9fd77b71c775c562097d47f71fc5a25d6fc9009e..056d0255be2b9c33cd107009c9e5bc74d8fd7668 100644 (file)
 #include <stdint.h>
 #include <stdlib.h>
 #include <assert.h>
-#include <pipebuffer/pb_bufmgr.h>
-#include "util/u_double_list.h"
+#include <util/u_double_list.h>
+#include <util/u_inlines.h>
+#include <os/os_thread.h>
 #include "r600.h"
 
+struct r600_bomgr;
+
 struct radeon {
        int                             fd;
        int                             refcount;
        unsigned                        device;
        unsigned                        family;
        enum chip_class                 chip_class;
-       struct pb_manager *kman; /* kernel bo manager */
-       struct pb_manager *cman; /* cached bo manager */
-       struct r600_tiling_info tiling_info;
+       struct r600_tiling_info         tiling_info;
+       struct r600_bomgr               *bomgr;
+       unsigned                        *cfence;
 };
 
-struct radeon *r600_new(int fd, unsigned device);
-void r600_delete(struct radeon *r600);
-
 struct r600_reg {
        unsigned                        opcode;
        unsigned                        offset_base;
@@ -75,28 +75,49 @@ struct radeon_bo {
 
 struct r600_bo {
        struct pipe_reference           reference;
-       struct pb_buffer                *pb;
        unsigned                        size;
        unsigned                        tiling_flags;
-       unsigned                        kernel_pitch;
+       unsigned                        kernel_pitch;
        unsigned                        domains;
+       struct radeon_bo                *bo;
+       unsigned                        fence;
+       /* manager data */
+       struct list_head                list;
+       unsigned                        manager_id;
+       unsigned                        alignment;
+       unsigned                        offset;
+       int64_t                         start;
+       int64_t                         end;
 };
 
+struct r600_bomgr {
+       struct radeon                   *radeon;
+       unsigned                        usecs;
+       pipe_mutex                      mutex;
+       struct list_head                delayed;
+       unsigned                        num_delayed;
+};
 
-/* radeon_pciid.c */
-unsigned radeon_family_from_device(unsigned device);
+/*
+ * r600_drm.c
+ */
+struct radeon *r600_new(int fd, unsigned device);
+void r600_delete(struct radeon *r600);
 
-/* r600_drm.c */
-struct radeon *radeon_decref(struct radeon *radeon);
+/*
+ * radeon_pciid.c
+ */
+unsigned radeon_family_from_device(unsigned device);
 
-/* radeon_bo.c */
+/*
+ * radeon_bo.c
+ */
 struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
                            unsigned size, unsigned alignment);
 void radeon_bo_reference(struct radeon *radeon, struct radeon_bo **dst,
                         struct radeon_bo *src);
 int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo);
 int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain);
-void radeon_bo_pbmgr_flush_maps(struct pb_manager *_mgr);
 int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist, uint32_t num_bo);
 int radeon_bo_get_tiling_flags(struct radeon *radeon,
                               struct radeon_bo *bo,
@@ -106,13 +127,9 @@ int radeon_bo_get_name(struct radeon *radeon,
                       struct radeon_bo *bo,
                       uint32_t *name);
 
-/* radeon_bo_pb.c */
-struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf);
-struct pb_manager *radeon_bo_pbmgr_create(struct radeon *radeon);
-struct pb_buffer *radeon_bo_pb_create_buffer_from_handle(struct pb_manager *_mgr,
-                                                        uint32_t handle);
-
-/* r600_hw_context.c */
+/*
+ * r600_hw_context.c
+ */
 int r600_context_init_fence(struct r600_context *ctx);
 void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *rbo);
 void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
@@ -120,14 +137,27 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
 struct r600_bo *r600_context_reg_bo(struct r600_context *ctx, unsigned offset);
 int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, unsigned nreg);
 
-/* r600_bo.c */
-unsigned r600_bo_get_handle(struct r600_bo *bo);
-unsigned r600_bo_get_size(struct r600_bo *bo);
-static INLINE struct radeon_bo *r600_bo_get_bo(struct r600_bo *bo)
-{
-       return radeon_bo_pb_get_bo(bo->pb);
-}
+/*
+ * r600_bo.c
+ */
+void r600_bo_destroy(struct radeon *radeon, struct r600_bo *bo);
 
+/*
+ * r600_bomgr.c
+ */
+struct r600_bomgr *r600_bomgr_create(struct radeon *radeon, unsigned usecs);
+void r600_bomgr_destroy(struct r600_bomgr *mgr);
+bool r600_bomgr_bo_destroy(struct r600_bomgr *mgr, struct r600_bo *bo);
+void r600_bomgr_bo_init(struct r600_bomgr *mgr, struct r600_bo *bo);
+struct r600_bo *r600_bomgr_bo_create(struct r600_bomgr *mgr,
+                                       unsigned size,
+                                       unsigned alignment,
+                                       unsigned cfence);
+
+
+/*
+ * helpers
+ */
 #define CTX_RANGE_ID(ctx, offset) (((offset) >> (ctx)->hash_shift) & 255)
 #define CTX_BLOCK_ID(ctx, offset) ((offset) & ((1 << (ctx)->hash_shift) - 1))
 
@@ -175,6 +205,9 @@ static inline void r600_context_block_emit_dirty(struct r600_context *ctx, struc
        LIST_DELINIT(&block->list);
 }
 
+/*
+ * radeon_bo.c
+ */
 static inline int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo)
 {
        bo->map_count++;
@@ -187,4 +220,35 @@ static inline void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo)
        assert(bo->map_count >= 0);
 }
 
+/*
+ * r600_bo
+ */
+static inline struct radeon_bo *r600_bo_get_bo(struct r600_bo *bo)
+{
+       return bo->bo;
+}
+
+static unsigned inline r600_bo_get_handle(struct r600_bo *bo)
+{
+       return bo->bo->handle;
+}
+
+static unsigned inline r600_bo_get_size(struct r600_bo *bo)
+{
+       return bo->size;
+}
+
+/*
+ * fence
+ */
+static inline bool fence_is_after(unsigned fence, unsigned ofence)
+{
+       /* handle wrap around */
+       if (fence < 0x80000000 && ofence > 0x80000000)
+               return TRUE;
+       if (fence > ofence)
+               return TRUE;
+       return FALSE;
+}
+
 #endif
index 4a08d504aabfcece687df22f606a90f8a71018e6..1c1ac76fe69d0b5099b1e91353b47e0a7597b3eb 100644 (file)
@@ -91,6 +91,7 @@
 #define PKT3_SET_CTL_CONST                     0x6F
 #define PKT3_SURFACE_BASE_UPDATE               0x73
 
+#define EVENT_TYPE_PS_PARTIAL_FLUSH            0x10
 #define EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT 0x14
 #define EVENT_TYPE_ZPASS_DONE                  0x15
 #define EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT   0x16
diff --git a/src/gallium/winsys/r600/drm/radeon_bo_pb.c b/src/gallium/winsys/r600/drm/radeon_bo_pb.c
deleted file mode 100644 (file)
index 312552f..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright 2010 Dave Airlie
- *
- * Permission is hereby granted, free of charge, to 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:
- *      Dave Airlie
- */
-#include <util/u_inlines.h>
-#include <util/u_memory.h>
-#include <util/u_double_list.h>
-#include <pipebuffer/pb_buffer.h>
-#include <pipebuffer/pb_bufmgr.h>
-#include "r600_priv.h"
-
-struct radeon_bo_pb {
-       struct pb_buffer b;
-       struct radeon_bo *bo;
-
-       struct radeon_bo_pbmgr *mgr;
-       struct list_head maplist;
-};
-
-extern const struct pb_vtbl radeon_bo_pb_vtbl;
-
-static INLINE struct radeon_bo_pb *radeon_bo_pb(struct pb_buffer *buf)
-{
-       assert(buf);
-       assert(buf->vtbl == &radeon_bo_pb_vtbl);
-       return (struct radeon_bo_pb *)buf;
-}
-
-struct radeon_bo_pbmgr {
-       struct pb_manager b;
-       struct radeon *radeon;
-       struct list_head buffer_map_list;
-};
-
-static INLINE struct radeon_bo_pbmgr *radeon_bo_pbmgr(struct pb_manager *mgr)
-{
-       assert(mgr);
-       return (struct radeon_bo_pbmgr *)mgr;
-}
-
-static void radeon_bo_pb_destroy(struct pb_buffer *_buf)
-{
-       struct radeon_bo_pb *buf = radeon_bo_pb(_buf);
-
-       /* If this buffer is on the list of buffers to unmap,
-        * do the unmapping now.
-        */
-       if (!LIST_IS_EMPTY(&buf->maplist))
-               radeon_bo_unmap(buf->mgr->radeon, buf->bo);
-
-       LIST_DEL(&buf->maplist);
-       radeon_bo_reference(buf->mgr->radeon, &buf->bo, NULL);
-       FREE(buf);
-}
-
-static void *
-radeon_bo_pb_map_internal(struct pb_buffer *_buf,
-                         unsigned flags, void *ctx)
-{
-       struct radeon_bo_pb *buf = radeon_bo_pb(_buf);
-       struct pipe_context *pctx = ctx;
-
-       if (flags & PB_USAGE_UNSYNCHRONIZED) {
-               if (radeon_bo_map(buf->mgr->radeon, buf->bo)) {
-                       return NULL;
-               }
-               LIST_DELINIT(&buf->maplist);
-               return buf->bo->data;
-       }
-
-       if (p_atomic_read(&buf->bo->reference.count) > 1) {
-               if (flags & PB_USAGE_DONTBLOCK) {
-                       return NULL;
-               }
-               if (ctx) {
-                       pctx->flush(pctx, 0, NULL);
-               }
-       }
-
-       if (flags & PB_USAGE_DONTBLOCK) {
-               uint32_t domain;
-               if (radeon_bo_busy(buf->mgr->radeon, buf->bo, &domain))
-                       return NULL;
-               if (radeon_bo_map(buf->mgr->radeon, buf->bo)) {
-                       return NULL;
-               }
-               goto out;
-       }
-
-       if (radeon_bo_map(buf->mgr->radeon, buf->bo)) {
-               return NULL;
-       }
-       if (radeon_bo_wait(buf->mgr->radeon, buf->bo)) {
-               radeon_bo_unmap(buf->mgr->radeon, buf->bo);
-               return NULL;
-       }
-out:
-       LIST_DELINIT(&buf->maplist);
-       return buf->bo->data;
-}
-
-static void radeon_bo_pb_unmap_internal(struct pb_buffer *_buf)
-{
-       struct radeon_bo_pb *buf = radeon_bo_pb(_buf);
-       LIST_ADDTAIL(&buf->maplist, &buf->mgr->buffer_map_list);
-}
-
-static void
-radeon_bo_pb_get_base_buffer(struct pb_buffer *buf,
-                            struct pb_buffer **base_buf,
-                            unsigned *offset)
-{
-       *base_buf = buf;
-       *offset = 0;
-}
-
-static enum pipe_error
-radeon_bo_pb_validate(struct pb_buffer *_buf, 
-                     struct pb_validate *vl,
-                     unsigned flags)
-{
-       /* Always pinned */
-       return PIPE_OK;
-}
-
-static void
-radeon_bo_pb_fence(struct pb_buffer *buf,
-                  struct pipe_fence_handle *fence)
-{
-}
-
-const struct pb_vtbl radeon_bo_pb_vtbl = {
-    radeon_bo_pb_destroy,
-    radeon_bo_pb_map_internal,
-    radeon_bo_pb_unmap_internal,
-    radeon_bo_pb_validate,
-    radeon_bo_pb_fence,
-    radeon_bo_pb_get_base_buffer,
-};
-
-struct pb_buffer *
-radeon_bo_pb_create_buffer_from_handle(struct pb_manager *_mgr,
-                                      uint32_t handle)
-{
-       struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
-       struct radeon *radeon = mgr->radeon;
-       struct radeon_bo_pb *bo;
-       struct radeon_bo *hw_bo;
-
-       hw_bo = radeon_bo(radeon, handle, 0, 0);
-       if (hw_bo == NULL)
-               return NULL;
-
-       bo = CALLOC_STRUCT(radeon_bo_pb);
-       if (!bo) {
-               radeon_bo_reference(radeon, &hw_bo, NULL);
-               return NULL;
-       }
-
-       LIST_INITHEAD(&bo->maplist);
-       pipe_reference_init(&bo->b.base.reference, 1);
-       bo->b.base.alignment = 0;
-       bo->b.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
-       bo->b.base.size = hw_bo->size;
-       bo->b.vtbl = &radeon_bo_pb_vtbl;
-       bo->mgr = mgr;
-
-       bo->bo = hw_bo;
-
-       return &bo->b;
-}
-
-static struct pb_buffer *
-radeon_bo_pb_create_buffer(struct pb_manager *_mgr,
-                          pb_size size,
-                          const struct pb_desc *desc)
-{
-       struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
-       struct radeon *radeon = mgr->radeon;
-       struct radeon_bo_pb *bo;
-
-       bo = CALLOC_STRUCT(radeon_bo_pb);
-       if (!bo)
-               goto error1;
-
-       pipe_reference_init(&bo->b.base.reference, 1);
-       bo->b.base.alignment = desc->alignment;
-       bo->b.base.usage = desc->usage;
-       bo->b.base.size = size;
-       bo->b.vtbl = &radeon_bo_pb_vtbl;
-       bo->mgr = mgr;
-
-       LIST_INITHEAD(&bo->maplist);
-
-       bo->bo = radeon_bo(radeon, 0, size, desc->alignment);
-       if (bo->bo == NULL)
-               goto error2;
-       return &bo->b;
-
-error2:
-       FREE(bo);
-error1:
-       return NULL;
-}
-
-static void
-radeon_bo_pbmgr_flush(struct pb_manager *mgr)
-{
-    /* NOP */
-}
-
-static void
-radeon_bo_pbmgr_destroy(struct pb_manager *_mgr)
-{
-       struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
-       FREE(mgr);
-}
-
-struct pb_manager *radeon_bo_pbmgr_create(struct radeon *radeon)
-{
-       struct radeon_bo_pbmgr *mgr;
-
-       mgr = CALLOC_STRUCT(radeon_bo_pbmgr);
-       if (!mgr)
-               return NULL;
-
-       mgr->b.destroy = radeon_bo_pbmgr_destroy;
-       mgr->b.create_buffer = radeon_bo_pb_create_buffer;
-       mgr->b.flush = radeon_bo_pbmgr_flush;
-
-       mgr->radeon = radeon;
-       LIST_INITHEAD(&mgr->buffer_map_list);
-       return &mgr->b;
-}
-
-void radeon_bo_pbmgr_flush_maps(struct pb_manager *_mgr)
-{
-       struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
-       struct radeon_bo_pb *rpb = NULL;
-       struct radeon_bo_pb *t_rpb;
-
-       LIST_FOR_EACH_ENTRY_SAFE(rpb, t_rpb, &mgr->buffer_map_list, maplist) {
-               radeon_bo_unmap(mgr->radeon, rpb->bo);
-               LIST_DELINIT(&rpb->maplist);
-       }
-
-       LIST_INITHEAD(&mgr->buffer_map_list);
-}
-
-struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf)
-{
-       struct radeon_bo_pb *buf;
-       if (_buf->vtbl == &radeon_bo_pb_vtbl) {
-               buf = radeon_bo_pb(_buf);
-               return buf->bo;
-       } else {
-               struct pb_buffer *base_buf;
-               pb_size offset;
-               pb_get_base_buffer(_buf, &base_buf, &offset);
-               if (base_buf->vtbl == &radeon_bo_pb_vtbl) {
-                       buf = radeon_bo_pb(base_buf);
-                       return buf->bo;
-               }
-       }
-       return NULL;
-}
index 08cc1c41e378513dad6ec76c10d41aebf2dbb450..92560a488ae5637981021e90f52581f95191a2ce 100644 (file)
@@ -24,7 +24,7 @@
  *      Jerome Glisse
  */
 #include <stdlib.h>
-#include "r600.h"
+#include "r600_priv.h"
 
 struct pci_id {
        unsigned        vendor;
@@ -441,6 +441,10 @@ struct pci_id radeon_pci_id[] = {
        {0x1002, 0x9713, CHIP_RS880},
        {0x1002, 0x9714, CHIP_RS880},
        {0x1002, 0x9715, CHIP_RS880},
+       {0x1002, 0x9802, CHIP_PALM},
+       {0x1002, 0x9803, CHIP_PALM},
+       {0x1002, 0x9804, CHIP_PALM},
+       {0x1002, 0x9805, CHIP_PALM},
        {0, 0},
 };
 
@@ -456,73 +460,3 @@ unsigned radeon_family_from_device(unsigned device)
        }
        return CHIP_UNKNOWN;
 }
-
-int radeon_is_family_compatible(unsigned family1, unsigned family2)
-{
-       switch (family1) {
-       case CHIP_R600:
-       case CHIP_RV610:
-       case CHIP_RV630:
-       case CHIP_RV670:
-       case CHIP_RV620:
-       case CHIP_RV635:
-       case CHIP_RS780:
-       case CHIP_RS880:
-       case CHIP_RV770:
-       case CHIP_RV730:
-       case CHIP_RV710:
-       case CHIP_RV740:
-               switch (family2) {
-               case CHIP_R600:
-               case CHIP_RV610:
-               case CHIP_RV630:
-               case CHIP_RV670:
-               case CHIP_RV620:
-               case CHIP_RV635:
-               case CHIP_RS780:
-               case CHIP_RS880:
-               case CHIP_RV770:
-               case CHIP_RV730:
-               case CHIP_RV710:
-               case CHIP_RV740:
-                       return 1;
-               default:
-                       return 0;
-               }
-               break;
-       case CHIP_R100:
-       case CHIP_RV100:
-       case CHIP_RS100:
-       case CHIP_RV200:
-       case CHIP_RS200:
-       case CHIP_R200:
-       case CHIP_RV250:
-       case CHIP_RS300:
-       case CHIP_RV280:
-       case CHIP_R300:
-       case CHIP_R350:
-       case CHIP_RV350:
-       case CHIP_RV380:
-       case CHIP_R420:
-       case CHIP_R423:
-       case CHIP_RV410:
-       case CHIP_RS400:
-       case CHIP_RS480:
-       case CHIP_RS600:
-       case CHIP_RS690:
-       case CHIP_RS740:
-       case CHIP_RV515:
-       case CHIP_R520:
-       case CHIP_RV530:
-       case CHIP_RV560:
-       case CHIP_RV570:
-       case CHIP_R580:
-       case CHIP_CEDAR:
-       case CHIP_REDWOOD:
-       case CHIP_JUNIPER:
-       case CHIP_CYPRESS:
-       case CHIP_HEMLOCK:
-       default:
-               return 0;
-       }
-}
index 7f69e39273599da042112859591c8394adb1d67f..aa73edde34e27139701dd8f263c34cbe83f2d8ce 100644 (file)
@@ -6,7 +6,7 @@ LIBNAME = radeonwinsys
 
 C_SOURCES = \
        radeon_drm_buffer.c \
-       radeon_drm.c \
+       radeon_drm_common.c \
        radeon_r300.c
 
 LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \
index 60e409fe10f01a588907ffcdefd23fc5f8d9eb36..2dbf61a7ba3bf214c177ec15747c04a38ecfe0b0 100644 (file)
@@ -4,7 +4,7 @@ env = env.Clone()
 
 radeon_sources = [
     'radeon_drm_buffer.c',
-    'radeon_drm.c',
+    'radeon_drm_common.c',
     'radeon_r300.c',
 ]
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
deleted file mode 100644 (file)
index a8137d8..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright © 2008 Jérôme Glisse
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
- * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors:
- *      Jérôme Glisse <glisse@freedesktop.org>
- */
-#ifndef RADEON_BUFFER_H
-#define RADEON_BUFFER_H
-
-#include <stdio.h>
-
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-
-#include "pipebuffer/pb_buffer.h"
-#include "pipebuffer/pb_bufmgr.h"
-
-#include "radeon_bo.h"
-#include "radeon_cs.h"
-
-#include "radeon_winsys.h"
-
-#define RADEON_PB_USAGE_VERTEX      (1 << 28)
-#define RADEON_PB_USAGE_DOMAIN_GTT  (1 << 29)
-#define RADEON_PB_USAGE_DOMAIN_VRAM (1 << 30)
-
-static INLINE struct pb_buffer *
-radeon_pb_buffer(struct r300_winsys_buffer *buffer)
-{
-    return (struct pb_buffer *)buffer;
-}
-
-static INLINE struct r300_winsys_buffer *
-radeon_libdrm_winsys_buffer(struct pb_buffer *buffer)
-{
-    return (struct r300_winsys_buffer *)buffer;
-}
-
-struct pb_manager *
-radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
-
-void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *cs,
-                                  struct r300_winsys_buffer *buf,
-                                  enum r300_buffer_domain rd,
-                                  enum r300_buffer_domain wd);
-
-void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *cs,
-                                   struct r300_winsys_buffer *buf,
-                                  enum r300_buffer_domain rd,
-                                   enum r300_buffer_domain wd);
-
-struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
-                                                             uint32_t handle);
-
-void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
-                                  struct r300_winsys_buffer *buf,
-                                  enum r300_buffer_tiling *microtiled,
-                                  enum r300_buffer_tiling *macrotiled);
-
-void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
-                                  struct r300_winsys_buffer *buf,
-                                  enum r300_buffer_tiling microtiled,
-                                  enum r300_buffer_tiling macrotiled,
-                                  uint32_t pitch);
-
-void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
-
-boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
-                                    struct winsys_handle *whandle);
-
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *cs,
-                                               struct r300_winsys_buffer *buf,
-                                               enum r300_reference_domain domain);
-
-void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
-                            struct r300_winsys_buffer *buf);
-
-void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
-                            struct r300_winsys_buffer *buf,
-                            struct r300_winsys_cs *cs,
-                            enum pipe_transfer_usage usage);
-
-void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
-                             struct r300_winsys_buffer *buf);
-
-#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c
deleted file mode 100644 (file)
index 86d4f94..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright © 2009 Corbin Simpson
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
- * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors:
- *      Corbin Simpson <MostAwesomeDude@gmail.com>
- *      Joakim Sindholt <opensource@zhasha.com>
- */
-
-#include "radeon_drm.h"
-#include "radeon_r300.h"
-#include "radeon_buffer.h"
-#include "radeon_drm_public.h"
-
-#include "r300_winsys.h"
-
-#include "util/u_memory.h"
-
-#include "xf86drm.h"
-
-static struct radeon_libdrm_winsys *
-radeon_winsys_create(int fd)
-{
-    struct radeon_libdrm_winsys *rws;
-
-    rws = CALLOC_STRUCT(radeon_libdrm_winsys);
-    if (rws == NULL) {
-        return NULL;
-    }
-
-    rws->fd = fd;
-    return rws;
-}
-
-/* Enable/disable Hyper-Z access. Return TRUE on success. */
-static boolean radeon_set_hyperz_access(int fd, boolean enable)
-{
-#ifndef RADEON_INFO_WANT_HYPERZ
-#define RADEON_INFO_WANT_HYPERZ 7
-#endif
-
-    struct drm_radeon_info info = {0};
-    unsigned value = enable ? 1 : 0;
-
-    if (!debug_get_bool_option("RADEON_HYPERZ", FALSE))
-        return FALSE;
-
-    info.value = (unsigned long)&value;
-    info.request = RADEON_INFO_WANT_HYPERZ;
-
-    if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
-        return FALSE;
-
-    if (enable && !value)
-        return FALSE;
-
-    return TRUE;
-}
-
-/* Helper function to do the ioctls needed for setup and init. */
-static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
-{
-    struct drm_radeon_gem_info gem_info = {0};
-    struct drm_radeon_info info = {0};
-    int target = 0;
-    int retval;
-    drmVersionPtr version;
-
-    info.value = (unsigned long)&target;
-
-    /* We do things in a specific order here.
-     *
-     * DRM version first. We need to be sure we're running on a KMS chipset.
-     * This is also for some features.
-     *
-     * Then, the PCI ID. This is essential and should return usable numbers
-     * for all Radeons. If this fails, we probably got handed an FD for some
-     * non-Radeon card.
-     *
-     * The GB and Z pipe requests should always succeed, but they might not
-     * return sensical values for all chipsets, but that's alright because
-     * the pipe drivers already know that.
-     *
-     * The GEM info is actually bogus on the kernel side, as well as our side
-     * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
-     * we don't actually use the info for anything yet. */
-
-    version = drmGetVersion(fd);
-    if (version->version_major != 2) {
-        fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
-                "only compatible with 2.x.x\n", __FUNCTION__,
-                version->version_major, version->version_minor,
-                version->version_patchlevel);
-        drmFreeVersion(version);
-        exit(1);
-    }
-
-/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
-#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
-    // Supported since 2.1.0.
-    winsys->squaretiling = version->version_major > 2 ||
-                           version->version_minor >= 1;
-#endif
-
-    winsys->drm_2_3_0 = version->version_major > 2 ||
-                        version->version_minor >= 3;
-
-    winsys->drm_2_6_0 = version->version_major > 2 ||
-                        (version->version_major == 2 &&
-                         version->version_minor >= 6);
-
-    info.request = RADEON_INFO_DEVICE_ID;
-    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get PCI ID, "
-                "error number %d\n", __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->pci_id = target;
-
-    info.request = RADEON_INFO_NUM_GB_PIPES;
-    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get GB pipe count, "
-                "error number %d\n", __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->gb_pipes = target;
-
-    info.request = RADEON_INFO_NUM_Z_PIPES;
-    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get Z pipe count, "
-                "error number %d\n", __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->z_pipes = target;
-
-    winsys->hyperz = radeon_set_hyperz_access(fd, TRUE);
-
-    retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
-            &gem_info, sizeof(gem_info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
-                __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->gart_size = gem_info.gart_size;
-    winsys->vram_size = gem_info.vram_size;
-
-    debug_printf("radeon: Successfully grabbed chipset info from kernel!\n"
-                 "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n"
-                 "radeon: GART size: %d MB VRAM size: %d MB\n"
-                 "radeon: HyperZ: %s\n",
-                 version->version_major, version->version_minor,
-                 version->version_patchlevel, winsys->pci_id,
-                 winsys->gb_pipes, winsys->z_pipes,
-                 winsys->gart_size / 1024 / 1024,
-                 winsys->vram_size / 1024 / 1024,
-                 winsys->hyperz ? "YES" : "NO");
-
-    drmFreeVersion(version);
-}
-
-/* Create a pipe_screen. */
-struct r300_winsys_screen* r300_drm_winsys_screen_create(int drmFB)
-{
-    struct radeon_libdrm_winsys* rws; 
-    boolean ret;
-
-    rws = radeon_winsys_create(drmFB);
-    if (!rws)
-       return NULL;
-
-    do_ioctls(drmFB, rws);
-
-    /* The state tracker can organize a softpipe fallback if no hw
-     * driver is found.
-     */
-    if (is_r3xx(rws->pci_id)) {
-        ret = radeon_setup_winsys(drmFB, rws);
-       if (ret == FALSE)
-           goto fail;
-        return &rws->base;
-    }
-
-fail:
-    FREE(rws);
-    return NULL;
-}
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.h b/src/gallium/winsys/radeon/drm/radeon_drm.h
deleted file mode 100644 (file)
index df6dd91..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 
- * Copyright © 2009 Corbin Simpson
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
- * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors:
- *      Corbin Simpson <MostAwesomeDude@gmail.com>
- */
-#ifndef RADEON_DRM_H
-#define RADEON_DRM_H
-
-#include "state_tracker/drm_driver.h"
-
-/* Guess at whether this chipset should use r300g.
- *
- * I believe that this check is valid, but I haven't been exhaustive. */
-static INLINE boolean is_r3xx(int pciid)
-{
-    return (pciid > 0x3150) && (pciid < 0x796f);
-}
-
-#endif
index 78723948d41fbdd1509cee863112f1ebc00df17a..dc4b51747f4c9bef0f32a878d063a2d9615ec279 100644 (file)
@@ -1,19 +1,17 @@
-
-#include <sys/ioctl.h>
-#include "radeon_drm.h"
-#include "radeon_bo_gem.h"
 #include "radeon_cs_gem.h"
-#include "radeon_buffer.h"
+#include "radeon_drm_buffer.h"
 
 #include "util/u_hash_table.h"
-#include "util/u_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_simple_list.h"
-#include "pipebuffer/pb_buffer.h"
 #include "pipebuffer/pb_bufmgr.h"
 #include "os/os_thread.h"
 
-#include "radeon_winsys.h"
+#include "state_tracker/drm_driver.h"
+
+#include <radeon_drm.h>
+#include <radeon_bo_gem.h>
+#include <sys/ioctl.h>
 
 struct radeon_drm_bufmgr;
 
@@ -45,7 +43,7 @@ struct radeon_drm_bufmgr {
     struct pb_manager base;
 
     /* Winsys. */
-    struct radeon_libdrm_winsys *rws;
+    struct radeon_drm_winsys *rws;
 
     /* List of mapped buffers and its mutex. */
     struct radeon_drm_buffer buffer_map_list;
@@ -115,7 +113,7 @@ radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
                               unsigned flags, void *flush_ctx)
 {
     struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
-    struct radeon_libdrm_cs *cs = flush_ctx;
+    struct radeon_drm_cs *cs = flush_ctx;
     int write = 0;
 
     /* Note how we use radeon_bo_is_referenced_by_cs here. There are
@@ -225,7 +223,7 @@ radeon_drm_bufmgr_create_buffer_from_handle_unsafe(struct pb_manager *_mgr,
                                                    uint32_t handle)
 {
     struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
-    struct radeon_libdrm_winsys *rws = mgr->rws;
+    struct radeon_drm_winsys *rws = mgr->rws;
     struct radeon_drm_buffer *buf;
     struct radeon_bo *bo;
 
@@ -284,7 +282,7 @@ radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
                                const struct pb_desc *desc)
 {
     struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
-    struct radeon_libdrm_winsys *rws = mgr->rws;
+    struct radeon_drm_winsys *rws = mgr->rws;
     struct radeon_drm_buffer *buf;
     uint32_t domain;
 
@@ -345,7 +343,7 @@ static int handle_compare(void *key1, void *key2)
 }
 
 struct pb_manager *
-radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
+radeon_drm_bufmgr_create(struct radeon_drm_winsys *rws)
 {
     struct radeon_drm_bufmgr *mgr;
 
@@ -383,18 +381,18 @@ static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
     return buf;
 }
 
-void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
-                            struct r300_winsys_buffer *buf,
-                            struct r300_winsys_cs *cs,
-                            enum pipe_transfer_usage usage)
+static void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
+                                   struct r300_winsys_buffer *buf,
+                                   struct r300_winsys_cs *cs,
+                                   enum pipe_transfer_usage usage)
 {
     struct pb_buffer *_buf = radeon_pb_buffer(buf);
 
-    return pb_map(_buf, get_pb_usage_from_transfer_flags(usage), radeon_libdrm_cs(cs));
+    return pb_map(_buf, get_pb_usage_from_transfer_flags(usage), radeon_drm_cs(cs));
 }
 
-void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
-                             struct r300_winsys_buffer *buf)
+static void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
+                                    struct r300_winsys_buffer *buf)
 {
     struct pb_buffer *_buf = radeon_pb_buffer(buf);
 
@@ -425,10 +423,10 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
     return TRUE;
 }
 
-void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
-                                  struct r300_winsys_buffer *_buf,
-                                  enum r300_buffer_tiling *microtiled,
-                                  enum r300_buffer_tiling *macrotiled)
+static void radeon_drm_buffer_get_tiling(struct r300_winsys_screen *ws,
+                                         struct r300_winsys_buffer *_buf,
+                                         enum r300_buffer_tiling *microtiled,
+                                         enum r300_buffer_tiling *macrotiled)
 {
     struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
     uint32_t flags = 0, pitch;
@@ -444,11 +442,11 @@ void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
        *macrotiled = R300_BUFFER_TILED;
 }
 
-void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
-                                  struct r300_winsys_buffer *_buf,
-                                  enum r300_buffer_tiling microtiled,
-                                  enum r300_buffer_tiling macrotiled,
-                                  uint32_t pitch)
+static void radeon_drm_buffer_set_tiling(struct r300_winsys_screen *ws,
+                                         struct r300_winsys_buffer *_buf,
+                                         enum r300_buffer_tiling microtiled,
+                                         enum r300_buffer_tiling macrotiled,
+                                         uint32_t pitch)
 {
     struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
     uint32_t flags = 0;
@@ -465,66 +463,60 @@ void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
     radeon_bo_set_tiling(buf->bo, flags, pitch);
 }
 
-static uint32_t get_gem_domain(enum r300_buffer_domain domain)
-{
-    uint32_t res = 0;
-
-    if (domain & R300_DOMAIN_GTT)
-        res |= RADEON_GEM_DOMAIN_GTT;
-    if (domain & R300_DOMAIN_VRAM)
-        res |= RADEON_GEM_DOMAIN_VRAM;
-    return res;
-}
-
-void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs,
-                                  struct r300_winsys_buffer *_buf,
-                                  enum r300_buffer_domain rd,
-                                  enum r300_buffer_domain wd)
+static void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs,
+                                         struct r300_winsys_cs_buffer *_buf,
+                                         enum r300_buffer_domain rd,
+                                         enum r300_buffer_domain wd)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
-    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
-    uint32_t gem_rd = get_gem_domain(rd);
-    uint32_t gem_wd = get_gem_domain(wd);
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
+    struct radeon_bo *bo = (struct radeon_bo*)_buf;
 
-    radeon_cs_space_add_persistent_bo(cs->cs, buf->bo, gem_rd, gem_wd);
+    radeon_cs_space_add_persistent_bo(cs->cs, bo, rd, wd);
 }
 
-void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs,
-                                   struct r300_winsys_buffer *_buf,
-                                  enum r300_buffer_domain rd,
-                                   enum r300_buffer_domain wd)
+static void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs,
+                                          struct r300_winsys_cs_buffer *_buf,
+                                          enum r300_buffer_domain rd,
+                                          enum r300_buffer_domain wd)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
-    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
+    struct radeon_bo *bo = (struct radeon_bo*)_buf;
     int retval;
-    uint32_t gem_rd = get_gem_domain(rd);
-    uint32_t gem_wd = get_gem_domain(wd);
 
     cs->cs->cdw = cs->base.cdw;
-    retval = radeon_cs_write_reloc(cs->cs, buf->bo, gem_rd, gem_wd, 0);
+    retval = radeon_cs_write_reloc(cs->cs, bo, rd, wd, 0);
     cs->base.cdw = cs->cs->cdw;
     if (retval) {
         fprintf(stderr, "radeon: Relocation of %p (%d, %d, %d) failed!\n",
-                buf, gem_rd, gem_wd, 0);
+                bo, rd, wd, 0);
     }
 }
 
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *rcs,
-                                               struct r300_winsys_buffer *_buf,
+static struct r300_winsys_cs_buffer *radeon_drm_get_cs_handle(
+        struct r300_winsys_screen *rws,
+        struct r300_winsys_buffer *_buf)
+{
+    /* return pure radeon_bo. */
+    return (struct r300_winsys_cs_buffer*)
+            get_drm_buffer(radeon_pb_buffer(_buf))->bo;
+}
+
+static boolean radeon_drm_is_buffer_referenced(struct r300_winsys_cs *rcs,
+                                               struct r300_winsys_cs_buffer *_buf,
                                                enum r300_reference_domain domain)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
-    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
+    struct radeon_bo *bo = (struct radeon_bo*)_buf;
     uint32_t tmp;
 
     if (domain & R300_REF_CS) {
-        if (radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
+        if (radeon_bo_is_referenced_by_cs(bo, cs->cs)) {
             return TRUE;
         }
     }
 
     if (domain & R300_REF_HW) {
-        if (radeon_bo_is_busy(buf->bo, &tmp)) {
+        if (radeon_bo_is_busy(bo, &tmp)) {
             return TRUE;
         }
     }
@@ -550,10 +542,23 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
     pipe_mutex_unlock(mgr->buffer_map_list_mutex);
 }
 
-void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
-                            struct r300_winsys_buffer *_buf)
+static void radeon_drm_buffer_wait(struct r300_winsys_screen *ws,
+                                   struct r300_winsys_buffer *_buf)
 {
     struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
 
     radeon_bo_wait(buf->bo);
 }
+
+void radeon_drm_bufmgr_init_functions(struct radeon_drm_winsys *ws)
+{
+    ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle;
+    ws->base.buffer_set_tiling = radeon_drm_buffer_set_tiling;
+    ws->base.buffer_get_tiling = radeon_drm_buffer_get_tiling;
+    ws->base.buffer_map = radeon_drm_buffer_map;
+    ws->base.buffer_unmap = radeon_drm_buffer_unmap;
+    ws->base.buffer_wait = radeon_drm_buffer_wait;
+    ws->base.cs_is_buffer_referenced = radeon_drm_is_buffer_referenced;
+    ws->base.cs_add_buffer = radeon_drm_bufmgr_add_buffer;
+    ws->base.cs_write_reloc = radeon_drm_bufmgr_write_reloc;
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.h b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.h
new file mode 100644 (file)
index 0000000..494abdc
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef RADEON_DRM_BUFFER_H
+#define RADEON_DRM_BUFFER_H
+
+#include "radeon_winsys.h"
+
+#define RADEON_PB_USAGE_VERTEX      (1 << 28)
+#define RADEON_PB_USAGE_DOMAIN_GTT  (1 << 29)
+#define RADEON_PB_USAGE_DOMAIN_VRAM (1 << 30)
+
+static INLINE struct pb_buffer *
+radeon_pb_buffer(struct r300_winsys_buffer *buffer)
+{
+    return (struct pb_buffer *)buffer;
+}
+
+struct pb_manager *radeon_drm_bufmgr_create(struct radeon_drm_winsys *rws);
+struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
+                                                             uint32_t handle);
+void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
+boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
+                                    struct winsys_handle *whandle);
+void radeon_drm_bufmgr_init_functions(struct radeon_drm_winsys *ws);
+
+#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_common.c b/src/gallium/winsys/radeon/drm/radeon_drm_common.c
new file mode 100644 (file)
index 0000000..6bc6244
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright © 2009 Corbin Simpson
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ *      Corbin Simpson <MostAwesomeDude@gmail.com>
+ *      Joakim Sindholt <opensource@zhasha.com>
+ */
+
+#include "radeon_winsys.h"
+#include "radeon_drm_buffer.h"
+#include "radeon_drm_public.h"
+
+#include "pipebuffer/pb_bufmgr.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/drm_driver.h"
+
+#include <radeon_drm.h>
+#include <radeon_bo_gem.h>
+#include <radeon_cs_gem.h>
+#include <xf86drm.h>
+#include <stdio.h>
+
+
+/* Enable/disable Hyper-Z access. Return TRUE on success. */
+static boolean radeon_set_hyperz_access(int fd, boolean enable)
+{
+#ifndef RADEON_INFO_WANT_HYPERZ
+#define RADEON_INFO_WANT_HYPERZ 7
+#endif
+
+    struct drm_radeon_info info = {0};
+    unsigned value = enable ? 1 : 0;
+
+    if (!debug_get_bool_option("RADEON_HYPERZ", FALSE))
+        return FALSE;
+
+    info.value = (unsigned long)&value;
+    info.request = RADEON_INFO_WANT_HYPERZ;
+
+    if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
+        return FALSE;
+
+    if (enable && !value)
+        return FALSE;
+
+    return TRUE;
+}
+
+/* Helper function to do the ioctls needed for setup and init. */
+static void do_ioctls(struct radeon_drm_winsys *winsys)
+{
+    struct drm_radeon_gem_info gem_info = {0};
+    struct drm_radeon_info info = {0};
+    int target = 0;
+    int retval;
+    drmVersionPtr version;
+
+    info.value = (unsigned long)&target;
+
+    /* We do things in a specific order here.
+     *
+     * DRM version first. We need to be sure we're running on a KMS chipset.
+     * This is also for some features.
+     *
+     * Then, the PCI ID. This is essential and should return usable numbers
+     * for all Radeons. If this fails, we probably got handed an FD for some
+     * non-Radeon card.
+     *
+     * The GB and Z pipe requests should always succeed, but they might not
+     * return sensical values for all chipsets, but that's alright because
+     * the pipe drivers already know that.
+     *
+     * The GEM info is actually bogus on the kernel side, as well as our side
+     * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
+     * we don't actually use the info for anything yet. */
+
+    version = drmGetVersion(winsys->fd);
+    if (version->version_major != 2) {
+        fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
+                "only compatible with 2.x.x\n", __FUNCTION__,
+                version->version_major, version->version_minor,
+                version->version_patchlevel);
+        drmFreeVersion(version);
+        exit(1);
+    }
+
+/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
+#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
+    // Supported since 2.1.0.
+    winsys->squaretiling = version->version_major > 2 ||
+                           version->version_minor >= 1;
+#endif
+
+    winsys->drm_2_3_0 = version->version_major > 2 ||
+                        version->version_minor >= 3;
+
+    winsys->drm_2_6_0 = version->version_major > 2 ||
+                        (version->version_major == 2 &&
+                         version->version_minor >= 6);
+
+    info.request = RADEON_INFO_DEVICE_ID;
+    retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get PCI ID, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->pci_id = target;
+
+    info.request = RADEON_INFO_NUM_GB_PIPES;
+    retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get GB pipe count, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->gb_pipes = target;
+
+    info.request = RADEON_INFO_NUM_Z_PIPES;
+    retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get Z pipe count, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->z_pipes = target;
+
+    winsys->hyperz = radeon_set_hyperz_access(winsys->fd, TRUE);
+
+    retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_GEM_INFO,
+            &gem_info, sizeof(gem_info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
+                __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->gart_size = gem_info.gart_size;
+    winsys->vram_size = gem_info.vram_size;
+
+    debug_printf("radeon: Successfully grabbed chipset info from kernel!\n"
+                 "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n"
+                 "radeon: GART size: %d MB VRAM size: %d MB\n"
+                 "radeon: HyperZ: %s\n",
+                 version->version_major, version->version_minor,
+                 version->version_patchlevel, winsys->pci_id,
+                 winsys->gb_pipes, winsys->z_pipes,
+                 winsys->gart_size / 1024 / 1024,
+                 winsys->vram_size / 1024 / 1024,
+                 winsys->hyperz ? "YES" : "NO");
+
+    drmFreeVersion(version);
+}
+
+static void radeon_winsys_destroy(struct r300_winsys_screen *rws)
+{
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+
+    ws->cman->destroy(ws->cman);
+    ws->kman->destroy(ws->kman);
+
+    radeon_bo_manager_gem_dtor(ws->bom);
+    radeon_cs_manager_gem_dtor(ws->csm);
+    FREE(rws);
+}
+
+struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd)
+{
+    struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys);
+    if (!ws) {
+        return NULL;
+    }
+
+    ws->fd = fd;
+    do_ioctls(ws);
+
+    if (!is_r3xx(ws->pci_id)) {
+        goto fail;
+    }
+
+    /* Create managers. */
+    ws->bom = radeon_bo_manager_gem_ctor(fd);
+    if (!ws->bom)
+       goto fail;
+    ws->csm = radeon_cs_manager_gem_ctor(fd);
+    if (!ws->csm)
+       goto fail;
+    ws->kman = radeon_drm_bufmgr_create(ws);
+    if (!ws->kman)
+       goto fail;
+    ws->cman = pb_cache_manager_create(ws->kman, 1000000);
+    if (!ws->cman)
+       goto fail;
+
+    /* Set functions. */
+    ws->base.destroy = radeon_winsys_destroy;
+
+    radeon_drm_bufmgr_init_functions(ws);
+    radeon_winsys_init_functions(ws);
+
+    return &ws->base;
+
+fail:
+    if (ws->bom)
+       radeon_bo_manager_gem_dtor(ws->bom);
+    if (ws->csm)
+       radeon_cs_manager_gem_dtor(ws->csm);
+
+    if (ws->cman)
+       ws->cman->destroy(ws->cman);
+    if (ws->kman)
+       ws->kman->destroy(ws->kman);
+
+    FREE(ws);
+    return NULL;
+}
index 0d96ae8c470f0cfc1d78da216908b2f59d715f60..3a208cdd4c467e7f5e21f2edd55da6a1f957bb0f 100644 (file)
@@ -1,9 +1,222 @@
-
 #ifndef RADEON_DRM_PUBLIC_H
 #define RADEON_DRM_PUBLIC_H
 
+#include "pipe/p_defines.h"
+
 struct r300_winsys_screen;
 
-struct r300_winsys_screen *r300_drm_winsys_screen_create(int drmFD);
+struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd);
+
+static INLINE boolean is_r3xx(int pciid)
+{
+      switch (pciid) {
+      case 0x4144: /* PCI_CHIP_R300_AD */
+      case 0x4145: /* PCI_CHIP_R300_AE */
+      case 0x4146: /* PCI_CHIP_R300_AF */
+      case 0x4147: /* PCI_CHIP_R300_AG */
+      case 0x4E44: /* PCI_CHIP_R300_ND */
+      case 0x4E45: /* PCI_CHIP_R300_NE */
+      case 0x4E46: /* PCI_CHIP_R300_NF */
+      case 0x4E47: /* PCI_CHIP_R300_NG */
+      case 0x4E48: /* PCI_CHIP_R350_NH */
+      case 0x4E49: /* PCI_CHIP_R350_NI */
+      case 0x4E4B: /* PCI_CHIP_R350_NK */
+      case 0x4148: /* PCI_CHIP_R350_AH */
+      case 0x4149: /* PCI_CHIP_R350_AI */
+      case 0x414A: /* PCI_CHIP_R350_AJ */
+      case 0x414B: /* PCI_CHIP_R350_AK */
+      case 0x4E4A: /* PCI_CHIP_R360_NJ */
+      case 0x4150: /* PCI_CHIP_RV350_AP */
+      case 0x4151: /* PCI_CHIP_RV350_AQ */
+      case 0x4152: /* PCI_CHIP_RV350_AR */
+      case 0x4153: /* PCI_CHIP_RV350_AS */
+      case 0x4154: /* PCI_CHIP_RV350_AT */
+      case 0x4155: /* PCI_CHIP_RV350_AU */
+      case 0x4156: /* PCI_CHIP_RV350_AV */
+      case 0x4E50: /* PCI_CHIP_RV350_NP */
+      case 0x4E51: /* PCI_CHIP_RV350_NQ */
+      case 0x4E52: /* PCI_CHIP_RV350_NR */
+      case 0x4E53: /* PCI_CHIP_RV350_NS */
+      case 0x4E54: /* PCI_CHIP_RV350_NT */
+      case 0x4E56: /* PCI_CHIP_RV350_NV */
+      case 0x5460: /* PCI_CHIP_RV370_5460 */
+      case 0x5462: /* PCI_CHIP_RV370_5462 */
+      case 0x5464: /* PCI_CHIP_RV370_5464 */
+      case 0x5B60: /* PCI_CHIP_RV370_5B60 */
+      case 0x5B62: /* PCI_CHIP_RV370_5B62 */
+      case 0x5B63: /* PCI_CHIP_RV370_5B63 */
+      case 0x5B64: /* PCI_CHIP_RV370_5B64 */
+      case 0x5B65: /* PCI_CHIP_RV370_5B65 */
+      case 0x3150: /* PCI_CHIP_RV380_3150 */
+      case 0x3152: /* PCI_CHIP_RV380_3152 */
+      case 0x3154: /* PCI_CHIP_RV380_3154 */
+      case 0x3155: /* PCI_CHIP_RV380_3155 */
+      case 0x3E50: /* PCI_CHIP_RV380_3E50 */
+      case 0x3E54: /* PCI_CHIP_RV380_3E54 */
+      case 0x4A48: /* PCI_CHIP_R420_JH */
+      case 0x4A49: /* PCI_CHIP_R420_JI */
+      case 0x4A4A: /* PCI_CHIP_R420_JJ */
+      case 0x4A4B: /* PCI_CHIP_R420_JK */
+      case 0x4A4C: /* PCI_CHIP_R420_JL */
+      case 0x4A4D: /* PCI_CHIP_R420_JM */
+      case 0x4A4E: /* PCI_CHIP_R420_JN */
+      case 0x4A4F: /* PCI_CHIP_R420_JO */
+      case 0x4A50: /* PCI_CHIP_R420_JP */
+      case 0x4A54: /* PCI_CHIP_R420_JT */
+      case 0x5548: /* PCI_CHIP_R423_UH */
+      case 0x5549: /* PCI_CHIP_R423_UI */
+      case 0x554A: /* PCI_CHIP_R423_UJ */
+      case 0x554B: /* PCI_CHIP_R423_UK */
+      case 0x5550: /* PCI_CHIP_R423_5550 */
+      case 0x5551: /* PCI_CHIP_R423_UQ */
+      case 0x5552: /* PCI_CHIP_R423_UR */
+      case 0x5554: /* PCI_CHIP_R423_UT */
+      case 0x5D57: /* PCI_CHIP_R423_5D57 */
+      case 0x554C: /* PCI_CHIP_R430_554C */
+      case 0x554D: /* PCI_CHIP_R430_554D */
+      case 0x554E: /* PCI_CHIP_R430_554E */
+      case 0x554F: /* PCI_CHIP_R430_554F */
+      case 0x5D48: /* PCI_CHIP_R430_5D48 */
+      case 0x5D49: /* PCI_CHIP_R430_5D49 */
+      case 0x5D4A: /* PCI_CHIP_R430_5D4A */
+      case 0x5D4C: /* PCI_CHIP_R480_5D4C */
+      case 0x5D4D: /* PCI_CHIP_R480_5D4D */
+      case 0x5D4E: /* PCI_CHIP_R480_5D4E */
+      case 0x5D4F: /* PCI_CHIP_R480_5D4F */
+      case 0x5D50: /* PCI_CHIP_R480_5D50 */
+      case 0x5D52: /* PCI_CHIP_R480_5D52 */
+      case 0x4B49: /* PCI_CHIP_R481_4B49 */
+      case 0x4B4A: /* PCI_CHIP_R481_4B4A */
+      case 0x4B4B: /* PCI_CHIP_R481_4B4B */
+      case 0x4B4C: /* PCI_CHIP_R481_4B4C */
+      case 0x564A: /* PCI_CHIP_RV410_564A */
+      case 0x564B: /* PCI_CHIP_RV410_564B */
+      case 0x564F: /* PCI_CHIP_RV410_564F */
+      case 0x5652: /* PCI_CHIP_RV410_5652 */
+      case 0x5653: /* PCI_CHIP_RV410_5653 */
+      case 0x5657: /* PCI_CHIP_RV410_5657 */
+      case 0x5E48: /* PCI_CHIP_RV410_5E48 */
+      case 0x5E4A: /* PCI_CHIP_RV410_5E4A */
+      case 0x5E4B: /* PCI_CHIP_RV410_5E4B */
+      case 0x5E4C: /* PCI_CHIP_RV410_5E4C */
+      case 0x5E4D: /* PCI_CHIP_RV410_5E4D */
+      case 0x5E4F: /* PCI_CHIP_RV410_5E4F */
+      case 0x5A41: /* PCI_CHIP_RS400_5A41 */
+      case 0x5A42: /* PCI_CHIP_RS400_5A42 */
+      case 0x5A61: /* PCI_CHIP_RC410_5A61 */
+      case 0x5A62: /* PCI_CHIP_RC410_5A62 */
+      case 0x5954: /* PCI_CHIP_RS480_5954 */
+      case 0x5955: /* PCI_CHIP_RS480_5955 */
+      case 0x5974: /* PCI_CHIP_RS482_5974 */
+      case 0x5975: /* PCI_CHIP_RS482_5975 */
+      case 0x7100: /* PCI_CHIP_R520_7100 */
+      case 0x7101: /* PCI_CHIP_R520_7101 */
+      case 0x7102: /* PCI_CHIP_R520_7102 */
+      case 0x7103: /* PCI_CHIP_R520_7103 */
+      case 0x7104: /* PCI_CHIP_R520_7104 */
+      case 0x7105: /* PCI_CHIP_R520_7105 */
+      case 0x7106: /* PCI_CHIP_R520_7106 */
+      case 0x7108: /* PCI_CHIP_R520_7108 */
+      case 0x7109: /* PCI_CHIP_R520_7109 */
+      case 0x710A: /* PCI_CHIP_R520_710A */
+      case 0x710B: /* PCI_CHIP_R520_710B */
+      case 0x710C: /* PCI_CHIP_R520_710C */
+      case 0x710E: /* PCI_CHIP_R520_710E */
+      case 0x710F: /* PCI_CHIP_R520_710F */
+      case 0x7140: /* PCI_CHIP_RV515_7140 */
+      case 0x7141: /* PCI_CHIP_RV515_7141 */
+      case 0x7142: /* PCI_CHIP_RV515_7142 */
+      case 0x7143: /* PCI_CHIP_RV515_7143 */
+      case 0x7144: /* PCI_CHIP_RV515_7144 */
+      case 0x7145: /* PCI_CHIP_RV515_7145 */
+      case 0x7146: /* PCI_CHIP_RV515_7146 */
+      case 0x7147: /* PCI_CHIP_RV515_7147 */
+      case 0x7149: /* PCI_CHIP_RV515_7149 */
+      case 0x714A: /* PCI_CHIP_RV515_714A */
+      case 0x714B: /* PCI_CHIP_RV515_714B */
+      case 0x714C: /* PCI_CHIP_RV515_714C */
+      case 0x714D: /* PCI_CHIP_RV515_714D */
+      case 0x714E: /* PCI_CHIP_RV515_714E */
+      case 0x714F: /* PCI_CHIP_RV515_714F */
+      case 0x7151: /* PCI_CHIP_RV515_7151 */
+      case 0x7152: /* PCI_CHIP_RV515_7152 */
+      case 0x7153: /* PCI_CHIP_RV515_7153 */
+      case 0x715E: /* PCI_CHIP_RV515_715E */
+      case 0x715F: /* PCI_CHIP_RV515_715F */
+      case 0x7180: /* PCI_CHIP_RV515_7180 */
+      case 0x7181: /* PCI_CHIP_RV515_7181 */
+      case 0x7183: /* PCI_CHIP_RV515_7183 */
+      case 0x7186: /* PCI_CHIP_RV515_7186 */
+      case 0x7187: /* PCI_CHIP_RV515_7187 */
+      case 0x7188: /* PCI_CHIP_RV515_7188 */
+      case 0x718A: /* PCI_CHIP_RV515_718A */
+      case 0x718B: /* PCI_CHIP_RV515_718B */
+      case 0x718C: /* PCI_CHIP_RV515_718C */
+      case 0x718D: /* PCI_CHIP_RV515_718D */
+      case 0x718F: /* PCI_CHIP_RV515_718F */
+      case 0x7193: /* PCI_CHIP_RV515_7193 */
+      case 0x7196: /* PCI_CHIP_RV515_7196 */
+      case 0x719B: /* PCI_CHIP_RV515_719B */
+      case 0x719F: /* PCI_CHIP_RV515_719F */
+      case 0x7200: /* PCI_CHIP_RV515_7200 */
+      case 0x7210: /* PCI_CHIP_RV515_7210 */
+      case 0x7211: /* PCI_CHIP_RV515_7211 */
+      case 0x71C0: /* PCI_CHIP_RV530_71C0 */
+      case 0x71C1: /* PCI_CHIP_RV530_71C1 */
+      case 0x71C2: /* PCI_CHIP_RV530_71C2 */
+      case 0x71C3: /* PCI_CHIP_RV530_71C3 */
+      case 0x71C4: /* PCI_CHIP_RV530_71C4 */
+      case 0x71C5: /* PCI_CHIP_RV530_71C5 */
+      case 0x71C6: /* PCI_CHIP_RV530_71C6 */
+      case 0x71C7: /* PCI_CHIP_RV530_71C7 */
+      case 0x71CD: /* PCI_CHIP_RV530_71CD */
+      case 0x71CE: /* PCI_CHIP_RV530_71CE */
+      case 0x71D2: /* PCI_CHIP_RV530_71D2 */
+      case 0x71D4: /* PCI_CHIP_RV530_71D4 */
+      case 0x71D5: /* PCI_CHIP_RV530_71D5 */
+      case 0x71D6: /* PCI_CHIP_RV530_71D6 */
+      case 0x71DA: /* PCI_CHIP_RV530_71DA */
+      case 0x71DE: /* PCI_CHIP_RV530_71DE */
+      case 0x7281: /* PCI_CHIP_RV560_7281 */
+      case 0x7283: /* PCI_CHIP_RV560_7283 */
+      case 0x7287: /* PCI_CHIP_RV560_7287 */
+      case 0x7290: /* PCI_CHIP_RV560_7290 */
+      case 0x7291: /* PCI_CHIP_RV560_7291 */
+      case 0x7293: /* PCI_CHIP_RV560_7293 */
+      case 0x7297: /* PCI_CHIP_RV560_7297 */
+      case 0x7280: /* PCI_CHIP_RV570_7280 */
+      case 0x7288: /* PCI_CHIP_RV570_7288 */
+      case 0x7289: /* PCI_CHIP_RV570_7289 */
+      case 0x728B: /* PCI_CHIP_RV570_728B */
+      case 0x728C: /* PCI_CHIP_RV570_728C */
+      case 0x7240: /* PCI_CHIP_R580_7240 */
+      case 0x7243: /* PCI_CHIP_R580_7243 */
+      case 0x7244: /* PCI_CHIP_R580_7244 */
+      case 0x7245: /* PCI_CHIP_R580_7245 */
+      case 0x7246: /* PCI_CHIP_R580_7246 */
+      case 0x7247: /* PCI_CHIP_R580_7247 */
+      case 0x7248: /* PCI_CHIP_R580_7248 */
+      case 0x7249: /* PCI_CHIP_R580_7249 */
+      case 0x724A: /* PCI_CHIP_R580_724A */
+      case 0x724B: /* PCI_CHIP_R580_724B */
+      case 0x724C: /* PCI_CHIP_R580_724C */
+      case 0x724D: /* PCI_CHIP_R580_724D */
+      case 0x724E: /* PCI_CHIP_R580_724E */
+      case 0x724F: /* PCI_CHIP_R580_724F */
+      case 0x7284: /* PCI_CHIP_R580_7284 */
+      case 0x793F: /* PCI_CHIP_RS600_793F */
+      case 0x7941: /* PCI_CHIP_RS600_7941 */
+      case 0x7942: /* PCI_CHIP_RS600_7942 */
+      case 0x791E: /* PCI_CHIP_RS690_791E */
+      case 0x791F: /* PCI_CHIP_RS690_791F */
+      case 0x796C: /* PCI_CHIP_RS740_796C */
+      case 0x796D: /* PCI_CHIP_RS740_796D */
+      case 0x796E: /* PCI_CHIP_RS740_796E */
+      case 0x796F: /* PCI_CHIP_RS740_796F */
+             return TRUE;
+      default:
+             return FALSE;
+      }
+}
 
 #endif
index 420522f5c1f355728b032f8f6cf2b2469e306b52..9f59b3de461e2edd5cb59447af870be80841b5c8 100644 (file)
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
-#include "radeon_r300.h"
-#include "radeon_buffer.h"
+#include "radeon_drm_buffer.h"
+
+#include "util/u_memory.h"
+#include "pipebuffer/pb_bufmgr.h"
 
-#include "radeon_bo_gem.h"
 #include "radeon_cs_gem.h"
 #include "state_tracker/drm_driver.h"
 
-#include "util/u_memory.h"
-
 static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage,
                                                enum r300_buffer_domain domain)
 {
@@ -73,7 +72,7 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
                                  unsigned usage,
                                  enum r300_buffer_domain domain)
 {
-    struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
+    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
     struct pb_desc desc;
     struct pb_manager *provider;
     struct pb_buffer *buffer;
@@ -92,7 +91,7 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
     if (!buffer)
        return NULL;
 
-    return radeon_libdrm_winsys_buffer(buffer);
+    return (struct r300_winsys_buffer*)buffer;
 }
 
 static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
@@ -104,7 +103,7 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
 
     pb_reference(&_dst, _src);
 
-    *pdst = radeon_libdrm_winsys_buffer(_dst);
+    *pdst = (struct r300_winsys_buffer*)_dst;
 }
 
 static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
@@ -112,7 +111,7 @@ static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r
                                                                         unsigned *stride,
                                                                         unsigned *size)
 {
-    struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
+    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
     struct pb_buffer *_buf;
 
     _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle);
@@ -122,7 +121,7 @@ static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r
     if (size)
         *size = _buf->base.size;
 
-    return radeon_libdrm_winsys_buffer(_buf);
+    return (struct r300_winsys_buffer*)_buf;
 }
 
 static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
@@ -139,7 +138,7 @@ static void radeon_r300_winsys_cs_set_flush(struct r300_winsys_cs *rcs,
                                             void (*flush)(void *),
                                             void *user)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     cs->flush_cs = flush;
     cs->flush_data = user;
     radeon_cs_space_set_flush(cs->cs, flush, user);
@@ -147,20 +146,20 @@ static void radeon_r300_winsys_cs_set_flush(struct r300_winsys_cs *rcs,
 
 static boolean radeon_r300_winsys_cs_validate(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
 
     return radeon_cs_space_check(cs->cs) >= 0;
 }
 
 static void radeon_r300_winsys_cs_reset_buffers(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     radeon_cs_space_reset_bos(cs->cs);
 }
 
 static void radeon_r300_winsys_cs_flush(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     int retval;
 
     /* Don't flush a zero-sized CS. */
@@ -190,15 +189,14 @@ static void radeon_r300_winsys_cs_flush(struct r300_winsys_cs *rcs)
      * spinning through one CS while another one is being filled. */
     radeon_cs_erase(cs->cs);
 
-    cs->base.ptr = cs->cs->packets;
+    cs->base.buf = cs->cs->packets;
     cs->base.cdw = cs->cs->cdw;
-    cs->base.ndw = cs->cs->ndw;
 }
 
 static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
                                  enum r300_value_id id)
 {
-    struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws;
 
     switch(id) {
     case R300_VID_PCI_ID:
@@ -221,8 +219,8 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
 
 static struct r300_winsys_cs *radeon_r300_winsys_cs_create(struct r300_winsys_screen *rws)
 {
-    struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
-    struct radeon_libdrm_cs *cs = CALLOC_STRUCT(radeon_libdrm_cs);
+    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
+    struct radeon_drm_cs *cs = CALLOC_STRUCT(radeon_drm_cs);
 
     if (!cs)
         return NULL;
@@ -240,83 +238,29 @@ static struct r300_winsys_cs *radeon_r300_winsys_cs_create(struct r300_winsys_sc
             RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
 
     cs->ws = ws;
-    cs->base.ptr = cs->cs->packets;
+    cs->base.buf = cs->cs->packets;
     cs->base.cdw = cs->cs->cdw;
-    cs->base.ndw = cs->cs->ndw;
     return &cs->base;
 }
 
 static void radeon_r300_winsys_cs_destroy(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     radeon_cs_destroy(cs->cs);
     FREE(cs);
 }
 
-static void radeon_winsys_destroy(struct r300_winsys_screen *rws)
-{
-    struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
-
-    ws->cman->destroy(ws->cman);
-    ws->kman->destroy(ws->kman);
-
-    radeon_bo_manager_gem_dtor(ws->bom);
-    radeon_cs_manager_gem_dtor(ws->csm);
-
-    FREE(rws);
-}
-
-boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
+void radeon_winsys_init_functions(struct radeon_drm_winsys *ws)
 {
-    ws->csm = radeon_cs_manager_gem_ctor(fd);
-    if (!ws->csm)
-       goto fail;
-    ws->bom = radeon_bo_manager_gem_ctor(fd);
-    if (!ws->bom)
-       goto fail;
-    ws->kman = radeon_drm_bufmgr_create(ws);
-    if (!ws->kman)
-       goto fail;
-
-    ws->cman = pb_cache_manager_create(ws->kman, 100000);
-    if (!ws->cman)
-       goto fail;
-
-    ws->base.destroy = radeon_winsys_destroy;
     ws->base.get_value = radeon_get_value;
-
     ws->base.buffer_create = radeon_r300_winsys_buffer_create;
-    ws->base.buffer_set_tiling = radeon_drm_bufmgr_set_tiling;
-    ws->base.buffer_get_tiling = radeon_drm_bufmgr_get_tiling;
-    ws->base.buffer_map = radeon_drm_buffer_map;
-    ws->base.buffer_unmap = radeon_drm_buffer_unmap;
-    ws->base.buffer_wait = radeon_drm_bufmgr_wait;
     ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
     ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
     ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
-
     ws->base.cs_create = radeon_r300_winsys_cs_create;
     ws->base.cs_destroy = radeon_r300_winsys_cs_destroy;
-    ws->base.cs_add_buffer = radeon_drm_bufmgr_add_buffer;
     ws->base.cs_validate = radeon_r300_winsys_cs_validate;
-    ws->base.cs_write_reloc = radeon_drm_bufmgr_write_reloc;
     ws->base.cs_flush = radeon_r300_winsys_cs_flush;
     ws->base.cs_reset_buffers = radeon_r300_winsys_cs_reset_buffers;
     ws->base.cs_set_flush = radeon_r300_winsys_cs_set_flush;
-    ws->base.cs_is_buffer_referenced = radeon_drm_bufmgr_is_buffer_referenced;
-    return TRUE;
-
-fail:
-    if (ws->csm)
-       radeon_cs_manager_gem_dtor(ws->csm);
-
-    if (ws->bom)
-       radeon_bo_manager_gem_dtor(ws->bom);
-
-    if (ws->cman)
-       ws->cman->destroy(ws->cman);
-    if (ws->kman)
-       ws->kman->destroy(ws->kman);
-
-    return FALSE;
 }
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.h b/src/gallium/winsys/radeon/drm/radeon_r300.h
deleted file mode 100644 (file)
index 2703464..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#ifndef RADEON_R300_H
-#define RADEON_R300_H
-
-#include "radeon_winsys.h"
-
-boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys);
-
-#endif /* RADEON_R300_H */
index 6f4aa4bce30c2cfc28629cb4b1e4dbac9d6a7c54..81da1a25e0fe40670ca5fc1be6b4a0c84b2ba22b 100644 (file)
 
 #include "r300_winsys.h"
 
-struct radeon_libdrm_winsys {
-    /* Parent class. */
+struct radeon_drm_winsys {
     struct r300_winsys_screen base;
 
-    struct pb_manager *kman;
+    int fd; /* DRM file descriptor */
 
+    struct radeon_bo_manager *bom; /* Radeon BO manager. */
+    struct pb_manager *kman;
     struct pb_manager *cman;
 
-    /* PCI ID */
-    uint32_t pci_id;
-
-    /* GB pipe count */
-    uint32_t gb_pipes;
-
-    /* Z pipe count (rv530 only) */
-    uint32_t z_pipes;
-
-    /* GART size. */
-    uint32_t gart_size;
-
-    /* VRAM size. */
-    uint32_t vram_size;
-
-    /* Square tiling support. */
-    boolean squaretiling;
-
-    /* DRM 2.3.0
-     *   - R500 VAP regs
-     *   - MSPOS regs
-     *   - Fixed texture 3D size calculation
-     */
+    uint32_t pci_id;        /* PCI ID */
+    uint32_t gb_pipes;      /* GB pipe count */
+    uint32_t z_pipes;       /* Z pipe count (rv530 only) */
+    uint32_t gart_size;     /* GART size. */
+    uint32_t vram_size;     /* VRAM size. */
+    boolean squaretiling;   /* Square tiling support. */
+    /* DRM 2.3.0 (R500 VAP regs, MSPOS regs, fixed tex3D size checking) */
     boolean drm_2_3_0;
-
-    /* DRM 2.6.0
-     *   - Hyper-Z
-     *   - GB_Z_PEQ_CONFIG allowed on rv350->r4xx, we should initialize it
-     */
+    /* DRM 2.6.0 (Hyper-Z, GB_Z_PEQ_CONFIG allowed on rv350->r4xx) */
     boolean drm_2_6_0;
-
-    /* hyperz user */
+    /* Hyper-Z user */
     boolean hyperz;
 
-    /* DRM FD */
-    int fd;
-
-    /* Radeon BO manager. */
-    struct radeon_bo_manager *bom;
-
     /* Radeon CS manager. */
     struct radeon_cs_manager *csm;
 };
 
-struct radeon_libdrm_cs {
+struct radeon_drm_cs {
     struct r300_winsys_cs base;
 
     /* The winsys. */
-    struct radeon_libdrm_winsys *ws;
+    struct radeon_drm_winsys *ws;
 
     /* The libdrm command stream. */
     struct radeon_cs *cs;
@@ -98,16 +72,18 @@ struct radeon_libdrm_cs {
     void *flush_data;
 };
 
-static INLINE struct radeon_libdrm_cs *
-radeon_libdrm_cs(struct r300_winsys_cs *base)
+static INLINE struct radeon_drm_cs *
+radeon_drm_cs(struct r300_winsys_cs *base)
 {
-    return (struct radeon_libdrm_cs*)base;
+    return (struct radeon_drm_cs*)base;
 }
 
-static INLINE struct radeon_libdrm_winsys *
-radeon_libdrm_winsys(struct r300_winsys_screen *base)
+static INLINE struct radeon_drm_winsys *
+radeon_drm_winsys(struct r300_winsys_screen *base)
 {
-    return (struct radeon_libdrm_winsys*)base;
+    return (struct radeon_drm_winsys*)base;
 }
 
+void radeon_winsys_init_functions(struct radeon_drm_winsys *ws);
+
 #endif
index bc2623e7b77ad35dd3d8cec8c6d3539478e138a8..8f9a90858dee1fd732ae46f719cd6dd9766b8b80 100644 (file)
@@ -93,9 +93,9 @@ wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)
    struct pipe_resource *tex = wdt->tex;
    struct pipe_transfer *tr;
 
-   tr = pipe_get_transfer(pipe, tex, 0, 0, 0,
-                         PIPE_TRANSFER_READ_WRITE,
-                         0, 0, wdt->width, wdt->height);
+   tr = pipe_get_transfer(pipe, tex, 0, 0,
+                          PIPE_TRANSFER_READ_WRITE,
+                          0, 0, wdt->width, wdt->height);
    if (!tr)
       return FALSE;
 
@@ -149,6 +149,8 @@ wsw_dt_create(struct sw_winsys *ws,
    templ.target = wsw->target;
    templ.width0 = width;
    templ.height0 = height;
+   templ.depth0 = 1;
+   templ.array_size = 1;
    templ.format = format;
    templ.bind = bind;
 
@@ -204,9 +206,9 @@ wsw_dt_map(struct sw_winsys *ws,
 
       assert(!wdt->transfer);
 
-      tr = pipe_get_transfer(pipe, tex, 0, 0, 0,
-                            PIPE_TRANSFER_READ_WRITE,
-                            0, 0, wdt->width, wdt->height);
+      tr = pipe_get_transfer(pipe, tex, 0, 0,
+                             PIPE_TRANSFER_READ_WRITE,
+                             0, 0, wdt->width, wdt->height);
       if (!tr)
          return NULL;
 
index f5aadc347bd5e20f86ef92521a32a82a4a405b77..2674c6ec4850e7ee6d0629c33eb498be09c7b48c 100644 (file)
@@ -52,6 +52,7 @@ CXX_SOURCES = \
        loop_analysis.cpp \
        loop_controls.cpp \
        loop_unroll.cpp \
+       lower_discard.cpp \
        lower_if_to_cond_assign.cpp \
        lower_instructions.cpp \
        lower_jumps.cpp \
@@ -70,6 +71,7 @@ CXX_SOURCES = \
        opt_dead_code.cpp \
        opt_dead_code_local.cpp \
        opt_dead_functions.cpp \
+       opt_discard_simplification.cpp \
        opt_function_inlining.cpp \
        opt_if_simplification.cpp \
        opt_noop_swizzle.cpp \
index fd22f668631f4bef7a32d29cf7e876881832a232..b5b1728beef30e814fce9715e4072b829e5be886 100644 (file)
@@ -49,6 +49,7 @@ sources = [
     'loop_analysis.cpp',
     'loop_controls.cpp',
     'loop_unroll.cpp',
+    'lower_discard.cpp',
     'lower_if_to_cond_assign.cpp',
     'lower_instructions.cpp',
     'lower_jumps.cpp',
@@ -66,6 +67,7 @@ sources = [
     'opt_dead_code.cpp',
     'opt_dead_code_local.cpp',
     'opt_dead_functions.cpp',
+    'opt_discard_simplification.cpp',
     'opt_function_inlining.cpp',
     'opt_if_simplification.cpp',
     'opt_noop_swizzle.cpp',
index e5aa5c1b3b5925207702eff31edca7b68c5f2b6c..a77b522705cce5b237ffe6294621d212a0afe462 100644 (file)
@@ -714,4 +714,8 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
                                 exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state);
 
+void
+emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
+             ir_function *f);
+
 #endif /* AST_H */
index 1e66033348c87191a54de7c8201eb396e5a9d08b..6ecf779c935abaf7a8ef7741f7ae5387f30b6a59 100644 (file)
@@ -93,13 +93,40 @@ prototype_string(const glsl_type *return_type, const char *name,
 
 
 static ir_rvalue *
-process_call(exec_list *instructions, ir_function *f,
-            YYLTYPE *loc, exec_list *actual_parameters,
-            struct _mesa_glsl_parse_state *state)
+match_function_by_name(exec_list *instructions, const char *name,
+                      YYLTYPE *loc, exec_list *actual_parameters,
+                      struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
+   ir_function *f = state->symbols->get_function(name);
+   ir_function_signature *sig;
+
+   sig = f ? f->matching_signature(actual_parameters) : NULL;
+
+   /* FINISHME: This doesn't handle the case where shader X contains a
+    * FINISHME: matching signature but shader X + N contains an _exact_
+    * FINISHME: matching signature.
+    */
+   if (sig == NULL && (f == NULL || state->es_shader || !f->has_user_signature()) && state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) {
+      /* The current shader doesn't contain a matching function or signature.
+       * Before giving up, look for the prototype in the built-in functions.
+       */
+      for (unsigned i = 0; i < state->num_builtins_to_link; i++) {
+        ir_function *builtin;
+        builtin = state->builtins_to_link[i]->symbols->get_function(name);
+        sig = builtin ? builtin->matching_signature(actual_parameters) : NULL;
+        if (sig != NULL) {
+           if (f == NULL) {
+              f = new(ctx) ir_function(name);
+              state->symbols->add_global_function(f);
+              emit_function(state, instructions, f);
+           }
 
-   ir_function_signature *sig = f->matching_signature(actual_parameters);
+           f->add_signature(sig->clone_prototype(f, NULL));
+           break;
+        }
+      }
+   }
 
    if (sig != NULL) {
       /* Verify that 'out' and 'inout' actual parameters are lvalues.  This
@@ -164,45 +191,35 @@ process_call(exec_list *instructions, ir_function *f,
         return NULL;
       }
    } else {
-      char *str = prototype_string(NULL, f->name, actual_parameters);
+      char *str = prototype_string(NULL, name, actual_parameters);
 
       _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
                       str);
       talloc_free(str);
 
       const char *prefix = "candidates are: ";
-      foreach_list (node, &f->signatures) {
-        ir_function_signature *sig = (ir_function_signature *) node;
 
-        str = prototype_string(sig->return_type, f->name, &sig->parameters);
-        _mesa_glsl_error(loc, state, "%s%s\n", prefix, str);
-        talloc_free(str);
+      for (int i = -1; i < state->num_builtins_to_link; i++) {
+        glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols
+                                         : state->symbols;
+        f = syms->get_function(name);
+        if (f == NULL)
+           continue;
 
-        prefix = "                ";
-      }
+        foreach_list (node, &f->signatures) {
+           ir_function_signature *sig = (ir_function_signature *) node;
 
-      return ir_call::get_error_instruction(ctx);
-   }
-}
+           str = prototype_string(sig->return_type, f->name, &sig->parameters);
+           _mesa_glsl_error(loc, state, "%s%s\n", prefix, str);
+           talloc_free(str);
 
+           prefix = "                ";
+        }
 
-static ir_rvalue *
-match_function_by_name(exec_list *instructions, const char *name,
-                      YYLTYPE *loc, exec_list *actual_parameters,
-                      struct _mesa_glsl_parse_state *state)
-{
-   void *ctx = state;
-   ir_function *f = state->symbols->get_function(name);
+      }
 
-   if (f == NULL) {
-      _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
       return ir_call::get_error_instruction(ctx);
    }
-
-   /* Once we've determined that the function being called might exist, try
-    * to find an overload of the function that matches the parameters.
-    */
-   return process_call(instructions, f, loc, actual_parameters, state);
 }
 
 
index d615b30e7daf23c0b75c8e1f811e8a3b2d89feec..1f4972cfca20a800e7513ebdc9355e7761697b7d 100644 (file)
@@ -745,6 +745,94 @@ ast_node::hir(exec_list *instructions,
    return NULL;
 }
 
+static void
+mark_whole_array_access(ir_rvalue *access)
+{
+   ir_dereference_variable *deref = access->as_dereference_variable();
+
+   if (deref) {
+      deref->var->max_array_access = deref->type->length - 1;
+   }
+}
+
+static ir_rvalue *
+do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
+{
+   int join_op;
+   ir_rvalue *cmp = NULL;
+
+   if (operation == ir_binop_all_equal)
+      join_op = ir_binop_logic_and;
+   else
+      join_op = ir_binop_logic_or;
+
+   switch (op0->type->base_type) {
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_BOOL:
+      return new(mem_ctx) ir_expression(operation, op0, op1);
+
+   case GLSL_TYPE_ARRAY: {
+      for (unsigned int i = 0; i < op0->type->length; i++) {
+        ir_rvalue *e0, *e1, *result;
+
+        e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
+                                               new(mem_ctx) ir_constant(i));
+        e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
+                                               new(mem_ctx) ir_constant(i));
+        result = do_comparison(mem_ctx, operation, e0, e1);
+
+        if (cmp) {
+           cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+        } else {
+           cmp = result;
+        }
+      }
+
+      mark_whole_array_access(op0);
+      mark_whole_array_access(op1);
+      break;
+   }
+
+   case GLSL_TYPE_STRUCT: {
+      for (unsigned int i = 0; i < op0->type->length; i++) {
+        ir_rvalue *e0, *e1, *result;
+        const char *field_name = op0->type->fields.structure[i].name;
+
+        e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
+                                                field_name);
+        e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
+                                                field_name);
+        result = do_comparison(mem_ctx, operation, e0, e1);
+
+        if (cmp) {
+           cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+        } else {
+           cmp = result;
+        }
+      }
+      break;
+   }
+
+   case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_VOID:
+   case GLSL_TYPE_SAMPLER:
+      /* I assume a comparison of a struct containing a sampler just
+       * ignores the sampler present in the type.
+       */
+      break;
+
+   default:
+      assert(!"Should not get here.");
+      break;
+   }
+
+   if (cmp == NULL)
+      cmp = new(mem_ctx) ir_constant(true);
+
+   return cmp;
+}
 
 ir_rvalue *
 ast_expression::hir(exec_list *instructions,
@@ -941,11 +1029,10 @@ ast_expression::hir(exec_list *instructions,
         error_emitted = true;
       }
 
-      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
-                                     op[0], op[1]);
+      result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
       type = glsl_type::bool_type;
 
-      assert(result->type == glsl_type::bool_type);
+      assert(error_emitted || (result->type == glsl_type::bool_type));
       break;
 
    case ast_bit_and:
@@ -1480,6 +1567,20 @@ ast_expression::hir(exec_list *instructions,
         }
       }
 
+      /* From section 4.1.7 of the GLSL 1.30 spec:
+       *    "Samplers aggregated into arrays within a shader (using square
+       *    brackets [ ]) can only be indexed with integral constant
+       *    expressions [...]."
+       */
+      if (array->type->is_array() &&
+          array->type->element_type()->is_sampler() &&
+          const_index == NULL) {
+
+         _mesa_glsl_error(&loc, state, "sampler arrays can only be indexed "
+                          "with constant expressions");
+         error_emitted = true;
+      }
+
       if (error_emitted)
         result->type = glsl_type::error_type;
 
@@ -2141,6 +2242,24 @@ ast_declarator_list::hir(exec_list *instructions,
            if (this->type->qualifier.flags.q.constant)
               var->read_only = false;
 
+           /* If the declared variable is an unsized array, it must inherrit
+            * its full type from the initializer.  A declaration such as
+            *
+            *     uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
+            *
+            * becomes
+            *
+            *     uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
+            *
+            * The assignment generated in the if-statement (below) will also
+            * automatically handle this case for non-uniforms.
+            *
+            * If the declared variable is not an array, the types must
+            * already match exactly.  As a result, the type assignment
+            * here can be done unconditionally.
+            */
+           var->type = rhs->type;
+
            /* Never emit code to initialize a uniform.
             */
            if (!this->type->qualifier.flags.q.uniform)
@@ -2253,7 +2372,7 @@ ast_declarator_list::hir(exec_list *instructions,
        *     after the initializer if present or immediately after the name
        *     being declared if not."
        */
-      if (!state->symbols->add_variable(var->name, var)) {
+      if (!state->symbols->add_variable(var)) {
         YYLTYPE loc = this->get_location();
         _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
                          "current scope", decl->identifier);
@@ -2393,6 +2512,27 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
 }
 
 
+void
+emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
+             ir_function *f)
+{
+   /* Emit the new function header */
+   if (state->current_function == NULL) {
+      instructions->push_tail(f);
+   } else {
+      /* IR invariants disallow function declarations or definitions nested
+       * within other function definitions.  Insert the new ir_function
+       * block in the instruction sequence before the ir_function block
+       * containing the current ir_function_signature.
+       */
+      ir_function *const curr =
+        const_cast<ir_function *>(state->current_function->function());
+
+      curr->insert_before(f);
+   }
+}
+
+
 ir_rvalue *
 ast_function::hir(exec_list *instructions,
                  struct _mesa_glsl_parse_state *state)
@@ -2495,7 +2635,7 @@ ast_function::hir(exec_list *instructions,
       }
    } else {
       f = new(ctx) ir_function(name);
-      if (!state->symbols->add_function(f->name, f)) {
+      if (!state->symbols->add_function(f)) {
         /* This function name shadows a non-function use of the same name. */
         YYLTYPE loc = this->get_location();
 
@@ -2504,24 +2644,7 @@ ast_function::hir(exec_list *instructions,
         return NULL;
       }
 
-      /* Emit the new function header */
-      if (state->current_function == NULL)
-        instructions->push_tail(f);
-      else {
-        /* IR invariants disallow function declarations or definitions nested
-         * within other function definitions.  Insert the new ir_function
-         * block in the instruction sequence before the ir_function block
-         * containing the current ir_function_signature.
-         *
-         * This can only happen in a GLSL 1.10 shader.  In all other GLSL
-         * versions this nesting is disallowed.  There is a check for this at
-         * the top of this function.
-         */
-        ir_function *const curr =
-           const_cast<ir_function *>(state->current_function->function());
-
-        curr->insert_before(f);
-      }
+      emit_function(state, instructions, f);
    }
 
    /* Verify the return type of main() */
@@ -2587,7 +2710,7 @@ ast_function_definition::hir(exec_list *instructions,
 
         _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
       } else {
-        state->symbols->add_variable(var->name, var);
+        state->symbols->add_variable(var);
       }
    }
 
index bc368141053d0ee38cd31db5755d6d4cff22934c..631aeac12ceb84cc4d5d64f47ef183971ca7fff8 100644 (file)
@@ -13590,7 +13590,6 @@ _mesa_read_profile(struct _mesa_glsl_parse_state *state,
       builtin_profiles[profile_index] = sh;
    }
 
-   import_prototypes(sh->ir, instructions, state->symbols, state);
    state->builtins_to_link[state->num_builtins_to_link] = sh;
    state->num_builtins_to_link++;
 }
index 1f1056ea096dcfef89598135c310ddfd72f287cc..5ea4b5c48f46a07320002c07863cdb3104a86977 100755 (executable)
@@ -214,7 +214,6 @@ _mesa_read_profile(struct _mesa_glsl_parse_state *state,
       builtin_profiles[profile_index] = sh;
    }
 
-   import_prototypes(sh->ir, instructions, state->symbols, state);
    state->builtins_to_link[state->num_builtins_to_link] = sh;
    state->num_builtins_to_link++;
 }
index 0cd1fe5d598b44032ec068f078bc74e232ba6791..ab7c30ed78a7a3076800acd25c29fdde99b6bab1 100644 (file)
@@ -638,11 +638,11 @@ static const yytype_uint16 yyrline[] =
      361,   364,   367,   370,   373,   376,   379,   382,   385,   388,
      391,   394,   397,   400,   403,   406,   409,   412,   415,   418,
      424,   429,   437,   438,   442,   448,   449,   452,   454,   461,
-     465,   469,   474,   480,   488,   494,   502,   506,   510,   514,
-     518,   525,   526,   527,   528,   529,   530,   531,   532,   533,
-     534,   535,   536,   537,   538,   539,   540,   541,   542,   543,
-     544,   545,   546,   547,   548,   549,   550,   551,   552,   553,
-     554,   555
+     465,   469,   474,   479,   487,   493,   501,   505,   509,   513,
+     517,   524,   525,   526,   527,   528,   529,   530,   531,   532,
+     533,   534,   535,   536,   537,   538,   539,   540,   541,   542,
+     543,   544,   545,   546,   547,   548,   549,   550,   551,   552,
+     553,   554
 };
 #endif
 
@@ -2349,7 +2349,6 @@ yyreduce:
 /* Line 1464 of yacc.c  */
 #line 474 "glcpp/glcpp-parse.y"
     {
-               parser->space_tokens = 1;
                (yyval.token_list) = _token_list_create (parser);
                _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token));
                talloc_unlink (parser, (yyvsp[(1) - (1)].token));
@@ -2359,7 +2358,7 @@ yyreduce:
   case 63:
 
 /* Line 1464 of yacc.c  */
-#line 480 "glcpp/glcpp-parse.y"
+#line 479 "glcpp/glcpp-parse.y"
     {
                (yyval.token_list) = (yyvsp[(1) - (2)].token_list);
                _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token));
@@ -2370,7 +2369,7 @@ yyreduce:
   case 64:
 
 /* Line 1464 of yacc.c  */
-#line 488 "glcpp/glcpp-parse.y"
+#line 487 "glcpp/glcpp-parse.y"
     {
                parser->space_tokens = 1;
                (yyval.token_list) = _token_list_create (parser);
@@ -2382,7 +2381,7 @@ yyreduce:
   case 65:
 
 /* Line 1464 of yacc.c  */
-#line 494 "glcpp/glcpp-parse.y"
+#line 493 "glcpp/glcpp-parse.y"
     {
                (yyval.token_list) = (yyvsp[(1) - (2)].token_list);
                _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token));
@@ -2393,7 +2392,7 @@ yyreduce:
   case 66:
 
 /* Line 1464 of yacc.c  */
-#line 502 "glcpp/glcpp-parse.y"
+#line 501 "glcpp/glcpp-parse.y"
     {
                (yyval.token) = _token_create_str (parser, IDENTIFIER, (yyvsp[(1) - (1)].str));
                (yyval.token)->location = yylloc;
@@ -2403,7 +2402,7 @@ yyreduce:
   case 67:
 
 /* Line 1464 of yacc.c  */
-#line 506 "glcpp/glcpp-parse.y"
+#line 505 "glcpp/glcpp-parse.y"
     {
                (yyval.token) = _token_create_str (parser, INTEGER_STRING, (yyvsp[(1) - (1)].str));
                (yyval.token)->location = yylloc;
@@ -2413,7 +2412,7 @@ yyreduce:
   case 68:
 
 /* Line 1464 of yacc.c  */
-#line 510 "glcpp/glcpp-parse.y"
+#line 509 "glcpp/glcpp-parse.y"
     {
                (yyval.token) = _token_create_ival (parser, (yyvsp[(1) - (1)].ival), (yyvsp[(1) - (1)].ival));
                (yyval.token)->location = yylloc;
@@ -2423,7 +2422,7 @@ yyreduce:
   case 69:
 
 /* Line 1464 of yacc.c  */
-#line 514 "glcpp/glcpp-parse.y"
+#line 513 "glcpp/glcpp-parse.y"
     {
                (yyval.token) = _token_create_str (parser, OTHER, (yyvsp[(1) - (1)].str));
                (yyval.token)->location = yylloc;
@@ -2433,7 +2432,7 @@ yyreduce:
   case 70:
 
 /* Line 1464 of yacc.c  */
-#line 518 "glcpp/glcpp-parse.y"
+#line 517 "glcpp/glcpp-parse.y"
     {
                (yyval.token) = _token_create_ival (parser, SPACE, SPACE);
                (yyval.token)->location = yylloc;
@@ -2443,224 +2442,224 @@ yyreduce:
   case 71:
 
 /* Line 1464 of yacc.c  */
-#line 525 "glcpp/glcpp-parse.y"
+#line 524 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '['; ;}
     break;
 
   case 72:
 
 /* Line 1464 of yacc.c  */
-#line 526 "glcpp/glcpp-parse.y"
+#line 525 "glcpp/glcpp-parse.y"
     { (yyval.ival) = ']'; ;}
     break;
 
   case 73:
 
 /* Line 1464 of yacc.c  */
-#line 527 "glcpp/glcpp-parse.y"
+#line 526 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '('; ;}
     break;
 
   case 74:
 
 /* Line 1464 of yacc.c  */
-#line 528 "glcpp/glcpp-parse.y"
+#line 527 "glcpp/glcpp-parse.y"
     { (yyval.ival) = ')'; ;}
     break;
 
   case 75:
 
 /* Line 1464 of yacc.c  */
-#line 529 "glcpp/glcpp-parse.y"
+#line 528 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '{'; ;}
     break;
 
   case 76:
 
 /* Line 1464 of yacc.c  */
-#line 530 "glcpp/glcpp-parse.y"
+#line 529 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '}'; ;}
     break;
 
   case 77:
 
 /* Line 1464 of yacc.c  */
-#line 531 "glcpp/glcpp-parse.y"
+#line 530 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '.'; ;}
     break;
 
   case 78:
 
 /* Line 1464 of yacc.c  */
-#line 532 "glcpp/glcpp-parse.y"
+#line 531 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '&'; ;}
     break;
 
   case 79:
 
 /* Line 1464 of yacc.c  */
-#line 533 "glcpp/glcpp-parse.y"
+#line 532 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '*'; ;}
     break;
 
   case 80:
 
 /* Line 1464 of yacc.c  */
-#line 534 "glcpp/glcpp-parse.y"
+#line 533 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '+'; ;}
     break;
 
   case 81:
 
 /* Line 1464 of yacc.c  */
-#line 535 "glcpp/glcpp-parse.y"
+#line 534 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '-'; ;}
     break;
 
   case 82:
 
 /* Line 1464 of yacc.c  */
-#line 536 "glcpp/glcpp-parse.y"
+#line 535 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '~'; ;}
     break;
 
   case 83:
 
 /* Line 1464 of yacc.c  */
-#line 537 "glcpp/glcpp-parse.y"
+#line 536 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '!'; ;}
     break;
 
   case 84:
 
 /* Line 1464 of yacc.c  */
-#line 538 "glcpp/glcpp-parse.y"
+#line 537 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '/'; ;}
     break;
 
   case 85:
 
 /* Line 1464 of yacc.c  */
-#line 539 "glcpp/glcpp-parse.y"
+#line 538 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '%'; ;}
     break;
 
   case 86:
 
 /* Line 1464 of yacc.c  */
-#line 540 "glcpp/glcpp-parse.y"
+#line 539 "glcpp/glcpp-parse.y"
     { (yyval.ival) = LEFT_SHIFT; ;}
     break;
 
   case 87:
 
 /* Line 1464 of yacc.c  */
-#line 541 "glcpp/glcpp-parse.y"
+#line 540 "glcpp/glcpp-parse.y"
     { (yyval.ival) = RIGHT_SHIFT; ;}
     break;
 
   case 88:
 
 /* Line 1464 of yacc.c  */
-#line 542 "glcpp/glcpp-parse.y"
+#line 541 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '<'; ;}
     break;
 
   case 89:
 
 /* Line 1464 of yacc.c  */
-#line 543 "glcpp/glcpp-parse.y"
+#line 542 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '>'; ;}
     break;
 
   case 90:
 
 /* Line 1464 of yacc.c  */
-#line 544 "glcpp/glcpp-parse.y"
+#line 543 "glcpp/glcpp-parse.y"
     { (yyval.ival) = LESS_OR_EQUAL; ;}
     break;
 
   case 91:
 
 /* Line 1464 of yacc.c  */
-#line 545 "glcpp/glcpp-parse.y"
+#line 544 "glcpp/glcpp-parse.y"
     { (yyval.ival) = GREATER_OR_EQUAL; ;}
     break;
 
   case 92:
 
 /* Line 1464 of yacc.c  */
-#line 546 "glcpp/glcpp-parse.y"
+#line 545 "glcpp/glcpp-parse.y"
     { (yyval.ival) = EQUAL; ;}
     break;
 
   case 93:
 
 /* Line 1464 of yacc.c  */
-#line 547 "glcpp/glcpp-parse.y"
+#line 546 "glcpp/glcpp-parse.y"
     { (yyval.ival) = NOT_EQUAL; ;}
     break;
 
   case 94:
 
 /* Line 1464 of yacc.c  */
-#line 548 "glcpp/glcpp-parse.y"
+#line 547 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '^'; ;}
     break;
 
   case 95:
 
 /* Line 1464 of yacc.c  */
-#line 549 "glcpp/glcpp-parse.y"
+#line 548 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '|'; ;}
     break;
 
   case 96:
 
 /* Line 1464 of yacc.c  */
-#line 550 "glcpp/glcpp-parse.y"
+#line 549 "glcpp/glcpp-parse.y"
     { (yyval.ival) = AND; ;}
     break;
 
   case 97:
 
 /* Line 1464 of yacc.c  */
-#line 551 "glcpp/glcpp-parse.y"
+#line 550 "glcpp/glcpp-parse.y"
     { (yyval.ival) = OR; ;}
     break;
 
   case 98:
 
 /* Line 1464 of yacc.c  */
-#line 552 "glcpp/glcpp-parse.y"
+#line 551 "glcpp/glcpp-parse.y"
     { (yyval.ival) = ';'; ;}
     break;
 
   case 99:
 
 /* Line 1464 of yacc.c  */
-#line 553 "glcpp/glcpp-parse.y"
+#line 552 "glcpp/glcpp-parse.y"
     { (yyval.ival) = ','; ;}
     break;
 
   case 100:
 
 /* Line 1464 of yacc.c  */
-#line 554 "glcpp/glcpp-parse.y"
+#line 553 "glcpp/glcpp-parse.y"
     { (yyval.ival) = '='; ;}
     break;
 
   case 101:
 
 /* Line 1464 of yacc.c  */
-#line 555 "glcpp/glcpp-parse.y"
+#line 554 "glcpp/glcpp-parse.y"
     { (yyval.ival) = PASTE; ;}
     break;
 
 
 
 /* Line 1464 of yacc.c  */
-#line 2664 "glcpp/glcpp-parse.c"
+#line 2663 "glcpp/glcpp-parse.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2879,7 +2878,7 @@ yyreturn:
 
 
 /* Line 1684 of yacc.c  */
-#line 558 "glcpp/glcpp-parse.y"
+#line 557 "glcpp/glcpp-parse.y"
 
 
 string_list_t *
index 8475e08f00c9776e505fb8f0b9de76432502deb4..558ad0acacc3bcbb2a6ca746f0d1ea1c61b79d2c 100644 (file)
@@ -472,7 +472,6 @@ conditional_token:
 conditional_tokens:
        /* Exactly the same as pp_tokens, but using conditional_token */
        conditional_token {
-               parser->space_tokens = 1;
                $$ = _token_list_create (parser);
                _token_list_append ($$, $1);
                talloc_unlink (parser, $1);
index 302cfbc5668e5917804e147d1e64f0be03e32ece..8dbe66927dc107359471f13b3139d5831e9175c3 100644 (file)
@@ -716,6 +716,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration
    }
    progress = do_structure_splitting(ir) || progress;
    progress = do_if_simplification(ir) || progress;
+   progress = do_discard_simplification(ir) || progress;
    progress = do_copy_propagation(ir) || progress;
    if (linked)
       progress = do_dead_code(ir) || progress;
index e9bf89b951df246cf312dbd9d75383f8290c0239..3dcd928016ac1b1c5c7af45d4a6e5e8b0ac26e63 100644 (file)
@@ -81,12 +81,12 @@ bool glsl_symbol_table::name_declared_this_scope(const char *name)
    return _mesa_symbol_table_symbol_scope(table, -1, name) == 0;
 }
 
-bool glsl_symbol_table::add_variable(const char *name, ir_variable *v)
+bool glsl_symbol_table::add_variable(ir_variable *v)
 {
    if (this->language_version == 110) {
       /* In 1.10, functions and variables have separate namespaces. */
-      symbol_table_entry *existing = get_entry(name);
-      if (name_declared_this_scope(name)) {
+      symbol_table_entry *existing = get_entry(v->name);
+      if (name_declared_this_scope(v->name)) {
         /* If there's already an existing function (not a constructor!) in
          * the current scope, just update the existing entry to include 'v'.
          */
@@ -102,7 +102,7 @@ bool glsl_symbol_table::add_variable(const char *name, ir_variable *v)
         symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v);
         if (existing != NULL)
            entry->f = existing->f;
-        int added = _mesa_symbol_table_add_symbol(table, -1, name, entry);
+        int added = _mesa_symbol_table_add_symbol(table, -1, v->name, entry);
         assert(added == 0);
         (void)added;
         return true;
@@ -112,7 +112,7 @@ bool glsl_symbol_table::add_variable(const char *name, ir_variable *v)
 
    /* 1.20+ rules: */
    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v);
-   return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
+   return _mesa_symbol_table_add_symbol(table, -1, v->name, entry) == 0;
 }
 
 bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
@@ -121,18 +121,25 @@ bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
    return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
 }
 
-bool glsl_symbol_table::add_function(const char *name, ir_function *f)
+bool glsl_symbol_table::add_function(ir_function *f)
 {
-   if (this->language_version == 110 && name_declared_this_scope(name)) {
+   if (this->language_version == 110 && name_declared_this_scope(f->name)) {
       /* In 1.10, functions and variables have separate namespaces. */
-      symbol_table_entry *existing = get_entry(name);
+      symbol_table_entry *existing = get_entry(f->name);
       if ((existing->f == NULL) && (existing->t == NULL)) {
         existing->f = f;
         return true;
       }
    }
    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
-   return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
+   return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0;
+}
+
+void glsl_symbol_table::add_global_function(ir_function *f)
+{
+   symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
+   int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry);
+   assert(added == 0);
 }
 
 ir_variable *glsl_symbol_table::get_variable(const char *name)
index f26de52432574e00d20e8642c535ebc1fd047964..28a44ebe91c24fa065755136f1bfd30d1efad338 100644 (file)
@@ -97,11 +97,16 @@ public:
     * reduces the clarity of the intention of code that uses these methods.
     */
    /*@{*/
-   bool add_variable(const char *name, ir_variable *v);
+   bool add_variable(ir_variable *v);
    bool add_type(const char *name, const glsl_type *t);
-   bool add_function(const char *name, ir_function *f);
+   bool add_function(ir_function *f);
    /*@}*/
 
+   /**
+    * Add an function at global scope without checking for scoping conflicts.
+    */
+   void add_global_function(ir_function *f);
+
    /**
     * \name Methods to get symbols from the table
     */
index 2abb95394fd04ef8d30e1e602d7d4653d1565102..b8b0fed9d1cc760da6081add81b81810bc776702 100644 (file)
@@ -231,6 +231,108 @@ ir_expression::ir_expression(int op, const struct glsl_type *type,
    this->operands[3] = op3;
 }
 
+ir_expression::ir_expression(int op, ir_rvalue *op0)
+{
+   this->ir_type = ir_type_expression;
+
+   this->operation = ir_expression_operation(op);
+   this->operands[0] = op0;
+   this->operands[1] = NULL;
+   this->operands[2] = NULL;
+   this->operands[3] = NULL;
+
+   assert(op <= ir_last_unop);
+
+   switch (this->operation) {
+   case ir_unop_bit_not:
+   case ir_unop_logic_not:
+   case ir_unop_neg:
+   case ir_unop_abs:
+   case ir_unop_sign:
+   case ir_unop_rcp:
+   case ir_unop_rsq:
+   case ir_unop_sqrt:
+   case ir_unop_exp:
+   case ir_unop_log:
+   case ir_unop_exp2:
+   case ir_unop_log2:
+   case ir_unop_trunc:
+   case ir_unop_ceil:
+   case ir_unop_floor:
+   case ir_unop_fract:
+   case ir_unop_round_even:
+   case ir_unop_cos:
+   case ir_unop_dFdx:
+   case ir_unop_dFdy:
+      this->type = op0->type;
+      break;
+
+   case ir_unop_any:
+      this->type = glsl_type::bool_type;
+      break;
+
+   default:
+      assert(!"not reached: missing automatic type setup for ir_expression");
+      this->type = op0->type;
+      break;
+   }
+}
+
+ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
+{
+   this->ir_type = ir_type_expression;
+
+   this->operation = ir_expression_operation(op);
+   this->operands[0] = op0;
+   this->operands[1] = op1;
+   this->operands[2] = NULL;
+   this->operands[3] = NULL;
+
+   assert(op > ir_last_unop);
+
+   switch (this->operation) {
+   case ir_binop_all_equal:
+   case ir_binop_any_nequal:
+      this->type = glsl_type::bool_type;
+      break;
+
+   case ir_binop_add:
+   case ir_binop_sub:
+   case ir_binop_min:
+   case ir_binop_max:
+   case ir_binop_pow:
+   case ir_binop_mul:
+      if (op0->type->is_scalar()) {
+        this->type = op1->type;
+      } else if (op1->type->is_scalar()) {
+        this->type = op0->type;
+      } else {
+        /* FINISHME: matrix types */
+        assert(!op0->type->is_matrix() && !op1->type->is_matrix());
+        assert(op0->type == op1->type);
+        this->type = op0->type;
+      }
+      break;
+
+   case ir_binop_logic_and:
+   case ir_binop_logic_or:
+      if (op0->type->is_scalar()) {
+        this->type = op1->type;
+      } else if (op1->type->is_scalar()) {
+        this->type = op0->type;
+      }
+      break;
+
+   case ir_binop_dot:
+      this->type = glsl_type::float_type;
+      break;
+
+   default:
+      assert(!"not reached: missing automatic type setup for ir_expression");
+      this->type = glsl_type::float_type;
+   }
+}
+
 unsigned int
 ir_expression::get_num_operands(ir_expression_operation op)
 {
@@ -676,7 +778,7 @@ ir_constant::has_value(const ir_constant *c) const
 
    if (this->type->is_array()) {
       for (unsigned i = 0; i < this->type->length; i++) {
-        if (this->array_elements[i]->has_value(c->array_elements[i]))
+        if (!this->array_elements[i]->has_value(c->array_elements[i]))
            return false;
       }
       return true;
index 850033b185fca229165b89afb8abdab9e83bb904..102a68b65516a207d7f7bf29c78a60a0330d00be 100644 (file)
@@ -122,6 +122,7 @@ public:
    virtual class ir_if *                as_if()               { return NULL; }
    virtual class ir_swizzle *           as_swizzle()          { return NULL; }
    virtual class ir_constant *          as_constant()         { return NULL; }
+   virtual class ir_discard *           as_discard()          { return NULL; }
    /*@}*/
 
 protected:
@@ -375,6 +376,8 @@ public:
 
    virtual ir_function_signature *clone(void *mem_ctx,
                                        struct hash_table *ht) const;
+   ir_function_signature *clone_prototype(void *mem_ctx,
+                                         struct hash_table *ht) const;
 
    virtual void accept(ir_visitor *v)
    {
@@ -841,12 +844,14 @@ public:
     * Constructor for unary operation expressions
     */
    ir_expression(int op, const struct glsl_type *type, ir_rvalue *);
+   ir_expression(int op, ir_rvalue *);
 
    /**
     * Constructor for binary operation expressions
     */
    ir_expression(int op, const struct glsl_type *type,
                 ir_rvalue *, ir_rvalue *);
+   ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
 
    /**
     * Constructor for quad operator expressions
@@ -1122,6 +1127,11 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
+   virtual ir_discard *as_discard()
+   {
+      return this;
+   }
+
    ir_rvalue *condition;
 };
 /*@}*/
index 325f60661541b37b073169fdf262dd0cb4c256a1..1522af682bb5d46ad0f185eb90d8cb36a214ac65 100644 (file)
@@ -275,14 +275,33 @@ ir_function::clone(void *mem_ctx, struct hash_table *ht) const
 
 ir_function_signature *
 ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const
+{
+   ir_function_signature *copy = this->clone_prototype(mem_ctx, ht);
+
+   copy->is_defined = this->is_defined;
+
+   /* Clone the instruction list.
+    */
+   foreach_list_const(node, &this->body) {
+      const ir_instruction *const inst = (const ir_instruction *) node;
+
+      ir_instruction *const inst_copy = inst->clone(mem_ctx, ht);
+      copy->body.push_tail(inst_copy);
+   }
+
+   return copy;
+}
+
+ir_function_signature *
+ir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) const
 {
    ir_function_signature *copy =
       new(mem_ctx) ir_function_signature(this->return_type);
 
-   copy->is_defined = this->is_defined;
+   copy->is_defined = false;
    copy->is_builtin = this->is_builtin;
 
-   /* Clone the parameter list.
+   /* Clone the parameter list, but NOT the body.
     */
    foreach_list_const(node, &this->parameters) {
       const ir_variable *const param = (const ir_variable *) node;
@@ -293,15 +312,6 @@ ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const
       copy->parameters.push_tail(param_copy);
    }
 
-   /* Clone the instruction list.
-    */
-   foreach_list_const(node, &this->body) {
-      const ir_instruction *const inst = (const ir_instruction *) node;
-
-      ir_instruction *const inst_copy = inst->clone(mem_ctx, ht);
-      copy->body.push_tail(inst_copy);
-   }
-
    return copy;
 }
 
index f29f277ef4b50683848e08d8c3960e5ba7f43860..c367c30e44f37a7453481784d1f96b370ea2047a 100644 (file)
@@ -60,6 +60,8 @@ can_inline(ir_call *call)
 {
    ir_function_can_inline_visitor v;
    const ir_function_signature *callee = call->get_callee();
+   if (!callee->is_defined)
+      return false;
 
    v.run((exec_list *) &callee->body);
 
index 066137e60aab5d9b372a64f9788050803231bbd8..4e0b30aa90e155ee4ee4bf4430bb23c7b69e47eb 100644 (file)
@@ -64,7 +64,7 @@ public:
 
         /* Add the new function to the symbol table.
          */
-        this->symbols->add_function(this->function->name, this->function);
+        this->symbols->add_function(this->function);
       }
       return visit_continue;
    }
@@ -82,22 +82,7 @@ public:
    {
       assert(this->function != NULL);
 
-      ir_function_signature *copy =
-        new(mem_ctx) ir_function_signature(ir->return_type);
-
-      copy->is_defined = false;
-      copy->is_builtin = ir->is_builtin;
-
-      /* Clone the parameter list, but NOT the body.
-       */
-      foreach_list_const(node, &ir->parameters) {
-        const ir_variable *const param = (const ir_variable *) node;
-
-        assert(const_cast<ir_variable *>(param)->as_variable() != NULL);
-
-        ir_variable *const param_copy = param->clone(mem_ctx, NULL);
-        copy->parameters.push_tail(param_copy);
-      }
+      ir_function_signature *copy = ir->clone_prototype(mem_ctx, NULL);
 
       this->function->add_signature(copy);
 
index fa497a45551419ac136c0ce04ba9c6d7dce6fc0d..f264265f4b14b673dca8f515f9cb2d4e59e5d935 100644 (file)
@@ -32,8 +32,9 @@
 #define SUB_TO_ADD_NEG 0x01
 #define DIV_TO_MUL_RCP 0x02
 #define EXP_TO_EXP2    0x04
-#define LOG_TO_LOG2    0x08
-#define MOD_TO_FRACT   0x10
+#define POW_TO_EXP2    0x08
+#define LOG_TO_LOG2    0x10
+#define MOD_TO_FRACT   0x20
 
 bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);
 
@@ -51,6 +52,7 @@ bool do_function_inlining(exec_list *instructions);
 bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lower_sub_return = true, bool lower_main_return = false, bool lower_continue = false, bool lower_break = false);
 bool do_lower_texture_projection(exec_list *instructions);
 bool do_if_simplification(exec_list *instructions);
+bool do_discard_simplification(exec_list *instructions);
 bool do_if_to_cond_assign(exec_list *instructions);
 bool do_mat_op_to_vec(exec_list *instructions);
 bool do_mod_to_fract(exec_list *instructions);
@@ -61,6 +63,7 @@ bool do_swizzle_swizzle(exec_list *instructions);
 bool do_tree_grafting(exec_list *instructions);
 bool do_vec_index_to_cond_assign(exec_list *instructions);
 bool do_vec_index_to_swizzle(exec_list *instructions);
+bool lower_discard(exec_list *instructions);
 bool lower_instructions(exec_list *instructions, unsigned what_to_lower);
 bool lower_noise(exec_list *instructions);
 bool lower_variable_index_to_cond_assign(exec_list *instructions,
index e5067bfdad03856ebfbc251cec5ee7b854ba8685..0aa0b0a5d32f3a7f0e54a37eb86aba174c0cd2be 100644 (file)
@@ -153,17 +153,10 @@ void ir_print_visitor::visit(ir_function_signature *ir)
 
 void ir_print_visitor::visit(ir_function *ir)
 {
-   if (!ir->has_user_signature())
-      return;
-
    printf("(function %s\n", ir->name);
    indentation++;
    foreach_iter(exec_list_iterator, iter, *ir) {
       ir_function_signature *const sig = (ir_function_signature *) iter.get();
-
-      if (sig->is_builtin)
-        continue;
-
       indent();
       sig->accept(this);
       printf("\n");
@@ -325,6 +318,15 @@ void ir_print_visitor::visit(ir_constant *ir)
    if (ir->type->is_array()) {
       for (unsigned i = 0; i < ir->type->length; i++)
         ir->get_array_element(i)->accept(this);
+   } else if (ir->type->is_record()) {
+      ir_constant *value = (ir_constant *) ir->components.get_head();
+      for (unsigned i = 0; i < ir->type->length; i++) {
+        printf("(%s ", ir->type->fields.structure->name);
+        value->accept(this);
+        printf(")");
+
+        value = (ir_constant *) value->next;
+      }
    } else {
       for (unsigned i = 0; i < ir->type->components(); i++) {
         if (i != 0)
index 7a22a945ec5aa956cb278428b59ae5980a512cc4..5a718d3b7569199839519445ace4ff824a451169 100644 (file)
@@ -221,7 +221,7 @@ read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
    ir_function *f = st->symbols->get_function(name->value());
    if (f == NULL) {
       f = new(ctx) ir_function(name->value());
-      added = st->symbols->add_function(f->name, f);
+      added = st->symbols->add_function(f);
       assert(added);
    }
 
@@ -474,7 +474,7 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list)
    }
 
    // Add the variable to the symbol table
-   st->symbols->add_variable(var->name, var);
+   st->symbols->add_variable(var);
 
    return var;
 }
index b3f1cc0d8b53205972560c0b6bea5d5134d5bbea..714281539ac1c654ed22815e644ec6153f8a3cfb 100644 (file)
@@ -66,7 +66,7 @@ public:
 };
 
 static void
-mark(struct gl_program *prog, ir_variable *var, int index)
+mark(struct gl_program *prog, ir_variable *var, int offset, int len)
 {
    /* As of GLSL 1.20, varyings can only be floats, floating-point
     * vectors or matrices, or arrays of them.  For Mesa programs using
@@ -75,25 +75,12 @@ mark(struct gl_program *prog, ir_variable *var, int index)
     * something doing a more clever packing would use something other
     * than InputsRead/OutputsWritten.
     */
-   const glsl_type *element_type;
-   int element_size;
 
-   if (var->type->is_array())
-      element_type = var->type->fields.array;
-   else
-      element_type = var->type;
-
-   if (element_type->is_matrix())
-      element_size = element_type->matrix_columns;
-   else
-      element_size = 1;
-
-   index *= element_size;
-   for (int i = 0; i < element_size; i++) {
+   for (int i = 0; i < len; i++) {
       if (var->mode == ir_var_in)
-        prog->InputsRead |= BITFIELD64_BIT(var->location + index + i);
+        prog->InputsRead |= BITFIELD64_BIT(var->location + offset + i);
       else
-        prog->OutputsWritten |= BITFIELD64_BIT(var->location + index + i);
+        prog->OutputsWritten |= BITFIELD64_BIT(var->location + offset + i);
    }
 }
 
@@ -106,10 +93,11 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
 
    if (ir->type->is_array()) {
       for (unsigned int i = 0; i < ir->type->length; i++) {
-        mark(this->prog, ir->var, i);
+        mark(this->prog, ir->var, i,
+             ir->type->length * ir->type->fields.array->matrix_columns);
       }
    } else {
-      mark(this->prog, ir->var, 0);
+      mark(this->prog, ir->var, 0, ir->type->matrix_columns);
    }
 
    return visit_continue;
@@ -128,7 +116,14 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
       var = (ir_variable *)hash_table_find(this->ht, deref_var->var);
 
    if (index && var) {
-      mark(this->prog, var, index->value.i[0]);
+      int width = 1;
+
+      if (deref_var->type->is_array() &&
+         deref_var->type->fields.array->is_matrix()) {
+        width = deref_var->type->fields.array->matrix_columns;
+      }
+
+      mark(this->prog, var, index->value.i[0] * width, width);
       return visit_continue_with_parent;
    }
 
index 6b9b29458d082044f837743d8c36b6570cb09374..5b8281e16e35580425c1b5e4a6bf38013d33ee66 100644 (file)
@@ -59,7 +59,7 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot,
     */
    instructions->push_tail(var);
 
-   symtab->add_variable(var->name, var);
+   symtab->add_variable(var);
    return var;
 }
 
index 78c8b48cf179c4060caa13c2a3cc91644eeaccb5..05930edb80e93241dda5509e4e4e7b41292a8e4c 100644 (file)
@@ -183,7 +183,7 @@ public:
             * it to the linked shader.
             */
            var = ir->var->clone(linked, NULL);
-           linked->symbols->add_variable(var->name, var);
+           linked->symbols->add_variable(var);
            linked->ir->push_head(var);
         }
 
index 616ec7800713c481db160d8c18a878b6a20f65a6..e62fe6d7e9fd4002a3ac070298da0d7da7fef9c2 100644 (file)
@@ -360,8 +360,12 @@ cross_validate_globals(struct gl_shader_program *prog,
                   && (var->type->fields.array == existing->type->fields.array)
                   && ((var->type->length == 0)
                       || (existing->type->length == 0))) {
-                 if (existing->type->length == 0)
+                 if (existing->type->length == 0) {
                     existing->type = var->type;
+                    existing->max_array_access =
+                       MAX2(existing->max_array_access,
+                            var->max_array_access);
+                 }
               } else {
                  linker_error_printf(prog, "%s `%s' declared as type "
                                      "`%s' and type `%s'\n",
@@ -411,8 +415,15 @@ cross_validate_globals(struct gl_shader_program *prog,
                  existing->constant_value =
                     var->constant_value->clone(talloc_parent(existing), NULL);
            }
+
+           if (existing->invariant != var->invariant) {
+              linker_error_printf(prog, "declarations for %s `%s' have "
+                                  "mismatching invariant qualifiers\n",
+                                  mode_string(var), var->name);
+              return false;
+           }
         } else
-           variables.add_variable(var->name, var);
+           variables.add_variable(var);
       }
    }
 
@@ -454,7 +465,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
       if ((var == NULL) || (var->mode != ir_var_out))
         continue;
 
-      parameters.add_variable(var->name, var);
+      parameters.add_variable(var);
    }
 
 
@@ -546,9 +557,9 @@ populate_symbol_table(gl_shader *sh)
       ir_function *func;
 
       if ((func = inst->as_function()) != NULL) {
-        sh->symbols->add_function(func->name, func);
+        sh->symbols->add_function(func);
       } else if ((var = inst->as_variable()) != NULL) {
-        sh->symbols->add_variable(var->name, var);
+        sh->symbols->add_variable(var);
       }
    }
 }
@@ -605,7 +616,7 @@ remap_variables(ir_instruction *inst, struct gl_shader *target,
         else {
            ir_variable *copy = ir->var->clone(this->target, NULL);
 
-           this->symbols->add_variable(copy->name, copy);
+           this->symbols->add_variable(copy);
            this->instructions->push_head(copy);
            ir->var = copy;
         }
@@ -726,7 +737,8 @@ get_main_function_signature(gl_shader *sh)
  * shader is returned.
  */
 static struct gl_shader *
-link_intrastage_shaders(struct gl_context *ctx,
+link_intrastage_shaders(void *mem_ctx,
+                       struct gl_context *ctx,
                        struct gl_shader_program *prog,
                        struct gl_shader **shader_list,
                        unsigned num_shaders)
@@ -802,7 +814,7 @@ link_intrastage_shaders(struct gl_context *ctx,
 
    gl_shader *linked = ctx->Driver.NewShader(NULL, 0, main->Type);
    linked->ir = new(linked) exec_list;
-   clone_ir_list(linked, linked->ir, main->ir);
+   clone_ir_list(mem_ctx, linked->ir, main->ir);
 
    populate_symbol_table(linked);
 
@@ -855,6 +867,32 @@ link_intrastage_shaders(struct gl_context *ctx,
 
    free(linking_shaders);
 
+   /* Make a pass over all global variables to ensure that arrays with
+    * unspecified sizes have a size specified.  The size is inferred from the
+    * max_array_access field.
+    */
+   if (linked != NULL) {
+      foreach_list(node, linked->ir) {
+        ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+        if (var == NULL)
+           continue;
+
+        if ((var->mode != ir_var_auto) && (var->mode != ir_var_temporary))
+           continue;
+
+        if (!var->type->is_array() || (var->type->length != 0))
+           continue;
+
+        const glsl_type *type =
+           glsl_type::get_array_instance(var->type->fields.array,
+                                         var->max_array_access);
+
+        assert(type != NULL);
+        var->type = type;
+      }
+   }
+
    return linked;
 }
 
@@ -1407,6 +1445,8 @@ assign_varying_locations(struct gl_shader_program *prog,
 void
 link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
+   void *mem_ctx = talloc_init("temporary linker context");
+
    prog->LinkStatus = false;
    prog->Validated = false;
    prog->_Used = false;
@@ -1475,7 +1515,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
     */
    if (num_vert_shaders > 0) {
       gl_shader *const sh =
-        link_intrastage_shaders(ctx, prog, vert_shader_list, num_vert_shaders);
+        link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list,
+                                num_vert_shaders);
 
       if (sh == NULL)
         goto done;
@@ -1489,7 +1530,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 
    if (num_frag_shaders > 0) {
       gl_shader *const sh =
-        link_intrastage_shaders(ctx, prog, frag_shader_list, num_frag_shaders);
+        link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list,
+                                num_frag_shaders);
 
       if (sh == NULL)
         goto done;
@@ -1598,4 +1640,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 
 done:
    free(vert_shader_list);
+
+   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+      if (prog->_LinkedShaders[i] == NULL)
+        continue;
+
+      /* Retain any live IR, but trash the rest. */
+      reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);
+   }
+
+   talloc_free(mem_ctx);
 }
index 11709587e24e57ce3c2adf43c2bb7d0463f4a68e..46000524ba105fdc56358d32261b44dc952711d5 100644 (file)
@@ -43,6 +43,14 @@ public:
 };
 
 
+static bool
+is_break(ir_instruction *ir)
+{
+   return ir != NULL && ir->ir_type == ir_type_loop_jump
+                    && ((ir_loop_jump *) ir)->is_break();
+}
+
+
 ir_visitor_status
 loop_unroll_visitor::visit_leave(ir_loop *ir)
 {
@@ -73,44 +81,74 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
    if (ls->num_loop_jumps > 1)
       return visit_continue;
    else if (ls->num_loop_jumps) {
-      /* recognize loops in the form produced by ir_lower_jumps */
-      ir_instruction *last_ir =
-        ((ir_instruction*)ir->body_instructions.get_tail());
-
+      ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
       assert(last_ir != NULL);
 
-      ir_if *last_if = last_ir->as_if();
-      if (last_if) {
-        bool continue_from_then_branch;
-
-        /* Determine which if-statement branch, if any, ends with a break.
-         * The branch that did *not* have the break will get a temporary
-         * continue inserted in each iteration of the loop unroll.
-         *
-         * Note that since ls->num_loop_jumps is <= 1, it is impossible for
-         * both branches to end with a break.
-         */
-        ir_instruction *last =
-           (ir_instruction *) last_if->then_instructions.get_tail();
-
-        if (last && last->ir_type == ir_type_loop_jump
-            && ((ir_loop_jump*) last)->is_break()) {
-           continue_from_then_branch = false;
-        } else {
-           last = (ir_instruction *) last_if->then_instructions.get_tail();
-
-           if (last && last->ir_type == ir_type_loop_jump
-               && ((ir_loop_jump*) last)->is_break())
-              continue_from_then_branch = true;
-           else
-              /* Bail out if neither if-statement branch ends with a break.
+      if (is_break(last_ir)) {
+         /* If the only loop-jump is a break at the end of the loop, the loop
+          * will execute exactly once.  Remove the break, set the iteration
+          * count, and fall through to the normal unroller.
+          */
+         last_ir->remove();
+         iterations = 1;
+
+         this->progress = true;
+      } else {
+         ir_if *ir_if = NULL;
+         ir_instruction *break_ir = NULL;
+         bool continue_from_then_branch = false;
+
+         foreach_list(node, &ir->body_instructions) {
+            /* recognize loops in the form produced by ir_lower_jumps */
+            ir_instruction *cur_ir = (ir_instruction *) node;
+
+            ir_if = cur_ir->as_if();
+            if (ir_if != NULL) {
+              /* Determine which if-statement branch, if any, ends with a
+               * break.  The branch that did *not* have the break will get a
+               * temporary continue inserted in each iteration of the loop
+               * unroll.
+               *
+               * Note that since ls->num_loop_jumps is <= 1, it is impossible
+               * for both branches to end with a break.
                */
-              return visit_continue;
-        }
+               ir_instruction *ir_if_last =
+                  (ir_instruction *) ir_if->then_instructions.get_tail();
+
+               if (is_break(ir_if_last)) {
+                  continue_from_then_branch = false;
+                  break_ir = ir_if_last;
+                  break;
+               } else {
+                  ir_if_last =
+                    (ir_instruction *) ir_if->else_instructions.get_tail();
+
+                  if (is_break(ir_if_last)) {
+                     break_ir = ir_if_last;
+                     continue_from_then_branch = true;
+                     break;
+                  }
+               }
+            }
+         }
+
+         if (break_ir == NULL)
+            return visit_continue;
+
+         /* move instructions after then if in the continue branch */
+         while (!ir_if->get_next()->is_tail_sentinel()) {
+            ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
+
+            move_ir->remove();
+            if (continue_from_then_branch)
+               ir_if->then_instructions.push_tail(move_ir);
+            else
+               ir_if->else_instructions.push_tail(move_ir);
+         }
 
-        /* Remove the break from the if-statement.
-         */
-        last->remove();
+         /* Remove the break from the if-statement.
+          */
+         break_ir->remove();
 
          void *const mem_ctx = talloc_parent(ir);
          ir_instruction *ir_to_replace = ir;
@@ -121,8 +159,8 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
             copy_list.make_empty();
             clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
 
-            last_if = ((ir_instruction*)copy_list.get_tail())->as_if();
-            assert(last_if);
+            ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
+            assert(ir_if != NULL);
 
             ir_to_replace->insert_before(&copy_list);
             ir_to_replace->remove();
@@ -132,7 +170,7 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
               new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
 
             exec_list *const list = (continue_from_then_branch)
-              ? &last_if->then_instructions : &last_if->else_instructions;
+               ? &ir_if->then_instructions : &ir_if->else_instructions;
 
             list->push_tail(ir_to_replace);
          }
@@ -141,18 +179,7 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
 
          this->progress = true;
          return visit_continue;
-      } else if (last_ir->ir_type == ir_type_loop_jump
-                && ((ir_loop_jump *)last_ir)->is_break()) {
-        /* If the only loop-jump is a break at the end of the loop, the loop
-         * will execute exactly once.  Remove the break, set the iteration
-         * count, and fall through to the normal unroller.
-         */
-         last_ir->remove();
-        iterations = 1;
-
-        this->progress = true;
-      } else
-         return visit_continue;
+      }
    }
 
    void *const mem_ctx = talloc_parent(ir);
diff --git a/src/glsl/lower_discard.cpp b/src/glsl/lower_discard.cpp
new file mode 100644 (file)
index 0000000..b95313d
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file lower_discard.cpp
+ *
+ * This pass moves discards out of if-statements.
+ *
+ * Case 1: The "then" branch contains a conditional discard:
+ * ---------------------------------------------------------
+ *
+ *    if (cond1) {
+ *      s1;
+ *      discard cond2;
+ *      s2;
+ *    } else {
+ *      s3;
+ *    }
+ *
+ * becomes:
+ *
+ *    temp = false;
+ *    if (cond1) {
+ *      s1;
+ *      temp = cond2;
+ *      s2;
+ *    } else {
+ *      s3;
+ *    }
+ *    discard temp;
+ *
+ * Case 2: The "else" branch contains a conditional discard:
+ * ---------------------------------------------------------
+ *
+ *    if (cond1) {
+ *      s1;
+ *    } else {
+ *      s2;
+ *      discard cond2;
+ *      s3;
+ *    }
+ *
+ * becomes:
+ *
+ *    temp = false;
+ *    if (cond1) {
+ *      s1;
+ *    } else {
+ *      s2;
+ *      temp = cond2;
+ *      s3;
+ *    }
+ *    discard temp;
+ *
+ * Case 3: Both branches contain a conditional discard:
+ * ----------------------------------------------------
+ *
+ *    if (cond1) {
+ *      s1;
+ *      discard cond2;
+ *      s2;
+ *    } else {
+ *      s3;
+ *      discard cond3;
+ *      s4;
+ *    }
+ *
+ * becomes:
+ *
+ *    temp = false;
+ *    if (cond1) {
+ *      s1;
+ *      temp = cond2;
+ *      s2;
+ *    } else {
+ *      s3;
+ *      temp = cond3;
+ *      s4;
+ *    }
+ *    discard temp;
+ *
+ * If there are multiple conditional discards, we need only deal with one of
+ * them.  Repeatedly applying this pass will take care of the others.
+ *
+ * Unconditional discards are treated as having a condition of "true".
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+
+class lower_discard_visitor : public ir_hierarchical_visitor {
+public:
+   lower_discard_visitor()
+   {
+      this->progress = false;
+   }
+
+   ir_visitor_status visit_leave(ir_if *);
+
+   bool progress;
+};
+
+
+bool
+lower_discard(exec_list *instructions)
+{
+   lower_discard_visitor v;
+
+   visit_list_elements(&v, instructions);
+
+   return v.progress;
+}
+
+
+static ir_discard *
+find_discard(exec_list &instructions)
+{
+   foreach_list(n, &instructions) {
+      ir_discard *ir = ((ir_instruction *) n)->as_discard();
+      if (ir != NULL)
+        return ir;
+   }
+   return NULL;
+}
+
+
+static void
+replace_discard(void *mem_ctx, ir_variable *var, ir_discard *ir)
+{
+   ir_rvalue *condition = ir->condition;
+
+   /* For unconditional discards, use "true" as the condition. */
+   if (condition == NULL)
+      condition = new(mem_ctx) ir_constant(true);
+
+   ir_assignment *assignment =
+      new(mem_ctx) ir_assignment(new(mem_ctx) ir_dereference_variable(var),
+                                condition, NULL);
+
+   ir->replace_with(assignment);
+}
+
+
+ir_visitor_status
+lower_discard_visitor::visit_leave(ir_if *ir)
+{
+   ir_discard *then_discard = find_discard(ir->then_instructions);
+   ir_discard *else_discard = find_discard(ir->else_instructions);
+
+   if (then_discard == NULL && else_discard == NULL)
+      return visit_continue;
+
+   void *mem_ctx = talloc_parent(ir);
+
+   ir_variable *temp = new(mem_ctx) ir_variable(glsl_type::bool_type,
+                                               "discard_cond_temp",
+                                               ir_var_temporary);
+   ir_assignment *temp_initializer =
+      new(mem_ctx) ir_assignment(new(mem_ctx) ir_dereference_variable(temp),
+                                new(mem_ctx) ir_constant(false), NULL);
+
+   ir->insert_before(temp);
+   ir->insert_before(temp_initializer);
+
+   if (then_discard != NULL)
+      replace_discard(mem_ctx, temp, then_discard);
+
+   if (else_discard != NULL)
+      replace_discard(mem_ctx, temp, else_discard);
+
+   ir_discard *discard = then_discard != NULL ? then_discard : else_discard;
+   discard->condition = new(mem_ctx) ir_dereference_variable(temp);
+   ir->insert_after(discard);
+
+   this->progress = true;
+
+   return visit_continue;
+}
index d460ba1a97abd2d3fe00f368c2ef5eba4f0e7d55..a5f61f213d056d8098083bdd2a479c292861b1e7 100644 (file)
@@ -33,6 +33,7 @@
  * - SUB_TO_ADD_NEG
  * - DIV_TO_MUL_RCP
  * - EXP_TO_EXP2
+ * - POW_TO_EXP2
  * - LOG_TO_LOG2
  * - MOD_TO_FRACT
  *
  * do have base 2 versions, so this pass converts exp and log to exp2
  * and log2 operations.
  *
+ * POW_TO_EXP2:
+ * -----------
+ * Many older GPUs don't have an x**y instruction.  For these GPUs, convert
+ * x**y to 2**(y * log2(x)).
+ *
  * MOD_TO_FRACT:
  * -------------
  * Breaks an ir_unop_mod expression down to (op1 * fract(op0 / op1))
@@ -70,7 +76,7 @@
  * opportunity to do things like constant fold the (1.0 / op1) easily.
  */
 
-#include "main/core.h" /* for M_E */
+#include "main/core.h" /* for M_LOG2E */
 #include "glsl_types.h"
 #include "ir.h"
 #include "ir_optimization.h"
@@ -91,6 +97,7 @@ private:
    void div_to_mul_rcp(ir_expression *);
    void mod_to_fract(ir_expression *);
    void exp_to_exp2(ir_expression *);
+   void pow_to_exp2(ir_expression *);
    void log_to_log2(ir_expression *);
 };
 
@@ -172,7 +179,7 @@ lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir)
 void
 lower_instructions_visitor::exp_to_exp2(ir_expression *ir)
 {
-   ir_constant *log2_e = new(ir) ir_constant(log2f(M_E));
+   ir_constant *log2_e = new(ir) ir_constant(float(M_LOG2E));
 
    ir->operation = ir_unop_exp2;
    ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[0]->type,
@@ -180,13 +187,27 @@ lower_instructions_visitor::exp_to_exp2(ir_expression *ir)
    this->progress = true;
 }
 
+void
+lower_instructions_visitor::pow_to_exp2(ir_expression *ir)
+{
+   ir_expression *const log2_x =
+      new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
+                           ir->operands[0]);
+
+   ir->operation = ir_unop_exp2;
+   ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[1]->type,
+                                          ir->operands[1], log2_x);
+   ir->operands[1] = NULL;
+   this->progress = true;
+}
+
 void
 lower_instructions_visitor::log_to_log2(ir_expression *ir)
 {
    ir->operation = ir_binop_mul;
    ir->operands[0] = new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
                                           ir->operands[0], NULL);
-   ir->operands[1] = new(ir) ir_constant(1.0f / log2f(M_E));
+   ir->operands[1] = new(ir) ir_constant(float(1.0 / M_LOG2E));
    this->progress = true;
 }
 
@@ -254,6 +275,11 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
         mod_to_fract(ir);
       break;
 
+   case ir_binop_pow:
+      if (lowering(POW_TO_EXP2))
+        pow_to_exp2(ir);
+      break;
+
    default:
       return visit_continue;
    }
index e1e7a5b0073dea95d7b7f9e6242639493928b86b..d99e0aa7398b95490c06defc13f59f300607a1f2 100644 (file)
 
 /**
  * \file lower_jumps.cpp
+ *
+ * This pass lowers jumps (break, continue, and return) to if/else structures.
+ *
+ * It can be asked to:
+ * 1. Pull jumps out of ifs where possible
+ * 2. Remove all "continue"s, replacing them with an "execute flag"
+ * 3. Replace all "break" with a single conditional one at the end of the loop
+ * 4. Replace all "return"s with a single return at the end of the function,
+ *    for the main function and/or other functions
+ *
+ * Applying this pass gives several benefits:
+ * 1. All functions can be inlined.
+ * 2. nv40 and other pre-DX10 chips without "continue" can be supported
+ * 3. nv30 and other pre-DX10 chips with no control flow at all are better
+ *    supported
+ *
+ * Continues are lowered by adding a per-loop "execute flag", initialized to
+ * true, that when cleared inhibits all execution until the end of the loop.
+ *
+ * Breaks are lowered to continues, plus setting a "break flag" that is checked
+ * at the end of the loop, and trigger the unique "break".
+ *
+ * Returns are lowered to breaks/continues, plus adding a "return flag" that
+ * causes loops to break again out of their enclosing loops until all the
+ * loops are exited: then the "execute flag" logic will ignore everything
+ * until the end of the function.
+ *
+ * Note that "continue" and "return" can also be implemented by adding
+ * a dummy loop and using break.
+ * However, this is bad for hardware with limited nesting depth, and
+ * prevents further optimization, and thus is not currently performed.
  */
 
 #include "glsl_types.h"
@@ -36,7 +67,6 @@ enum jump_strength
    strength_continue,
    strength_break,
    strength_return,
-   strength_discard
 };
 
 struct block_record
@@ -202,8 +232,6 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
 
    virtual void visit(class ir_discard * ir)
    {
-      truncate_after_instruction(ir);
-      this->block.min_strength = strength_discard;
    }
 
    enum jump_strength get_jump_strength(ir_instruction* ir)
@@ -217,8 +245,6 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
             return strength_continue;
       } else if(ir->ir_type == ir_type_return)
          return strength_return;
-      else if(ir->ir_type == ir_type_discard)
-         return strength_discard;
       else
          return strength_none;
    }
@@ -253,9 +279,6 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
          else
             lower = lower_sub_return;
          break;
-      case strength_discard:
-         lower = false; /* probably nothing needs this lowered */
-         break;
       }
       return lower;
    }
@@ -313,9 +336,8 @@ retry: /* we get here if we put code after the if inside a branch */
             /* FINISHME: unify returns with identical expressions */
             else if(jump_strengths[0] == strength_return && this->function.signature->return_type->is_void())
                ir->insert_after(new(ir) ir_return(NULL));
-            /* FINISHME: unify discards */
-            else
-               unify = false;
+           else
+              unify = false;
 
             if(unify) {
                jumps[0]->remove();
@@ -490,7 +512,11 @@ lower_continue:
       if(this->loop.may_set_return_flag) {
          assert(this->function.return_flag);
          ir_if* return_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->function.return_flag));
-         return_if->then_instructions.push_tail(new(ir) ir_loop_jump(saved_loop.loop ? ir_loop_jump::jump_break : ir_loop_jump::jump_continue));
+         saved_loop.may_set_return_flag = true;
+         if(saved_loop.loop)
+            return_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
+         else
+            move_outer_block_inside(ir, &return_if->else_instructions);
          ir->insert_after(return_if);
       }
 
index 33028512644c1eddfa30de353dc06d15a4248716..c8fc2676253095c05a466f5d3d63b22f3e6c3566 100644 (file)
@@ -218,26 +218,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader)
    if (!state->error && !shader->ir->is_empty()) {
       bool progress;
       do {
-        progress = false;
-
-        progress = do_function_inlining(shader->ir) || progress;
-        progress = do_if_simplification(shader->ir) || progress;
-        progress = do_copy_propagation(shader->ir) || progress;
-        progress = do_dead_code_local(shader->ir) || progress;
-        progress = do_dead_code_unlinked(shader->ir) || progress;
-        progress = do_tree_grafting(shader->ir) || progress;
-        progress = do_constant_propagation(shader->ir) || progress;
-        progress = do_constant_variable_unlinked(shader->ir) || progress;
-        progress = do_constant_folding(shader->ir) || progress;
-        progress = do_algebraic(shader->ir) || progress;
-        progress = do_vec_index_to_swizzle(shader->ir) || progress;
-        progress = do_vec_index_to_cond_assign(shader->ir) || progress;
-        progress = do_swizzle_swizzle(shader->ir) || progress;
-
-        loop_state *ls = analyze_loop_variables(shader->ir);
-        progress = set_loop_controls(shader->ir, ls) || progress;
-        progress = unroll_loops(shader->ir, ls, 32) || progress;
-        delete ls;
+        progress = do_common_optimization(shader->ir, false, 32);
       } while (progress);
 
       validate_ir_tree(shader->ir);
index 3c9af85f312bd17b2ab3143d7dee4c9f9dbf8251..20f6159f0e689449352917e311224e5696a51e4e 100644 (file)
@@ -123,8 +123,8 @@ ir_algebraic_visitor::reassociate_constant(ir_expression *ir1, int const_index,
 
    /* Don't want to even think about matrices. */
    if (ir1->operands[0]->type->is_matrix() ||
-       ir1->operands[0]->type->is_matrix() ||
-       ir2->operands[1]->type->is_matrix() ||
+       ir1->operands[1]->type->is_matrix() ||
+       ir2->operands[0]->type->is_matrix() ||
        ir2->operands[1]->type->is_matrix())
       return false;
 
diff --git a/src/glsl/opt_discard_simplification.cpp b/src/glsl/opt_discard_simplification.cpp
new file mode 100644 (file)
index 0000000..0e577c4
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file opt_discard_simplification.cpp
+ *
+ * This pass simplifies if-statements and loops containing unconditional
+ * discards.
+ *
+ * Case 1: Both branches contain unconditional discards:
+ * -----------------------------------------------------
+ *
+ *    if (cond) {
+ *      s1;
+ *      discard;
+ *      s2;
+ *    } else {
+ *      s3;
+ *      discard;
+ *      s4;
+ *    }
+ *
+ * becomes:
+ *
+ *    discard
+ *
+ * Case 2: The "then" clause contains an unconditional discard:
+ * ------------------------------------------------------------
+ *
+ *    if (cond) {
+ *       s1;
+ *       discard;
+ *       s2;
+ *    } else {
+ *      s3;
+ *    }
+ *
+ * becomes:
+ *
+ *    if (cond) {
+ *      discard;
+ *    } else {
+ *      s3;
+ *    }
+ *
+ * Case 3: The "else" clause contains an unconditional discard:
+ * ------------------------------------------------------------
+ *
+ *    if (cond) {
+ *       s1;
+ *    } else {
+ *       s2;
+ *       discard;
+ *      s3;
+ *    }
+ *
+ * becomes:
+ *
+ *    if (cond) {
+ *      s1;
+ *    } else {
+ *      discard;
+ *    }
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+
+class discard_simplifier : public ir_hierarchical_visitor {
+public:
+   discard_simplifier()
+   {
+      this->progress = false;
+   }
+
+   ir_visitor_status visit_enter(ir_if *);
+   ir_visitor_status visit_enter(ir_loop *);
+
+   bool progress;
+};
+
+static ir_discard *
+find_unconditional_discard(exec_list &instructions)
+{
+   foreach_list(n, &instructions) {
+      ir_discard *ir = ((ir_instruction *) n)->as_discard();
+      if (ir != NULL && ir->condition == NULL)
+        return ir;
+   }
+   return NULL;
+}
+
+static bool
+is_only_instruction(ir_discard *discard)
+{
+   return (discard->prev->is_head_sentinel() &&
+          discard->next->is_tail_sentinel());
+}
+
+ir_visitor_status
+discard_simplifier::visit_enter(ir_if *ir)
+{
+   ir_discard *then_discard = find_unconditional_discard(ir->then_instructions);
+   ir_discard *else_discard = find_unconditional_discard(ir->else_instructions);
+
+   if (then_discard == NULL && else_discard == NULL)
+      return visit_continue;
+
+   /* If both branches result in discard, replace whole if with discard. */
+   if (then_discard != NULL && else_discard != NULL) {
+      this->progress = true;
+      ir->replace_with(then_discard);
+      return visit_continue_with_parent;
+   }
+
+   /* Otherwise, one branch has a discard. */
+   if (then_discard != NULL && !is_only_instruction(then_discard)) {
+      this->progress = true;
+      ir->then_instructions.make_empty();
+      ir->then_instructions.push_tail(then_discard);
+   } else if (else_discard != NULL && !is_only_instruction(else_discard)) {
+      this->progress = true;
+      ir->else_instructions.make_empty();
+      ir->else_instructions.push_tail(else_discard);
+   }
+
+   visit_list_elements(this, &ir->then_instructions);
+   return visit_continue_with_parent;
+}
+
+ir_visitor_status
+discard_simplifier::visit_enter(ir_loop *ir)
+{
+   ir_discard *discard = find_unconditional_discard(ir->body_instructions);
+
+   if (discard) {
+      ir->replace_with(discard);
+      return visit_continue_with_parent;
+   }
+
+   return visit_continue;
+}
+
+bool
+do_discard_simplification(exec_list *instructions)
+{
+   /* Look for a top-level unconditional discard */
+   ir_discard *discard = find_unconditional_discard(*instructions);
+   if (discard != NULL) {
+      instructions->make_empty();
+      instructions->push_tail(discard);
+      return true;
+   }
+
+   discard_simplifier v;
+
+   visit_list_elements(&v, instructions);
+
+   return v.progress;
+}
index 77a5f9bd2e32f774e81bbf92e4d46d364b14314d..4ef855fc350d5bf404672d85611546f3f45a49c8 100644 (file)
@@ -16,7 +16,6 @@ if env['platform'] != 'winddk':
         env.Append(CPPDEFINES = [
             '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers
             'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
-            'WIN32_THREADS', # use Win32 thread API
         ])
 
     env.Append(CPPPATH = [
index e6e78c42f3b24b45cc5625826c6c071bde52e35e..2fa140dc308c3de7b6517226db6c9be4bfad806e 100644 (file)
@@ -138,7 +138,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
                print '#  define GL_PREFIX(n) GLNAME(CONCAT(gl,n))'
                print '# endif'
                print ''
-               print '#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
+               print '#if defined(PTHREADS) || defined(WIN32) || defined(BEOS_THREADS)'
                print '#  define THREADS'
                print '#endif'
                print ''
index 3b1d035f04aac9d28799fece86a453efbc4d3fde..21996a394214d758efb0ac1b9ec7e66ee2f4093e 100644 (file)
@@ -78,7 +78,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
                print '#define GLOBL_FN(x) GLOBL x'
                print '#endif'
                print ''
-               print '#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
+               print '#if defined(PTHREADS) || defined(WIN32) || defined(BEOS_THREADS)'
                print '#  define THREADS'
                print '#endif'
                print ''
index 47a01176d5a242a2162dbe98d35c6409ba148260..0a6ff7795fbd6b82389ee838bf156bfbf47596fd 100644 (file)
@@ -42,7 +42,7 @@
  */
 
 
-#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server)
+#if !defined(DISPATCH_FUNCTION_SIZE) 
 # define NEED_FUNCTION_POINTER
 #endif
 #include "glapi/glprocs.h"
@@ -88,7 +88,6 @@ get_static_proc_offset(const char *funcName)
 }
 
 
-#if !defined(XFree86Server)
 
 /**
  * Return dispatch function address for the named static (built-in) function.
@@ -113,16 +112,6 @@ get_static_proc_address(const char *funcName)
 #endif
 }
 
-#else
-
-static _glapi_proc
-get_static_proc_address(const char *funcName)
-{
-   (void) funcName;
-   return NULL;
-}
-
-#endif /* !defined(XFree86Server) */
 
 
 /**
index ce0cf680b1ddcbee2a6dad076eaa36e773aff546..af46f2b337e18a5eaeb2760aa99dd6bf0b4f7d51 100644 (file)
@@ -45,7 +45,7 @@
 #  define GL_PREFIX(n) GLNAME(CONCAT(gl,n))
 # endif
 
-#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#if defined(PTHREADS) || defined(WIN32) || defined(BEOS_THREADS)
 #  define THREADS
 #endif
 
index 72729f2f091c9a1eb7a6944d49061dc75f240968..215295d69b21867ed3d97149e05a552410209cf6 100644 (file)
@@ -51,7 +51,7 @@
 #define GLOBL_FN(x) GLOBL x
 #endif
 
-#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#if defined(PTHREADS) || defined(WIN32) || defined(BEOS_THREADS)
 #  define THREADS
 #endif
 
index 2f1c3fff6ccee372a73be77420e250742f42f9a7..5476d37fdc9fc931a74ed6fa3fbd287fda993001 100644 (file)
@@ -36,8 +36,7 @@
 #include "table.h"
 
 /* dynamic stubs will run out before this array */
-#define MAPI_MAX_STUBS (sizeof(struct mapi_table) / sizeof(mapi_func))
-static const struct mapi_stub *mapi_stub_map[MAPI_MAX_STUBS];
+static const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS];
 static int mapi_num_stubs;
 
 static const struct mapi_stub *
@@ -145,9 +144,9 @@ mapi_table_create(void)
    const struct mapi_table *noop = table_get_noop();
    struct mapi_table *tbl;
 
-   tbl = malloc(sizeof(*tbl));
+   tbl = malloc(MAPI_TABLE_SIZE);
    if (tbl)
-      memcpy(tbl, noop, sizeof(*tbl));
+      memcpy(tbl, noop, MAPI_TABLE_SIZE);
 
    return tbl;
 }
index 440eb4bb9c06e059ced9b7938d890bcd7565548f..3a872666f965959d70cb1135adcf679129df3372 100644 (file)
@@ -202,201 +202,360 @@ def abi_parse(filename):
 
     return entries
 
-def abi_dynamics():
-    """Return the dynamic entries."""
-    entries = []
-    for i in xrange(ABI_NUM_DYNAMIC_ENTRIES):
-        cols = ['void', 'dynamic%d' % (i), 'void']
-        attrs = { 'slot': -1, 'hidden': False, 'alias': None }
-        entries.append(ABIEntry(cols, attrs))
-    return entries
-
 class ABIPrinter(object):
-    """ABIEntry Printer"""
+    """MAPI Printer"""
 
-    def __init__(self, entries, options):
+    def __init__(self, entries):
         self.entries = entries
-        self.options = options
-        self._undefs = []
 
-    def _add_undefs(self, undefs):
-        self._undefs.extend(undefs)
+        # sort entries by their names
+        self.entries_sorted_by_names = self.entries[:]
+        self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name))
 
-    def output_header(self):
-        print '/* This file is automatically generated.  Do not modify. */'
-        print
+        self.indent = ' ' * 3
+        self.noop_warn = 'noop_warn'
+        self.noop_generic = 'noop_generic'
 
-    def output_footer(self):
-        print '/* clean up */'
-        for m in self._undefs:
-            print '#undef %s' % (m)
+        self.api_defines = []
+        self.api_headers = ['"KHR/khrplatform.h"']
+        self.api_call = 'KHRONOS_APICALL'
+        self.api_entry = 'KHRONOS_APIENTRY'
+        self.api_attrs = 'KHRONOS_APIATTRIBUTES'
 
-    def output_entry(self, ent):
-        if ent.slot < 0:
-            out_ent = 'MAPI_DYNAMIC_ENTRY(%s, %s, (%s))' % \
-                    (ent.c_return(), ent.name, ent.c_params())
-            out_code = ''
-        else:
+    def c_header(self):
+        return '/* This file is automatically generated by mapi_abi.py.  Do not modify. */'
+
+    def c_includes(self):
+        """Return includes of the client API headers."""
+        defines = ['#define ' + d for d in self.api_defines]
+        includes = ['#include ' + h for h in self.api_headers]
+        return "\n".join(defines + includes)
+
+    def c_mapi_table(self):
+        """Return defines of the dispatch table size."""
+        num_static_entries = 0
+        for ent in self.entries:
+            if not ent.alias:
+                num_static_entries += 1
+
+        return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
+                '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
+                        num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
+
+    def c_mapi_table_initializer(self, prefix):
+        """Return the array initializer for mapi_table_fill."""
+        entries = [ent.name for ent in self.entries if not ent.alias]
+        pre = self.indent + '(mapi_proc) ' + prefix
+        return pre + (',\n' + pre).join(entries)
+
+    def c_mapi_table_spec(self):
+        """Return the spec for mapi_init."""
+        specv1 = []
+        line = '"1'
+        for ent in self.entries:
+            if not ent.alias:
+                line += '\\0"\n'
+                specv1.append(line)
+                line = '"'
+            line += '%s\\0' % ent.name
+        line += '";'
+        specv1.append(line)
+
+        return self.indent + self.indent.join(specv1)
+
+    def _c_decl(self, ent, prefix, need_attr=True):
+        """Return the C declaration for the entry."""
+        decl = '%s %s %s%s(%s)' % (ent.c_return(), self.api_entry,
+                prefix, ent.name, ent.c_params())
+        if need_attr and self.api_attrs:
+            decl += ' ' + self.api_attrs
+
+        return decl
+
+    def _c_cast(self, ent):
+        """Return the C cast for the entry."""
+        cast = '%s (%s *)(%s)' % (
+                ent.c_return(), self.api_entry, ent.c_params())
+
+        return cast
+
+    def c_private_declarations(self, prefix):
+        """Return the declarations of private functions."""
+        decls = [self._c_decl(ent, prefix)
+                for ent in self.entries if not ent.alias]
+
+        return ";\n".join(decls) + ";"
+
+    def c_public_dispatches(self, prefix):
+        """Return the public dispatch functions."""
+        dispatches = []
+        for ent in self.entries:
+            if ent.hidden:
+                continue
+
+            proto = self.api_call + ' ' + self._c_decl(ent, prefix)
+            cast = self._c_cast(ent)
+
+            ret = ''
+            if ent.ret:
+                ret = 'return '
+            stmt1 = self.indent
+            stmt1 += 'const struct mapi_table *tbl = u_current_get();'
+            stmt2 = self.indent
+            stmt2 += 'mapi_func func = ((const mapi_func *) tbl)[%d];' % (
+                    ent.slot)
+            stmt3 = self.indent
+            stmt3 += '%s((%s) func)(%s);' % (ret, cast, ent.c_args())
+
+            disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
+            dispatches.append(disp)
+
+        return '\n\n'.join(dispatches)
+
+    def c_stub_string_pool(self):
+        """Return the string pool for use by stubs."""
+        # sort entries by their names
+        sorted_entries = self.entries[:]
+        sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
+
+        pool = []
+        offsets = {}
+        count = 0
+        for ent in sorted_entries:
+            offsets[ent] = count
+            pool.append('%s' % (ent.name))
+            count += len(ent.name) + 1
+
+        pool_str =  self.indent + '"' + \
+                ('\\0"\n' + self.indent + '"').join(pool) + '";'
+        return (pool_str, offsets)
+
+    def c_stub_initializer(self, prefix, pool_offsets):
+        """Return the initializer for struct mapi_stub array."""
+        stubs = []
+        for ent in self.entries_sorted_by_names:
+            stubs.append('%s{ (mapi_func) %s%s, %d, (void *) %d }' % (
+                self.indent, prefix, ent.name, ent.slot, pool_offsets[ent]))
+
+        return ',\n'.join(stubs)
+
+    def c_noop_functions(self, prefix, warn_prefix):
+        """Return the noop functions."""
+        noops = []
+        for ent in self.entries:
             if ent.alias:
-                macro_ent = 'MAPI_ALIAS_ENTRY'
-                macro_code = 'MAPI_ALIAS_CODE'
-            else:
-                macro_ent = 'MAPI_ABI_ENTRY'
-                macro_code = 'MAPI_ABI_CODE'
+                continue
+
+            proto = 'static ' + self._c_decl(ent, prefix)
+
+            stmt1 = self.indent + '%s("%s%s");' % (
+                    self.noop_warn, warn_prefix, ent.name)
 
             if ent.ret:
-                macro_code += '_RETURN'
+                stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
+                noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
+            else:
+                noop = '%s\n{\n%s\n}' % (proto, stmt1)
+
+            noops.append(noop)
+
+        return '\n\n'.join(noops)
+
+    def c_noop_initializer(self, prefix, use_generic):
+        """Return an initializer for the noop dispatch table."""
+        entries = [prefix + ent.name for ent in self.entries if not ent.alias]
+        if use_generic:
+            entries = [self.noop_generic] * len(entries)
+
+        entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
+
+        pre = self.indent + '(mapi_func) '
+        return pre + (',\n' + pre).join(entries)
+
+    def c_asm_gcc(self, prefix):
+        asm = []
+        to_name = None
+
+        asm.append('__asm__(')
+        for ent in self.entries:
+            name = prefix + ent.name
+
             if ent.hidden:
-                macro_ent += '_HIDDEN'
-                macro_code += '_HIDDEN'
+                asm.append('".hidden %s\\n"' % (name))
 
             if ent.alias:
-                out_ent = '%s(%s, %s, %s, (%s))' % (macro_ent,
-                        ent.alias, ent.c_return(), ent.name, ent.c_params())
-                out_code = '%s(%s, %s, %s, (%s))' % (macro_code,
-                        ent.alias, ent.c_return(), ent.name, ent.c_args())
-            else:
-                out_ent = '%s(%s, %s, (%s))' % (macro_ent,
-                        ent.c_return(), ent.name, ent.c_params())
-                out_code = '%s(%s, %s, (%s))' % (macro_code,
-                        ent.c_return(), ent.name, ent.c_args())
-
-        print out_ent
-        if out_code:
-            print '   ' + out_code
-
-    def output_entries(self, pool_offsets):
-        defs = [
-                # normal entries
-                ('MAPI_ABI_ENTRY', '(ret, name, params)', ''),
-                ('MAPI_ABI_CODE', '(ret, name, args)', ''),
-                ('MAPI_ABI_CODE_RETURN', '', 'MAPI_ABI_CODE'),
-                # alias entries
-                ('MAPI_ALIAS_ENTRY', '(alias, ret, name, params)', ''),
-                ('MAPI_ALIAS_CODE', '(alias, ret, name, args)', ''),
-                ('MAPI_ALIAS_CODE_RETURN', '', 'MAPI_ALIAS_CODE'),
-                # hidden normal entries
-                ('MAPI_ABI_ENTRY_HIDDEN', '', 'MAPI_ABI_ENTRY'),
-                ('MAPI_ABI_CODE_HIDDEN', '', 'MAPI_ABI_CODE'),
-                ('MAPI_ABI_CODE_RETURN_HIDDEN', '', 'MAPI_ABI_CODE_RETURN'),
-                # hidden alias entries
-                ('MAPI_ALIAS_ENTRY_HIDDEN', '', 'MAPI_ALIAS_ENTRY'),
-                ('MAPI_ALIAS_CODE_HIDDEN', '', 'MAPI_ALIAS_CODE'),
-                ('MAPI_ALIAS_CODE_RETURN_HIDDEN', '', 'MAPI_ALIAS_CODE_RETURN'),
-                # dynamic entries
-                ('MAPI_DYNAMIC_ENTRY', '(ret, name, params)', ''),
-        ]
-        undefs = [d[0] for d in defs]
-
-        print '#if defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN)'
-        print
-        for d in defs:
-            print '#ifndef %s' % (d[0])
-            if d[2]:
-                print '#define %s%s %s' % d
+                asm.append('".globl %s\\n"' % (name))
+                asm.append('".set %s, %s\\n"' % (name, to_name))
             else:
-                print '#define %s%s' % d[:2]
+                asm.append('STUB_ASM_ENTRY("%s")"\\n"' % (name))
+                asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
+                to_name = name
+        asm.append(');')
 
-            print '#endif'
+        return "\n".join(asm)
+
+    def output_for_lib(self):
+        print self.c_header()
+        print
+        print '#ifdef MAPI_TMP_DEFINES'
+        print self.c_includes()
+        print '#undef MAPI_TMP_DEFINES'
+        print '#endif /* MAPI_TMP_DEFINES */'
+        print
+        print '#ifdef MAPI_TMP_TABLE'
+        print self.c_mapi_table()
+        print '#undef MAPI_TMP_TABLE'
+        print '#endif /* MAPI_TMP_TABLE */'
         print
 
-        print '/* see MAPI_TMP_TABLE */'
-        for ent in self.entries:
-            print '#define MAPI_SLOT_%s %d' % (ent.name, ent.slot)
+        pool, pool_offsets = self.c_stub_string_pool()
+        print '#ifdef MAPI_TMP_PUBLIC_STUBS'
+        print 'static const char public_string_pool[] ='
+        print pool
         print
-        print '/* see MAPI_TMP_PUBLIC_STUBS */'
-        for ent in self.entries:
-            print '#define MAPI_POOL_%s %d' % (ent.name, pool_offsets[ent])
+        print 'static const struct mapi_stub public_stubs[] = {'
+        print self.c_stub_initializer(self.prefix_lib, pool_offsets)
+        print '};'
+        print '#undef MAPI_TMP_PUBLIC_STUBS'
+        print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
         print
 
-        # define macros that generate code
-        for ent in self.entries:
-            self.output_entry(ent)
+        print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
+        print self.c_public_dispatches(self.prefix_lib)
+        print '#undef MAPI_TMP_PUBLIC_ENTRIES'
+        print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
+        print
+
+        print '#ifdef MAPI_TMP_NOOP_ARRAY'
+        print '#ifdef DEBUG'
+        print
+        print self.c_noop_functions(self.prefix_noop, self.prefix_lib)
         print
-        dynamics = abi_dynamics()
-        for ent in dynamics:
-            self.output_entry(ent)
+        print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
+        print self.c_noop_initializer(self.prefix_noop, False)
+        print '};'
+        print
+        print '#else /* DEBUG */'
+        print
+        print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
+        print self.c_noop_initializer(self.prefix_noop, True)
+        print '};'
+        print '#endif /* DEBUG */'
+        print '#undef MAPI_TMP_NOOP_ARRAY'
+        print '#endif /* MAPI_TMP_NOOP_ARRAY */'
         print
 
-        for ent in self.entries:
-            print '#undef MAPI_SLOT_%s' % (ent.name)
-        for ent in self.entries:
-            print '#undef MAPI_POOL_%s' % (ent.name)
+        print '#ifdef MAPI_TMP_STUB_ASM_GCC'
+        print self.c_asm_gcc(self.prefix_lib)
+        print '#undef MAPI_TMP_STUB_ASM_GCC'
+        print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
+
+    def output_for_app(self):
+        print self.c_header()
+        print
+        print self.c_private_declarations(self.prefix_app)
         print
-        print '#endif /* defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN) */'
+        print '#ifdef API_TMP_DEFINE_SPEC'
         print
+        print 'static const char %s_spec[] =' % (self.prefix_app)
+        print self.c_mapi_table_spec()
+        print
+        print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
+        print self.c_mapi_table_initializer(self.prefix_app)
+        print '};'
+        print
+        print '#endif /* API_TMP_DEFINE_SPEC */'
 
-        self._add_undefs(undefs)
+class GLAPIPrinter(ABIPrinter):
+    """OpenGL API Printer"""
 
-    def _get_string_pool(self):
-        """Get the string pool."""
-        pool = []
-        offsets = {}
+    def __init__(self, entries):
+        super(GLAPIPrinter, self).__init__(entries)
 
-        count = 0
-        for ent in self.entries:
-            offsets[ent] = count
-            pool.append(ent.name + '\\0')
-            count += len(ent.name) + 1
+        self.api_defines = ['GL_GLEXT_PROTOTYPES']
+        self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
+        self.api_call = 'GLAPI'
+        self.api_entry = 'APIENTRY'
+        self.api_attrs = ''
 
-        return (pool, offsets)
+        self.prefix_lib = 'gl'
+        self.prefix_app = '_mesa_'
+        self.prefix_noop = 'noop'
 
-    def output_sorted_indices(self):
-        entry_index_pairs = []
-        for i in xrange(len(self.entries)):
-            entry_index_pairs.append((self.entries[i], i))
-        entry_index_pairs.sort(lambda x, y: cmp(x[0].name, y[0].name))
+    def output_for_app(self):
+        # not used
+        pass
 
-        print '/* see MAPI_TMP_PUBLIC_STUBS */'
-        print '#ifdef MAPI_ABI_SORTED_INDICES'
-        print
-        print 'static const int MAPI_ABI_SORTED_INDICES[] = {'
-        for ent, idx in entry_index_pairs:
-            print '   %d, /* %s */' % (idx, ent.name)
-        print '   -1'
-        print '};'
-        print
-        print '#endif /* MAPI_ABI_SORTED_INDICES */'
-        print
+class ES1APIPrinter(GLAPIPrinter):
+    """OpenGL ES 1.x API Printer"""
 
-        self._add_undefs(['MAPI_ABI_SORTED_INDICES'])
+    def __init__(self, entries):
+        super(ES1APIPrinter, self).__init__(entries)
 
-    def output_defines(self):
-        print '/* ABI defines */'
-        print '#ifdef MAPI_ABI_DEFINES'
-        print '#include "%s"' % (self.options.include)
-        print '#endif /* MAPI_ABI_DEFINES */'
-        print
+        self.api_headers = ['"GLES/gl.h"', '"GLES/glext.h"']
+        self.api_call = 'GL_API'
+        self.api_entry = 'GL_APIENTRY'
+
+class ES2APIPrinter(GLAPIPrinter):
+    """OpenGL ES 2.x API Printer"""
+
+    def __init__(self, entries):
+        super(ES2APIPrinter, self).__init__(entries)
+
+        self.api_headers = ['"GLES2/gl2.h"', '"GLES2/gl2ext.h"']
+        self.api_call = 'GL_APICALL'
+        self.api_entry = 'GL_APIENTRY'
 
-        self._add_undefs(['MAPI_ABI_DEFINES'])
+class VGAPIPrinter(ABIPrinter):
+    """OpenVG API Printer"""
 
-    def output(self):
-        pool, pool_offsets = self._get_string_pool()
+    def __init__(self, entries):
+        super(VGAPIPrinter, self).__init__(entries)
 
-        self.output_header()
-        self.output_defines()
-        self.output_entries(pool_offsets)
-        self.output_sorted_indices()
-        self.output_footer()
+        self.api_defines = ['VG_VGEXT_PROTOTYPES']
+        self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
+        self.api_call = 'VG_API_CALL'
+        self.api_entry = 'VG_API_ENTRY'
+        self.api_attrs = 'VG_API_EXIT'
+
+        self.prefix_lib = 'vg'
+        self.prefix_app = 'vega'
+        self.prefix_noop = 'noop'
 
 def parse_args():
+    printers = ['glapi', 'es1api', 'es2api', 'vgapi']
+    modes = ['lib', 'app']
+
     parser = OptionParser(usage='usage: %prog [options] <filename>')
-    parser.add_option('-i', '--include', dest='include',
-            help='include the header for API defines')
+    parser.add_option('-p', '--printer', dest='printer',
+            help='printer to use: %s' % (", ".join(printers)))
+    parser.add_option('-m', '--mode', dest='mode',
+            help='target user: %s' % (", ".join(modes)))
 
     options, args = parser.parse_args()
-    if not args or not options.include:
+    if not args or options.printer not in printers or \
+            options.mode not in modes:
         parser.print_help()
         sys.exit(1)
 
     return (args[0], options)
 
 def main():
+    printers = {
+        'vgapi': VGAPIPrinter,
+        'glapi': GLAPIPrinter,
+        'es1api': ES1APIPrinter,
+        'es2api': ES2APIPrinter
+    }
+
     filename, options = parse_args()
 
     entries = abi_parse(filename)
-    printer = ABIPrinter(entries, options)
-    printer.output()
+    printer = printers[options.printer](entries)
+    if options.mode == 'lib':
+        printer.output_for_lib()
+    else:
+        printer.output_for_app()
 
 if __name__ == '__main__':
     main()
index 79beca47d2a1e038aa5690867ab0254b743563ec..a1b067fb73ce41fa9d5cedde60a6de59160b3938 100644 (file)
  *    Chia-I Wu <olv@lunarg.com>
  */
 
-#include "u_macros.h"
-
 #ifndef MAPI_ABI_HEADER
 #error "MAPI_ABI_HEADER must be defined"
 #endif
 
-
-/**
- * Get API defines.
- */
-#ifdef MAPI_TMP_DEFINES
-#   define MAPI_ABI_DEFINES
-#   include MAPI_ABI_HEADER
-
-#ifndef MAPI_ABI_PREFIX
-#error "MAPI_ABI_PREFIX must be defined"
-#endif
-#ifndef MAPI_ABI_PUBLIC
-#error "MAPI_ABI_PUBLIC must be defined"
-#endif
-#ifndef MAPI_ABI_ATTR
-#error "MAPI_ABI_ATTR must be defined"
-#endif
-
-#undef MAPI_TMP_DEFINES
-#endif /* MAPI_TMP_DEFINES */
-
-
-/**
- * Generate fields of struct mapi_table.
- */
-#ifdef MAPI_TMP_TABLE
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      ret (MAPI_ABI_ATTR *name) params;
-#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
-      ret (MAPI_ABI_ATTR *name) params;
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_TABLE
-#endif /* MAPI_TMP_TABLE */
-
-
-/**
- * Declare public entries.
- */
-#ifdef MAPI_TMP_PUBLIC_DECLARES
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      MAPI_ABI_PUBLIC ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params);
-#   define MAPI_ABI_ENTRY_HIDDEN(ret, name, params)            \
-      HIDDEN ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
-#   define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params)   \
-      MAPI_ABI_ENTRY_HIDDEN(ret, name, params)
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_PUBLIC_DECLARES
-#endif /* MAPI_TMP_PUBLIC_DECLARES */
-
-
-/**
- * Generate string pool and public stubs.
- */
-#ifdef MAPI_TMP_PUBLIC_STUBS
-/* define the string pool */
-static const char public_string_pool[] =
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      U_STRINGIFY(name) "\0"
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params)
-#   include MAPI_ABI_HEADER
-   ;
-/* define public_sorted_indices */
-#   define MAPI_ABI_SORTED_INDICES public_sorted_indices
-#   include MAPI_ABI_HEADER
-
-/* define public_stubs */
-static const struct mapi_stub public_stubs[] = {
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      { (mapi_func) U_CONCAT(MAPI_ABI_PREFIX, name),           \
-         MAPI_SLOT_ ## name, (void *) MAPI_POOL_ ## name },
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params)
-#   include MAPI_ABI_HEADER
-   { NULL, -1, (void *) -1 }
-};
-
-#undef MAPI_TMP_PUBLIC_STUBS
-#endif /* MAPI_TMP_PUBLIC_STUBS */
-
-
-/**
- * Generate public entries.
- */
-#ifdef MAPI_TMP_PUBLIC_ENTRIES
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params
-#   define MAPI_ABI_CODE(ret, name, args)                      \
-      {                                                        \
-         const struct mapi_table *tbl = u_current_get();       \
-         tbl->name args;                                       \
-      }
-#   define MAPI_ABI_CODE_RETURN(ret, name, args)               \
-      {                                                        \
-         const struct mapi_table *tbl = u_current_get();       \
-         return tbl->name args;                                \
-      }
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params)
-#   define MAPI_ALIAS_CODE(alias, ret, name, args)             \
-      MAPI_ABI_CODE(ret, alias, args)
-#   define MAPI_ALIAS_CODE_RETURN(alias, ret, name, args)      \
-      MAPI_ABI_CODE_RETURN(ret, alias, args)
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_PUBLIC_ENTRIES
-#endif /* MAPI_TMP_PUBLIC_ENTRIES */
-
-
-/**
- * Generate noop entries.
- */
-#ifdef MAPI_TMP_NOOP_ARRAY
-#ifdef DEBUG
-#   define MAPI_ABI_ENTRY(ret, name, params)                         \
-      static ret MAPI_ABI_ATTR U_CONCAT(noop_, name) params
-#   define MAPI_ABI_CODE(ret, name, args)                            \
-      {                                                              \
-         noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name));             \
-      }
-#   define MAPI_ABI_CODE_RETURN(ret, name, args)                     \
-      {                                                              \
-         noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name));             \
-         return (ret) 0;                                             \
-      }
-#   include MAPI_ABI_HEADER
-
-/* define the noop function array that may be casted to mapi_table */
-const mapi_func table_noop_array[] = {
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      (mapi_func) U_CONCAT(noop_, name),
-#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
-      (mapi_func) noop_generic,
-#   include MAPI_ABI_HEADER
-      (mapi_func) noop_generic
-};
-
-#else /* DEBUG */
-
-const mapi_func table_noop_array[] = {
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      (mapi_func) noop_generic,
-#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
-      (mapi_func) noop_generic,
-#   include MAPI_ABI_HEADER
-      (mapi_func) noop_generic
-};
-
-#endif /* DEBUG */
-#undef MAPI_TMP_NOOP_ARRAY
-#endif /* MAPI_TMP_NOOP_ARRAY */
-
-
-#ifdef MAPI_TMP_STUB_ASM_GCC
-#   define STUB_ASM_ALIAS(func, to)    \
-      ".globl " func "\n"              \
-      ".set " func ", " to
-#   define STUB_ASM_HIDE(func)         \
-      ".hidden " func
-
-#   define MAPI_ABI_ENTRY(ret, name, params)                         \
-      __asm__(STUB_ASM_ENTRY(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));
-#   define MAPI_ABI_CODE(ret, name, args)                            \
-      __asm__(STUB_ASM_CODE(U_STRINGIFY(MAPI_SLOT_ ## name)));
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)                \
-      __asm__(STUB_ASM_ALIAS(U_CONCAT_STR(MAPI_ABI_PREFIX, name),    \
-            U_CONCAT_STR(MAPI_ABI_PREFIX, alias)));
-#   define MAPI_ABI_ENTRY_HIDDEN(ret, name, params)                  \
-      __asm__(STUB_ASM_HIDE(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));   \
-      MAPI_ABI_ENTRY(ret, name, params);
-#   define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params)         \
-      __asm__(STUB_ASM_HIDE(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));   \
-      MAPI_ALIAS_ENTRY(alias, ret, name, params);
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_STUB_ASM_GCC
-#endif /* MAPI_TMP_STUB_ASM_GCC */
+#include MAPI_ABI_HEADER
index 8ceaec3132bf36bdf873e086b501278c80e61799..3594eacb4ecabb0e359b2ca0f0619b2ea5ae4dac 100644 (file)
 #include "stub.h"
 #include "table.h"
 
-#define MAPI_TABLE_FIRST_DYNAMIC \
-   (offsetof(struct mapi_table, dynamic0) / sizeof(mapi_func))
-#define MAPI_TABLE_NUM_DYNAMIC \
-   ((offsetof(struct mapi_table, last) - \
-     offsetof(struct mapi_table, dynamic0)) / sizeof(mapi_func))
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
 
-/*
- * This will define public_string_pool, public_sorted_indices, and
- * public_stubs.
- */
+/* define public_string_pool and public_stubs */
 #define MAPI_TMP_PUBLIC_STUBS
 #include "mapi_tmp.h"
 
 static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
 static int num_dynamic_stubs;
-static int next_dynamic_slot = MAPI_TABLE_FIRST_DYNAMIC;
+static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC;
 
 void
 stub_init_once(void)
@@ -74,11 +66,9 @@ static int
 stub_compare(const void *key, const void *elem)
 {
    const char *name = (const char *) key;
-   const int *index = (const int *) elem;
-   const struct mapi_stub *stub;
+   const struct mapi_stub *stub = (const struct mapi_stub *) elem;
    const char *stub_name;
 
-   stub = &public_stubs[*index];
    stub_name = &public_string_pool[(unsigned long) stub->name];
 
    return strcmp(name, stub_name);
@@ -90,13 +80,8 @@ stub_compare(const void *key, const void *elem)
 const struct mapi_stub *
 stub_find_public(const char *name)
 {
-   const int *index;
-
-   index = (const int *) bsearch(name, public_sorted_indices,
-         ARRAY_SIZE(public_sorted_indices) - 1,
-         sizeof(public_sorted_indices[0]), stub_compare);
-
-   return (index) ? &public_stubs[*index] : NULL;
+   return (const struct mapi_stub *) bsearch(name, public_stubs,
+         ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare);
 }
 
 /**
@@ -109,14 +94,15 @@ stub_add_dynamic(const char *name)
    int idx;
 
    idx = num_dynamic_stubs;
-   if (idx >= MAPI_TABLE_NUM_DYNAMIC)
+   /* minus 1 to make sure we can never reach the last slot */
+   if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1)
       return NULL;
 
    stub = &dynamic_stubs[idx];
 
-   /* dispatch to mapi_table->last, which is always no-op */
-   stub->addr =
-      entry_generate(MAPI_TABLE_FIRST_DYNAMIC + MAPI_TABLE_NUM_DYNAMIC);
+   /* dispatch to the last slot, which is reserved for no-op */
+   stub->addr = entry_generate(
+         MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1);
    if (!stub->addr)
       return NULL;
 
index 48c99018aa39828189859274fe793bb5d0a8ef47..ca2be568c705d4a18f1bbd7724bc46a74f847262 100644 (file)
 #include "stub.h"
 
 #define MAPI_TMP_DEFINES
-#include "mapi_tmp.h"
-
-struct mapi_table {
 #define MAPI_TMP_TABLE
 #include "mapi_tmp.h"
-   mapi_func last;
-};
+
+#define MAPI_TABLE_NUM_SLOTS (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC)
+#define MAPI_TABLE_SIZE (MAPI_TABLE_NUM_SLOTS * sizeof(mapi_func))
 
 extern const mapi_func table_noop_array[];
 
index ed9ccfe229958760546818c4f8c8c63bbc911784..77a593b330c7b61372cc5ae44074d8f1efed0827 100644 (file)
@@ -128,7 +128,7 @@ static int ThreadSafe;
 void
 u_current_destroy(void)
 {
-#if defined(THREADS) && defined(WIN32_THREADS)
+#if defined(THREADS) && defined(WIN32)
    u_tsd_destroy(&u_current_table_tsd);
    u_tsd_destroy(&u_current_user_tsd);
 #endif
@@ -147,7 +147,7 @@ u_current_init_tsd(void)
 /**
  * Mutex for multithread check.
  */
-#ifdef WIN32_THREADS
+#ifdef WIN32
 /* _glthread_DECLARE_STATIC_MUTEX is broken on windows.  There will be race! */
 #define CHECK_MULTITHREAD_LOCK()
 #define CHECK_MULTITHREAD_UNLOCK()
index e0fa64ae034d92081cdcc8c34818bc9d9d75a97e..e9eae55364bb9b64fc00861382cbe3f3d7c718fd 100644 (file)
@@ -111,7 +111,7 @@ u_tsd_set(struct u_tsd *tsd, void *ptr)
  * Be sure that you compile using the Multithreaded runtime, otherwise
  * bad things will happen.
  */
-#ifdef WIN32_THREADS
+#ifdef WIN32
 
 static void InsteadOf_exit(int nCode)
 {
@@ -172,7 +172,7 @@ u_tsd_set(struct u_tsd *tsd, void *ptr)
    }
 }
 
-#endif /* WIN32_THREADS */
+#endif /* WIN32 */
 
 /*
  * BeOS threads
index b4487a3400f86a8f2aa8ed9dbf692db16482c076..92a0a3916d0179614c53d2301d1b54782314aee7 100644 (file)
@@ -44,7 +44,7 @@
 
 #include "u_compiler.h"
 
-#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#if defined(PTHREADS) || defined(WIN32) || defined(BEOS_THREADS)
 #ifndef THREADS
 #define THREADS
 #endif
@@ -85,7 +85,7 @@ typedef pthread_mutex_t u_mutex;
  * IMPORTANT: Link with multithreaded runtime library when THREADS are
  * used!
  */
-#ifdef WIN32_THREADS
+#ifdef WIN32
 #include <windows.h>
 
 struct u_tsd {
@@ -104,7 +104,7 @@ typedef CRITICAL_SECTION u_mutex;
 #define u_mutex_lock(name)    EnterCriticalSection(&name)
 #define u_mutex_unlock(name)  LeaveCriticalSection(&name)
 
-#endif /* WIN32_THREADS */
+#endif /* WIN32 */
 
 
 /*
index 702db03d1542aae9e526cbce53d4dff8d1f51ec0..e239e20987e7d80ba720f623fd1c39cab1ef15f6 100644 (file)
@@ -44,7 +44,7 @@ $(VGAPI_OBJECTS): %.o: $(MAPI)/%.c
 
 vgapi_tmp.h: vgapi.csv $(MAPI)/mapi_abi.py
        $(PYTHON2) $(PYTHON_FLAGS) $(MAPI)/mapi_abi.py \
-               -i vgapi/vgapi_defines.h $< > $@
+               --printer vgapi --mode lib $< > $@
 
 .PHONY: clean
 clean:
@@ -87,3 +87,5 @@ depend: $(VGAPI_SOURCES)
        @$(MKDEP) $(MKDEP_OPTIONS) -f- $(DEFINES) $(INCLUDE_DIRS) \
                $(VGAPI_CPPFLAGS) $(VGAPI_SOURCES) 2>/dev/null | \
                sed -e 's,^$(MAPI)/,,' > depend
+
+-include depend
index 20d7f2744d09c3605fe0895dc179d411b76ec104..42d86b69eefa40fdf5c4785ba2598f8048868b1f 100644 (file)
@@ -13,7 +13,7 @@ if env['platform'] != 'winddk':
                target = '#src/mapi/vgapi/vgapi_tmp.h',
                script = '../mapi/mapi_abi.py',
                source = 'vgapi.csv',
-               command = python_cmd + ' $SCRIPT -i vgapi/vgapi_defines.h $SOURCE > $TARGET'
+               command = python_cmd + ' $SCRIPT --printer vgapi --mode lib $SOURCE > $TARGET'
        )
 
        env.Append(CPPDEFINES = [
@@ -53,4 +53,4 @@ if env['platform'] != 'winddk':
 
        vgapi = [env.FindIxes(openvg, 'LIBPREFIX', 'LIBSUFFIX')]
 
-       Export(['vgapi', 'vgapi_header'])
+       Export(['vgapi'])
index d28ee32b28be142471a3a51ed7646d6623a83a88..5b11d062aea63aa793bcd4648e3db31f8352157a 100644 (file)
@@ -79,15 +79,15 @@ void,                   Translate,                 VGfloat tx, VGfloat ty
 void,                   WritePixels,               const void *data, VGint dataStride, VGImageFormat dataFormat, VGint dx, VGint dy, VGint width, VGint height
 
 ## OpenVG 1.1
-#void,                   ClearGlyph,                VGFont font,VGuint glyphIndex
-#void,                   CopyMask,                  VGMaskLayer maskLayer, VGint dx, VGint dy, VGint sx, VGint sy, VGint width, VGint height
-#VGFont,                 CreateFont,                VGint glyphCapacityHint
-#VGMaskLayer,            CreateMaskLayer,           VGint width, VGint height
-#void,                   DestroyFont,               VGFont font
-#void,                   DestroyMaskLayer,          VGMaskLayer maskLayer
-#void,                   DrawGlyph,                 VGFont font, VGuint glyphIndex, VGbitfield paintModes, VGboolean allowAutoHinting
-#void,                   DrawGlyphs,                VGFont font, VGint glyphCount, const VGuint *glyphIndices, const VGfloat *adjustments_x, const VGfloat *adjustments_y, VGbitfield paintModes, VGboolean allowAutoHinting
-#void,                   FillMaskLayer,             VGMaskLayer maskLayer, VGint x, VGint y, VGint width, VGint height, VGfloat value
-#void,                   RenderToMask,              VGPath path, VGbitfield paintModes, VGMaskOperation operation
-#void,                   SetGlyphToImage,           VGFont font, VGuint glyphIndex, VGImage image, const VGfloat glyphOrigin[2], const VGfloat escapement[2]
-#void,                   SetGlyphToPath,            VGFont font, VGuint glyphIndex, VGPath path, VGboolean isHinted, const VGfloat glyphOrigin[2], const VGfloat escapement[2]
+void,                   ClearGlyph,                VGFont font, VGuint glyphIndex
+void,                   CopyMask,                  VGMaskLayer maskLayer, VGint dx, VGint dy, VGint sx, VGint sy, VGint width, VGint height
+VGFont,                 CreateFont,                VGint glyphCapacityHint
+VGMaskLayer,            CreateMaskLayer,           VGint width, VGint height
+void,                   DestroyFont,               VGFont font
+void,                   DestroyMaskLayer,          VGMaskLayer maskLayer
+void,                   DrawGlyph,                 VGFont font, VGuint glyphIndex, VGbitfield paintModes, VGboolean allowAutoHinting
+void,                   DrawGlyphs,                VGFont font, VGint glyphCount, const VGuint *glyphIndices, const VGfloat *adjustments_x, const VGfloat *adjustments_y, VGbitfield paintModes, VGboolean allowAutoHinting
+void,                   FillMaskLayer,             VGMaskLayer maskLayer, VGint x, VGint y, VGint width, VGint height, VGfloat value
+void,                   RenderToMask,              VGPath path, VGbitfield paintModes, VGMaskOperation operation
+void,                   SetGlyphToImage,           VGFont font, VGuint glyphIndex, VGImage image, const VGfloat glyphOrigin[2], const VGfloat escapement[2]
+void,                   SetGlyphToPath,            VGFont font, VGuint glyphIndex, VGPath path, VGboolean isHinted, const VGfloat glyphOrigin[2], const VGfloat escapement[2]
diff --git a/src/mapi/vgapi/vgapi_defines.h b/src/mapi/vgapi/vgapi_defines.h
deleted file mode 100644 (file)
index fb9f68c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef VGAPI_DEFINES_H
-#define VGAPI_DEFINES_H
-
-#include "VG/openvg.h"
-#include "VG/vgext.h"
-
-#define MAPI_ABI_PREFIX vg
-#define MAPI_ABI_PUBLIC VG_API_CALL
-#define MAPI_ABI_ATTR VG_API_ENTRY
-
-#endif /* VGAPI_DEFINES_H */
index 08d731de2d55e832cb5c982f63d7a0cef011678d..cc4ad09fa339050288c80e891e211d521fd68813 100644 (file)
@@ -16,7 +16,6 @@ if env['platform'] == 'windows':
     env.Append(CPPDEFINES = [
         '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers
         'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
-        'WIN32_THREADS', # use Win32 thread API
     ])
     env.Prepend(CPPPATH = ['#src/talloc'])
 else:
index ba8be125718d27411550606752901cd3000a1a7e..cdb2500f7c2ab4e7c047e7a3db634eb27d109f8a 100644 (file)
@@ -266,13 +266,16 @@ struct gen_mipmap_state
    GLuint FBO;
 };
 
-
+#define MAX_META_OPS_DEPTH      2
 /**
  * All per-context meta state.
  */
 struct gl_meta_state
 {
-   struct save_state Save;    /**< state saved during meta-ops */
+   /** Stack of state saved during meta-ops */
+   struct save_state Save[MAX_META_OPS_DEPTH];
+   /** Save stack depth */
+   GLuint SaveStackDepth;
 
    struct temp_texture TempTex;
 
@@ -324,8 +327,13 @@ _mesa_meta_free(struct gl_context *ctx)
 static void
 _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
 {
-   struct save_state *save = &ctx->Meta->Save;
+   struct save_state *save;
+
+   /* hope MAX_META_OPS_DEPTH is large enough */
+   assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH);
 
+   save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++];
+   memset(save, 0, sizeof(*save));
    save->SavedState = state;
 
    if (state & META_ALPHA_TEST) {
@@ -575,7 +583,7 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
 static void
 _mesa_meta_end(struct gl_context *ctx)
 {
-   struct save_state *save = &ctx->Meta->Save;
+   struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth];
    const GLbitfield state = save->SavedState;
 
    if (state & META_ALPHA_TEST) {
@@ -1398,6 +1406,7 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
    struct vertex verts[4];
    /* save all state but scissor, pixel pack/unpack */
    GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
+   const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
 
    if (buffers & BUFFER_BITS_COLOR) {
       /* if clearing color buffers, don't save/restore colormask */
@@ -1453,7 +1462,7 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
-                                ctx->Stencil.Clear & 0x7fffffff,
+                                ctx->Stencil.Clear & stencilMax,
                                 ctx->Stencil.WriteMask[0]);
    }
    else {
index f943f81dd0571923a371c16e902f55bc6390e54e..f32f3cf6020d3b807936f4b5370c4c49c09f89db 100644 (file)
@@ -176,6 +176,7 @@ i915CreateContext(int api,
    ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitCondCodes = GL_TRUE;
    ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT].EmitNoIfs = GL_TRUE;
    ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT].EmitNoNoise = GL_TRUE;
+   ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT].EmitNoPow = GL_TRUE;
 
    ctx->Const.MaxDrawBuffers = 1;
 
index c00ee415b6b19336335843db3e25f98310080aec..7a9fb7f088bcfd7c5b90fab3d443782be1820e45 100644 (file)
@@ -569,10 +569,14 @@ upload_program(struct i915_fragment_program *p)
         if (inst->DstReg.CondMask == COND_TR) {
            tmp = i915_get_utemp(p);
 
+           /* The KIL instruction discards the fragment if any component of
+            * the source is < 0.  Emit an immediate operand of {-1}.xywz.
+            */
            i915_emit_texld(p, get_live_regs(p, inst),
                            tmp, A0_DEST_CHANNEL_ALL,
                            0, /* use a dummy dest reg */
-                           swizzle(tmp, ONE, ONE, ONE, ONE), /* always */
+                           negate(swizzle(tmp, ONE, ONE, ONE, ONE),
+                                  1, 1, 1, 1),
                            T0_TEXKILL);
         } else {
            p->error = 1;
index e3ca863fe51e3eb5152195cbee1e9414db53b8d0..7c3ac0c14ef02131a77ef99b504ec8036eae86cb 100644 (file)
@@ -81,7 +81,6 @@ DRIVER_SOURCES = \
        brw_wm_emit.c \
        brw_wm_fp.c \
        brw_wm_iz.c \
-       brw_wm_glsl.c \
        brw_wm_pass0.c \
        brw_wm_pass1.c \
        brw_wm_pass2.c \
index a8369b07c35413fda273790704c4cfa97b6e1c3a..d3a1233aac0fe3d0e1d906b335b109f2a1ac9ad8 100644 (file)
@@ -232,3 +232,28 @@ const struct brw_tracked_state brw_cc_unit = {
    .prepare = prepare_cc_unit,
    .emit = upload_cc_unit,
 };
+
+static void upload_blend_constant_color(struct brw_context *brw)
+{
+   struct gl_context *ctx = &brw->intel.ctx;
+   struct brw_blend_constant_color bcc;
+
+   memset(&bcc, 0, sizeof(bcc));
+   bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
+   bcc.header.length = sizeof(bcc)/4-2;
+   bcc.blend_constant_color[0] = ctx->Color.BlendColor[0];
+   bcc.blend_constant_color[1] = ctx->Color.BlendColor[1];
+   bcc.blend_constant_color[2] = ctx->Color.BlendColor[2];
+   bcc.blend_constant_color[3] = ctx->Color.BlendColor[3];
+
+   BRW_CACHED_BATCH_STRUCT(brw, &bcc);
+}
+
+const struct brw_tracked_state brw_blend_constant_color = {
+   .dirty = {
+      .mesa = _NEW_COLOR,
+      .brw = BRW_NEW_CONTEXT,
+      .cache = 0
+   },
+   .emit = upload_blend_constant_color
+};
index cb0a8b96c9c3cdb03b7e3de33320a9461a381a96..28549f2574ad2f1e064718fb172ee0ec7f1a8852 100644 (file)
@@ -122,9 +122,6 @@ GLboolean brwCreateContext( int api,
         (i == MESA_SHADER_FRAGMENT);
       ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
         (i == MESA_SHADER_FRAGMENT);
-
-      if (intel->gen == 6)
-        ctx->ShaderCompilerOptions[i].EmitNoIfs = (i == MESA_SHADER_VERTEX);
    }
 
    ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
index 335339515a248550b0d8050bc759d1261f792f64..7069724466ab5f4e7693eac4757849143df8657a 100644 (file)
@@ -171,7 +171,6 @@ struct brw_vertex_program {
 struct brw_fragment_program {
    struct gl_fragment_program program;
    GLuint id;  /**< serial no. to identify frag progs, never re-used */
-   GLboolean isGLSL;  /**< really, any IF/LOOP/CONT/BREAK instructions */
 
    /** for debugging, which texture units are referenced */
    GLbitfield tex_units_used;
@@ -211,6 +210,7 @@ struct brw_wm_prog_data {
    GLuint nr_params;       /**< number of float params/constants */
    GLuint nr_pull_params;
    GLboolean error;
+   int dispatch_width;
 
    /* Pointer to tracked values (only valid once
     * _mesa_load_state_parameters has been called at runtime).
index 7b823eb201b0a54d9250c44a6ca46aaf577eb2b1..877b22fec19ad165ae29a67ca8448e698f8aa442 100644 (file)
@@ -242,21 +242,13 @@ static void prepare_constant_buffer(struct brw_context *brw)
       GLuint offset = brw->curbe.vs_start * 16;
       GLuint nr = brw->vs.prog_data->nr_params / 4;
 
-      if (vp->use_const_buffer) {
-        /* Load the subset of push constants that will get used when
-         * we also have a pull constant buffer.
-         */
-        for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) {
-           if (brw->vs.constant_map[i] != -1) {
-              assert(brw->vs.constant_map[i] <= nr);
-              memcpy(buf + offset + brw->vs.constant_map[i] * 4,
-                     vp->program.Base.Parameters->ParameterValues[i],
-                     4 * sizeof(float));
-           }
-        }
-      } else {
-        for (i = 0; i < nr; i++) {
-           memcpy(buf + offset + i * 4,
+      /* Load the subset of push constants that will get used when
+       * we also have a pull constant buffer.
+       */
+      for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) {
+        if (brw->vs.constant_map[i] != -1) {
+           assert(brw->vs.constant_map[i] <= nr);
+           memcpy(buf + offset + brw->vs.constant_map[i] * 4,
                   vp->program.Base.Parameters->ParameterValues[i],
                   4 * sizeof(float));
         }
index 239586a0366b46b58a26ede591c6b99877fcda80..7f3e4986808b82a04a4002793d0ef96d58736494 100644 (file)
 #define BRW_COMPRESSION_2NDHALF       1
 #define BRW_COMPRESSION_COMPRESSED    2
 
+#define GEN6_COMPRESSION_1Q            0
+#define GEN6_COMPRESSION_2Q            1
+#define GEN6_COMPRESSION_3Q            2
+#define GEN6_COMPRESSION_4Q            3
+#define GEN6_COMPRESSION_1H            0
+#define GEN6_COMPRESSION_2H            2
+
 #define BRW_CONDITIONAL_NONE  0
 #define BRW_CONDITIONAL_Z     1
 #define BRW_CONDITIONAL_NZ    2
 # define ATTRIBUTE_0_CONST_SOURCE_SHIFT                        9
 # define ATTRIBUTE_0_SWIZZLE_SHIFT                     6
 # define ATTRIBUTE_0_SOURCE_SHIFT                      0
+
+# define ATTRIBUTE_SWIZZLE_INPUTATTR                    0
+# define ATTRIBUTE_SWIZZLE_INPUTATTR_FACING             1
+# define ATTRIBUTE_SWIZZLE_INPUTATTR_W                  2
+# define ATTRIBUTE_SWIZZLE_INPUTATTR_FACING_W           3
+# define ATTRIBUTE_SWIZZLE_SHIFT                        6
+
 /* DW16: Point sprite texture coordinate enables */
 /* DW17: Constant interpolation enables */
 /* DW18: attr 0-7 wrap shortest enables */
index 962c04128b8280deb74b9f6a3a7638ee32b05556..6b61f7af15d7e4a1addc66373f4d62da22ff0ce1 100644 (file)
@@ -899,7 +899,8 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
        err |= dest (file, inst);
     } else if (gen >= 6 && (inst->header.opcode == BRW_OPCODE_IF ||
                            inst->header.opcode == BRW_OPCODE_ELSE ||
-                           inst->header.opcode == BRW_OPCODE_ENDIF)) {
+                           inst->header.opcode == BRW_OPCODE_ENDIF ||
+                           inst->header.opcode == BRW_OPCODE_WHILE)) {
        format (file, " %d", inst->bits1.branch_gen6.jump_count);
     }
 
index 2ff39e8e64a4eec3290bf48acda433ec4425f795..3b5c4c071e3416f2b5e217661067143bfa00bc73 100644 (file)
@@ -72,7 +72,37 @@ void brw_set_access_mode( struct brw_compile *p, GLuint access_mode )
 
 void brw_set_compression_control( struct brw_compile *p, GLboolean compression_control )
 {
-   p->current->header.compression_control = compression_control;
+   p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED);
+
+   if (p->brw->intel.gen >= 6) {
+      /* Since we don't use the 32-wide support in gen6, we translate
+       * the pre-gen6 compression control here.
+       */
+      switch (compression_control) {
+      case BRW_COMPRESSION_NONE:
+        /* This is the "use the first set of bits of dmask/vmask/arf
+         * according to execsize" option.
+         */
+        p->current->header.compression_control = GEN6_COMPRESSION_1Q;
+        break;
+      case BRW_COMPRESSION_2NDHALF:
+        /* For 8-wide, this is "use the second set of 8 bits." */
+        p->current->header.compression_control = GEN6_COMPRESSION_2Q;
+        break;
+      case BRW_COMPRESSION_COMPRESSED:
+        /* For 16-wide instruction compression, use the first set of 16 bits
+         * since we don't do 32-wide dispatch.
+         */
+        p->current->header.compression_control = GEN6_COMPRESSION_1H;
+        break;
+      default:
+        assert(!"not reached");
+        p->current->header.compression_control = GEN6_COMPRESSION_1H;
+        break;
+      }
+   } else {
+      p->current->header.compression_control = compression_control;
+   }
 }
 
 void brw_set_mask_control( struct brw_compile *p, GLuint value )
@@ -95,6 +125,7 @@ void brw_push_insn_state( struct brw_compile *p )
 {
    assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
    memcpy(p->current+1, p->current, sizeof(struct brw_instruction));
+   p->compressed_stack[p->current - p->stack] = p->compressed;
    p->current++;   
 }
 
@@ -102,6 +133,7 @@ void brw_pop_insn_state( struct brw_compile *p )
 {
    assert(p->current != p->stack);
    p->current--;
+   p->compressed = p->compressed_stack[p->current - p->stack];
 }
 
 
@@ -112,6 +144,7 @@ void brw_init_compile( struct brw_context *brw, struct brw_compile *p )
    p->brw = brw;
    p->nr_insn = 0;
    p->current = p->stack;
+   p->compressed = false;
    memset(p->current, 0, sizeof(p->current[0]));
 
    /* Some defaults?
index b4538e6e8a7a23f17e6880c1244334c71afc39f8..4dbdc52210011581acbfbd067861cf54df956045 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef BRW_EU_H
 #define BRW_EU_H
 
+#include <stdbool.h>
 #include "brw_structs.h"
 #include "brw_defines.h"
 #include "program/prog_instruction.h"
@@ -106,10 +107,12 @@ struct brw_compile {
    /* Allow clients to push/pop instruction state:
     */
    struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
+   bool compressed_stack[BRW_EU_MAX_INSN_STACK];
    struct brw_instruction *current;
 
    GLuint flag_value;
    GLboolean single_program_flow;
+   bool compressed;
    struct brw_context *brw;
 
    struct brw_glsl_label *first_label;  /**< linked list of labels */
@@ -954,6 +957,8 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
               struct brw_instruction *patch_insn);
 
 struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count);
+struct brw_instruction *brw_CONT_gen6(struct brw_compile *p,
+                                     struct brw_instruction *do_insn);
 struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count);
 /* Forward jumps:
  */
@@ -1009,6 +1014,7 @@ void brw_math_invert( struct brw_compile *p,
 void brw_set_src1( struct brw_instruction *insn,
                           struct brw_reg reg );
 
+void brw_set_uip_jip(struct brw_compile *p);
 
 /* brw_optimize.c */
 void brw_optimize(struct brw_compile *p);
index 9cb941dacfdcabb53ef93237ed42beaa8a8a6a83..9c764fe779d9fc46680ca4503e4090b40ef88fb8 100644 (file)
  * Internal helper for constructing instructions
  */
 
-static void guess_execution_size( struct brw_instruction *insn,
-                                 struct brw_reg reg )
+static void guess_execution_size(struct brw_compile *p,
+                                struct brw_instruction *insn,
+                                struct brw_reg reg)
 {
-   if (reg.width == BRW_WIDTH_8 && 
-       insn->header.compression_control == BRW_COMPRESSION_COMPRESSED) 
+   if (reg.width == BRW_WIDTH_8 && p->compressed)
       insn->header.execution_size = BRW_EXECUTE_16;
    else
       insn->header.execution_size = reg.width; /* note - definitions are compatible */
 }
 
 
-static void brw_set_dest( struct brw_instruction *insn,
-                         struct brw_reg dest )
+static void brw_set_dest(struct brw_compile *p,
+                        struct brw_instruction *insn,
+                        struct brw_reg dest)
 {
    if (dest.file != BRW_ARCHITECTURE_REGISTER_FILE &&
        dest.file != BRW_MESSAGE_REGISTER_FILE)
@@ -100,7 +101,7 @@ static void brw_set_dest( struct brw_instruction *insn,
    /* NEW: Set the execution size based on dest.width and
     * insn->compression_control:
     */
-   guess_execution_size(insn, dest);
+   guess_execution_size(p, insn, dest);
 }
 
 extern int reg_type_size[];
@@ -629,7 +630,7 @@ static struct brw_instruction *brw_alu1( struct brw_compile *p,
                                         struct brw_reg src )
 {
    struct brw_instruction *insn = next_insn(p, opcode);
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src);   
    return insn;
 }
@@ -641,7 +642,7 @@ static struct brw_instruction *brw_alu2(struct brw_compile *p,
                                        struct brw_reg src1 )
 {
    struct brw_instruction *insn = next_insn(p, opcode);   
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src0);
    brw_set_src1(insn, src1);
    return insn;
@@ -680,7 +681,7 @@ void brw_##OP(struct brw_compile *p,                                              \
 {                                                                            \
    struct brw_instruction *rnd, *add;                                        \
    rnd = next_insn(p, BRW_OPCODE_##OP);                                              \
-   brw_set_dest(rnd, dest);                                                  \
+   brw_set_dest(p, rnd, dest);                                               \
    brw_set_src0(rnd, src);                                                   \
    rnd->header.destreg__conditionalmod = 0x7; /* turn on round-increments */  \
                                                                              \
@@ -779,7 +780,7 @@ struct brw_instruction *brw_MUL(struct brw_compile *p,
 void brw_NOP(struct brw_compile *p)
 {
    struct brw_instruction *insn = next_insn(p, BRW_OPCODE_NOP);   
-   brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+   brw_set_dest(p, insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
    brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
    brw_set_src1(insn, brw_imm_ud(0x0));
 }
@@ -840,11 +841,11 @@ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size)
    /* Override the defaults for this instruction:
     */
    if (intel->gen < 6) {
-      brw_set_dest(insn, brw_ip_reg());
+      brw_set_dest(p, insn, brw_ip_reg());
       brw_set_src0(insn, brw_ip_reg());
       brw_set_src1(insn, brw_imm_d(0x0));
    } else {
-      brw_set_dest(insn, brw_imm_w(0));
+      brw_set_dest(p, insn, brw_imm_w(0));
       insn->bits1.branch_gen6.jump_count = 0;
       brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
       brw_set_src1(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
@@ -870,7 +871,7 @@ brw_IF_gen6(struct brw_compile *p, uint32_t conditional,
 
    insn = next_insn(p, BRW_OPCODE_IF);
 
-   brw_set_dest(insn, brw_imm_w(0));
+   brw_set_dest(p, insn, brw_imm_w(0));
    insn->header.execution_size = BRW_EXECUTE_8;
    insn->bits1.branch_gen6.jump_count = 0;
    brw_set_src0(insn, src0);
@@ -905,11 +906,11 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
    }
 
    if (intel->gen < 6) {
-      brw_set_dest(insn, brw_ip_reg());
+      brw_set_dest(p, insn, brw_ip_reg());
       brw_set_src0(insn, brw_ip_reg());
       brw_set_src1(insn, brw_imm_d(0x0));
    } else {
-      brw_set_dest(insn, brw_imm_w(0));
+      brw_set_dest(p, insn, brw_imm_w(0));
       insn->bits1.branch_gen6.jump_count = 0;
       brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
       brw_set_src1(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
@@ -965,11 +966,11 @@ void brw_ENDIF(struct brw_compile *p,
       struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF);
 
       if (intel->gen < 6) {
-        brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+        brw_set_dest(p, insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
         brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
         brw_set_src1(insn, brw_imm_d(0x0));
       } else {
-        brw_set_dest(insn, brw_imm_w(0));
+        brw_set_dest(p, insn, brw_imm_w(0));
         brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
         brw_set_src1(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
       }
@@ -1029,16 +1030,44 @@ void brw_ENDIF(struct brw_compile *p,
 
 struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count)
 {
+   struct intel_context *intel = &p->brw->intel;
    struct brw_instruction *insn;
+
    insn = next_insn(p, BRW_OPCODE_BREAK);
-   brw_set_dest(insn, brw_ip_reg());
+   if (intel->gen >= 6) {
+      brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+      brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+      brw_set_src1(insn, brw_imm_d(0x0));
+   } else {
+      brw_set_dest(p, insn, brw_ip_reg());
+      brw_set_src0(insn, brw_ip_reg());
+      brw_set_src1(insn, brw_imm_d(0x0));
+      insn->bits3.if_else.pad0 = 0;
+      insn->bits3.if_else.pop_count = pop_count;
+   }
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = BRW_EXECUTE_8;
+
+   return insn;
+}
+
+struct brw_instruction *brw_CONT_gen6(struct brw_compile *p,
+                                     struct brw_instruction *do_insn)
+{
+   struct brw_instruction *insn;
+   int br = 2;
+
+   insn = next_insn(p, BRW_OPCODE_CONTINUE);
+   brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+   brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+   brw_set_dest(p, insn, brw_ip_reg());
    brw_set_src0(insn, brw_ip_reg());
    brw_set_src1(insn, brw_imm_d(0x0));
+
+   insn->bits3.break_cont.uip = br * (do_insn - insn);
+
    insn->header.compression_control = BRW_COMPRESSION_NONE;
    insn->header.execution_size = BRW_EXECUTE_8;
-   /* insn->header.mask_control = BRW_MASK_DISABLE; */
-   insn->bits3.if_else.pad0 = 0;
-   insn->bits3.if_else.pop_count = pop_count;
    return insn;
 }
 
@@ -1046,7 +1075,7 @@ struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count)
 {
    struct brw_instruction *insn;
    insn = next_insn(p, BRW_OPCODE_CONTINUE);
-   brw_set_dest(insn, brw_ip_reg());
+   brw_set_dest(p, insn, brw_ip_reg());
    brw_set_src0(insn, brw_ip_reg());
    brw_set_src1(insn, brw_imm_d(0x0));
    insn->header.compression_control = BRW_COMPRESSION_NONE;
@@ -1058,17 +1087,33 @@ struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count)
 }
 
 /* DO/WHILE loop:
+ *
+ * The DO/WHILE is just an unterminated loop -- break or continue are
+ * used for control within the loop.  We have a few ways they can be
+ * done.
+ *
+ * For uniform control flow, the WHILE is just a jump, so ADD ip, ip,
+ * jip and no DO instruction.
+ *
+ * For non-uniform control flow pre-gen6, there's a DO instruction to
+ * push the mask, and a WHILE to jump back, and BREAK to get out and
+ * pop the mask.
+ *
+ * For gen6, there's no more mask stack, so no need for DO.  WHILE
+ * just points back to the first instruction of the loop.
  */
 struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
 {
-   if (p->single_program_flow) {
+   struct intel_context *intel = &p->brw->intel;
+
+   if (intel->gen >= 6 || p->single_program_flow) {
       return &p->store[p->nr_insn];
    } else {
       struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO);
 
       /* Override the defaults for this instruction:
        */
-      brw_set_dest(insn, brw_null_reg());
+      brw_set_dest(p, insn, brw_null_reg());
       brw_set_src0(insn, brw_null_reg());
       brw_set_src1(insn, brw_null_reg());
 
@@ -1094,34 +1139,42 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
    if (intel->gen >= 5)
       br = 2;
 
-   if (p->single_program_flow)
-      insn = next_insn(p, BRW_OPCODE_ADD);
-   else
+   if (intel->gen >= 6) {
       insn = next_insn(p, BRW_OPCODE_WHILE);
 
-   brw_set_dest(insn, brw_ip_reg());
-   brw_set_src0(insn, brw_ip_reg());
-   brw_set_src1(insn, brw_imm_d(0x0));
+      brw_set_dest(p, insn, brw_imm_w(0));
+      insn->bits1.branch_gen6.jump_count = br * (do_insn - insn);
+      brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+      brw_set_src1(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
 
-   insn->header.compression_control = BRW_COMPRESSION_NONE;
+      insn->header.execution_size = do_insn->header.execution_size;
+      assert(insn->header.execution_size == BRW_EXECUTE_8);
+   } else {
+      if (p->single_program_flow) {
+        insn = next_insn(p, BRW_OPCODE_ADD);
 
-   if (p->single_program_flow) {
-      insn->header.execution_size = BRW_EXECUTE_1;
+        brw_set_dest(p, insn, brw_ip_reg());
+        brw_set_src0(insn, brw_ip_reg());
+        brw_set_src1(insn, brw_imm_d((do_insn - insn) * 16));
+        insn->header.execution_size = BRW_EXECUTE_1;
+      } else {
+        insn = next_insn(p, BRW_OPCODE_WHILE);
 
-      insn->bits3.d = (do_insn - insn) * 16;
-   } else {
-      insn->header.execution_size = do_insn->header.execution_size;
+        assert(do_insn->header.opcode == BRW_OPCODE_DO);
 
-      assert(do_insn->header.opcode == BRW_OPCODE_DO);
-      insn->bits3.if_else.jump_count = br * (do_insn - insn + 1);
-      insn->bits3.if_else.pop_count = 0;
-      insn->bits3.if_else.pad0 = 0;
-   }
+        brw_set_dest(p, insn, brw_ip_reg());
+        brw_set_src0(insn, brw_ip_reg());
+        brw_set_src1(insn, brw_imm_d(0));
 
-/*    insn->header.mask_control = BRW_MASK_ENABLE; */
+        insn->header.execution_size = do_insn->header.execution_size;
+        insn->bits3.if_else.jump_count = br * (do_insn - insn + 1);
+        insn->bits3.if_else.pop_count = 0;
+        insn->bits3.if_else.pad0 = 0;
+      }
+   }
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   p->current->header.predicate_control = BRW_PREDICATE_NONE;
 
-   /* insn->header.mask_control = BRW_MASK_DISABLE; */
-   p->current->header.predicate_control = BRW_PREDICATE_NONE;   
    return insn;
 }
 
@@ -1159,7 +1212,7 @@ void brw_CMP(struct brw_compile *p,
    struct brw_instruction *insn = next_insn(p, BRW_OPCODE_CMP);
 
    insn->header.destreg__conditionalmod = conditional;
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src0);
    brw_set_src1(insn, src1);
 
@@ -1184,7 +1237,7 @@ void brw_WAIT (struct brw_compile *p)
    struct brw_instruction *insn = next_insn(p, BRW_OPCODE_WAIT);
    struct brw_reg src = brw_notification_1_reg();
 
-   brw_set_dest(insn, src);
+   brw_set_dest(p, insn, src);
    brw_set_src0(insn, src);
    brw_set_src1(insn, brw_null_reg());
    insn->header.execution_size = 0; /* must */
@@ -1219,6 +1272,10 @@ void brw_math( struct brw_compile *p,
       assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
       assert(src.hstride == BRW_HORIZONTAL_STRIDE_1);
 
+      /* Source modifiers are ignored for extended math instructions. */
+      assert(!src.negate);
+      assert(!src.abs);
+
       if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
          function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
         assert(src.type == BRW_REGISTER_TYPE_F);
@@ -1228,8 +1285,9 @@ void brw_math( struct brw_compile *p,
        * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
        */
       insn->header.destreg__conditionalmod = function;
+      insn->header.saturate = saturate;
 
-      brw_set_dest(insn, dest);
+      brw_set_dest(p, insn, dest);
       brw_set_src0(insn, src);
       brw_set_src1(insn, brw_null_reg());
    } else {
@@ -1242,7 +1300,7 @@ void brw_math( struct brw_compile *p,
       insn->header.predicate_control = 0;
       insn->header.destreg__conditionalmod = msg_reg_nr;
 
-      brw_set_dest(insn, dest);
+      brw_set_dest(p, insn, dest);
       brw_set_src0(insn, src);
       brw_set_math_message(p->brw,
                           insn,
@@ -1284,12 +1342,18 @@ void brw_math2(struct brw_compile *p,
       assert(src1.type == BRW_REGISTER_TYPE_F);
    }
 
+   /* Source modifiers are ignored for extended math instructions. */
+   assert(!src0.negate);
+   assert(!src0.abs);
+   assert(!src1.negate);
+   assert(!src1.abs);
+
    /* Math is the same ISA format as other opcodes, except that CondModifier
     * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
     */
    insn->header.destreg__conditionalmod = function;
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src0);
    brw_set_src1(insn, src1);
 }
@@ -1318,8 +1382,13 @@ void brw_math_16( struct brw_compile *p,
        * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
        */
       insn->header.destreg__conditionalmod = function;
+      insn->header.saturate = saturate;
+
+      /* Source modifiers are ignored for extended math instructions. */
+      assert(!src.negate);
+      assert(!src.abs);
 
-      brw_set_dest(insn, dest);
+      brw_set_dest(p, insn, dest);
       brw_set_src0(insn, src);
       brw_set_src1(insn, brw_null_reg());
       return;
@@ -1334,7 +1403,7 @@ void brw_math_16( struct brw_compile *p,
    insn = next_insn(p, BRW_OPCODE_SEND);
    insn->header.destreg__conditionalmod = msg_reg_nr;
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src);
    brw_set_math_message(p->brw,
                        insn, 
@@ -1351,7 +1420,7 @@ void brw_math_16( struct brw_compile *p,
    insn->header.compression_control = BRW_COMPRESSION_2NDHALF;
    insn->header.destreg__conditionalmod = msg_reg_nr+1;
 
-   brw_set_dest(insn, offset(dest,1));
+   brw_set_dest(p, insn, offset(dest,1));
    brw_set_src0(insn, src);
    brw_set_math_message(p->brw, 
                        insn, 
@@ -1446,7 +1515,7 @@ void brw_oword_block_write_scratch(struct brw_compile *p,
         send_commit_msg = 1;
       }
 
-      brw_set_dest(insn, dest);
+      brw_set_dest(p, insn, dest);
       brw_set_src0(insn, brw_null_reg());
 
       brw_set_dp_write_message(p->brw,
@@ -1516,7 +1585,7 @@ brw_oword_block_read_scratch(struct brw_compile *p,
       insn->header.compression_control = BRW_COMPRESSION_NONE;
       insn->header.destreg__conditionalmod = mrf.nr;
 
-      brw_set_dest(insn, dest);        /* UW? */
+      brw_set_dest(p, insn, dest);     /* UW? */
       brw_set_src0(insn, brw_null_reg());
 
       brw_set_dp_read_message(p->brw,
@@ -1569,7 +1638,7 @@ void brw_oword_block_read(struct brw_compile *p,
    /* cast dest to a uword[8] vector */
    dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW);
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    if (intel->gen >= 6) {
       brw_set_src0(insn, mrf);
    } else {
@@ -1614,7 +1683,7 @@ void brw_dword_scattered_read(struct brw_compile *p,
    /* cast dest to a uword[8] vector */
    dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW);
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, brw_null_reg());
 
    brw_set_dp_read_message(p->brw,
@@ -1639,29 +1708,21 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
                       GLuint location,
                       GLuint bind_table_index)
 {
+   struct intel_context *intel = &p->brw->intel;
    struct brw_instruction *insn;
    GLuint msg_reg_nr = 1;
-   struct brw_reg b;
 
-   /*
-   printf("vs const read msg, location %u, msg_reg_nr %d\n",
-          location, msg_reg_nr);
-   */
+   if (intel->gen >= 6)
+      location /= 16;
 
    /* Setup MRF[1] with location/offset into const buffer */
    brw_push_insn_state(p);
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_set_mask_control(p, BRW_MASK_DISABLE);
    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-
-   /* XXX I think we're setting all the dwords of MRF[1] to 'location'.
-    * when the docs say only dword[2] should be set.  Hmmm.  But it works.
-    */
-   b = brw_message_reg(msg_reg_nr);
-   b = retype(b, BRW_REGISTER_TYPE_UD);
-   /*b = get_element_ud(b, 2);*/
-   brw_MOV(p, b, brw_imm_ud(location));
-
+   brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, msg_reg_nr, 2),
+                    BRW_REGISTER_TYPE_UD),
+          brw_imm_ud(location));
    brw_pop_insn_state(p);
 
    insn = next_insn(p, BRW_OPCODE_SEND);
@@ -1671,8 +1732,12 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
    insn->header.destreg__conditionalmod = msg_reg_nr;
    insn->header.mask_control = BRW_MASK_DISABLE;
 
-   brw_set_dest(insn, dest);
-   brw_set_src0(insn, brw_null_reg());
+   brw_set_dest(p, insn, dest);
+   if (intel->gen >= 6) {
+      brw_set_src0(insn, brw_message_reg(msg_reg_nr));
+   } else {
+      brw_set_src0(insn, brw_null_reg());
+   }
 
    brw_set_dp_read_message(p->brw,
                           insn,
@@ -1706,7 +1771,7 @@ void brw_dp_READ_4_vs_relative(struct brw_compile *p,
    /* M1.0 is block offset 0, M1.4 is block offset 1, all other
     * fields ignored.
     */
-   brw_ADD(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD),
+   brw_ADD(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_D),
           addr_reg, brw_imm_d(offset));
    brw_pop_insn_state(p);
 
@@ -1717,7 +1782,7 @@ void brw_dp_READ_4_vs_relative(struct brw_compile *p,
    insn->header.destreg__conditionalmod = 0;
    insn->header.mask_control = BRW_MASK_DISABLE;
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, brw_vec8_grf(0, 0));
 
    if (intel->gen == 6)
@@ -1782,7 +1847,7 @@ void brw_fb_WRITE(struct brw_compile *p,
    else
       msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01;
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src0);
    brw_set_dp_write_message(p->brw,
                            insn,
@@ -1860,7 +1925,7 @@ void brw_SAMPLE(struct brw_compile *p,
 
         struct brw_reg m1 = brw_message_reg(msg_reg_nr);
 
-        guess_execution_size(p->current, dest);
+        guess_execution_size(p, p->current, dest);
         if (p->current->header.execution_size == BRW_EXECUTE_16)
            dispatch_16 = GL_TRUE;
 
@@ -1895,12 +1960,15 @@ void brw_SAMPLE(struct brw_compile *p,
        * and the first message register index comes from src0.
        */
       if (intel->gen >= 6) {
-         brw_push_insn_state(p);
-         brw_set_mask_control( p, BRW_MASK_DISABLE );
-         /* m1 contains header? */
-         brw_MOV(p, brw_message_reg(msg_reg_nr), src0);
-         brw_pop_insn_state(p);
-         src0 = brw_message_reg(msg_reg_nr);
+        if (src0.file != BRW_ARCHITECTURE_REGISTER_FILE ||
+            src0.nr != BRW_ARF_NULL) {
+           brw_push_insn_state(p);
+           brw_set_mask_control( p, BRW_MASK_DISABLE );
+           brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+           brw_MOV(p, retype(brw_message_reg(msg_reg_nr), src0.type), src0);
+           brw_pop_insn_state(p);
+        }
+        src0 = brw_message_reg(msg_reg_nr);
       }
 
       insn = next_insn(p, BRW_OPCODE_SEND);
@@ -1909,7 +1977,7 @@ void brw_SAMPLE(struct brw_compile *p,
       if (intel->gen < 6)
          insn->header.destreg__conditionalmod = msg_reg_nr;
 
-      brw_set_dest(insn, dest);
+      brw_set_dest(p, insn, dest);
       brw_set_src0(insn, src0);
       brw_set_sampler_message(p->brw, insn,
                              binding_table_index,
@@ -1970,7 +2038,7 @@ void brw_urb_WRITE(struct brw_compile *p,
 
    assert(msg_length < BRW_MAX_MRF);
 
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src0);
    brw_set_src1(insn, brw_imm_d(0));
 
@@ -1989,6 +2057,80 @@ void brw_urb_WRITE(struct brw_compile *p,
                       swizzle);
 }
 
+static int
+brw_find_next_block_end(struct brw_compile *p, int start)
+{
+   int ip;
+
+   for (ip = start + 1; ip < p->nr_insn; ip++) {
+      struct brw_instruction *insn = &p->store[ip];
+
+      switch (insn->header.opcode) {
+      case BRW_OPCODE_ENDIF:
+      case BRW_OPCODE_ELSE:
+      case BRW_OPCODE_WHILE:
+        return ip;
+      }
+   }
+   assert(!"not reached");
+   return start + 1;
+}
+
+/* There is no DO instruction on gen6, so to find the end of the loop
+ * we have to see if the loop is jumping back before our start
+ * instruction.
+ */
+static int
+brw_find_loop_end(struct brw_compile *p, int start)
+{
+   int ip;
+   int br = 2;
+
+   for (ip = start + 1; ip < p->nr_insn; ip++) {
+      struct brw_instruction *insn = &p->store[ip];
+
+      if (insn->header.opcode == BRW_OPCODE_WHILE) {
+        if (ip + insn->bits1.branch_gen6.jump_count / br < start)
+           return ip;
+      }
+   }
+   assert(!"not reached");
+   return start + 1;
+}
+
+/* After program generation, go back and update the UIP and JIP of
+ * BREAK and CONT instructions to their correct locations.
+ */
+void
+brw_set_uip_jip(struct brw_compile *p)
+{
+   struct intel_context *intel = &p->brw->intel;
+   int ip;
+   int br = 2;
+
+   if (intel->gen < 6)
+      return;
+
+   for (ip = 0; ip < p->nr_insn; ip++) {
+      struct brw_instruction *insn = &p->store[ip];
+
+      switch (insn->header.opcode) {
+      case BRW_OPCODE_BREAK:
+        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
+        insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip + 1);
+        break;
+      case BRW_OPCODE_CONTINUE:
+        /* JIP is set at CONTINUE emit time, since that's when we
+         * know where the start of the loop is.
+         */
+        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
+        assert(insn->bits3.break_cont.uip != 0);
+        assert(insn->bits3.break_cont.jip != 0);
+        break;
+      }
+   }
+}
+
 void brw_ff_sync(struct brw_compile *p,
                   struct brw_reg dest,
                   GLuint msg_reg_nr,
@@ -2013,7 +2155,7 @@ void brw_ff_sync(struct brw_compile *p,
    }
 
    insn = next_insn(p, BRW_OPCODE_SEND);
-   brw_set_dest(insn, dest);
+   brw_set_dest(p, insn, dest);
    brw_set_src0(insn, src0);
    brw_set_src1(insn, brw_imm_d(0));
 
index edb02fabb2344cf9f24e8c6e8ee270c3f99c883e..c3cbe0df618bc869530655e6dff181b0faef1ddd 100644 (file)
@@ -600,8 +600,13 @@ fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src)
     * 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 (intel->gen >= 6 && src.file == UNIFORM) {
+   if (intel->gen >= 6 && (src.file == UNIFORM ||
+                          src.abs ||
+                          src.negate)) {
       fs_reg expanded = fs_reg(this, glsl_type::float_type);
       emit(fs_inst(BRW_OPCODE_MOV, expanded, src));
       src = expanded;
@@ -933,6 +938,10 @@ fs_visitor::visit(ir_expression *ir)
       assert(!"not reached: should be handled by lower_noise");
       break;
 
+   case ir_quadop_vector:
+      assert(!"not reached: should be handled by lower_quadop_vector");
+      break;
+
    case ir_unop_sqrt:
       emit_math(FS_OPCODE_SQRT, this->result, op[0]);
       break;
@@ -1423,28 +1432,70 @@ fs_visitor::visit(ir_discard *ir)
 void
 fs_visitor::visit(ir_constant *ir)
 {
-   fs_reg reg(this, ir->type);
-   this->result = reg;
+   /* 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(this, ir->type);
+   fs_reg dst_reg = reg;
 
-   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
-      switch (ir->type->base_type) {
-      case GLSL_TYPE_FLOAT:
-        emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg(ir->value.f[i])));
-        break;
-      case GLSL_TYPE_UINT:
-        emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg(ir->value.u[i])));
-        break;
-      case GLSL_TYPE_INT:
-        emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg(ir->value.i[i])));
-        break;
-      case GLSL_TYPE_BOOL:
-        emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg((int)ir->value.b[i])));
-        break;
-      default:
-        assert(!"Non-float/uint/int/bool constant");
+   if (ir->type->is_array()) {
+      const unsigned size = type_size(ir->type->fields.array);
+
+      for (unsigned i = 0; i < ir->type->length; i++) {
+        ir->array_elements[i]->accept(this);
+        fs_reg src_reg = this->result;
+
+        dst_reg.type = src_reg.type;
+        for (unsigned j = 0; j < size; j++) {
+           emit(fs_inst(BRW_OPCODE_MOV, dst_reg, src_reg));
+           src_reg.reg_offset++;
+           dst_reg.reg_offset++;
+        }
+      }
+   } else if (ir->type->is_record()) {
+      foreach_list(node, &ir->components) {
+        ir_instruction *const field = (ir_instruction *) node;
+        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(fs_inst(BRW_OPCODE_MOV, dst_reg, src_reg));
+           src_reg.reg_offset++;
+           dst_reg.reg_offset++;
+        }
+      }
+   } 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(fs_inst(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i])));
+           break;
+        case GLSL_TYPE_UINT:
+           emit(fs_inst(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i])));
+           break;
+        case GLSL_TYPE_INT:
+           emit(fs_inst(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i])));
+           break;
+        case GLSL_TYPE_BOOL:
+           emit(fs_inst(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i])));
+           break;
+        default:
+           assert(!"Non-float/uint/int/bool constant");
+        }
+        dst_reg.reg_offset++;
       }
-      reg.reg_offset++;
    }
+
+   this->result = reg;
 }
 
 void
@@ -1574,7 +1625,7 @@ fs_visitor::emit_if_gen6(ir_if *ir)
 
       switch (expr->operation) {
       case ir_unop_logic_not:
-        inst = emit(fs_inst(BRW_OPCODE_IF, temp, op[0], fs_reg(1)));
+        inst = emit(fs_inst(BRW_OPCODE_IF, temp, op[0], fs_reg(0)));
         inst->conditional_mod = BRW_CONDITIONAL_Z;
         return;
 
@@ -1951,7 +2002,7 @@ fs_visitor::emit_interpolation_setup_gen6()
    emit(fs_inst(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y));
 
    this->current_annotation = "compute 1/pos.w";
-   this->wpos_w = fs_reg(brw_vec8_grf(c->key.source_w_reg, 0));
+   this->wpos_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0));
    this->pixel_w = fs_reg(this, glsl_type::float_type);
    emit_math(FS_OPCODE_RCP, this->pixel_w, wpos_w);
 
@@ -1979,17 +2030,17 @@ fs_visitor::emit_fb_writes()
       nr += 2;
    }
 
-   if (c->key.aa_dest_stencil_reg) {
+   if (c->aa_dest_stencil_reg) {
       emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
-                  fs_reg(brw_vec8_grf(c->key.aa_dest_stencil_reg, 0))));
+                  fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0))));
    }
 
    /* Reserve space for color. It'll be filled in per MRT below. */
    int color_mrf = nr;
    nr += 4;
 
-   if (c->key.source_depth_to_render_target) {
-      if (c->key.computes_depth) {
+   if (c->source_depth_to_render_target) {
+      if (c->computes_depth) {
         /* Hand over gl_FragDepth. */
         assert(this->frag_depth);
         fs_reg depth = *(variable_storage(this->frag_depth));
@@ -1998,20 +2049,22 @@ fs_visitor::emit_fb_writes()
       } else {
         /* Pass through the payload depth. */
         emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
-                     fs_reg(brw_vec8_grf(c->key.source_depth_reg, 0))));
+                     fs_reg(brw_vec8_grf(c->source_depth_reg, 0))));
       }
    }
 
-   if (c->key.dest_depth_reg) {
+   if (c->dest_depth_reg) {
       emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
-                  fs_reg(brw_vec8_grf(c->key.dest_depth_reg, 0))));
+                  fs_reg(brw_vec8_grf(c->dest_depth_reg, 0))));
    }
 
    fs_reg color = reg_undef;
    if (this->frag_color)
       color = *(variable_storage(this->frag_color));
-   else if (this->frag_data)
+   else if (this->frag_data) {
       color = *(variable_storage(this->frag_data));
+      color.type = BRW_REGISTER_TYPE_F;
+   }
 
    for (int target = 0; target < c->key.nr_color_regions; target++) {
       this->current_annotation = talloc_asprintf(this->mem_ctx,
@@ -2452,7 +2505,7 @@ fs_visitor::generate_pull_constant_load(fs_inst *inst, struct brw_reg dst)
 void
 fs_visitor::assign_curb_setup()
 {
-   c->prog_data.first_curbe_grf = c->key.nr_payload_regs;
+   c->prog_data.first_curbe_grf = c->nr_payload_regs;
    c->prog_data.curb_read_length = ALIGN(c->prog_data.nr_params, 8) / 8;
 
    /* Map the offsets in the UNIFORM file to fixed HW regs. */
@@ -3227,6 +3280,7 @@ static struct brw_reg brw_reg_from_fs_reg(fs_reg *reg)
         break;
       default:
         assert(!"not reached");
+        brw_reg = brw_null_reg();
         break;
       }
       break;
@@ -3241,6 +3295,10 @@ static struct brw_reg brw_reg_from_fs_reg(fs_reg *reg)
       assert(!"not reached");
       brw_reg = brw_null_reg();
       break;
+   default:
+      assert(!"not reached");
+      brw_reg = brw_null_reg();
+      break;
    }
    if (reg->abs)
       brw_reg = brw_abs(brw_reg);
@@ -3373,10 +3431,6 @@ fs_visitor::generate_code()
         break;
 
       case BRW_OPCODE_DO:
-        /* FINISHME: We need to write the loop instruction support still. */
-        if (intel->gen >= 6)
-           this->fail = true;
-
         loop_stack[loop_stack_depth++] = brw_DO(p, BRW_EXECUTE_8);
         if_depth_in_loop[loop_stack_depth] = 0;
         break;
@@ -3386,7 +3440,11 @@ fs_visitor::generate_code()
         brw_set_predicate_control(p, BRW_PREDICATE_NONE);
         break;
       case BRW_OPCODE_CONTINUE:
-        brw_CONT(p, if_depth_in_loop[loop_stack_depth]);
+        /* FINISHME: We need to write the loop instruction support still. */
+        if (intel->gen >= 6)
+           brw_CONT_gen6(p, loop_stack[loop_stack_depth - 1]);
+        else
+           brw_CONT(p, if_depth_in_loop[loop_stack_depth]);
         brw_set_predicate_control(p, BRW_PREDICATE_NONE);
         break;
 
@@ -3400,16 +3458,18 @@ fs_visitor::generate_code()
         assert(loop_stack_depth > 0);
         loop_stack_depth--;
         inst0 = inst1 = brw_WHILE(p, loop_stack[loop_stack_depth]);
-        /* patch all the BREAK/CONT instructions from last BGNLOOP */
-        while (inst0 > loop_stack[loop_stack_depth]) {
-           inst0--;
-           if (inst0->header.opcode == BRW_OPCODE_BREAK &&
-               inst0->bits3.if_else.jump_count == 0) {
-              inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
+        if (intel->gen < 6) {
+           /* patch all the BREAK/CONT instructions from last BGNLOOP */
+           while (inst0 > loop_stack[loop_stack_depth]) {
+              inst0--;
+              if (inst0->header.opcode == BRW_OPCODE_BREAK &&
+                  inst0->bits3.if_else.jump_count == 0) {
+                 inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
            }
-           else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-                    inst0->bits3.if_else.jump_count == 0) {
-              inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
+              else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
+                       inst0->bits3.if_else.jump_count == 0) {
+                 inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
+              }
            }
         }
       }
@@ -3486,6 +3546,26 @@ fs_visitor::generate_code()
 
       last_native_inst = p->nr_insn;
    }
+
+   brw_set_uip_jip(p);
+
+   /* OK, while the INTEL_DEBUG=wm above is very nice for debugging FS
+    * emit issues, it doesn't get the jump distances into the output,
+    * which is often something we want to debug.  So this is here in
+    * case you're doing that.
+    */
+   if (0) {
+      if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+        for (unsigned int i = 0; i < p->nr_insn; i++) {
+           printf("0x%08x 0x%08x 0x%08x 0x%08x ",
+                  ((uint32_t *)&p->store[i])[3],
+                  ((uint32_t *)&p->store[i])[2],
+                  ((uint32_t *)&p->store[i])[1],
+                  ((uint32_t *)&p->store[i])[0]);
+           brw_disasm(stdout, &p->store[i], intel->gen);
+        }
+      }
+   }
 }
 
 GLboolean
index 3b7b03a05b80193557591d8589f8022b15dd2a85..20bfa4c3ea372ccd7f07aef72b07b852891c223b 100644 (file)
@@ -205,6 +205,8 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_round_even:
    case ir_unop_sin:
    case ir_unop_cos:
+   case ir_unop_sin_reduced:
+   case ir_unop_cos_reduced:
    case ir_unop_dFdx:
    case ir_unop_dFdy:
       for (i = 0; i < vector_elements; i++) {
@@ -328,6 +330,9 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_noise:
       assert(!"noise should have been broken down to function call");
       break;
+   case ir_quadop_vector:
+      assert(!"should have been lowered");
+      break;
    }
 
    ir->remove();
index b0c76f4094d9cbba1cc10a74f6f1400057e7ed53..73b41fdbcef703c390f4ac0a07ef085b63ccad6b 100644 (file)
@@ -166,6 +166,9 @@ static void populate_key( struct brw_context *brw,
                          struct brw_gs_prog_key *key )
 {
    struct gl_context *ctx = &brw->intel.ctx;
+   struct intel_context *intel = &brw->intel;
+   int prim_gs_always;
+
    memset(key, 0, sizeof(*key));
 
    /* CACHE_NEW_VS_PROG */
@@ -185,10 +188,14 @@ static void populate_key( struct brw_context *brw,
       key->pv_first = GL_TRUE;
    }
 
-   key->need_gs_prog = (key->hint_gs_always ||
-                       brw->primitive == GL_QUADS ||
+   if (intel->gen == 6)
+       prim_gs_always = brw->primitive == GL_LINE_LOOP;
+   else
+       prim_gs_always = brw->primitive == GL_QUADS ||
                        brw->primitive == GL_QUAD_STRIP ||
-                       brw->primitive == GL_LINE_LOOP);
+                       brw->primitive == GL_LINE_LOOP;
+
+   key->need_gs_prog = (key->hint_gs_always || prim_gs_always);
 }
 
 /* Calculate interpolants for triangle and line rasterization.
@@ -205,8 +212,10 @@ static void prepare_gs_prog(struct brw_context *brw)
       brw->gs.prog_active = key.need_gs_prog;
    }
 
+   drm_intel_bo_unreference(brw->gs.prog_bo);
+   brw->gs.prog_bo = NULL;
+
    if (brw->gs.prog_active) {
-      drm_intel_bo_unreference(brw->gs.prog_bo);
       brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG,
                                         &key, sizeof(key),
                                         NULL, 0,
index 1d350bc04138d97a13f9179fc4befe6d1e478fac..a91b0528fac61394f51b5727ce26fd39a55f2fab 100644 (file)
 #include "brw_state.h"
 #include "brw_defines.h"
 
-
-
-
-
-/***********************************************************************
- * Blend color
- */
-
-static void upload_blend_constant_color(struct brw_context *brw)
-{
-   struct gl_context *ctx = &brw->intel.ctx;
-   struct brw_blend_constant_color bcc;
-
-   memset(&bcc, 0, sizeof(bcc));      
-   bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
-   bcc.header.length = sizeof(bcc)/4-2;
-   bcc.blend_constant_color[0] = ctx->Color.BlendColor[0];
-   bcc.blend_constant_color[1] = ctx->Color.BlendColor[1];
-   bcc.blend_constant_color[2] = ctx->Color.BlendColor[2];
-   bcc.blend_constant_color[3] = ctx->Color.BlendColor[3];
-
-   BRW_CACHED_BATCH_STRUCT(brw, &bcc);
-}
-
-
-const struct brw_tracked_state brw_blend_constant_color = {
-   .dirty = {
-      .mesa = _NEW_COLOR,
-      .brw = BRW_NEW_CONTEXT,
-      .cache = 0
-   },
-   .emit = upload_blend_constant_color
-};
-
 /* Constant single cliprect for framebuffer object or DRI2 drawing */
 static void upload_drawing_rect(struct brw_context *brw)
 {
@@ -339,6 +305,9 @@ static void upload_polygon_stipple(struct brw_context *brw)
    struct brw_polygon_stipple bps;
    GLuint i;
 
+   if (!ctx->Polygon.StippleFlag)
+      return;
+
    memset(&bps, 0, sizeof(bps));
    bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
    bps.header.length = sizeof(bps)/4-2;
@@ -381,6 +350,9 @@ static void upload_polygon_stipple_offset(struct brw_context *brw)
    struct gl_context *ctx = &brw->intel.ctx;
    struct brw_polygon_stipple_offset bpso;
 
+   if (!ctx->Polygon.StippleFlag)
+      return;
+
    memset(&bpso, 0, sizeof(bpso));
    bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
    bpso.header.length = sizeof(bpso)/4-2;
@@ -409,7 +381,7 @@ static void upload_polygon_stipple_offset(struct brw_context *brw)
 
 const struct brw_tracked_state brw_polygon_stipple_offset = {
    .dirty = {
-      .mesa = _NEW_WINDOW_POS,
+      .mesa = _NEW_WINDOW_POS | _NEW_POLYGONSTIPPLE,
       .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
@@ -421,9 +393,10 @@ const struct brw_tracked_state brw_polygon_stipple_offset = {
  */
 static void upload_aa_line_parameters(struct brw_context *brw)
 {
+   struct gl_context *ctx = &brw->intel.ctx;
    struct brw_aa_line_parameters balp;
 
-   if (!brw->has_aa_line_parameters)
+   if (!ctx->Line.SmoothFlag || !brw->has_aa_line_parameters)
       return;
 
    /* use legacy aa line coverage computation */
@@ -436,7 +409,7 @@ static void upload_aa_line_parameters(struct brw_context *brw)
 
 const struct brw_tracked_state brw_aa_line_parameters = {
    .dirty = {
-      .mesa = 0,
+      .mesa = _NEW_LINE,
       .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
@@ -454,6 +427,9 @@ static void upload_line_stipple(struct brw_context *brw)
    GLfloat tmp;
    GLint tmpi;
 
+   if (!ctx->Line.StippleFlag)
+      return;
+
    memset(&bls, 0, sizeof(bls));
    bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
    bls.header.length = sizeof(bls)/4 - 2;
index 1367d8146968ff0e72a12c055840fd21e9d7011b..94efa79109187bb5a8ff77e1a0717145111cc0e4 100644 (file)
@@ -142,7 +142,6 @@ static GLboolean brwProgramStringNotify( struct gl_context *ctx,
       if (newFP == curFP)
         brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
       newFP->id = brw->program_id++;      
-      newFP->isGLSL = brw_wm_is_glsl(fprog);
 
       /* Don't reject fragment shaders for their Mesa IR state when we're
        * using the new FS backend.
index 338f3876b31bdc6c1c77cf7ec9ffc60bee411a71..eba4411ca702a77e369cc80df47b7bd30260dfef 100644 (file)
@@ -129,7 +129,7 @@ const struct brw_tracked_state *gen6_atoms[] =
 
    &brw_vs_constants, /* Before vs_surfaces and constant_buffer */
    &brw_wm_constants, /* Before wm_surfaces and constant_buffer */
-   &gen6_wm_constants, /* Before wm_surfaces and constant_buffer */
+   &gen6_wm_constants, /* Before wm_state */
 
    &brw_vs_surfaces,           /* must do before unit */
    &brw_wm_constant_surface,   /* must do before wm surfaces/bind bo */
index 8ce9af9c4fed79a43d7b7e75e98551d926ed2ddf..461f27048cc1b7e39a9d0d6fbef73b2b04ca15da 100644 (file)
@@ -1064,6 +1064,15 @@ struct brw_sampler_default_color {
    GLfloat color[4];
 };
 
+struct gen5_sampler_default_color {
+   uint8_t ub[4];
+   float f[4];
+   uint16_t hf[4];
+   uint16_t us[4];
+   int16_t s[4];
+   uint8_t b[4];
+};
+
 struct brw_sampler_state
 {
    
@@ -1169,7 +1178,12 @@ struct brw_surface_state
       GLuint cube_neg_y:1; 
       GLuint cube_pos_x:1; 
       GLuint cube_neg_x:1; 
-      GLuint pad:4;
+      GLuint pad:2;
+      /* Required on gen6 for surfaces accessed through render cache messages.
+       */
+      GLuint render_cache_read_write:1;
+      /* Ironlake and newer: instead of replicating one of the texels */
+      GLuint cube_corner_average:1;
       GLuint mipmap_layout_mode:1; 
       GLuint vert_line_stride_ofs:1; 
       GLuint vert_line_stride:1; 
@@ -1539,6 +1553,21 @@ struct brw_instruction
         GLuint  pad0:12;
       } if_else;
 
+      struct
+      {
+        /* Signed jump distance to the ip to jump to if all channels
+         * are disabled after the break or continue.  It should point
+         * to the end of the innermost control flow block, as that's
+         * where some channel could get re-enabled.
+         */
+        int jip:16;
+
+        /* Signed jump distance to the location to resume execution
+         * of this channel if it's enabled for the break or continue.
+         */
+        int uip:16;
+      } break_cont;
+
       struct {
         GLuint function:4;
         GLuint int_type:1;
index 4a41c7a517629f03f17479a18d218c2d1a3b31f3..6ae75d22c149e6dc2e92c3afe3ef0fa9c1cc34ff 100644 (file)
@@ -99,8 +99,8 @@ static void do_vs_prog( struct brw_context *brw,
    (void) ctx;
 
    aux_size = sizeof(c.prog_data);
-   if (c.vp->use_const_buffer)
-      aux_size += c.vp->program.Base.Parameters->NumParameters;
+   /* constant_map */
+   aux_size += c.vp->program.Base.Parameters->NumParameters;
 
    drm_intel_bo_unreference(brw->vs.prog_bo);
    brw->vs.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_VS_PROG,
@@ -130,6 +130,7 @@ static void brw_upload_vs_prog(struct brw_context *brw)
    key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled);
    key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL ||
                        ctx->Polygon.BackMode != GL_FILL);
+   key.two_side_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
 
    /* _NEW_POINT */
    if (ctx->Point.PointSprite) {
@@ -157,7 +158,7 @@ static void brw_upload_vs_prog(struct brw_context *brw)
  */
 const struct brw_tracked_state brw_vs_prog = {
    .dirty = {
-      .mesa  = _NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT,
+      .mesa  = _NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT | _NEW_LIGHT,
       .brw   = BRW_NEW_VERTEX_PROGRAM,
       .cache = 0
    },
index 9338a6b7dbfe988fbe26e4baf61e2aae2c762bd7..0b88cc1ec76453fb512243f75941c7edc12182b4 100644 (file)
@@ -44,6 +44,7 @@ struct brw_vs_prog_key {
    GLuint nr_userclip:4;
    GLuint copy_edgeflag:1;
    GLuint point_coord_replace:8;
+   GLuint two_side_color: 1;
 };
 
 
index 7e43324a1f9c8e7b707d12b872682664f44d7a0f..09887dae95d5ad426941feded4824002cad07c02 100644 (file)
@@ -140,9 +140,13 @@ clear_current_const(struct brw_vs_compile *c)
 static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 {
    struct intel_context *intel = &c->func.brw->intel;
-   GLuint i, reg = 0, mrf;
+   GLuint i, reg = 0, mrf, j;
    int attributes_in_vue;
    int first_reladdr_output;
+   int max_constant;
+   int constant = 0;
+   int vert_result_reoder[VERT_RESULT_MAX];
+   int bfc = 0;
 
    /* Determine whether to use a real constant buffer or use a block
     * of GRF registers for constants.  The later is faster but only
@@ -181,62 +185,81 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 
    }
 
-   /* Vertex program parameters from curbe:
+   /* Assign some (probably all) of the vertex program constants to
+    * the push constant buffer/CURBE.
+    *
+    * There's an obvious limit to the numer of push constants equal to
+    * the number of register available, and that number is smaller
+    * than the minimum maximum number of vertex program parameters, so
+    * support for pull constants is required if we overflow.
+    * Additionally, on gen6 the number of push constants is even
+    * lower.
+    *
+    * When there's relative addressing, we don't know what range of
+    * Mesa IR registers can be accessed.  And generally, when relative
+    * addressing is used we also have too many constants to load them
+    * all as push constants.  So, we'll just support relative
+    * addressing out of the pull constant buffers, and try to load as
+    * many statically-accessed constants into the push constant buffer
+    * as we can.
     */
-   if (c->vp->use_const_buffer) {
-      int max_constant = BRW_MAX_GRF - 20 - c->vp->program.Base.NumTemporaries;
-      int constant = 0;
-
-      /* We've got more constants than we can load with the push
-       * mechanism.  This is often correlated with reladdr loads where
-       * we should probably be using a pull mechanism anyway to avoid
-       * excessive reading.  However, the pull mechanism is slow in
-       * general.  So, we try to allocate as many non-reladdr-loaded
-       * constants through the push buffer as we can before giving up.
-       */
-      memset(c->constant_map, -1, c->vp->program.Base.Parameters->NumParameters);
-      for (i = 0;
-          i < c->vp->program.Base.NumInstructions && constant < max_constant;
-          i++) {
-        struct prog_instruction *inst = &c->vp->program.Base.Instructions[i];
-        int arg;
-
-        for (arg = 0; arg < 3 && constant < max_constant; arg++) {
-           if ((inst->SrcReg[arg].File != PROGRAM_STATE_VAR &&
-                inst->SrcReg[arg].File != PROGRAM_CONSTANT &&
-                inst->SrcReg[arg].File != PROGRAM_UNIFORM &&
-                inst->SrcReg[arg].File != PROGRAM_ENV_PARAM &&
-                inst->SrcReg[arg].File != PROGRAM_LOCAL_PARAM) ||
-               inst->SrcReg[arg].RelAddr)
-              continue;
-
-           if (c->constant_map[inst->SrcReg[arg].Index] == -1) {
-              c->constant_map[inst->SrcReg[arg].Index] = constant++;
-           }
+   if (intel->gen >= 6) {
+      /* We can only load 32 regs of push constants. */
+      max_constant = 32 * 2 - c->key.nr_userclip;
+   } else {
+      max_constant = BRW_MAX_GRF - 20 - c->vp->program.Base.NumTemporaries;
+   }
+
+   /* constant_map maps from ParameterValues[] index to index in the
+    * push constant buffer, or -1 if it's only in the pull constant
+    * buffer.
+    */
+   memset(c->constant_map, -1, c->vp->program.Base.Parameters->NumParameters);
+   for (i = 0;
+       i < c->vp->program.Base.NumInstructions && constant < max_constant;
+       i++) {
+      struct prog_instruction *inst = &c->vp->program.Base.Instructions[i];
+      int arg;
+
+      for (arg = 0; arg < 3 && constant < max_constant; arg++) {
+        if (inst->SrcReg[arg].File != PROGRAM_STATE_VAR &&
+            inst->SrcReg[arg].File != PROGRAM_CONSTANT &&
+            inst->SrcReg[arg].File != PROGRAM_UNIFORM &&
+            inst->SrcReg[arg].File != PROGRAM_ENV_PARAM &&
+            inst->SrcReg[arg].File != PROGRAM_LOCAL_PARAM) {
+           continue;
         }
-      }
 
-      for (i = 0; i < constant; i++) {
-         c->regs[PROGRAM_STATE_VAR][i] = stride( brw_vec4_grf(reg+i/2,
-                                                             (i%2) * 4),
-                                                0, 4, 1);
+        if (inst->SrcReg[arg].RelAddr) {
+           c->vp->use_const_buffer = GL_TRUE;
+           continue;
+        }
+
+        if (c->constant_map[inst->SrcReg[arg].Index] == -1) {
+           c->constant_map[inst->SrcReg[arg].Index] = constant++;
+        }
       }
-      reg += (constant + 1) / 2;
-      c->prog_data.curb_read_length = reg - 1;
-      /* XXX 0 causes a bug elsewhere... */
-      c->prog_data.nr_params = MAX2(constant * 4, 4);
    }
-   else {
-      /* use a section of the GRF for constants */
-      GLuint nr_params = c->vp->program.Base.Parameters->NumParameters;
-      for (i = 0; i < nr_params; i++) {
-         c->regs[PROGRAM_STATE_VAR][i] = stride( brw_vec4_grf(reg+i/2, (i%2) * 4), 0, 4, 1);
-      }
-      reg += (nr_params + 1) / 2;
-      c->prog_data.curb_read_length = reg - 1;
 
-      c->prog_data.nr_params = nr_params * 4;
+   /* If we ran out of push constant space, then we'll also upload all
+    * constants through the pull constant buffer so that they can be
+    * accessed no matter what.  For relative addressing (the common
+    * case) we need them all in place anyway.
+    */
+   if (constant == max_constant)
+      c->vp->use_const_buffer = GL_TRUE;
+
+   for (i = 0; i < constant; i++) {
+      c->regs[PROGRAM_STATE_VAR][i] = stride(brw_vec4_grf(reg + i / 2,
+                                                         (i % 2) * 4),
+                                            0, 4, 1);
    }
+   reg += (constant + 1) / 2;
+   c->prog_data.curb_read_length = reg - 1;
+   c->prog_data.nr_params = constant * 4;
+   /* XXX 0 causes a bug elsewhere... */
+   if (intel->gen < 6 && c->prog_data.nr_params == 0)
+      c->prog_data.nr_params = 4;
 
    /* Allocate input regs:  
     */
@@ -270,7 +293,36 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
       mrf = 4;
 
    first_reladdr_output = get_first_reladdr_output(&c->vp->program);
-   for (i = 0; i < VERT_RESULT_MAX; i++) {
+
+   for (i = 0; i < VERT_RESULT_MAX; i++)
+       vert_result_reoder[i] = i;
+
+   /* adjust attribute order in VUE for BFC0/BFC1 on Gen6+ */
+   if (intel->gen >= 6 && c->key.two_side_color) {
+       if ((c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_COL1)) &&
+           (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC1))) {
+           assert(c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0));
+           assert(c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0));
+           bfc = 2;
+       } else if ((c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0)) &&
+           (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0)))
+           bfc = 1;
+
+       if (bfc) {
+           for (i = 0; i < bfc; i++) {
+               vert_result_reoder[VERT_RESULT_COL0 + i * 2 + 0] = VERT_RESULT_COL0 + i;
+               vert_result_reoder[VERT_RESULT_COL0 + i * 2 + 1] = VERT_RESULT_BFC0 + i;
+           }
+
+           for (i = VERT_RESULT_COL0 + bfc * 2; i < VERT_RESULT_BFC0 + bfc; i++) {
+               vert_result_reoder[i] = i - bfc;
+           }
+       }
+   }
+
+   for (j = 0; j < VERT_RESULT_MAX; j++) {
+      i = vert_result_reoder[j];
+
       if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
         c->nr_outputs++;
          assert(i < Elements(c->regs[PROGRAM_OUTPUT]));
@@ -281,7 +333,6 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
         else if (i == VERT_RESULT_PSIZ) {
            c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
            reg++;
-           mrf++;              /* just a placeholder?  XXX fix later stages & remove this */
         }
         else {
            /* Two restrictions on our compute-to-MRF here.  The
@@ -574,9 +625,18 @@ static void emit_max( struct brw_compile *p,
                      struct brw_reg arg0,
                      struct brw_reg arg1 )
 {
-   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-   brw_SEL(p, dst, arg0, arg1);
-   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   struct intel_context *intel = &p->brw->intel;
+
+   if (intel->gen >= 6) {
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
+      brw_SEL(p, dst, arg0, arg1);
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   } else {
+      brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
+      brw_SEL(p, dst, arg0, arg1);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   }
 }
 
 static void emit_min( struct brw_compile *p, 
@@ -584,9 +644,18 @@ static void emit_min( struct brw_compile *p,
                      struct brw_reg arg0,
                      struct brw_reg arg1 )
 {
-   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
-   brw_SEL(p, dst, arg0, arg1);
-   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   struct intel_context *intel = &p->brw->intel;
+
+   if (intel->gen >= 6) {
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
+      brw_SEL(p, dst, arg0, arg1);
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   } else {
+      brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
+      brw_SEL(p, dst, arg0, arg1);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   }
 }
 
 static void emit_math1_gen4(struct brw_vs_compile *c,
@@ -680,7 +749,7 @@ emit_math1(struct brw_vs_compile *c,
       emit_math1_gen4(c, function, dst, arg0, precision);
 }
 
-static void emit_math2( struct brw_vs_compile *c, 
+static void emit_math2_gen4( struct brw_vs_compile *c, 
                        GLuint function,
                        struct brw_reg dst,
                        struct brw_reg arg0,
@@ -688,14 +757,11 @@ static void emit_math2( struct brw_vs_compile *c,
                        GLuint precision)
 {
    struct brw_compile *p = &c->func;
-   struct intel_context *intel = &p->brw->intel;
    struct brw_reg tmp = dst;
    GLboolean need_tmp = GL_FALSE;
 
-   if (dst.file != BRW_GENERAL_REGISTER_FILE)
-      need_tmp = GL_TRUE;
-
-   if (intel->gen < 6 && dst.dw1.bits.writemask != 0xf)
+   if (dst.file != BRW_GENERAL_REGISTER_FILE ||
+       dst.dw1.bits.writemask != 0xf)
       need_tmp = GL_TRUE;
 
    if (need_tmp) 
@@ -718,6 +784,53 @@ static void emit_math2( struct brw_vs_compile *c,
    }
 }
 
+static void emit_math2_gen6( struct brw_vs_compile *c, 
+                       GLuint function,
+                       struct brw_reg dst,
+                       struct brw_reg arg0,
+                       struct brw_reg arg1,
+                       GLuint precision)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp_src0, tmp_src1, tmp_dst;
+
+   tmp_src0 = get_tmp(c);
+   tmp_src1 = get_tmp(c);
+   tmp_dst = get_tmp(c);
+
+   brw_MOV(p, tmp_src0, arg0);
+   brw_MOV(p, tmp_src1, arg1);
+   
+   brw_set_access_mode(p, BRW_ALIGN_1);
+   brw_math2(p,
+           tmp_dst,
+           function,
+           tmp_src0,
+           tmp_src1);
+   brw_set_access_mode(p, BRW_ALIGN_16);
+
+   brw_MOV(p, dst, tmp_dst);
+
+   release_tmp(c, tmp_src0);
+   release_tmp(c, tmp_src1);
+   release_tmp(c, tmp_dst);
+}
+
+static void emit_math2( struct brw_vs_compile *c, 
+                       GLuint function,
+                       struct brw_reg dst,
+                       struct brw_reg arg0,
+                       struct brw_reg arg1,
+                       GLuint precision)
+{
+   struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
+
+   if (intel->gen >= 6)
+      emit_math2_gen6(c, function, dst, arg0, arg1, precision);
+   else
+      emit_math2_gen4(c, function, dst, arg0, arg1, precision);
+}
 
 static void emit_exp_noalias( struct brw_vs_compile *c,
                              struct brw_reg dst,
@@ -990,8 +1103,6 @@ get_constant(struct brw_vs_compile *c,
 
    assert(argIndex < 3);
 
-   assert(c->func.brw->intel.gen < 6); /* FINISHME */
-
    if (c->current_const[argIndex].index != src->Index) {
       /* Keep track of the last constant loaded in this slot, for reuse. */
       c->current_const[argIndex].index = src->Index;
@@ -1022,14 +1133,14 @@ get_reladdr_constant(struct brw_vs_compile *c,
 {
    const struct prog_src_register *src = &inst->SrcReg[argIndex];
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
+   struct intel_context *intel = &brw->intel;
    struct brw_reg const_reg = c->current_const[argIndex].reg;
-   struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
-   struct brw_reg byte_addr_reg = retype(get_tmp(c), BRW_REGISTER_TYPE_D);
+   struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0];
+   uint32_t offset;
 
    assert(argIndex < 3);
 
-   assert(c->func.brw->intel.gen < 6); /* FINISHME */
-
    /* Can't reuse a reladdr constant load. */
    c->current_const[argIndex].index = -1;
 
@@ -1038,15 +1149,21 @@ get_reladdr_constant(struct brw_vs_compile *c,
          src->Index, argIndex, c->current_const[argIndex].reg.nr);
 #endif
 
-   brw_MUL(p, byte_addr_reg, addrReg, brw_imm_ud(16));
+   if (intel->gen >= 6) {
+      offset = src->Index;
+   } else {
+      struct brw_reg byte_addr_reg = retype(get_tmp(c), BRW_REGISTER_TYPE_D);
+      brw_MUL(p, byte_addr_reg, addr_reg, brw_imm_d(16));
+      addr_reg = byte_addr_reg;
+      offset = 16 * src->Index;
+   }
 
    /* fetch the first vec4 */
    brw_dp_READ_4_vs_relative(p,
-                            const_reg,                     /* writeback dest */
-                            byte_addr_reg,                 /* address register */
-                            16 * src->Index,               /* byte offset */
-                            SURF_INDEX_VERT_CONST_BUFFER   /* binding table index */
-                            );
+                            const_reg,
+                            addr_reg,
+                            offset,
+                            SURF_INDEX_VERT_CONST_BUFFER);
 
    return const_reg;
 }
@@ -1241,22 +1358,18 @@ get_src_reg( struct brw_vs_compile *c,
    case PROGRAM_UNIFORM:
    case PROGRAM_ENV_PARAM:
    case PROGRAM_LOCAL_PARAM:
-      if (c->vp->use_const_buffer) {
-        if (!relAddr && c->constant_map[index] != -1) {
-           assert(c->regs[PROGRAM_STATE_VAR][c->constant_map[index]].nr != 0);
-           return c->regs[PROGRAM_STATE_VAR][c->constant_map[index]];
-        } else if (relAddr)
+      if (!relAddr && c->constant_map[index] != -1) {
+        /* Take from the push constant buffer if possible. */
+        assert(c->regs[PROGRAM_STATE_VAR][c->constant_map[index]].nr != 0);
+        return c->regs[PROGRAM_STATE_VAR][c->constant_map[index]];
+      } else {
+        /* Must be in the pull constant buffer then .*/
+        assert(c->vp->use_const_buffer);
+        if (relAddr)
            return get_reladdr_constant(c, inst, argIndex);
         else
            return get_constant(c, inst, argIndex);
       }
-      else if (relAddr) {
-         return deref(c, c->regs[PROGRAM_STATE_VAR][0], index, 16);
-      }
-      else {
-         assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
-         return c->regs[PROGRAM_STATE_VAR][index];
-      }
    case PROGRAM_ADDRESS:
       assert(index == 0);
       return c->regs[file][index];
@@ -1585,6 +1698,8 @@ static void emit_vertex_write( struct brw_vs_compile *c)
         break;
       if (!(c->prog_data.outputs_written & BITFIELD64_BIT(i)))
         continue;
+      if (i == VERT_RESULT_PSIZ)
+        continue;
 
       if (i >= VERT_RESULT_TEX0 &&
          c->regs[PROGRAM_OUTPUT][i].file == BRW_GENERAL_REGISTER_FILE) {
@@ -1895,7 +2010,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
         emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL);
         break;
       case OPCODE_RSQ:
-        emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
+        emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, brw_abs(args[0]), BRW_MATH_PRECISION_FULL);
         break;
 
       case OPCODE_SEQ:
@@ -1969,35 +2084,42 @@ void brw_vs_emit(struct brw_vs_compile *c )
          break;
       case OPCODE_CONT:
         brw_set_predicate_control(p, get_predicate(inst));
-        brw_CONT(p, if_depth_in_loop[loop_depth]);
+        if (intel->gen >= 6) {
+           brw_CONT_gen6(p, loop_inst[loop_depth - 1]);
+        } else {
+           brw_CONT(p, if_depth_in_loop[loop_depth]);
+        }
          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
          break;
-      case OPCODE_ENDLOOP: 
-         {
-           clear_current_const(c);
-            struct brw_instruction *inst0, *inst1;
-           GLuint br = 1;
-
-            loop_depth--;
-
-           if (intel->gen == 5)
-              br = 2;
-
-            inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
-            /* patch all the BREAK/CONT instructions from last BEGINLOOP */
-            while (inst0 > loop_inst[loop_depth]) {
-               inst0--;
-               if (inst0->header.opcode == BRW_OPCODE_BREAK &&
+
+      case OPCODE_ENDLOOP: {
+        clear_current_const(c);
+        struct brw_instruction *inst0, *inst1;
+        GLuint br = 1;
+
+        loop_depth--;
+
+        if (intel->gen == 5)
+           br = 2;
+
+        inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
+
+        if (intel->gen < 6) {
+           /* patch all the BREAK/CONT instructions from last BEGINLOOP */
+           while (inst0 > loop_inst[loop_depth]) {
+              inst0--;
+              if (inst0->header.opcode == BRW_OPCODE_BREAK &&
                   inst0->bits3.if_else.jump_count == 0) {
-                  inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
-               }
-               else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-                       inst0->bits3.if_else.jump_count == 0) {
-                  inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
-               }
-            }
-         }
+                 inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
+              } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
+                         inst0->bits3.if_else.jump_count == 0) {
+                 inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
+              }
+           }
+        }
+      }
          break;
+
       case OPCODE_BRA:
         brw_set_predicate_control(p, get_predicate(inst));
          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
@@ -2088,6 +2210,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
    }
 
    brw_resolve_cals(p);
+   brw_set_uip_jip(p);
 
    brw_optimize(p);
 
index ccdc18e0b8df4d4bea18d3e93450edb8d019d95e..656501b4f79c33993bf7325ece53056be0c10595 100644 (file)
@@ -119,6 +119,62 @@ brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
    brw_wm_emit(c);
 }
 
+static void
+brw_wm_payload_setup(struct brw_context *brw,
+                    struct brw_wm_compile *c)
+{
+   struct intel_context *intel = &brw->intel;
+   bool uses_depth = (c->fp->program.Base.InputsRead &
+                     (1 << FRAG_ATTRIB_WPOS)) != 0;
+
+   if (intel->gen >= 6) {
+      /* R0-1: masks, pixel X/Y coordinates. */
+      c->nr_payload_regs = 2;
+      /* R2: only for 32-pixel dispatch.*/
+      /* R3-4: perspective pixel location barycentric */
+      c->nr_payload_regs += 2;
+      /* R5-6: perspective pixel location bary for dispatch width != 8 */
+      if (c->dispatch_width == 16) {
+        c->nr_payload_regs += 2;
+      }
+      /* R7-10: perspective centroid barycentric */
+      /* R11-14: perspective sample barycentric */
+      /* R15-18: linear pixel location barycentric */
+      /* R19-22: linear centroid barycentric */
+      /* R23-26: linear sample barycentric */
+
+      /* R27: interpolated depth if uses source depth */
+      if (uses_depth) {
+        c->source_depth_reg = c->nr_payload_regs;
+        c->nr_payload_regs++;
+        if (c->dispatch_width == 16) {
+           /* R28: interpolated depth if not 8-wide. */
+           c->nr_payload_regs++;
+        }
+      }
+      /* R29: interpolated W set if GEN6_WM_USES_SOURCE_W.
+       */
+      if (uses_depth) {
+        c->source_w_reg = c->nr_payload_regs;
+        c->nr_payload_regs++;
+        if (c->dispatch_width == 16) {
+           /* R30: interpolated W if not 8-wide. */
+           c->nr_payload_regs++;
+        }
+      }
+      /* R31: MSAA position offsets. */
+      /* R32-: bary for 32-pixel. */
+      /* R58-59: interp W for 32-pixel. */
+
+      if (c->fp->program.Base.OutputsWritten &
+         BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+        c->source_depth_to_render_target = GL_TRUE;
+        c->computes_depth = GL_TRUE;
+      }
+   } else {
+      brw_wm_lookup_iz(intel, c);
+   }
+}
 
 /**
  * All Mesa program -> GPU code generation goes through this function.
@@ -167,23 +223,18 @@ static void do_wm_prog( struct brw_context *brw,
 
    brw_init_compile(brw, &c->func);
 
-   /* temporary sanity check assertion */
-   ASSERT(fp->isGLSL == brw_wm_is_glsl(&c->fp->program));
+   brw_wm_payload_setup(brw, c);
 
    if (!brw_wm_fs_emit(brw, c)) {
       /*
        * Shader which use GLSL features such as flow control are handled
        * differently from "simple" shaders.
        */
-      if (fp->isGLSL) {
-        c->dispatch_width = 8;
-        brw_wm_glsl_emit(brw, c);
-      }
-      else {
-        c->dispatch_width = 16;
-        brw_wm_non_glsl_emit(brw, c);
-      }
+      c->dispatch_width = 16;
+      brw_wm_payload_setup(brw, c);
+      brw_wm_non_glsl_emit(brw, c);
    }
+   c->prog_data.dispatch_width = c->dispatch_width;
 
    /* Scratch space is used for register spilling */
    if (c->last_scratch) {
@@ -220,12 +271,10 @@ static void do_wm_prog( struct brw_context *brw,
 static void brw_wm_populate_key( struct brw_context *brw,
                                 struct brw_wm_prog_key *key )
 {
-   struct intel_context *intel = &brw->intel;
    struct gl_context *ctx = &brw->intel.ctx;
    /* BRW_NEW_FRAGMENT_PROGRAM */
    const struct brw_fragment_program *fp = 
       (struct brw_fragment_program *)brw->fragment_program;
-   GLboolean uses_depth = (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
    GLuint lookup = 0;
    GLuint line_aa;
    GLuint i;
@@ -285,57 +334,9 @@ static void brw_wm_populate_key( struct brw_context *brw,
       }
    }
 
-   if (intel->gen >= 6) {
-      /* R0-1: masks, pixel X/Y coordinates. */
-      key->nr_payload_regs = 2;
-      /* R2: only for 32-pixel dispatch.*/
-      /* R3-4: perspective pixel location barycentric */
-      key->nr_payload_regs += 2;
-      /* R5-6: perspective pixel location bary for dispatch width != 8 */
-      if (!fp->isGLSL) { /* dispatch_width != 8 */
-        key->nr_payload_regs += 2;
-      }
-      /* R7-10: perspective centroid barycentric */
-      /* R11-14: perspective sample barycentric */
-      /* R15-18: linear pixel location barycentric */
-      /* R19-22: linear centroid barycentric */
-      /* R23-26: linear sample barycentric */
-
-      /* R27: interpolated depth if uses source depth */
-      if (uses_depth) {
-        key->source_depth_reg = key->nr_payload_regs;
-        key->nr_payload_regs++;
-        if (!fp->isGLSL) { /* dispatch_width != 8 */
-           /* R28: interpolated depth if not 8-wide. */
-           key->nr_payload_regs++;
-        }
-      }
-      /* R29: interpolated W set if GEN6_WM_USES_SOURCE_W.
-       */
-      if (uses_depth) {
-        key->source_w_reg = key->nr_payload_regs;
-        key->nr_payload_regs++;
-        if (!fp->isGLSL) { /* dispatch_width != 8 */
-           /* R30: interpolated W if not 8-wide. */
-           key->nr_payload_regs++;
-        }
-      }
-      /* R31: MSAA position offsets. */
-      /* R32-: bary for 32-pixel. */
-      /* R58-59: interp W for 32-pixel. */
-
-      if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
-        key->source_depth_to_render_target = GL_TRUE;
-        key->computes_depth = GL_TRUE;
-      }
-
-   } else {
-      brw_wm_lookup_iz(intel,
-                      line_aa,
-                      lookup,
-                      uses_depth,
-                      key);
-   }
+   key->iz_lookup = lookup;
+   key->line_aa = line_aa;
+   key->stats_wm = brw->intel.stats_wm;
 
    /* BRW_NEW_WM_INPUT_DIMENSIONS */
    key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
@@ -377,6 +378,10 @@ static void brw_wm_populate_key( struct brw_context *brw,
               swizzles[2] = SWIZZLE_ZERO;
            } else if (t->DepthMode == GL_LUMINANCE) {
               swizzles[3] = SWIZZLE_ONE;
+           } else if (t->DepthMode == GL_RED) {
+              swizzles[1] = SWIZZLE_ZERO;
+              swizzles[2] = SWIZZLE_ZERO;
+              swizzles[3] = SWIZZLE_ZERO;
            }
         }
 
index 2ca685784fce8926023f4eb1dc560e60bf6e3873..e7f3cfbb75fab9abeaa868248425ed72f38b1ccc 100644 (file)
 #define AA_ALWAYS    2
 
 struct brw_wm_prog_key {
-   GLuint source_depth_reg:3;
-   GLuint source_w_reg:3;
-   GLuint aa_dest_stencil_reg:3;
-   GLuint dest_depth_reg:3;
-   GLuint nr_payload_regs:4;
-   GLuint computes_depth:1;    /* could be derived from program string */
-   GLuint source_depth_to_render_target:1;
+   GLuint stats_wm:1;
    GLuint flat_shade:1;
    GLuint linear_color:1;  /**< linear interpolation vs perspective interp */
-   GLuint runtime_check_aads_emit:1;
    GLuint nr_color_regions:5;
    GLuint render_to_fbo:1;
 
@@ -81,6 +74,8 @@ struct brw_wm_prog_key {
 
    GLushort drawable_height;
    GLbitfield64 vp_outputs_written;
+   GLuint iz_lookup;
+   GLuint line_aa;
    GLuint program_string_id:32;
 };
 
@@ -204,6 +199,15 @@ struct brw_wm_compile {
       PASS2_DONE
    } state;
 
+   GLuint source_depth_reg:3;
+   GLuint source_w_reg:3;
+   GLuint aa_dest_stencil_reg:3;
+   GLuint dest_depth_reg:3;
+   GLuint nr_payload_regs:4;
+   GLuint computes_depth:1;    /* could be derived from program string */
+   GLuint source_depth_to_render_target:1;
+   GLuint runtime_check_aads_emit:1;
+
    /* Initial pass - translate fp instructions to fp instructions,
     * simplifying and adding instructions for interpolation and
     * framebuffer writes.
@@ -306,14 +310,9 @@ void brw_wm_print_insn( struct brw_wm_compile *c,
 void brw_wm_print_program( struct brw_wm_compile *c,
                           const char *stage );
 
-void brw_wm_lookup_iz( struct intel_context *intel,
-                      GLuint line_aa,
-                      GLuint lookup,
-                      GLboolean ps_uses_depth,
-                      struct brw_wm_prog_key *key );
+void brw_wm_lookup_iz(struct intel_context *intel,
+                     struct brw_wm_compile *c);
 
-GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
-void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c);
 GLboolean brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c);
 
 /* brw_wm_emit.c */
@@ -381,7 +380,6 @@ void emit_fb_write(struct brw_wm_compile *c,
 void emit_frontfacing(struct brw_compile *p,
                      const struct brw_reg *dst,
                      GLuint mask);
-void emit_kil_nv(struct brw_wm_compile *c);
 void emit_linterp(struct brw_compile *p,
                  const struct brw_reg *dst,
                  GLuint mask,
index 96fecc97ee2bf1c03eae446d3b169336db7e3be8..a0e86034e1e2cd7d352f3b556b23322377b436d0 100644 (file)
@@ -896,10 +896,14 @@ void emit_math1(struct brw_wm_compile *c,
                      BRW_MATH_SATURATE_NONE);
    struct brw_reg src;
 
-   if (intel->gen >= 6 && (arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
-                          arg0[0].file != BRW_GENERAL_REGISTER_FILE)) {
+   if (intel->gen >= 6 && ((arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
+                           arg0[0].file != BRW_GENERAL_REGISTER_FILE) ||
+                          arg0[0].negate || arg0[0].abs)) {
       /* Gen6 math requires that source and dst horizontal stride be 1,
        * and that the argument be in the GRF.
+       *
+       * The hardware ignores source modifiers (negate and abs) on math
+       * instructions, so we also move to a temp to set those up.
        */
       src = dst[dst_chan];
       brw_MOV(p, src, arg0[0]);
@@ -1301,9 +1305,15 @@ static void emit_kil( struct brw_wm_compile *c,
                      struct brw_reg *arg0)
 {
    struct brw_compile *p = &c->func;
-   struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+   struct intel_context *intel = &p->brw->intel;
+   struct brw_reg pixelmask;
    GLuint i, j;
 
+   if (intel->gen >= 6)
+      pixelmask = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW);
+   else
+      pixelmask = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+
    for (i = 0; i < 4; i++) {
       /* Check if we've already done the comparison for this reg
        * -- common when someone does KIL TEMP.wwww.
@@ -1319,26 +1329,11 @@ static void emit_kil( struct brw_wm_compile *c,
       brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], brw_imm_f(0));   
       brw_set_predicate_control_flag_value(p, 0xff);
       brw_set_compression_control(p, BRW_COMPRESSION_NONE);
-      brw_AND(p, r0uw, brw_flag_reg(), r0uw);
+      brw_AND(p, pixelmask, brw_flag_reg(), pixelmask);
       brw_pop_insn_state(p);
    }
 }
 
-/* KIL_NV kills the pixels that are currently executing, not based on a test
- * of the arguments.
- */
-void emit_kil_nv( struct brw_wm_compile *c )
-{
-   struct brw_compile *p = &c->func;
-   struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
-
-   brw_push_insn_state(p);
-   brw_set_mask_control(p, BRW_MASK_DISABLE);
-   brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); /* IMASK */
-   brw_AND(p, r0uw, c->emit_mask_reg, r0uw);
-   brw_pop_insn_state(p);
-}
-
 static void fire_fb_write( struct brw_wm_compile *c,
                           GLuint base_reg,
                           GLuint nr,
@@ -1387,8 +1382,8 @@ static void emit_aa( struct brw_wm_compile *c,
                     GLuint reg )
 {
    struct brw_compile *p = &c->func;
-   GLuint comp = c->key.aa_dest_stencil_reg / 2;
-   GLuint off = c->key.aa_dest_stencil_reg % 2;
+   GLuint comp = c->aa_dest_stencil_reg / 2;
+   GLuint off = c->aa_dest_stencil_reg % 2;
    struct brw_reg aa = offset(arg1[comp], off);
 
    brw_push_insn_state(p);
@@ -1416,11 +1411,10 @@ void emit_fb_write(struct brw_wm_compile *c,
    struct intel_context *intel = &brw->intel;
    GLuint nr = 2;
    GLuint channel;
-   int base_reg; /* For gen6 fb write with no header, starting from color payload directly!. */
 
    /* Reserve a space for AA - may not be needed:
     */
-   if (c->key.aa_dest_stencil_reg)
+   if (c->aa_dest_stencil_reg)
       nr += 1;
 
    /* I don't really understand how this achieves the color interleave
@@ -1428,11 +1422,6 @@ void emit_fb_write(struct brw_wm_compile *c,
     */
    brw_push_insn_state(p);
 
-   if (intel->gen >= 6)
-       base_reg = nr;
-   else
-       base_reg = 0;
-
    for (channel = 0; channel < 4; channel++) {
       if (intel->gen >= 6) {
         /* gen6 SIMD16 single source DP write looks like:
@@ -1493,9 +1482,9 @@ void emit_fb_write(struct brw_wm_compile *c,
 
    brw_pop_insn_state(p);
 
-   if (c->key.source_depth_to_render_target)
+   if (c->source_depth_to_render_target)
    {
-      if (c->key.computes_depth) 
+      if (c->computes_depth)
         brw_MOV(p, brw_message_reg(nr), arg2[2]);
       else 
         brw_MOV(p, brw_message_reg(nr), arg1[1]); /* ? */
@@ -1503,10 +1492,10 @@ void emit_fb_write(struct brw_wm_compile *c,
       nr += 2;
    }
 
-   if (c->key.dest_depth_reg)
+   if (c->dest_depth_reg)
    {
-      GLuint comp = c->key.dest_depth_reg / 2;
-      GLuint off = c->key.dest_depth_reg % 2;
+      GLuint comp = c->dest_depth_reg / 2;
+      GLuint off = c->dest_depth_reg % 2;
 
       if (off != 0) {
          brw_push_insn_state(p);
@@ -1524,15 +1513,27 @@ void emit_fb_write(struct brw_wm_compile *c,
    }
 
    if (intel->gen >= 6) {
-      /* Subtract off the message header, since we send headerless. */
-      nr -= 2;
+      /* Load the message header.  There's no implied move from src0
+       * to the base mrf on gen6.
+       */
+      brw_push_insn_state(p);
+      brw_set_mask_control(p, BRW_MASK_DISABLE);
+      brw_MOV(p, brw_message_reg(0), brw_vec8_grf(0, 0));
+      brw_pop_insn_state(p);
+
+      if (target != 0) {
+        brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
+                                       0,
+                                       2), BRW_REGISTER_TYPE_UD),
+                brw_imm_ud(target));
+      }
    }
 
-   if (!c->key.runtime_check_aads_emit) {
-      if (c->key.aa_dest_stencil_reg)
+   if (!c->runtime_check_aads_emit) {
+      if (c->aa_dest_stencil_reg)
         emit_aa(c, arg1, 2);
 
-      fire_fb_write(c, base_reg, nr, target, eot);
+      fire_fb_write(c, 0, nr, target, eot);
    }
    else {
       struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
@@ -1897,10 +1898,6 @@ void brw_wm_emit( struct brw_wm_compile *c )
         emit_kil(c, args[0]);
         break;
 
-      case OPCODE_KIL_NV:
-        emit_kil_nv(c);
-        break;
-
       default:
         printf("Unsupported opcode %i (%s) in fragment shader\n",
                inst->opcode, inst->opcode < MAX_OPCODE ?
index 2cae6988804efaf29b078afed4953d342d0ca69e..4759b289a0c87496cadda4b41da83fc0328c6edd 100644 (file)
@@ -338,11 +338,13 @@ static struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
 
 static struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
 {
-   /* This is only called for producing 1/w in pre-gen6 interp.  for
-    * gen6, the interp opcodes don't use this argument.
+   /* This is called for producing 1/w in pre-gen6 interp.  for gen6,
+    * the interp opcodes don't use this argument.  But to keep the
+    * nr_args = 3 expectations of pinterp happy, just stuff delta_xy
+    * into the slot.
     */
    if (c->func.brw->intel.gen >= 6)
-      return src_undef();
+      return c->delta_xy;
 
    if (src_is_undef(c->pixel_w)) {
       struct prog_dst_register pixel_w = get_temp(c);
@@ -373,11 +375,7 @@ static void emit_interp( struct brw_wm_compile *c,
    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
    struct prog_src_register deltas;
 
-   if (c->func.brw->intel.gen < 6) {
-      deltas = get_delta_xy(c);
-   } else {
-      deltas = src_undef();
-   }
+   deltas = get_delta_xy(c);
 
    /* Need to use PINTERP on attributes which have been
     * multiplied by 1/W in the SF program, and LINTERP on those
@@ -1133,6 +1131,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
         precalc_lit(c, inst);
         break;
 
+      case OPCODE_RSQ:
+        out = emit_scalar_insn(c, inst);
+        out->SrcReg[0].Abs = GL_TRUE;
+        break;
+
       case OPCODE_TEX:
         precalc_tex(c, inst);
         break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
deleted file mode 100644 (file)
index 7fe8ab1..0000000
+++ /dev/null
@@ -1,1035 +0,0 @@
-#include "main/macros.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "program/prog_optimize.h"
-#include "brw_context.h"
-#include "brw_eu.h"
-#include "brw_wm.h"
-
-static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
-                                  const struct prog_instruction *inst,
-                                  GLuint component);
-
-/**
- * Determine if the given fragment program uses GLSL features such
- * as flow conditionals, loops, subroutines.
- * Some GLSL shaders may use these features, others might not.
- */
-GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
-{
-    int i;
-
-    if (unlikely(INTEL_DEBUG & DEBUG_GLSL_FORCE))
-       return GL_TRUE;
-
-    for (i = 0; i < fp->Base.NumInstructions; i++) {
-       const struct prog_instruction *inst = &fp->Base.Instructions[i];
-       switch (inst->Opcode) {
-           case OPCODE_ARL:
-           case OPCODE_IF:
-           case OPCODE_ENDIF:
-           case OPCODE_CAL:
-           case OPCODE_BRK:
-           case OPCODE_RET:
-           case OPCODE_BGNLOOP:
-               return GL_TRUE; 
-           default:
-               break;
-       }
-    }
-    return GL_FALSE; 
-}
-
-
-
-static void
-reclaim_temps(struct brw_wm_compile *c);
-
-
-/** Mark GRF register as used. */
-static void
-prealloc_grf(struct brw_wm_compile *c, int r)
-{
-   c->used_grf[r] = GL_TRUE;
-}
-
-
-/** Mark given GRF register as not in use. */
-static void
-release_grf(struct brw_wm_compile *c, int r)
-{
-   /*assert(c->used_grf[r]);*/
-   c->used_grf[r] = GL_FALSE;
-   c->first_free_grf = MIN2(c->first_free_grf, r);
-}
-
-
-/** Return index of a free GRF, mark it as used. */
-static int
-alloc_grf(struct brw_wm_compile *c)
-{
-   GLuint r;
-   for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) {
-      if (!c->used_grf[r]) {
-         c->used_grf[r] = GL_TRUE;
-         c->first_free_grf = r + 1;  /* a guess */
-         return r;
-      }
-   }
-
-   /* no free temps, try to reclaim some */
-   reclaim_temps(c);
-   c->first_free_grf = 0;
-
-   /* try alloc again */
-   for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) {
-      if (!c->used_grf[r]) {
-         c->used_grf[r] = GL_TRUE;
-         c->first_free_grf = r + 1;  /* a guess */
-         return r;
-      }
-   }
-
-   for (r = 0; r < BRW_WM_MAX_GRF; r++) {
-      assert(c->used_grf[r]);
-   }
-
-   /* really, no free GRF regs found */
-   if (!c->out_of_regs) {
-      /* print warning once per compilation */
-      _mesa_warning(NULL, "i965: ran out of registers for fragment program");
-      c->out_of_regs = GL_TRUE;
-   }
-
-   return -1;
-}
-
-
-/** Return number of GRF registers used */
-static int
-num_grf_used(const struct brw_wm_compile *c)
-{
-   int r;
-   for (r = BRW_WM_MAX_GRF - 1; r >= 0; r--)
-      if (c->used_grf[r])
-         return r + 1;
-   return 0;
-}
-
-
-
-/**
- * Record the mapping of a Mesa register to a hardware register.
- */
-static void set_reg(struct brw_wm_compile *c, int file, int index, 
-       int component, struct brw_reg reg)
-{
-    c->wm_regs[file][index][component].reg = reg;
-    c->wm_regs[file][index][component].inited = GL_TRUE;
-}
-
-static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
-{
-    struct brw_reg reg;
-
-    /* if we need to allocate another temp, grow the tmp_regs[] array */
-    if (c->tmp_index == c->tmp_max) {
-       int r = alloc_grf(c);
-       if (r < 0) {
-          /*printf("Out of temps in %s\n", __FUNCTION__);*/
-          r = 50; /* XXX random register! */
-       }
-       c->tmp_regs[ c->tmp_max++ ] = r;
-    }
-
-    /* form the GRF register */
-    reg = brw_vec8_grf(c->tmp_regs[ c->tmp_index++ ], 0);
-    /*printf("alloc_temp %d\n", reg.nr);*/
-    assert(reg.nr < BRW_WM_MAX_GRF);
-    return reg;
-
-}
-
-/**
- * Save current temp register info.
- * There must be a matching call to release_tmps().
- */
-static int mark_tmps(struct brw_wm_compile *c)
-{
-    return c->tmp_index;
-}
-
-static void release_tmps(struct brw_wm_compile *c, int mark)
-{
-    c->tmp_index = mark;
-}
-
-/**
- * Convert Mesa src register to brw register.
- *
- * Since we're running in SOA mode each Mesa register corresponds to four
- * hardware registers.  We allocate the hardware registers as needed here.
- *
- * \param file  register file, one of PROGRAM_x
- * \param index  register number
- * \param component  src component (X=0, Y=1, Z=2, W=3)
- * \param nr  not used?!?
- * \param neg  negate value?
- * \param abs  take absolute value?
- */
-static struct brw_reg 
-get_reg(struct brw_wm_compile *c, int file, int index, int component,
-        int nr, GLuint neg, GLuint abs)
-{
-    struct brw_reg reg;
-    switch (file) {
-       case PROGRAM_STATE_VAR:
-       case PROGRAM_CONSTANT:
-       case PROGRAM_UNIFORM:
-           file = PROGRAM_STATE_VAR;
-           break;
-       case PROGRAM_UNDEFINED:
-           return brw_null_reg();      
-       case PROGRAM_TEMPORARY:
-       case PROGRAM_INPUT:
-       case PROGRAM_OUTPUT:
-       case PROGRAM_PAYLOAD:
-           break;
-       default:
-           _mesa_problem(NULL, "Unexpected file in get_reg()");
-           return brw_null_reg();
-    }
-
-    assert(index < 256);
-    assert(component < 4);
-
-    /* see if we've already allocated a HW register for this Mesa register */
-    if (c->wm_regs[file][index][component].inited) {
-       /* yes, re-use */
-       reg = c->wm_regs[file][index][component].reg;
-    }
-    else {
-       /* no, allocate new register */
-       int grf = alloc_grf(c);
-       /*printf("alloc grf %d for reg %d:%d.%d\n", grf, file, index, component);*/
-       if (grf < 0) {
-          /* totally out of temps */
-          grf = 51; /* XXX random register! */
-       }
-
-       reg = brw_vec8_grf(grf, 0);
-       /*printf("Alloc new grf %d for %d.%d\n", reg.nr, index, component);*/
-
-       set_reg(c, file, index, component, reg);
-    }
-
-    if (neg & (1 << component)) {
-       reg = negate(reg);
-    }
-    if (abs)
-       reg = brw_abs(reg);
-    return reg;
-}
-
-
-
-/**
- * This is called if we run out of GRF registers.  Examine the live intervals
- * of temp regs in the program and free those which won't be used again.
- */
-static void
-reclaim_temps(struct brw_wm_compile *c)
-{
-   GLint intBegin[MAX_PROGRAM_TEMPS];
-   GLint intEnd[MAX_PROGRAM_TEMPS];
-   int index;
-
-   /*printf("Reclaim temps:\n");*/
-
-   _mesa_find_temp_intervals(c->prog_instructions, c->nr_fp_insns,
-                             intBegin, intEnd);
-
-   for (index = 0; index < MAX_PROGRAM_TEMPS; index++) {
-      if (intEnd[index] != -1 && intEnd[index] < c->cur_inst) {
-         /* program temp[i] can be freed */
-         int component;
-         /*printf("  temp[%d] is dead\n", index);*/
-         for (component = 0; component < 4; component++) {
-            if (c->wm_regs[PROGRAM_TEMPORARY][index][component].inited) {
-               int r = c->wm_regs[PROGRAM_TEMPORARY][index][component].reg.nr;
-               release_grf(c, r);
-               /*
-               printf("  Reclaim temp %d, reg %d at inst %d\n",
-                      index, r, c->cur_inst);
-               */
-               c->wm_regs[PROGRAM_TEMPORARY][index][component].inited = GL_FALSE;
-            }
-         }
-      }
-   }
-}
-
-
-
-
-/**
- * Preallocate registers.  This sets up the Mesa to hardware register
- * mapping for certain registers, such as constants (uniforms/state vars)
- * and shader inputs.
- */
-static void prealloc_reg(struct brw_wm_compile *c)
-{
-    struct intel_context *intel = &c->func.brw->intel;
-    int i, j;
-    struct brw_reg reg;
-    int urb_read_length = 0;
-    GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
-    GLuint reg_index = 0;
-
-    memset(c->used_grf, GL_FALSE, sizeof(c->used_grf));
-    c->first_free_grf = 0;
-
-    for (i = 0; i < 4; i++) {
-       if (i < (c->key.nr_payload_regs + 1) / 2)
-            reg = brw_vec8_grf(i * 2, 0);
-        else
-            reg = brw_vec8_grf(0, 0);
-       set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
-    }
-    set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_W, 0,
-           brw_vec8_grf(c->key.source_w_reg, 0));
-    reg_index += c->key.nr_payload_regs;
-
-    /* constants */
-    {
-        const GLuint nr_params = c->fp->program.Base.Parameters->NumParameters;
-        const GLuint nr_temps = c->fp->program.Base.NumTemporaries;
-
-        /* use a real constant buffer, or just use a section of the GRF? */
-        /* XXX this heuristic may need adjustment... */
-        if ((nr_params + nr_temps) * 4 + reg_index > 80) {
-          for (i = 0; i < nr_params; i++) {
-             float *pv = c->fp->program.Base.Parameters->ParameterValues[i];
-             for (j = 0; j < 4; j++) {
-                c->prog_data.pull_param[c->prog_data.nr_pull_params] = &pv[j];
-                c->prog_data.nr_pull_params++;
-             }
-          }
-
-          c->prog_data.nr_params = 0;
-       }
-        /*printf("WM use_const_buffer = %d\n", c->fp->use_const_buffer);*/
-
-        if (!c->prog_data.nr_pull_params) {
-           const struct gl_program_parameter_list *plist = 
-              c->fp->program.Base.Parameters;
-           int index = 0;
-
-           /* number of float constants in CURBE */
-           c->prog_data.nr_params = 4 * nr_params;
-
-           /* loop over program constants (float[4]) */
-           for (i = 0; i < nr_params; i++) {
-              /* loop over XYZW channels */
-              for (j = 0; j < 4; j++, index++) {
-                 reg = brw_vec1_grf(reg_index + index / 8, index % 8);
-                 /* Save pointer to parameter/constant value.
-                  * Constants will be copied in prepare_constant_buffer()
-                  */
-                 c->prog_data.param[index] = &plist->ParameterValues[i][j];
-                 set_reg(c, PROGRAM_STATE_VAR, i, j, reg);
-              }
-           }
-           /* number of constant regs used (each reg is float[8]) */
-          c->nr_creg = ALIGN(nr_params, 2) / 2;
-          reg_index += c->nr_creg;
-        }
-    }
-
-    /* fragment shader inputs: One 2-reg pair of interpolation
-     * coefficients for each vec4 to be set up.
-     */
-    if (intel->gen >= 6) {
-       for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
-         if (!(c->fp->program.Base.InputsRead & BITFIELD64_BIT(i)))
-            continue;
-
-         reg = brw_vec8_grf(reg_index, 0);
-         for (j = 0; j < 4; j++) {
-            set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
-         }
-         reg_index += 2;
-       }
-       urb_read_length = reg_index;
-    } else {
-       for (i = 0; i < VERT_RESULT_MAX; i++) {
-         int fp_input;
-
-         if (i >= VERT_RESULT_VAR0)
-            fp_input = i - VERT_RESULT_VAR0 + FRAG_ATTRIB_VAR0;
-         else if (i <= VERT_RESULT_TEX7)
-            fp_input = i;
-         else
-            fp_input = -1;
-
-         if (fp_input >= 0 && inputs & (1 << fp_input)) {
-            urb_read_length = reg_index;
-            reg = brw_vec8_grf(reg_index, 0);
-            for (j = 0; j < 4; j++)
-               set_reg(c, PROGRAM_PAYLOAD, fp_input, j, reg);
-         }
-         if (c->key.vp_outputs_written & BITFIELD64_BIT(i)) {
-            reg_index += 2;
-         }
-       }
-    }
-
-    c->prog_data.first_curbe_grf = c->key.nr_payload_regs;
-    c->prog_data.urb_read_length = urb_read_length;
-    c->prog_data.curb_read_length = c->nr_creg;
-    c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
-    reg_index++;
-    c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
-    reg_index += 2;
-
-    /* mark GRF regs [0..reg_index-1] as in-use */
-    for (i = 0; i < reg_index; i++)
-       prealloc_grf(c, i);
-
-    /* Don't use GRF 126, 127.  Using them seems to lead to GPU lock-ups */
-    prealloc_grf(c, 126);
-    prealloc_grf(c, 127);
-
-    for (i = 0; i < c->nr_fp_insns; i++) {
-       const struct prog_instruction *inst = &c->prog_instructions[i];
-       struct brw_reg dst[4];
-
-       switch (inst->Opcode) {
-       case OPCODE_TEX:
-       case OPCODE_TXB:
-           /* Allocate the channels of texture results contiguously,
-            * since they are written out that way by the sampler unit.
-            */
-           for (j = 0; j < 4; j++) {
-               dst[j] = get_dst_reg(c, inst, j);
-               if (j != 0)
-                   assert(dst[j].nr == dst[j - 1].nr + 1);
-           }
-           break;
-       default:
-           break;
-       }
-    }
-
-    for (i = 0; i < c->nr_fp_insns; i++) {
-       const struct prog_instruction *inst = &c->prog_instructions[i];
-
-       switch (inst->Opcode) {
-       case WM_DELTAXY:
-           /* Allocate WM_DELTAXY destination on G45/GM45 to an
-            * even-numbered GRF if possible so that we can use the PLN
-            * instruction.
-            */
-           if (inst->DstReg.WriteMask == WRITEMASK_XY &&
-               !c->wm_regs[inst->DstReg.File][inst->DstReg.Index][0].inited &&
-               !c->wm_regs[inst->DstReg.File][inst->DstReg.Index][1].inited &&
-               (IS_G4X(intel->intelScreen->deviceID) || intel->gen == 5)) {
-               int grf;
-
-               for (grf = c->first_free_grf & ~1;
-                    grf < BRW_WM_MAX_GRF;
-                    grf += 2)
-               {
-                   if (!c->used_grf[grf] && !c->used_grf[grf + 1]) {
-                       c->used_grf[grf] = GL_TRUE;
-                       c->used_grf[grf + 1] = GL_TRUE;
-                       c->first_free_grf = grf + 2;  /* a guess */
-
-                       set_reg(c, inst->DstReg.File, inst->DstReg.Index, 0,
-                               brw_vec8_grf(grf, 0));
-                       set_reg(c, inst->DstReg.File, inst->DstReg.Index, 1,
-                               brw_vec8_grf(grf + 1, 0));
-                       break;
-                   }
-               }
-           }
-       default:
-           break;
-       }
-    }
-
-    /* An instruction may reference up to three constants.
-     * They'll be found in these registers.
-     * XXX alloc these on demand!
-     */
-    if (c->prog_data.nr_pull_params) {
-       for (i = 0; i < 3; i++) {
-          c->current_const[i].index = -1;
-          c->current_const[i].reg = brw_vec8_grf(alloc_grf(c), 0);
-       }
-    }
-#if 0
-    printf("USE CONST BUFFER? %d\n", c->fp->use_const_buffer);
-    printf("AFTER PRE_ALLOC, reg_index = %d\n", reg_index);
-#endif
-}
-
-
-/**
- * Check if any of the instruction's src registers are constants, uniforms,
- * or statevars.  If so, fetch any constants that we don't already have in
- * the three GRF slots.
- */
-static void fetch_constants(struct brw_wm_compile *c,
-                            const struct prog_instruction *inst)
-{
-   struct brw_compile *p = &c->func;
-   GLuint i;
-
-   /* loop over instruction src regs */
-   for (i = 0; i < 3; i++) {
-      const struct prog_src_register *src = &inst->SrcReg[i];
-      if (src->File == PROGRAM_STATE_VAR ||
-          src->File == PROGRAM_CONSTANT ||
-          src->File == PROGRAM_UNIFORM) {
-        c->current_const[i].index = src->Index;
-
-#if 0
-        printf("  fetch const[%d] for arg %d into reg %d\n",
-               src->Index, i, c->current_const[i].reg.nr);
-#endif
-
-        /* need to fetch the constant now */
-        brw_oword_block_read(p,
-                             c->current_const[i].reg,
-                             brw_message_reg(1),
-                             16 * src->Index,
-                             SURF_INDEX_FRAG_CONST_BUFFER);
-      }
-   }
-}
-
-
-/**
- * Convert Mesa dst register to brw register.
- */
-static struct brw_reg get_dst_reg(struct brw_wm_compile *c, 
-                                  const struct prog_instruction *inst,
-                                  GLuint component)
-{
-    const int nr = 1;
-    return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
-           0, 0);
-}
-
-
-static struct brw_reg
-get_src_reg_const(struct brw_wm_compile *c,
-                  const struct prog_instruction *inst,
-                  GLuint srcRegIndex, GLuint component)
-{
-   /* We should have already fetched the constant from the constant
-    * buffer in fetch_constants().  Now we just have to return a
-    * register description that extracts the needed component and
-    * smears it across all eight vector components.
-    */
-   const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
-   struct brw_reg const_reg;
-
-   assert(component < 4);
-   assert(srcRegIndex < 3);
-   assert(c->current_const[srcRegIndex].index != -1);
-   const_reg = c->current_const[srcRegIndex].reg;
-
-   /* extract desired float from the const_reg, and smear */
-   const_reg = stride(const_reg, 0, 1, 0);
-   const_reg.subnr = component * 4;
-
-   if (src->Negate & (1 << component))
-      const_reg = negate(const_reg);
-   if (src->Abs)
-      const_reg = brw_abs(const_reg);
-
-#if 0
-   printf("  form const[%d].%d for arg %d, reg %d\n",
-          c->current_const[srcRegIndex].index,
-          component,
-          srcRegIndex,
-          const_reg.nr);
-#endif
-
-   return const_reg;
-}
-
-
-/**
- * Convert Mesa src register to brw register.
- */
-static struct brw_reg get_src_reg(struct brw_wm_compile *c, 
-                                  const struct prog_instruction *inst,
-                                  GLuint srcRegIndex, GLuint channel)
-{
-    const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
-    const GLuint nr = 1;
-    const GLuint component = GET_SWZ(src->Swizzle, channel);
-
-    /* Only one immediate value can be used per native opcode, and it
-     * has be in the src1 slot, so not all Mesa instructions will get
-     * to take advantage of immediate constants.
-     */
-    if (brw_wm_arg_can_be_immediate(inst->Opcode, srcRegIndex)) {
-       const struct gl_program_parameter_list *params;
-
-       params = c->fp->program.Base.Parameters;
-
-       /* Extended swizzle terms */
-       if (component == SWIZZLE_ZERO) {
-         return brw_imm_f(0.0F);
-       } else if (component == SWIZZLE_ONE) {
-         if (src->Negate)
-            return brw_imm_f(-1.0F);
-         else
-            return brw_imm_f(1.0F);
-       }
-
-       if (src->File == PROGRAM_CONSTANT) {
-         float f = params->ParameterValues[src->Index][component];
-
-         if (src->Abs)
-            f = fabs(f);
-         if (src->Negate)
-            f = -f;
-
-         return brw_imm_f(f);
-       }
-    }
-
-    if (c->prog_data.nr_pull_params &&
-        (src->File == PROGRAM_STATE_VAR ||
-         src->File == PROGRAM_CONSTANT ||
-         src->File == PROGRAM_UNIFORM)) {
-       return get_src_reg_const(c, inst, srcRegIndex, component);
-    }
-    else {
-       /* other type of source register */
-       return get_reg(c, src->File, src->Index, component, nr, 
-                      src->Negate, src->Abs);
-    }
-}
-
-static void emit_arl(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg src0, addr_reg;
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    addr_reg = brw_uw8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
-                           BRW_ARF_ADDRESS, 0);
-    src0 = get_src_reg(c, inst, 0, 0); /* channel 0 */
-    brw_MOV(p, addr_reg, src0);
-    brw_set_saturate(p, 0);
-}
-
-static INLINE struct brw_reg high_words( struct brw_reg reg )
-{
-    return stride( suboffset( retype( reg, BRW_REGISTER_TYPE_W ), 1 ),
-                  0, 8, 2 );
-}
-
-static INLINE struct brw_reg low_words( struct brw_reg reg )
-{
-    return stride( retype( reg, BRW_REGISTER_TYPE_W ), 0, 8, 2 );
-}
-
-static INLINE struct brw_reg even_bytes( struct brw_reg reg )
-{
-    return stride( retype( reg, BRW_REGISTER_TYPE_B ), 0, 16, 2 );
-}
-
-static INLINE struct brw_reg odd_bytes( struct brw_reg reg )
-{
-    return stride( suboffset( retype( reg, BRW_REGISTER_TYPE_B ), 1 ),
-                  0, 16, 2 );
-}
-
-/**
- * Resolve subroutine calls after code emit is done.
- */
-static void post_wm_emit( struct brw_wm_compile *c )
-{
-    brw_resolve_cals(&c->func);
-}
-
-static void
-get_argument_regs(struct brw_wm_compile *c,
-                 const struct prog_instruction *inst,
-                 int index,
-                 struct brw_reg *dst,
-                 struct brw_reg *regs,
-                 int mask)
-{
-    struct brw_compile *p = &c->func;
-    int i, j;
-
-    for (i = 0; i < 4; i++) {
-       if (mask & (1 << i)) {
-           regs[i] = get_src_reg(c, inst, index, i);
-
-           /* Unalias destination registers from our sources. */
-           if (regs[i].file == BRW_GENERAL_REGISTER_FILE) {
-              for (j = 0; j < 4; j++) {
-                  if (memcmp(&regs[i], &dst[j], sizeof(regs[0])) == 0) {
-                      struct brw_reg tmp = alloc_tmp(c);
-                      brw_MOV(p, tmp, regs[i]);
-                      regs[i] = tmp;
-                      break;
-                  }
-              }
-           }
-       }
-    }
-}
-
-static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
-{
-   struct intel_context *intel = &brw->intel;
-#define MAX_IF_DEPTH 32
-#define MAX_LOOP_DEPTH 32
-    struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH];
-    int if_depth_in_loop[MAX_LOOP_DEPTH];
-    GLuint i, if_depth = 0, loop_depth = 0;
-    struct brw_compile *p = &c->func;
-    struct brw_indirect stack_index = brw_indirect(0, 0);
-
-    c->out_of_regs = GL_FALSE;
-
-    if_depth_in_loop[loop_depth] = 0;
-
-    prealloc_reg(c);
-    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
-    brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
-
-    if (intel->gen >= 6)
-       brw_set_acc_write_control(p, 1);
-
-    for (i = 0; i < c->nr_fp_insns; i++) {
-        const struct prog_instruction *inst = &c->prog_instructions[i];
-       int dst_flags;
-       struct brw_reg args[3][4], dst[4];
-       int j;
-       int mark = mark_tmps( c );
-
-        c->cur_inst = i;
-
-#if 0
-        printf("Inst %d: ", i);
-        _mesa_print_instruction(inst);
-#endif
-
-        /* fetch any constants that this instruction needs */
-        if (c->prog_data.nr_pull_params)
-           fetch_constants(c, inst);
-
-       if (inst->Opcode != OPCODE_ARL) {
-          for (j = 0; j < 4; j++) {
-             if (inst->DstReg.WriteMask & (1 << j))
-                dst[j] = get_dst_reg(c, inst, j);
-             else
-                dst[j] = brw_null_reg();
-          }
-       }
-       for (j = 0; j < brw_wm_nr_args(inst->Opcode); j++)
-           get_argument_regs(c, inst, j, dst, args[j], WRITEMASK_XYZW);
-
-       dst_flags = inst->DstReg.WriteMask;
-       if (inst->SaturateMode == SATURATE_ZERO_ONE)
-           dst_flags |= SATURATE;
-
-       if (inst->CondUpdate)
-           brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
-       else
-           brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
-
-       switch (inst->Opcode) {
-           case WM_PIXELXY:
-               emit_pixel_xy(c, dst, dst_flags);
-               break;
-           case WM_DELTAXY: 
-               emit_delta_xy(p, dst, dst_flags, args[0]);
-               break;
-           case WM_PIXELW:
-               emit_pixel_w(c, dst, dst_flags, args[0], args[1]);
-               break;  
-           case WM_LINTERP:
-               emit_linterp(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case WM_PINTERP:
-               emit_pinterp(p, dst, dst_flags, args[0], args[1], args[2]);
-               break;
-           case WM_CINTERP:
-               emit_cinterp(p, dst, dst_flags, args[0]);
-               break;
-           case WM_WPOSXY:
-               emit_wpos_xy(c, dst, dst_flags, args[0]);
-               break;
-           case WM_FB_WRITE:
-               emit_fb_write(c, args[0], args[1], args[2],
-                             INST_AUX_GET_TARGET(inst->Aux),
-                             inst->Aux & INST_AUX_EOT);
-               break;
-           case WM_FRONTFACING:
-               emit_frontfacing(p, dst, dst_flags);
-               break;
-           case OPCODE_ADD:
-               emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_ARL:
-               emit_arl(c, inst);
-               break;
-           case OPCODE_FRC:
-               emit_alu1(p, brw_FRC, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_FLR:
-               emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_LRP:
-               emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]);
-               break;
-           case OPCODE_TRUNC:
-               emit_alu1(p, brw_RNDZ, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_MOV:
-           case OPCODE_SWZ:
-               emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_DP2:
-               emit_dp2(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_DP3:
-               emit_dp3(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_DP4:
-               emit_dp4(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_XPD:
-               emit_xpd(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_DPH:
-               emit_dph(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_RCP:
-               emit_math1(c, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_RSQ:
-               emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_SIN:
-               emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_COS:
-               emit_math1(c, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_EX2:
-               emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_LG2:
-               emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_CMP:
-               emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]);
-               break;
-           case OPCODE_MIN:    
-               emit_min(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_MAX:    
-               emit_max(p, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_DDX:
-           case OPCODE_DDY:
-               emit_ddxy(p, dst, dst_flags, (inst->Opcode == OPCODE_DDX),
-                         args[0]);
-                break;
-           case OPCODE_SLT:
-               emit_sop(p, dst, dst_flags,
-                        BRW_CONDITIONAL_L, args[0], args[1]);
-               break;
-           case OPCODE_SLE:
-               emit_sop(p, dst, dst_flags,
-                        BRW_CONDITIONAL_LE, args[0], args[1]);
-               break;
-           case OPCODE_SGT:
-               emit_sop(p, dst, dst_flags,
-                        BRW_CONDITIONAL_G, args[0], args[1]);
-               break;
-           case OPCODE_SGE:
-               emit_sop(p, dst, dst_flags,
-                        BRW_CONDITIONAL_GE, args[0], args[1]);
-               break;
-           case OPCODE_SEQ:
-               emit_sop(p, dst, dst_flags,
-                        BRW_CONDITIONAL_EQ, args[0], args[1]);
-               break;
-           case OPCODE_SNE:
-               emit_sop(p, dst, dst_flags,
-                        BRW_CONDITIONAL_NEQ, args[0], args[1]);
-               break;
-           case OPCODE_SSG:
-               emit_sign(p, dst, dst_flags, args[0]);
-               break;
-           case OPCODE_MUL:
-               emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_POW:
-               emit_math2(c, BRW_MATH_FUNCTION_POW,
-                          dst, dst_flags, args[0], args[1]);
-               break;
-           case OPCODE_MAD:
-               emit_mad(p, dst, dst_flags, args[0], args[1], args[2]);
-               break;
-           case OPCODE_TEX:
-               emit_tex(c, dst, dst_flags, args[0],
-                        get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH,
-                                0, 1, 0, 0),
-                        inst->TexSrcTarget,
-                        inst->TexSrcUnit,
-                        (c->key.shadowtex_mask & (1 << inst->TexSrcUnit)) != 0);
-               break;
-           case OPCODE_TXB:
-               emit_txb(c, dst, dst_flags, args[0],
-                        get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH,
-                                0, 1, 0, 0),
-                        inst->TexSrcTarget,
-                        c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]);
-               break;
-           case OPCODE_KIL_NV:
-               emit_kil_nv(c);
-               break;
-           case OPCODE_IF:
-               assert(if_depth < MAX_IF_DEPTH);
-               if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
-               if_depth_in_loop[loop_depth]++;
-               break;
-           case OPCODE_ELSE:
-               assert(if_depth > 0);
-               if_inst[if_depth-1]  = brw_ELSE(p, if_inst[if_depth-1]);
-               break;
-           case OPCODE_ENDIF:
-               assert(if_depth > 0);
-               brw_ENDIF(p, if_inst[--if_depth]);
-               if_depth_in_loop[loop_depth]--;
-               break;
-           case OPCODE_BGNSUB:
-               brw_save_label(p, inst->Comment, p->nr_insn);
-               break;
-           case OPCODE_ENDSUB:
-               /* no-op */
-               break;
-           case OPCODE_CAL: 
-               brw_push_insn_state(p);
-               brw_set_mask_control(p, BRW_MASK_DISABLE);
-                brw_set_access_mode(p, BRW_ALIGN_1);
-                brw_ADD(p, deref_1ud(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
-                brw_set_access_mode(p, BRW_ALIGN_16);
-                brw_ADD(p, get_addr_reg(stack_index),
-                         get_addr_reg(stack_index), brw_imm_d(4));
-               brw_save_call(&c->func, inst->Comment, p->nr_insn);
-                brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
-                brw_pop_insn_state(p);
-               break;
-
-           case OPCODE_RET:
-               brw_push_insn_state(p);
-               brw_set_mask_control(p, BRW_MASK_DISABLE);
-                brw_ADD(p, get_addr_reg(stack_index),
-                        get_addr_reg(stack_index), brw_imm_d(-4));
-                brw_set_access_mode(p, BRW_ALIGN_1);
-                brw_MOV(p, brw_ip_reg(), deref_1ud(stack_index, 0));
-                brw_set_access_mode(p, BRW_ALIGN_16);
-               brw_pop_insn_state(p);
-
-               break;
-           case OPCODE_BGNLOOP:
-                /* XXX may need to invalidate the current_constant regs */
-               loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
-               if_depth_in_loop[loop_depth] = 0;
-               break;
-           case OPCODE_BRK:
-               brw_BREAK(p, if_depth_in_loop[loop_depth]);
-               brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-               break;
-           case OPCODE_CONT:
-               brw_CONT(p, if_depth_in_loop[loop_depth]);
-               brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-               break;
-           case OPCODE_ENDLOOP: 
-               {
-                  struct brw_instruction *inst0, *inst1;
-                  GLuint br = 1;
-
-                  if (intel->gen == 5)
-                     br = 2;
-
-                 assert(loop_depth > 0);
-                  loop_depth--;
-                  inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
-                  /* patch all the BREAK/CONT instructions from last BGNLOOP */
-                  while (inst0 > loop_inst[loop_depth]) {
-                     inst0--;
-                     if (inst0->header.opcode == BRW_OPCODE_BREAK &&
-                        inst0->bits3.if_else.jump_count == 0) {
-                       inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
-                     }
-                     else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-                             inst0->bits3.if_else.jump_count == 0) {
-                        inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
-                     }
-                  }
-               }
-               break;
-           default:
-               printf("unsupported opcode %d (%s) in fragment shader\n",
-                      inst->Opcode, inst->Opcode < MAX_OPCODE ?
-                      _mesa_opcode_string(inst->Opcode) : "unknown");
-       }
-
-       /* Release temporaries containing any unaliased source regs. */
-       release_tmps( c, mark );
-
-       if (inst->CondUpdate)
-           brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-       else
-           brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-    }
-    post_wm_emit(c);
-
-    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-      printf("wm-native:\n");
-      for (i = 0; i < p->nr_insn; i++)
-        brw_disasm(stdout, &p->store[i], intel->gen);
-      printf("\n");
-    }
-}
-
-/**
- * Do GPU code generation for shaders that use GLSL features such as
- * flow control.  Other shaders will be compiled with the 
- */
-void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
-{
-    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-        printf("brw_wm_glsl_emit:\n");
-    }
-
-    /* initial instruction translation/simplification */
-    brw_wm_pass_fp(c);
-
-    /* actual code generation */
-    brw_wm_emit_glsl(brw, c);
-
-    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
-        brw_wm_print_program(c, "brw_wm_glsl_emit done");
-    }
-
-    c->prog_data.total_grf = num_grf_used(c);
-    c->prog_data.total_scratch = 0;
-}
index 62e556698ba8dea4fba3cb87840efe40042cd8d6..471ea1c18d68ac0e8cef6630cd8db569852a82b6 100644 (file)
@@ -120,14 +120,14 @@ const struct {
  * \param line_aa  AA_NEVER, AA_ALWAYS or AA_SOMETIMES
  * \param lookup  bitmask of IZ_* flags
  */
-void brw_wm_lookup_iz( struct intel_context *intel,
-                      GLuint line_aa,
-                      GLuint lookup,
-                      GLboolean ps_uses_depth,
-                      struct brw_wm_prog_key *key )
+void brw_wm_lookup_iz(struct intel_context *intel,
+                     struct brw_wm_compile *c)
 {
    GLuint reg = 2;
    GLboolean kill_stats_promoted_workaround = GL_FALSE;
+   int lookup = c->key.iz_lookup;
+   bool uses_depth = (c->fp->program.Base.InputsRead &
+                     (1 << FRAG_ATTRIB_WPOS)) != 0;
 
    assert (lookup < IZ_BIT_MAX);
 
@@ -136,36 +136,36 @@ void brw_wm_lookup_iz( struct intel_context *intel,
     * statistics are enabled..." paragraph of 11.5.3.2: Early Depth
     * Test Cases [Pre-DevGT] of the 3D Pipeline - Windower B-Spec.
     */
-   if (intel->stats_wm &&
+   if (c->key.stats_wm &&
        (lookup & IZ_PS_KILL_ALPHATEST_BIT) &&
        wm_iz_table[lookup].mode == P) {
       kill_stats_promoted_workaround = GL_TRUE;
    }
 
    if (lookup & IZ_PS_COMPUTES_DEPTH_BIT)
-      key->computes_depth = 1;
+      c->computes_depth = 1;
 
-   if (wm_iz_table[lookup].sd_present || ps_uses_depth ||
+   if (wm_iz_table[lookup].sd_present || uses_depth ||
        kill_stats_promoted_workaround) {
-      key->source_depth_reg = reg;
+      c->source_depth_reg = reg;
       reg += 2;
    }
 
    if (wm_iz_table[lookup].sd_to_rt || kill_stats_promoted_workaround)
-      key->source_depth_to_render_target = 1;
+      c->source_depth_to_render_target = 1;
 
-   if (wm_iz_table[lookup].ds_present || line_aa != AA_NEVER) {
-      key->aa_dest_stencil_reg = reg;
-      key->runtime_check_aads_emit = (!wm_iz_table[lookup].ds_present &&
-                                     line_aa == AA_SOMETIMES);
+   if (wm_iz_table[lookup].ds_present || c->key.line_aa != AA_NEVER) {
+      c->aa_dest_stencil_reg = reg;
+      c->runtime_check_aads_emit = (!wm_iz_table[lookup].ds_present &&
+                                   c->key.line_aa == AA_SOMETIMES);
       reg++;
    }
 
    if (wm_iz_table[lookup].dd_present) {
-      key->dest_depth_reg = reg;
+      c->dest_depth_reg = reg;
       reg+=2;
    }
 
-   key->nr_payload_regs = reg;
+   c->nr_payload_regs = reg;
 }
 
index 83152526b3ad61d319a795f709e869e51b9c199f..f78bdc31866c576a67aa815b8be66935871e0534 100644 (file)
@@ -380,7 +380,7 @@ static void pass0_init_payload( struct brw_wm_compile *c )
    GLuint i;
 
    for (i = 0; i < 4; i++) {
-      GLuint j = i >= (c->key.nr_payload_regs + 1) / 2 ? 0 : i;
+      GLuint j = i >= (c->nr_payload_regs + 1) / 2 ? 0 : i;
       pass0_set_fpreg_value( c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, 
                             &c->payload.depth[j] );
    }
index 3a2874b6ddfba8cd50516da9ccd18499e54cb66d..7d6a3fa9f12e38fd3640b26a141a8b45c687508e 100644 (file)
@@ -128,8 +128,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
       if (inst->opcode == WM_FB_WRITE) {
         track_arg(c, inst, 0, WRITEMASK_XYZW); 
         track_arg(c, inst, 1, WRITEMASK_XYZW); 
-        if (c->key.source_depth_to_render_target &&
-            c->key.computes_depth)
+        if (c->source_depth_to_render_target && c->computes_depth)
            track_arg(c, inst, 2, WRITEMASK_Z); 
         else
            track_arg(c, inst, 2, 0); 
@@ -281,7 +280,6 @@ void brw_wm_pass1( struct brw_wm_compile *c )
 
       case OPCODE_DST:
       case WM_FRONTFACING:
-      case OPCODE_KIL_NV:
       default:
         break;
       }
index 44e39538145877a413a25078af4ffdd18149dbc7..8c2b9e7020b32c75ed02508bbdc487c6a980408f 100644 (file)
@@ -69,6 +69,8 @@ static void prealloc_reg(struct brw_wm_compile *c,
  */
 static void init_registers( struct brw_wm_compile *c )
 {
+   struct brw_context *brw = c->func.brw;
+   struct intel_context *intel = &brw->intel;
    GLuint nr_interp_regs = 0;
    GLuint i = 0;
    GLuint j;
@@ -76,32 +78,41 @@ static void init_registers( struct brw_wm_compile *c )
    for (j = 0; j < c->grf_limit; j++) 
       c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;
 
-   for (j = 0; j < (c->key.nr_payload_regs + 1) / 2; j++)
+   for (j = 0; j < (c->nr_payload_regs + 1) / 2; j++)
       prealloc_reg(c, &c->payload.depth[j], i++);
 
    for (j = 0; j < c->nr_creg; j++) 
       prealloc_reg(c, &c->creg[j], i++);
 
-   for (j = 0; j < VERT_RESULT_MAX; j++) {
-      if (c->key.vp_outputs_written & BITFIELD64_BIT(j)) {
-        int fp_index;
-
-        if (j >= VERT_RESULT_VAR0)
-           fp_index = j - (VERT_RESULT_VAR0 - FRAG_ATTRIB_VAR0);
-        else if (j <= VERT_RESULT_TEX7)
-           fp_index = j;
-        else
-           fp_index = -1;
-
-        nr_interp_regs++;
-        if (fp_index >= 0)
-           prealloc_reg(c, &c->payload.input_interp[fp_index], i++);
+   if (intel->gen >= 6) {
+      for (unsigned int j = 0; j < FRAG_ATTRIB_MAX; j++) {
+        if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(j)) {
+           nr_interp_regs++;
+           prealloc_reg(c, &c->payload.input_interp[j], i++);
+        }
+      }
+   } else {
+      for (j = 0; j < VERT_RESULT_MAX; j++) {
+        if (c->key.vp_outputs_written & BITFIELD64_BIT(j)) {
+           int fp_index;
+
+           if (j >= VERT_RESULT_VAR0)
+              fp_index = j - (VERT_RESULT_VAR0 - FRAG_ATTRIB_VAR0);
+           else if (j <= VERT_RESULT_TEX7)
+              fp_index = j;
+           else
+              fp_index = -1;
+
+           nr_interp_regs++;
+           if (fp_index >= 0)
+              prealloc_reg(c, &c->payload.input_interp[fp_index], i++);
+        }
       }
+      assert(nr_interp_regs >= 1);
    }
 
-   assert(nr_interp_regs >= 1);
 
-   c->prog_data.first_curbe_grf = ALIGN(c->key.nr_payload_regs, 2);
+   c->prog_data.first_curbe_grf = ALIGN(c->nr_payload_regs, 2);
    c->prog_data.urb_read_length = nr_interp_regs * 2;
    c->prog_data.curb_read_length = c->nr_creg * 2;
 
index fea96d353818e67361274e931a770beb771c7201..e7c97a1cb05e2fff40c11f8968d4a4b107a7a98d 100644 (file)
@@ -69,12 +69,43 @@ static GLuint translate_wrap_mode( GLenum wrap )
 static drm_intel_bo *upload_default_color( struct brw_context *brw,
                                     const GLfloat *color )
 {
-   struct brw_sampler_default_color sdc;
+   struct intel_context *intel = &brw->intel;
 
-   COPY_4V(sdc.color, color); 
-   
-   return brw_cache_data(&brw->cache, BRW_SAMPLER_DEFAULT_COLOR,
-                        &sdc, sizeof(sdc));
+   if (intel->gen >= 5) {
+      struct gen5_sampler_default_color sdc;
+
+      memset(&sdc, 0, sizeof(sdc));
+
+      UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[0], color[0]);
+      UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[1], color[1]);
+      UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[2], color[2]);
+      UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[3], color[3]);
+
+      UNCLAMPED_FLOAT_TO_USHORT(sdc.us[0], color[0]);
+      UNCLAMPED_FLOAT_TO_USHORT(sdc.us[1], color[1]);
+      UNCLAMPED_FLOAT_TO_USHORT(sdc.us[2], color[2]);
+      UNCLAMPED_FLOAT_TO_USHORT(sdc.us[3], color[3]);
+
+      UNCLAMPED_FLOAT_TO_SHORT(sdc.s[0], color[0]);
+      UNCLAMPED_FLOAT_TO_SHORT(sdc.s[1], color[1]);
+      UNCLAMPED_FLOAT_TO_SHORT(sdc.s[2], color[2]);
+      UNCLAMPED_FLOAT_TO_SHORT(sdc.s[3], color[3]);
+
+      /* XXX: Fill in half floats */
+      /* XXX: Fill in signed bytes */
+
+      COPY_4V(sdc.f, color);
+
+      return brw_cache_data(&brw->cache, BRW_SAMPLER_DEFAULT_COLOR,
+                           &sdc, sizeof(sdc));
+   } else {
+      struct brw_sampler_default_color sdc;
+
+      COPY_4V(sdc.color, color);
+
+      return brw_cache_data(&brw->cache, BRW_SAMPLER_DEFAULT_COLOR,
+                           &sdc, sizeof(sdc));
+   }
 }
 
 
index 76de7b7b6f63e33264abfd1ac8ccfff775dfe646..e9ef635bca2d2489da2bad8d009edfe8df0054b3 100644 (file)
@@ -87,7 +87,6 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
 {
    struct gl_context *ctx = &brw->intel.ctx;
    const struct gl_fragment_program *fp = brw->fragment_program;
-   const struct brw_fragment_program *bfp = (struct brw_fragment_program *) fp;
    struct intel_context *intel = &brw->intel;
 
    memset(key, 0, sizeof(*key));
@@ -132,7 +131,6 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
 
    /* _NEW_COLOR */
    key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled;
-   key->is_glsl = bfp->isGLSL;
 
    /* If using the fragment shader backend, the program is always
     * 8-wide.
index 76fc94df1f6bbcaaec3652c11950fa97a7696ffb..ad744044c70c2221292836d00a1e96d86150ffda 100644 (file)
@@ -139,6 +139,8 @@ static GLuint translate_tex_format( gl_format mesa_format,
          return BRW_SURFACEFORMAT_I16_UNORM;
       else if (depth_mode == GL_ALPHA)
          return BRW_SURFACEFORMAT_A16_UNORM;
+      else if (depth_mode == GL_RED)
+         return BRW_SURFACEFORMAT_R16_UNORM;
       else
          return BRW_SURFACEFORMAT_L16_UNORM;
 
@@ -174,6 +176,8 @@ static GLuint translate_tex_format( gl_format mesa_format,
          return BRW_SURFACEFORMAT_I24X8_UNORM;
       else if (depth_mode == GL_ALPHA)
          return BRW_SURFACEFORMAT_A24X8_UNORM;
+      else if (depth_mode == GL_RED)
+         return BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS;
       else
          return BRW_SURFACEFORMAT_L24X8_UNORM;
 
@@ -274,6 +278,7 @@ brw_create_constant_surface(struct brw_context *brw,
                            drm_intel_bo **out_bo,
                            uint32_t *out_offset)
 {
+   struct intel_context *intel = &brw->intel;
    const GLint w = width - 1;
    struct brw_surface_state surf;
    void *map;
@@ -284,6 +289,9 @@ brw_create_constant_surface(struct brw_context *brw,
    surf.ss0.surface_type = BRW_SURFACE_BUFFER;
    surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
 
+   if (intel->gen >= 6)
+      surf.ss0.render_cache_read_write = 1;
+
    assert(bo);
    surf.ss1.base_addr = bo->offset; /* reloc */
 
index 800a25552141bb76aae204f02b383d056a08a55e..c2631a7b4df6d947759bd806cc418e3e94ae40df 100644 (file)
@@ -35,6 +35,7 @@
 struct gen6_blend_state_key {
    GLboolean color_blend, alpha_enabled;
    GLboolean dither;
+   GLboolean color_mask[BRW_MAX_DRAW_BUFFERS][4];
 
    GLenum logic_op;
 
@@ -53,6 +54,9 @@ blend_state_populate_key(struct brw_context *brw,
 
    memset(key, 0, sizeof(*key));
 
+   /* _NEW_COLOR */
+   memcpy(key->color_mask, ctx->Color.ColorMask, sizeof(key->color_mask));
+
    /* _NEW_COLOR */
    if (ctx->Color._LogicOpEnabled)
       key->logic_op = ctx->Color.LogicOp;
@@ -87,54 +91,62 @@ static drm_intel_bo *
 blend_state_create_from_key(struct brw_context *brw,
                            struct gen6_blend_state_key *key)
 {
-   struct gen6_blend_state blend;
+   struct gen6_blend_state blend[BRW_MAX_DRAW_BUFFERS];
    drm_intel_bo *bo;
+   int b;
 
    memset(&blend, 0, sizeof(blend));
 
-   if (key->logic_op != GL_COPY) {
-      blend.blend1.logic_op_enable = 1;
-      blend.blend1.logic_op_func = intel_translate_logic_op(key->logic_op);
-   } else if (key->color_blend) {
-      GLenum eqRGB = key->blend_eq_rgb;
-      GLenum eqA = key->blend_eq_a;
-      GLenum srcRGB = key->blend_src_rgb;
-      GLenum dstRGB = key->blend_dst_rgb;
-      GLenum srcA = key->blend_src_a;
-      GLenum dstA = key->blend_dst_a;
-
-      if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
-        srcRGB = dstRGB = GL_ONE;
-      }
-
-      if (eqA == GL_MIN || eqA == GL_MAX) {
-        srcA = dstA = GL_ONE;
+   for (b = 0; b < BRW_MAX_DRAW_BUFFERS; b++) {
+      if (key->logic_op != GL_COPY) {
+        blend[b].blend1.logic_op_enable = 1;
+        blend[b].blend1.logic_op_func = intel_translate_logic_op(key->logic_op);
+      } else if (key->color_blend & (1 << b)) {
+        GLenum eqRGB = key->blend_eq_rgb;
+        GLenum eqA = key->blend_eq_a;
+        GLenum srcRGB = key->blend_src_rgb;
+        GLenum dstRGB = key->blend_dst_rgb;
+        GLenum srcA = key->blend_src_a;
+        GLenum dstA = key->blend_dst_a;
+
+        if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
+           srcRGB = dstRGB = GL_ONE;
+        }
+
+        if (eqA == GL_MIN || eqA == GL_MAX) {
+           srcA = dstA = GL_ONE;
+        }
+
+        blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
+        blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
+        blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB);
+
+        blend[b].blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
+        blend[b].blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
+        blend[b].blend0.ia_blend_func = brw_translate_blend_equation(eqA);
+
+        blend[b].blend0.blend_enable = 1;
+        blend[b].blend0.ia_blend_enable = (srcA != srcRGB ||
+                                        dstA != dstRGB ||
+                                        eqA != eqRGB);
       }
 
-      blend.blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
-      blend.blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
-      blend.blend0.blend_func = brw_translate_blend_equation(eqRGB);
-
-      blend.blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
-      blend.blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
-      blend.blend0.ia_blend_func = brw_translate_blend_equation(eqA);
+      if (key->alpha_enabled) {
+        blend[b].blend1.alpha_test_enable = 1;
+        blend[b].blend1.alpha_test_func = intel_translate_compare_func(key->alpha_func);
 
-      blend.blend0.blend_enable = 1;
-      blend.blend0.ia_blend_enable = (srcA != srcRGB ||
-                                     dstA != dstRGB ||
-                                     eqA != eqRGB);
-   }
-
-   if (key->alpha_enabled) {
-      blend.blend1.alpha_test_enable = 1;
-      blend.blend1.alpha_test_func = intel_translate_compare_func(key->alpha_func);
+      }
 
-   }
+      if (key->dither) {
+        blend[b].blend1.dither_enable = 1;
+        blend[b].blend1.y_dither_offset = 0;
+        blend[b].blend1.x_dither_offset = 0;
+      }
 
-   if (key->dither) {
-      blend.blend1.dither_enable = 1;
-      blend.blend1.y_dither_offset = 0;
-      blend.blend1.x_dither_offset = 0;
+      blend[b].blend1.write_disable_r = !key->color_mask[b][0];
+      blend[b].blend1.write_disable_g = !key->color_mask[b][1];
+      blend[b].blend1.write_disable_b = !key->color_mask[b][2];
+      blend[b].blend1.write_disable_a = !key->color_mask[b][3];
    }
 
    bo = brw_upload_cache(&brw->cache, BRW_BLEND_STATE,
@@ -172,7 +184,7 @@ const struct brw_tracked_state gen6_blend_state = {
 };
 
 struct gen6_color_calc_state_key {
-   GLubyte blend_constant_color[4];
+   float blend_constant_color[4];
    GLclampf alpha_ref;
    GLubyte stencil_ref[2];
 };
index c65b41e2b6bf9c71c30d707bdc67fddd54657e2b..c7c4eb1f27d6272323f683f012a5b941865e54f1 100644 (file)
@@ -64,7 +64,9 @@ upload_clip_state(struct brw_context *brw)
             userclip << GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT |
             depth_clamp |
             provoking);
-   OUT_BATCH(GEN6_CLIP_FORCE_ZERO_RTAINDEX);
+   OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT |
+             U_FIXED(225.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT |
+             GEN6_CLIP_FORCE_ZERO_RTAINDEX);
    ADVANCE_BATCH();
 }
 
index 471067e8f02ac1481357579505e65b75608afa7d..45c148baedd275153ba9aa538f00a6bb7b480547 100644 (file)
 #include "intel_batchbuffer.h"
 
 static uint32_t
-get_attr_override(struct brw_context *brw, int fs_attr)
+get_attr_override(struct brw_context *brw, int fs_attr, int two_side_color)
 {
    int attr_index = 0, i, vs_attr;
+   int bfc = 0;
 
    if (fs_attr <= FRAG_ATTRIB_TEX7)
       vs_attr = fs_attr;
@@ -57,6 +58,30 @@ get_attr_override(struct brw_context *brw, int fs_attr)
         attr_index++;
    }
 
+   assert(attr_index < 32);
+
+   if (two_side_color) {
+       if ((brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL1)) &&
+           (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC1))) {
+           assert(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0));
+           assert(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0));
+           bfc = 2;
+       } else if ((brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0)) &&
+                (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0)))
+           bfc = 1;
+   }
+
+   if (bfc && (fs_attr <= FRAG_ATTRIB_TEX7 && fs_attr > FRAG_ATTRIB_WPOS)) {
+       if (fs_attr == FRAG_ATTRIB_COL0)
+           attr_index |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
+       else if (fs_attr == FRAG_ATTRIB_COL1 && bfc == 2) {
+           attr_index++;
+           attr_index |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
+       } else {
+           attr_index += bfc;
+       }
+   }
+
    return attr_index;
 }
 
@@ -67,13 +92,15 @@ upload_sf_state(struct brw_context *brw)
    struct gl_context *ctx = &intel->ctx;
    /* CACHE_NEW_VS_PROG */
    uint32_t num_inputs = brw_count_bits(brw->vs.prog_data->outputs_written);
+   /* BRW_NEW_FRAGMENT_PROGRAM */
    uint32_t num_outputs = brw_count_bits(brw->fragment_program->Base.InputsRead);
-   uint32_t dw1, dw2, dw3, dw4, dw16;
+   uint32_t dw1, dw2, dw3, dw4, dw16, dw17;
    int i;
    /* _NEW_BUFFER */
    GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
    int attr = 0;
    int urb_start;
+   int two_side_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
 
    /* _NEW_TRANSFORM */
    if (ctx->Transform.ClipPlanesEnabled)
@@ -91,6 +118,7 @@ upload_sf_state(struct brw_context *brw)
    dw3 = 0;
    dw4 = 0;
    dw16 = 0;
+   dw17 = 0;
 
    /* _NEW_POLYGON */
    if ((ctx->Polygon.FrontFace == GL_CCW) ^ render_to_fbo)
@@ -99,6 +127,48 @@ upload_sf_state(struct brw_context *brw)
    if (ctx->Polygon.OffsetFill)
        dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID;
 
+   if (ctx->Polygon.OffsetLine)
+       dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME;
+
+   if (ctx->Polygon.OffsetPoint)
+       dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT;
+
+   switch (ctx->Polygon.FrontMode) {
+   case GL_FILL:
+       dw2 |= GEN6_SF_FRONT_SOLID;
+       break;
+
+   case GL_LINE:
+       dw2 |= GEN6_SF_FRONT_WIREFRAME;
+       break;
+
+   case GL_POINT:
+       dw2 |= GEN6_SF_FRONT_POINT;
+       break;
+
+   default:
+       assert(0);
+       break;
+   }
+
+   switch (ctx->Polygon.BackMode) {
+   case GL_FILL:
+       dw2 |= GEN6_SF_BACK_SOLID;
+       break;
+
+   case GL_LINE:
+       dw2 |= GEN6_SF_BACK_WIREFRAME;
+       break;
+
+   case GL_POINT:
+       dw2 |= GEN6_SF_BACK_POINT;
+       break;
+
+   default:
+       assert(0);
+       break;
+   }
+
    /* _NEW_SCISSOR */
    if (ctx->Scissor.Enabled)
       dw3 |= GEN6_SF_SCISSOR_ENABLE;
@@ -160,6 +230,12 @@ upload_sf_state(struct brw_context *brw)
        }
    }
 
+   /* flat shading */
+   if (ctx->Light.ShadeModel == GL_FLAT) {
+       dw17 |= ((brw->fragment_program->Base.InputsRead & (FRAG_BIT_COL0 | FRAG_BIT_COL1)) >>
+                ((brw->fragment_program->Base.InputsRead & FRAG_BIT_WPOS) ? 0 : 1));
+   }
+
    BEGIN_BATCH(20);
    OUT_BATCH(CMD_3D_SF_STATE << 16 | (20 - 2));
    OUT_BATCH(dw1);
@@ -174,7 +250,7 @@ upload_sf_state(struct brw_context *brw)
 
       for (; attr < 64; attr++) {
         if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) {
-           attr_overrides |= get_attr_override(brw, attr);
+           attr_overrides |= get_attr_override(brw, attr, two_side_color);
            attr++;
            break;
         }
@@ -182,7 +258,7 @@ upload_sf_state(struct brw_context *brw)
 
       for (; attr < 64; attr++) {
         if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) {
-           attr_overrides |= get_attr_override(brw, attr) << 16;
+           attr_overrides |= get_attr_override(brw, attr, two_side_color) << 16;
            attr++;
            break;
         }
@@ -190,7 +266,7 @@ upload_sf_state(struct brw_context *brw)
       OUT_BATCH(attr_overrides);
    }
    OUT_BATCH(dw16); /* point sprite texcoord bitmask */
-   OUT_BATCH(0); /* constant interp bitmask */
+   OUT_BATCH(dw17); /* constant interp bitmask */
    OUT_BATCH(0); /* wrapshortest enables 0-7 */
    OUT_BATCH(0); /* wrapshortest enables 8-15 */
    ADVANCE_BATCH();
@@ -205,7 +281,8 @@ const struct brw_tracked_state gen6_sf_state = {
                _NEW_BUFFERS |
                _NEW_POINT |
                _NEW_TRANSFORM),
-      .brw   = BRW_NEW_CONTEXT,
+      .brw   = (BRW_NEW_CONTEXT |
+               BRW_NEW_FRAGMENT_PROGRAM),
       .cache = CACHE_NEW_VS_PROG
    },
    .emit = upload_sf_state,
index a34123478fb7f8d1a6e697cb7c2abd9e64c0fb15..de97fd3783d34907d0fb06b819b1b84ad7899e35 100644 (file)
@@ -72,7 +72,7 @@ const struct brw_tracked_state gen6_urb = {
    .dirty = {
       .mesa = 0,
       .brw = BRW_NEW_CONTEXT,
-      .cache = CACHE_NEW_VS_PROG,
+      .cache = (CACHE_NEW_VS_PROG | CACHE_NEW_GS_PROG),
    },
    .prepare = prepare_urb,
    .emit = upload_urb,
index e94d0c0ddbb6e2d02afc8a18c0162b1a940e10dc..4ef9e2e6072fd2946c95dc38ce8bee2d58e04a71 100644 (file)
@@ -54,7 +54,7 @@ upload_vs_state(struct brw_context *brw)
       OUT_BATCH(0);
       ADVANCE_BATCH();
    } else {
-      int params_uploaded = 0;
+      int params_uploaded = 0, param_regs;
       float *param;
 
       if (brw->vertex_program->IsNVProgram)
@@ -88,20 +88,11 @@ upload_vs_state(struct brw_context *brw)
         params_uploaded++;
       }
 
-      if (vp->use_const_buffer) {
-        for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) {
-           if (brw->vs.constant_map[i] != -1) {
-              memcpy(param + brw->vs.constant_map[i] * 4,
-                     vp->program.Base.Parameters->ParameterValues[i],
-                     4 * sizeof(float));
-              params_uploaded++;
-           }
-        }
-      } else {
-        for (i = 0; i < nr_params; i++) {
-           memcpy(param, vp->program.Base.Parameters->ParameterValues[i],
+      for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) {
+        if (brw->vs.constant_map[i] != -1) {
+           memcpy(param + brw->vs.constant_map[i] * 4,
+                  vp->program.Base.Parameters->ParameterValues[i],
                   4 * sizeof(float));
-           param += 4;
            params_uploaded++;
         }
       }
@@ -117,13 +108,16 @@ upload_vs_state(struct brw_context *brw)
 
       drm_intel_gem_bo_unmap_gtt(constant_bo);
 
+      param_regs = (params_uploaded + 1) / 2;
+      assert(param_regs <= 32);
+
       BEGIN_BATCH(5);
       OUT_BATCH(CMD_3D_CONSTANT_VS_STATE << 16 |
                GEN6_CONSTANT_BUFFER_0_ENABLE |
                (5 - 2));
       OUT_RELOC(constant_bo,
                I915_GEM_DOMAIN_RENDER, 0, /* XXX: bad domain */
-               ALIGN(params_uploaded, 2) / 2 - 1);
+               param_regs - 1);
       OUT_BATCH(0);
       OUT_BATCH(0);
       OUT_BATCH(0);
index ea5418bacf1c9f6cad5b7b86851d82d754ec9489..d80df4e254be5e7d6343629ea946129197983952 100644 (file)
@@ -66,6 +66,21 @@ prepare_wm_constants(struct brw_context *brw)
         constants[i] = convert_param(brw->wm.prog_data->param_convert[i],
                                      *brw->wm.prog_data->param[i]);
       }
+
+      if (0) {
+        printf("WM constants:\n");
+        for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
+           if ((i & 7) == 0)
+              printf("g%d: ", brw->wm.prog_data->first_curbe_grf + i / 8);
+           printf("%8f ", constants[i]);
+           if ((i & 7) == 7)
+              printf("\n");
+        }
+        if ((i & 7) != 0)
+           printf("\n");
+        printf("\n");
+      }
+
       drm_intel_gem_bo_unmap_gtt(brw->wm.push_const_bo);
    }
 }
@@ -88,6 +103,7 @@ upload_wm_state(struct brw_context *brw)
       brw_fragment_program_const(brw->fragment_program);
    uint32_t dw2, dw4, dw5, dw6;
 
+   /* CACHE_NEW_WM_PROG */
    if (brw->wm.prog_data->nr_params == 0) {
       /* Disable the push constant buffers. */
       BEGIN_BATCH(5);
@@ -104,7 +120,8 @@ upload_wm_state(struct brw_context *brw)
                (5 - 2));
       OUT_RELOC(brw->wm.push_const_bo,
                I915_GEM_DOMAIN_RENDER, 0, /* XXX: bad domain */
-               ALIGN(brw->wm.prog_data->nr_params, 8) / 8 - 1);
+               ALIGN(brw->wm.prog_data->nr_params,
+                     brw->wm.prog_data->dispatch_width) / 8 - 1);
       OUT_BATCH(0);
       OUT_BATCH(0);
       OUT_BATCH(0);
@@ -126,8 +143,8 @@ upload_wm_state(struct brw_context *brw)
 
    dw5 |= (40 - 1) << GEN6_WM_MAX_THREADS_SHIFT;
 
-   /* BRW_NEW_FRAGMENT_PROGRAM */
-   if (fp->isGLSL)
+   /* CACHE_NEW_WM_PROG */
+   if (brw->wm.prog_data->dispatch_width == 8)
       dw5 |= GEN6_WM_8_DISPATCH_ENABLE;
    else
       dw5 |= GEN6_WM_16_DISPATCH_ENABLE;
@@ -176,13 +193,14 @@ upload_wm_state(struct brw_context *brw)
 const struct brw_tracked_state gen6_wm_state = {
    .dirty = {
       .mesa  = (_NEW_LINE | _NEW_POLYGONSTIPPLE | _NEW_COLOR | _NEW_BUFFERS |
-               _NEW_PROGRAM_CONSTANTS),
+               _NEW_PROGRAM_CONSTANTS | _NEW_POLYGON),
       .brw   = (BRW_NEW_CURBE_OFFSETS |
                BRW_NEW_FRAGMENT_PROGRAM |
                 BRW_NEW_NR_WM_SURFACES |
                BRW_NEW_URB_FENCE |
                BRW_NEW_BATCH),
-      .cache = CACHE_NEW_SAMPLER
+      .cache = (CACHE_NEW_SAMPLER |
+               CACHE_NEW_WM_PROG)
    },
    .emit = upload_wm_state,
 };
index 4b498f8c5b2b28b77bd69014bc0094b70398cbb6..21fc9ece8867357c1d5596cbb1e55e5f6443f9df 100644 (file)
@@ -92,7 +92,7 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint used)
 
    batch->ptr = NULL;
 
-   if (!intel->no_hw) {
+   if (!intel->intelScreen->no_hw) {
       drm_intel_bo_exec(batch->buf, used, NULL, 0,
                        (x_off & 0xffff) | (y_off << 16));
    }
index 152cdcaf37d69b73fbc166a27413697c0e5cf0b5..9c222c7b4857e7b0b68727718d2cc5220dc15b2b 100644 (file)
@@ -519,7 +519,6 @@ static const struct dri_debug_control debug_control[] = {
    { "sing",  DEBUG_SINGLE_THREAD },
    { "thre",  DEBUG_SINGLE_THREAD },
    { "wm",    DEBUG_WM },
-   { "glsl_force", DEBUG_GLSL_FORCE },
    { "urb",   DEBUG_URB },
    { "vs",    DEBUG_VS },
    { "clip",  DEBUG_CLIP },
@@ -800,11 +799,6 @@ intelInitContext(struct intel_context *intel,
    if (INTEL_DEBUG & DEBUG_BUFMGR)
       dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
 
-   /* XXX force SIMD8 kernel for Sandybridge before we fixed
-      SIMD16 interpolation. */
-   if (intel->gen == 6)
-       INTEL_DEBUG |= DEBUG_GLSL_FORCE;
-
    intel->batch = intel_batchbuffer_alloc(intel);
 
    intel_fbo_init(intel);
@@ -838,11 +832,6 @@ intelInitContext(struct intel_context *intel,
       intel->always_flush_cache = 1;
    }
 
-   /* Disable all hardware rendering (skip emitting batches and fences/waits
-    * to the kernel)
-    */
-   intel->no_hw = getenv("INTEL_NO_HW") != NULL;
-
    return GL_TRUE;
 }
 
index 9d5139c00003bc7c06a5d8eb04c0801c8a9e7d91..96493c0f2bb5810e1f63c0821b48b6166727c52e 100644 (file)
@@ -207,7 +207,6 @@ struct intel_context
    GLboolean hw_stipple;
    GLboolean depth_buffer_is_float;
    GLboolean no_rast;
-   GLboolean no_hw;
    GLboolean always_flush_batch;
    GLboolean always_flush_cache;
 
@@ -362,7 +361,6 @@ extern int INTEL_DEBUG;
 #define DEBUG_WM        0x800000
 #define DEBUG_URB       0x1000000
 #define DEBUG_VS        0x2000000
-#define DEBUG_GLSL_FORCE 0x4000000
 #define DEBUG_CLIP      0x8000000
 
 #define DBG(...) do {                                          \
index 862a13d2ea51605aeb39ecd8452a060c80d25192..18e796a11869a6694441c76faaac2e749886ec74 100644 (file)
@@ -465,10 +465,12 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to XGBA8 texture OK\n");
    }
+#ifndef I915
    else if (texImage->TexFormat == MESA_FORMAT_SARGB8) {
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to SARGB8 texture OK\n");
    }
+#endif
    else if (texImage->TexFormat == MESA_FORMAT_RGB565) {
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to RGB5 texture OK\n");
@@ -481,6 +483,7 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to ARGB4444 texture OK\n");
    }
+#ifndef I915
    else if (texImage->TexFormat == MESA_FORMAT_A8) {
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to A8 texture OK\n");
@@ -501,6 +504,7 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
       irb->Base.DataType = GL_UNSIGNED_SHORT;
       DBG("Render to RG88 texture OK\n");
    }
+#endif
    else if (texImage->TexFormat == MESA_FORMAT_Z16) {
       irb->Base.DataType = GL_UNSIGNED_SHORT;
       DBG("Render to DEPTH16 texture OK\n");
@@ -710,15 +714,17 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
       switch (irb->Base.Format) {
       case MESA_FORMAT_ARGB8888:
       case MESA_FORMAT_XRGB8888:
-      case MESA_FORMAT_SARGB8:
       case MESA_FORMAT_RGB565:
       case MESA_FORMAT_ARGB1555:
       case MESA_FORMAT_ARGB4444:
+#ifndef I915
+      case MESA_FORMAT_SARGB8:
       case MESA_FORMAT_A8:
       case MESA_FORMAT_R8:
       case MESA_FORMAT_R16:
       case MESA_FORMAT_RG88:
       case MESA_FORMAT_RG1616:
+#endif
         break;
       default:
         fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
index 061f0d278d6a99d050c6dc9aad436c639246396f..3f13589a214c39d1eea7cf169bd532936c14c15e 100644 (file)
@@ -452,7 +452,7 @@ intelCreateContext(gl_api api,
       return brwCreateContext(api, mesaVis,
                              driContextPriv, sharedContextPrivate);
 #endif
-   fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
+   fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
    return GL_FALSE;
 }
 
@@ -462,7 +462,8 @@ intel_init_bufmgr(struct intel_screen *intelScreen)
    __DRIscreen *spriv = intelScreen->driScrnPriv;
    int num_fences = 0;
 
-   intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
+   intelScreen->no_hw = (getenv("INTEL_NO_HW") != NULL ||
+                        getenv("INTEL_DEVID_OVERRIDE") != NULL);
 
    intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
    if (intelScreen->bufmgr == NULL) {
@@ -497,6 +498,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
    GLenum fb_format[3];
    GLenum fb_type[3];
    unsigned int api_mask;
+   char *devid_override;
 
    static const GLenum back_buffer_modes[] = {
        GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
@@ -523,6 +525,16 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
                        &intelScreen->deviceID))
       return GL_FALSE;
 
+   /* Allow an override of the device ID for the purpose of making the
+    * driver produce dumps for debugging of new chipset enablement.
+    * This implies INTEL_NO_HW, to avoid programming your actual GPU
+    * incorrectly.
+    */
+   devid_override = getenv("INTEL_DEVID_OVERRIDE");
+   if (devid_override) {
+      intelScreen->deviceID = strtod(devid_override, NULL);
+   }
+
    api_mask = (1 << __DRI_API_OPENGL);
 #if FEATURE_ES1
    api_mask |= (1 << __DRI_API_GLES);
index 9d73a2fb3757535e0e98d780fe427ddd9b9615eb..f8316ae2f8d26403e497b80739cae13439820eb8 100644 (file)
@@ -204,11 +204,13 @@ intelChooseTextureFormat(struct gl_context * ctx, GLint internalFormat,
     * { R, G, 1.0, 1.0 } from a red-green texture would be useful.
     */
    case GL_RED:
+   case GL_COMPRESSED_RED:
    case GL_R8:
       return MESA_FORMAT_R8;
    case GL_R16:
       return MESA_FORMAT_R16;
    case GL_RG:
+   case GL_COMPRESSED_RG:
    case GL_RG8:
       return MESA_FORMAT_RG88;
    case GL_RG16:
index 8a047e6419b38522ebcbdb3595ae1355490f1256..b62290231b97933914a8ba057a0c20d7e4786cbf 100644 (file)
@@ -200,6 +200,7 @@ void r200EmitArrays( struct gl_context *ctx, GLubyte *vimap_rev )
            }
         default:
            assert(0);
+           emitsize = 0;
         }
         if (!rmesa->radeon.tcl.aos[nr].bo) {
           rcommon_emit_vector( ctx,
index 8be32ea91fe78bbe168ab2ef22668b8d8145a6e1..1db8678e890e23c718eaab589bdc8c3ba67e848e 100644 (file)
@@ -76,6 +76,9 @@ static void use_temporary(struct r300_fragment_program_code *code, unsigned int
 
 static unsigned int use_source(struct r300_fragment_program_code* code, struct rc_pair_instruction_source src)
 {
+       if (!src.Used)
+               return 0;
+
        if (src.File == RC_FILE_CONSTANT) {
                return src.Index | (1 << 5);
        } else if (src.File == RC_FILE_TEMPORARY) {
index 2d28b065390a36dd6c105e36d2a7aa5d52765206..05d3da8a10d2e018eef0ea970b92be49f18c4161 100644 (file)
@@ -94,6 +94,7 @@ static const struct swizzle_data* lookup_native_swizzle(unsigned int swizzle)
  */
 static int r300_swizzle_is_native(rc_opcode opcode, struct rc_src_register reg)
 {
+       const struct swizzle_data* sd;
        unsigned int relevant;
        int j;
 
@@ -127,7 +128,8 @@ static int r300_swizzle_is_native(rc_opcode opcode, struct rc_src_register reg)
        if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant))
                return 0;
 
-       if (!lookup_native_swizzle(reg.Swizzle))
+       sd = lookup_native_swizzle(reg.Swizzle);
+       if (!sd || (reg.File == RC_FILE_PRESUB && sd->srcp_stride == 0))
                return 0;
 
        return 1;
@@ -201,7 +203,7 @@ unsigned int r300FPTranslateRGBSwizzle(unsigned int src, unsigned int swizzle)
 {
        const struct swizzle_data* sd = lookup_native_swizzle(swizzle);
 
-       if (!sd) {
+       if (!sd || (src == RC_PAIR_PRESUB_SRC && sd->srcp_stride == 0)) {
                fprintf(stderr, "Not a native swizzle: %08x\n", swizzle);
                return 0;
        }
index 2f130198d350130ca78c6faf6b2b1d1fbc307f0c..e0d349b98ce147b33c17cd3b61b5857a6785b99d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <stdio.h>
 
+#include "radeon_compiler_util.h"
 #include "radeon_dataflow.h"
 #include "radeon_emulate_branches.h"
 #include "radeon_emulate_loops.h"
@@ -54,6 +55,8 @@ static void rc_rewrite_depth_out(struct radeon_compiler *cc, void *user)
 
        for (rci = c->Base.Program.Instructions.Next; rci != &c->Base.Program.Instructions; rci = rci->Next) {
                struct rc_sub_instruction * inst = &rci->U.I;
+               unsigned i;
+               const struct rc_opcode_info *info = rc_get_opcode_info(inst->Opcode);
 
                if (inst->DstReg.File != RC_FILE_OUTPUT || inst->DstReg.Index != c->OutputDepth)
                        continue;
@@ -65,27 +68,12 @@ static void rc_rewrite_depth_out(struct radeon_compiler *cc, void *user)
                        continue;
                }
 
-               switch (inst->Opcode) {
-                       case RC_OPCODE_FRC:
-                       case RC_OPCODE_MOV:
-                               inst->SrcReg[0] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[0]);
-                               break;
-                       case RC_OPCODE_ADD:
-                       case RC_OPCODE_MAX:
-                       case RC_OPCODE_MIN:
-                       case RC_OPCODE_MUL:
-                               inst->SrcReg[0] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[0]);
-                               inst->SrcReg[1] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[1]);
-                               break;
-                       case RC_OPCODE_CMP:
-                       case RC_OPCODE_MAD:
-                               inst->SrcReg[0] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[0]);
-                               inst->SrcReg[1] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[1]);
-                               inst->SrcReg[2] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[2]);
-                               break;
-                       default:
-                               // Scalar instructions needn't be reswizzled
-                               break;
+               if (!info->IsComponentwise) {
+                       continue;
+               }
+
+               for (i = 0; i < info->NumSrcRegs; i++) {
+                       inst->SrcReg[i] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[i]);
                }
        }
 }
@@ -93,7 +81,6 @@ static void rc_rewrite_depth_out(struct radeon_compiler *cc, void *user)
 void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 {
        int is_r500 = c->Base.is_r500;
-       int kill_consts = c->Base.remove_unused_constants;
        int opt = !c->Base.disable_optimizations;
 
        /* Lists of instruction transformations. */
@@ -133,11 +120,11 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
                {"emulate loops",               1, !is_r500,    rc_emulate_loops,               NULL},
                {"dataflow optimize",           1, opt,         rc_optimize,                    NULL},
                {"dataflow swizzles",           1, 1,           rc_dataflow_swizzles,           NULL},
-               {"dead constants",              1, kill_consts, rc_remove_unused_constants,     &c->code->constants_remap_table},
+               {"dead constants",              1, 1,           rc_remove_unused_constants,     &c->code->constants_remap_table},
                /* This pass makes it easier for the scheduler to group TEX
                 * instructions and reduces the chances of creating too
                 * many texture indirections.*/
-               {"register rename",             1, !is_r500,    rc_rename_regs,                 NULL},
+               {"register rename",             1, !is_r500 || opt, rc_rename_regs,             NULL},
                {"pair translate",              1, 1,           rc_pair_translate,              NULL},
                {"pair scheduling",             1, 1,           rc_pair_schedule,               NULL},
                {"register allocation",         1, opt,         rc_pair_regalloc,               NULL},
@@ -150,9 +137,10 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
                {NULL, 0, 0, NULL, NULL}
        };
 
+       c->Base.type = RC_FRAGMENT_PROGRAM;
        c->Base.SwizzleCaps = c->Base.is_r500 ? &r500_swizzle_caps : &r300_swizzle_caps;
 
-       rc_run_compiler(&c->Base, fs_list, "Fragment Program");
+       rc_run_compiler(&c->Base, fs_list);
 
        rc_constants_copy(&c->code->constants, &c->Base.Program.Constants);
 }
index bf8341f0173662a826c003e7e8fbd4b8ed4e75be..472029f63d0758d2b0b8d7c5f508da794edc8d34 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "../r300_reg.h"
 
+#include "radeon_compiler_util.h"
 #include "radeon_dataflow.h"
 #include "radeon_program_alu.h"
 #include "radeon_swizzle.h"
@@ -790,19 +791,14 @@ static void allocate_temporary_registers(struct radeon_compiler *c, void *user)
                                                if (!hwtemps[j])
                                                        break;
                                        }
-                                       if (j >= c->max_temp_regs) {
-                                               rc_error(c, "Too many temporaries\n");
-                                               return;
+                                       ta[orig].Allocated = 1;
+                                       if (last_inst_src_reladdr &&
+                                           last_inst_src_reladdr->IP > inst->IP) {
+                                               ta[orig].HwTemp = orig;
                                        } else {
-                                               ta[orig].Allocated = 1;
-                                               if (last_inst_src_reladdr &&
-                                                   last_inst_src_reladdr->IP > inst->IP) {
-                                                       ta[orig].HwTemp = orig;
-                                               } else {
-                                                       ta[orig].HwTemp = j;
-                                               }
-                                               hwtemps[ta[orig].HwTemp] = 1;
+                                               ta[orig].HwTemp = j;
                                        }
+                                       hwtemps[ta[orig].HwTemp] = 1;
                                }
 
                                inst->U.I.DstReg.Index = ta[orig].HwTemp;
@@ -1018,7 +1014,6 @@ static struct rc_swizzle_caps r300_vertprog_swizzle_caps = {
 void r3xx_compile_vertex_program(struct r300_vertex_program_compiler *c)
 {
        int is_r500 = c->Base.is_r500;
-       int kill_consts = c->Base.remove_unused_constants;
        int opt = !c->Base.disable_optimizations;
 
        /* Lists of instruction transformations. */
@@ -1062,18 +1057,18 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler *c)
                {"dataflow optimize",           1, opt,         rc_optimize,                    NULL},
                /* This pass must be done after optimizations. */
                {"source conflict resolve",     1, 1,           rc_local_transform,             resolve_src_conflicts},
-               {"dataflow swizzles",           1, 1,           rc_dataflow_swizzles,           NULL},
                {"register allocation",         1, opt,         allocate_temporary_registers,   NULL},
-               {"dead constants",              1, kill_consts, rc_remove_unused_constants,     &c->code->constants_remap_table},
+               {"dead constants",              1, 1,           rc_remove_unused_constants,     &c->code->constants_remap_table},
                {"final code validation",       0, 1,           rc_validate_final_shader,       NULL},
                {"machine code generation",     0, 1,           translate_vertex_program,       NULL},
                {"dump machine code",           0, c->Base.Debug & RC_DBG_LOG, r300_vertex_program_dump,        NULL},
                {NULL, 0, 0, NULL, NULL}
        };
 
+       c->Base.type = RC_VERTEX_PROGRAM;
        c->Base.SwizzleCaps = &r300_vertprog_swizzle_caps;
 
-       rc_run_compiler(&c->Base, vs_list, "Vertex Program");
+       rc_run_compiler(&c->Base, vs_list);
 
        c->code->InputsRead = c->Base.Program.InputsRead;
        c->code->OutputsWritten = c->Base.Program.OutputsWritten;
index 289bb87ae593dd83d5ad8fc46c270782bfa4e0ed..ef81be48f7779afe93c651db5fdfc27198abb0e1 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <stdio.h>
 
+#include "radeon_compiler_util.h"
 #include "../r300_reg.h"
 
 /**
index 6f101c68eb68630f872a2d2b681b9cf0283b8693..5da82d90f6716a117a092af86ed1b3a49d32452f 100644 (file)
@@ -45,9 +45,6 @@
 
 #include "radeon_program_pair.h"
 
-#define MAX_BRANCH_DEPTH_FULL 32
-#define MAX_BRANCH_DEPTH_PARTIAL 4
-
 #define PROG_CODE \
        struct r500_fragment_program_code *code = &c->code->code.r500
 
@@ -200,6 +197,9 @@ static void use_temporary(struct r500_fragment_program_code* code, unsigned int
 
 static unsigned int use_source(struct r500_fragment_program_code* code, struct rc_pair_instruction_source src)
 {
+       if (!src.Used)
+               return 0;
+
        if (src.File == RC_FILE_CONSTANT) {
                return src.Index | 0x100;
        } else if (src.File == RC_FILE_TEMPORARY) {
@@ -506,7 +506,7 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
                break;
        }
        case RC_OPCODE_IF:
-               if ( s->CurrentBranchDepth >= MAX_BRANCH_DEPTH_FULL) {
+               if ( s->CurrentBranchDepth >= R500_PFS_MAX_BRANCH_DEPTH_FULL) {
                        rc_error(s->C, "Branch depth exceeds hardware limit");
                        return;
                }
index cfb6df2cd796c4375b195c617b17f1a2cb7d81aa..b69e81698ae9cf3bdb29e54131bae11d23227b82 100644 (file)
@@ -34,6 +34,8 @@
 #define R500_PFS_MAX_INST         512
 #define R500_PFS_NUM_TEMP_REGS    128
 #define R500_PFS_NUM_CONST_REGS   256
+#define R500_PFS_MAX_BRANCH_DEPTH_FULL 32
+#define R500_PFS_MAX_BRANCH_DEPTH_PARTIAL 4
 
 
 #define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
index 4286baed0c69467de17c64ea169112b0b85c9986..65548604bcca832c25abca83ae7dc0cedd8fb590 100644 (file)
@@ -29,6 +29,7 @@
 #include "radeon_dataflow.h"
 #include "radeon_program.h"
 #include "radeon_program_pair.h"
+#include "radeon_compiler_util.h"
 
 
 void rc_init(struct radeon_compiler * c)
@@ -356,66 +357,92 @@ void rc_transform_fragment_face(struct radeon_compiler *c, unsigned face)
 static void reg_count_callback(void * userdata, struct rc_instruction * inst,
                rc_register_file file, unsigned int index, unsigned int mask)
 {
-       unsigned int * max_reg = userdata;
+       int *max_reg = userdata;
        if (file == RC_FILE_TEMPORARY)
-               index > *max_reg ? *max_reg = index : 0;
+               (int)index > *max_reg ? *max_reg = index : 0;
 }
 
-static void print_stats(struct radeon_compiler * c)
+void rc_get_stats(struct radeon_compiler *c, struct rc_program_stats *s)
 {
+       int max_reg = -1;
        struct rc_instruction * tmp;
-       unsigned max_reg, insts, fc, tex, alpha, rgb, presub;
-       max_reg = insts = fc = tex = alpha = rgb = presub = 0;
+       memset(s, 0, sizeof(*s));
+
        for(tmp = c->Program.Instructions.Next; tmp != &c->Program.Instructions;
                                                        tmp = tmp->Next){
                const struct rc_opcode_info * info;
                rc_for_all_reads_mask(tmp, reg_count_callback, &max_reg);
                if (tmp->Type == RC_INSTRUCTION_NORMAL) {
                        if (tmp->U.I.PreSub.Opcode != RC_PRESUB_NONE)
-                               presub++;
+                               s->num_presub_ops++;
                        info = rc_get_opcode_info(tmp->U.I.Opcode);
                } else {
                        if (tmp->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Used)
-                               presub++;
+                               s->num_presub_ops++;
                        if (tmp->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Used)
-                               presub++;
+                               s->num_presub_ops++;
                        /* Assuming alpha will never be a flow control or
                         * a tex instruction. */
                        if (tmp->U.P.Alpha.Opcode != RC_OPCODE_NOP)
-                               alpha++;
+                               s->num_alpha_insts++;
                        if (tmp->U.P.RGB.Opcode != RC_OPCODE_NOP)
-                               rgb++;
+                               s->num_rgb_insts++;
                        info = rc_get_opcode_info(tmp->U.P.RGB.Opcode);
                }
                if (info->IsFlowControl)
-                       fc++;
+                       s->num_fc_insts++;
                if (info->HasTexture)
-                       tex++;
-               insts++;
+                       s->num_tex_insts++;
+               s->num_insts++;
        }
-       if (insts < 4)
-               return;
-       fprintf(stderr,"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
-                      "~%4u Instructions\n"
-                      "~%4u Vector Instructions (RGB)\n"
-                      "~%4u Scalar Instructions (Alpha)\n"
-                      "~%4u Flow Control Instructions\n"
-                      "~%4u Texture Instructions\n"
-                      "~%4u Presub Operations\n"
-                      "~%4u Temporary Registers\n"
-                      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
-                      insts, rgb, alpha, fc, tex, presub, max_reg + 1);
+       s->num_temp_regs = max_reg + 1;
 }
 
-/* Executes a list of compiler passes given in the parameter 'list'. */
-void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *list,
-                    const char *shader_name)
+static void print_stats(struct radeon_compiler * c)
 {
-       if (c->Debug & RC_DBG_LOG) {
-               fprintf(stderr, "%s: before compilation\n", shader_name);
-               rc_print_program(&c->Program);
+       struct rc_program_stats s;
+
+       rc_get_stats(c, &s);
+
+       if (s.num_insts < 4)
+               return;
+
+       switch (c->type) {
+       case RC_VERTEX_PROGRAM:
+               fprintf(stderr,"~~~~~~~~~ VERTEX PROGRAM ~~~~~~~~\n"
+                              "~%4u Instructions\n"
+                              "~%4u Flow Control Instructions\n"
+                              "~%4u Temporary Registers\n"
+                              "~~~~~~~~~~~~~~ END ~~~~~~~~~~~~~~\n",
+                              s.num_insts, s.num_fc_insts, s.num_temp_regs);
+               break;
+
+       case RC_FRAGMENT_PROGRAM:
+               fprintf(stderr,"~~~~~~~~ FRAGMENT PROGRAM ~~~~~~~\n"
+                              "~%4u Instructions\n"
+                              "~%4u Vector Instructions (RGB)\n"
+                              "~%4u Scalar Instructions (Alpha)\n"
+                              "~%4u Flow Control Instructions\n"
+                              "~%4u Texture Instructions\n"
+                              "~%4u Presub Operations\n"
+                              "~%4u Temporary Registers\n"
+                              "~~~~~~~~~~~~~~ END ~~~~~~~~~~~~~~\n",
+                              s.num_insts, s.num_rgb_insts, s.num_alpha_insts,
+                              s.num_fc_insts, s.num_tex_insts, s.num_presub_ops,
+                              s.num_temp_regs);
+               break;
+       default:
+               assert(0);
        }
+}
 
+static const char *shader_name[RC_NUM_PROGRAM_TYPES] = {
+       "Vertex Program",
+       "Fragment Program"
+};
+
+void rc_run_compiler_passes(struct radeon_compiler *c, struct radeon_compiler_pass *list)
+{
        for (unsigned i = 0; list[i].name; i++) {
                if (list[i].predicate) {
                        list[i].run(c, list[i].user);
@@ -424,11 +451,23 @@ void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *lis
                                return;
 
                        if ((c->Debug & RC_DBG_LOG) && list[i].dump) {
-                               fprintf(stderr, "%s: after '%s'\n", shader_name, list[i].name);
+                               fprintf(stderr, "%s: after '%s'\n", shader_name[c->type], list[i].name);
                                rc_print_program(&c->Program);
                        }
                }
        }
+}
+
+/* Executes a list of compiler passes given in the parameter 'list'. */
+void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *list)
+{
+       if (c->Debug & RC_DBG_LOG) {
+               fprintf(stderr, "%s: before compilation\n", shader_name[c->type]);
+               rc_print_program(&c->Program);
+       }
+
+       rc_run_compiler_passes(c, list);
+
        if (c->Debug & RC_DBG_STATS)
                print_stats(c);
 }
index 31fd469a04f8ec8fb55448f1b5358a904c5c88c2..e6633395895b7dbb2a0fe7ef3878b04a9ec2b436 100644 (file)
 
 struct rc_swizzle_caps;
 
+enum rc_program_type {
+       RC_VERTEX_PROGRAM,
+       RC_FRAGMENT_PROGRAM,
+       RC_NUM_PROGRAM_TYPES
+};
+
 struct radeon_compiler {
        struct memory_pool Pool;
        struct rc_program Program;
+       enum rc_program_type type;
        unsigned Debug:2;
        unsigned Error:1;
        char * ErrorMsg;
@@ -140,9 +147,21 @@ struct radeon_compiler_pass {
        void *user;             /* Optional parameter which is passed to the run function. */
 };
 
+struct rc_program_stats {
+       unsigned num_insts;
+       unsigned num_fc_insts;
+       unsigned num_tex_insts;
+       unsigned num_rgb_insts;
+       unsigned num_alpha_insts;
+       unsigned num_presub_ops;
+       unsigned num_temp_regs;
+};
+
+void rc_get_stats(struct radeon_compiler *c, struct rc_program_stats *s);
+
 /* Executes a list of compiler passes given in the parameter 'list'. */
-void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *list,
-                    const char *shader_name);
+void rc_run_compiler_passes(struct radeon_compiler *c, struct radeon_compiler_pass *list);
+void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *list);
 void rc_validate_final_shader(struct radeon_compiler *c, void *user);
 
 #endif /* RADEON_COMPILER_H */
index 97f4c75849268a137f63faa42a6ba2a6bf1e2218..bf393a9fb160a0b8a9db2e0246f3df479288a17b 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "radeon_compiler_util.h"
 
+#include "radeon_compiler.h"
+#include "radeon_dataflow.h"
 /**
  */
 unsigned int rc_swizzle_to_writemask(unsigned int swz)
@@ -46,6 +48,91 @@ unsigned int rc_swizzle_to_writemask(unsigned int swz)
        return mask;
 }
 
+rc_swizzle get_swz(unsigned int swz, rc_swizzle idx)
+{
+       if (idx & 0x4)
+               return idx;
+       return GET_SWZ(swz, idx);
+}
+
+unsigned int combine_swizzles4(unsigned int src,
+               rc_swizzle swz_x, rc_swizzle swz_y, rc_swizzle swz_z, rc_swizzle swz_w)
+{
+       unsigned int ret = 0;
+
+       ret |= get_swz(src, swz_x);
+       ret |= get_swz(src, swz_y) << 3;
+       ret |= get_swz(src, swz_z) << 6;
+       ret |= get_swz(src, swz_w) << 9;
+
+       return ret;
+}
+
+unsigned int combine_swizzles(unsigned int src, unsigned int swz)
+{
+       unsigned int ret = 0;
+
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_X));
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Y)) << 3;
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Z)) << 6;
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_W)) << 9;
+
+       return ret;
+}
+
+/**
+ * @param mask Must be either RC_MASK_X, RC_MASK_Y, RC_MASK_Z, or RC_MASK_W
+ */
+rc_swizzle rc_mask_to_swizzle(unsigned int mask)
+{
+       switch (mask) {
+       case RC_MASK_X: return RC_SWIZZLE_X;
+       case RC_MASK_Y: return RC_SWIZZLE_Y;
+       case RC_MASK_Z: return RC_SWIZZLE_Z;
+       case RC_MASK_W: return RC_SWIZZLE_W;
+       }
+       return RC_SWIZZLE_UNUSED;
+}
+
+/* Reorder mask bits according to swizzle. */
+unsigned swizzle_mask(unsigned swizzle, unsigned mask)
+{
+       unsigned ret = 0;
+       for (unsigned chan = 0; chan < 4; ++chan) {
+               unsigned swz = GET_SWZ(swizzle, chan);
+               if (swz < 4)
+                       ret |= GET_BIT(mask, swz) << chan;
+       }
+       return ret;
+}
+
+/**
+ * Left multiplication of a register with a swizzle
+ */
+struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg)
+{
+       struct rc_src_register tmp = srcreg;
+       int i;
+       tmp.Swizzle = 0;
+       tmp.Negate = 0;
+       for(i = 0; i < 4; ++i) {
+               rc_swizzle swz = GET_SWZ(swizzle, i);
+               if (swz < 4) {
+                       tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
+                       tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
+               } else {
+                       tmp.Swizzle |= swz << (i*3);
+               }
+       }
+       return tmp;
+}
+
+void reset_srcreg(struct rc_src_register* reg)
+{
+       memset(reg, 0, sizeof(struct rc_src_register));
+       reg->Swizzle = RC_SWIZZLE_XYZW;
+}
+
 unsigned int rc_src_reads_dst_mask(
                rc_register_file src_file,
                unsigned int src_idx,
@@ -59,3 +146,123 @@ unsigned int rc_src_reads_dst_mask(
        }
        return dst_mask & rc_swizzle_to_writemask(src_swz);
 }
+
+unsigned int rc_source_type_swz(unsigned int swizzle, unsigned int channels)
+{
+       unsigned int chan;
+       unsigned int swz = RC_SWIZZLE_UNUSED;
+       unsigned int ret = RC_SOURCE_NONE;
+
+       for(chan = 0; chan < channels; chan++) {
+               swz = GET_SWZ(swizzle, chan);
+               if (swz == RC_SWIZZLE_W) {
+                       ret |= RC_SOURCE_ALPHA;
+               } else if (swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y
+                                               || swz == RC_SWIZZLE_Z) {
+                       ret |= RC_SOURCE_RGB;
+               }
+       }
+       return ret;
+}
+
+unsigned int rc_source_type_mask(unsigned int mask)
+{
+       unsigned int ret = RC_SOURCE_NONE;
+
+       if (mask & RC_MASK_XYZ)
+               ret |= RC_SOURCE_RGB;
+
+       if (mask & RC_MASK_W)
+               ret |= RC_SOURCE_ALPHA;
+
+       return ret;
+}
+
+struct can_use_presub_data {
+       struct rc_src_register RemoveSrcs[3];
+       unsigned int RGBCount;
+       unsigned int AlphaCount;
+};
+
+static void can_use_presub_read_cb(
+       void * userdata,
+       struct rc_instruction * inst,
+       rc_register_file file,
+       unsigned int index,
+       unsigned int mask)
+{
+       struct can_use_presub_data * d = userdata;
+       unsigned int src_type = rc_source_type_mask(mask);
+       unsigned int i;
+
+       if (file == RC_FILE_NONE)
+               return;
+
+       for(i = 0; i < 3; i++) {
+               if (d->RemoveSrcs[i].File == file
+                   && d->RemoveSrcs[i].Index == index) {
+                       src_type &=
+                               ~rc_source_type_swz(d->RemoveSrcs[i].Swizzle, 4);
+               }
+       }
+
+       if (src_type & RC_SOURCE_RGB)
+               d->RGBCount++;
+
+       if (src_type & RC_SOURCE_ALPHA)
+               d->AlphaCount++;
+}
+
+unsigned int rc_inst_can_use_presub(
+       struct rc_instruction * inst,
+       rc_presubtract_op presub_op,
+       unsigned int presub_writemask,
+       struct rc_src_register replace_reg,
+       struct rc_src_register presub_src0,
+       struct rc_src_register presub_src1)
+{
+       struct can_use_presub_data d;
+       unsigned int num_presub_srcs;
+       unsigned int presub_src_type = rc_source_type_mask(presub_writemask);
+       const struct rc_opcode_info * info =
+                                       rc_get_opcode_info(inst->U.I.Opcode);
+
+       if (presub_op == RC_PRESUB_NONE) {
+               return 1;
+       }
+
+       if (info->HasTexture) {
+               return 0;
+       }
+
+       /* We can't use more than one presubtract value in an
+        * instruction, unless the two prsubtract operations
+        * are the same and read from the same registers.
+        * XXX For now we will limit instructions to only one presubtract
+        * value.*/
+       if (inst->U.I.PreSub.Opcode != RC_PRESUB_NONE) {
+               return 0;
+       }
+
+       memset(&d, 0, sizeof(d));
+       d.RemoveSrcs[0] = replace_reg;
+       d.RemoveSrcs[1] = presub_src0;
+       d.RemoveSrcs[2] = presub_src1;
+
+       rc_for_all_reads_mask(inst, can_use_presub_read_cb, &d);
+
+       num_presub_srcs = rc_presubtract_src_reg_count(presub_op);
+
+       if ((presub_src_type & RC_SOURCE_RGB)
+                                       && d.RGBCount + num_presub_srcs > 3) {
+               return 0;
+       }
+
+       if ((presub_src_type & RC_SOURCE_ALPHA)
+                                       && d.AlphaCount + num_presub_srcs > 3) {
+               return 0;
+       }
+
+       return 1;
+}
+
index 1a14e7cb0efcd72956bdf0225b71558af00e70bc..461ab9ffb10676484bfe5870ddd4ee4072475468 100644 (file)
@@ -3,8 +3,27 @@
 #ifndef RADEON_PROGRAM_UTIL_H
 #define RADEON_PROGRAM_UTIL_H
 
+struct rc_instruction;
+struct rc_src_register;
+
 unsigned int rc_swizzle_to_writemask(unsigned int swz);
 
+rc_swizzle get_swz(unsigned int swz, rc_swizzle idx);
+
+unsigned int combine_swizzles4(unsigned int src,
+                              rc_swizzle swz_x, rc_swizzle swz_y,
+                              rc_swizzle swz_z, rc_swizzle swz_w);
+
+unsigned int combine_swizzles(unsigned int src, unsigned int swz);
+
+rc_swizzle rc_mask_to_swizzle(unsigned int mask);
+
+unsigned swizzle_mask(unsigned swizzle, unsigned mask);
+
+struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg);
+
+void reset_srcreg(struct rc_src_register* reg);
+
 unsigned int rc_src_reads_dst_mask(
                rc_register_file src_file,
                unsigned int src_idx,
@@ -13,4 +32,16 @@ unsigned int rc_src_reads_dst_mask(
                unsigned int dst_idx,
                unsigned int dst_mask);
 
+unsigned int rc_source_type_swz(unsigned int swizzle, unsigned int channels);
+
+unsigned int rc_source_type_mask(unsigned int mask);
+
+unsigned int rc_inst_can_use_presub(
+       struct rc_instruction * inst,
+       rc_presubtract_op presub_op,
+       unsigned int presub_writemask,
+       struct rc_src_register replace_reg,
+       struct rc_src_register presub_src0,
+       struct rc_src_register presub_src1);
+
 #endif /* RADEON_PROGRAM_UTIL_H */
index fd94194dc34d0a639d299b013eb1b35539a0d028..d0a64d936e055fdab01db8fa3e0b0fead73b6172 100644 (file)
@@ -139,7 +139,46 @@ static void pair_sub_for_all_args(
        const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode);
 
        for(i = 0; i < info->NumSrcRegs; i++) {
-               cb(userdata, fullinst, &sub->Arg[i]);
+               unsigned int src_type;
+               unsigned int channels = 0;
+               if (&fullinst->U.P.RGB == sub)
+                       channels = 3;
+               else if (&fullinst->U.P.Alpha == sub)
+                       channels = 1;
+
+               assert(channels > 0);
+               src_type = rc_source_type_swz(sub->Arg[i].Swizzle, channels);
+
+               if (src_type == RC_SOURCE_NONE)
+                       continue;
+
+               if (sub->Arg[i].Source == RC_PAIR_PRESUB_SRC) {
+                       unsigned int presub_type;
+                       unsigned int presub_src_count;
+                       struct rc_pair_instruction_source * src_array;
+                       unsigned int j;
+                       if (src_type & RC_SOURCE_RGB) {
+                               presub_type = fullinst->
+                                       U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Index;
+                               src_array = fullinst->U.P.RGB.Src;
+                       } else {
+                               presub_type = fullinst->
+                                       U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Index;
+                               src_array = fullinst->U.P.Alpha.Src;
+                       }
+                       presub_src_count
+                               = rc_presubtract_src_reg_count(presub_type);
+                       for(j = 0; j < presub_src_count; j++) {
+                               cb(userdata, fullinst, &sub->Arg[i],
+                                                               &src_array[j]);
+                       }
+               } else {
+                       struct rc_pair_instruction_source * src =
+                               rc_pair_get_src(&fullinst->U.P, &sub->Arg[i]);
+                       if (src) {
+                               cb(userdata, fullinst, &sub->Arg[i], src);
+                       }
+               }
        }
 }
 
@@ -308,6 +347,7 @@ static void remap_normal_instruction(struct rc_instruction * fullinst,
 {
        struct rc_sub_instruction * inst = &fullinst->U.I;
        const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
+       unsigned int remapped_presub = 0;
 
        if (opcode->HasDstReg) {
                rc_register_file file = inst->DstReg.File;
@@ -327,6 +367,12 @@ static void remap_normal_instruction(struct rc_instruction * fullinst,
                        unsigned int i;
                        unsigned int srcp_srcs = rc_presubtract_src_reg_count(
                                                inst->PreSub.Opcode);
+                       /* Make sure we only remap presubtract sources once in
+                        * case more than one source register reads the
+                        * presubtract result. */
+                       if (remapped_presub)
+                               continue;
+
                        for(i = 0; i < srcp_srcs; i++) {
                                file = inst->PreSub.SrcReg[i].File;
                                index = inst->PreSub.SrcReg[i].Index;
@@ -334,7 +380,7 @@ static void remap_normal_instruction(struct rc_instruction * fullinst,
                                inst->PreSub.SrcReg[i].File = file;
                                inst->PreSub.SrcReg[i].Index = index;
                        }
-
+                       remapped_presub = 1;
                }
                else {
                        cb(userdata, fullinst, &file, &index);
@@ -430,12 +476,29 @@ static rc_opcode get_flow_control_inst(struct rc_instruction * inst)
 
 }
 
+struct branch_write_mask {
+       unsigned int IfWriteMask:4;
+       unsigned int ElseWriteMask:4;
+       unsigned int HasElse:1;
+};
+
+union get_readers_read_cb {
+       rc_read_src_fn I;
+       rc_pair_read_arg_fn P;
+};
+
 struct get_readers_callback_data {
        struct radeon_compiler * C;
        struct rc_reader_data * ReaderData;
-       rc_read_src_fn ReadCB;
+       rc_read_src_fn ReadNormalCB;
+       rc_pair_read_arg_fn ReadPairCB;
        rc_read_write_mask_fn WriteCB;
+       rc_register_file DstFile;
+       unsigned int DstIndex;
+       unsigned int DstMask;
        unsigned int AliveWriteMask;
+       /*  For convenience, this is indexed starting at 1 */
+       struct branch_write_mask BranchMasks[R500_PFS_MAX_BRANCH_DEPTH_FULL + 1];
 };
 
 static void add_reader(
@@ -443,7 +506,7 @@ static void add_reader(
        struct rc_reader_data * data,
        struct rc_instruction * inst,
        unsigned int mask,
-       struct rc_src_register * src)
+       void * arg_or_src)
 {
        struct rc_reader * new;
        memory_pool_array_reserve(pool, struct rc_reader, data->Readers,
@@ -451,7 +514,74 @@ static void add_reader(
        new = &data->Readers[data->ReaderCount++];
        new->Inst = inst;
        new->WriteMask = mask;
-       new->Src = src;
+       if (inst->Type == RC_INSTRUCTION_NORMAL) {
+               new->U.Src = arg_or_src;
+       } else {
+               new->U.Arg = arg_or_src;
+       }
+}
+
+static unsigned int get_readers_read_callback(
+       struct get_readers_callback_data * cb_data,
+       unsigned int has_rel_addr,
+       rc_register_file file,
+       unsigned int index,
+       unsigned int swizzle)
+{
+       unsigned int shared_mask, read_mask;
+
+       if (has_rel_addr) {
+               cb_data->ReaderData->Abort = 1;
+               return RC_MASK_NONE;
+       }
+
+       shared_mask = rc_src_reads_dst_mask(file, index, swizzle,
+               cb_data->DstFile, cb_data->DstIndex, cb_data->AliveWriteMask);
+
+       if (shared_mask == RC_MASK_NONE)
+               return shared_mask;
+
+       /* If we make it this far, it means that this source reads from the
+        * same register written to by d->ReaderData->Writer. */
+
+       read_mask = rc_swizzle_to_writemask(swizzle);
+       if (cb_data->ReaderData->AbortOnRead & read_mask) {
+               cb_data->ReaderData->Abort = 1;
+               return shared_mask;
+       }
+
+       /* XXX The behavior in this case should be configurable. */
+       if ((read_mask & cb_data->AliveWriteMask) != read_mask) {
+               cb_data->ReaderData->Abort = 1;
+               return shared_mask;
+       }
+
+       return shared_mask;
+}
+
+static void get_readers_pair_read_callback(
+       void * userdata,
+       struct rc_instruction * inst,
+       struct rc_pair_instruction_arg * arg,
+       struct rc_pair_instruction_source * src)
+{
+       unsigned int shared_mask;
+       struct get_readers_callback_data * d = userdata;
+
+       shared_mask = get_readers_read_callback(d,
+                               0 /*Pair Instructions don't use RelAddr*/,
+                               src->File, src->Index, arg->Swizzle);
+
+       if (shared_mask == RC_MASK_NONE)
+               return;
+
+       if (d->ReadPairCB)
+               d->ReadPairCB(d->ReaderData, inst, arg, src);
+
+       if (d->ReaderData->Abort)
+               return;
+
+       add_reader(&d->C->Pool, d->ReaderData, inst, shared_mask, arg);
 }
 
 /**
@@ -464,37 +594,18 @@ static void get_readers_normal_read_callback(
        struct rc_src_register * src)
 {
        struct get_readers_callback_data * d = userdata;
-       unsigned int read_mask;
        unsigned int shared_mask;
 
-       if (src->RelAddr)
-               d->ReaderData->Abort = 1;
-
-       shared_mask = rc_src_reads_dst_mask(src->File, src->Index,
-               src->Swizzle,
-               d->ReaderData->Writer->U.I.DstReg.File,
-               d->ReaderData->Writer->U.I.DstReg.Index,
-               d->AliveWriteMask);
+       shared_mask = get_readers_read_callback(d,
+                       src->RelAddr, src->File, src->Index, src->Swizzle);
 
        if (shared_mask == RC_MASK_NONE)
                return;
+       /* The callback function could potentially clear d->ReaderData->Abort,
+        * so we need to call it before we return. */
+       if (d->ReadNormalCB)
+               d->ReadNormalCB(d->ReaderData, inst, src);
 
-       /* If we make it this far, it means that this source reads from the
-        * same register written to by d->ReaderData->Writer. */
-
-       if (d->ReaderData->AbortOnRead) {
-               d->ReaderData->Abort = 1;
-               return;
-       }
-
-       read_mask = rc_swizzle_to_writemask(src->Swizzle);
-       /* XXX The behavior in this case should be configurable. */
-       if ((read_mask & d->AliveWriteMask) != read_mask) {
-               d->ReaderData->Abort = 1;
-               return;
-       }
-
-       d->ReadCB(d->ReaderData, inst, src);
        if (d->ReaderData->Abort)
                return;
 
@@ -515,29 +626,132 @@ static void get_readers_write_callback(
 {
        struct get_readers_callback_data * d = userdata;
 
-       if (index == d->ReaderData->Writer->U.I.DstReg.Index
-               && file == d->ReaderData->Writer->U.I.DstReg.File) {
-                       unsigned int shared_mask = mask
-                               & d->ReaderData->Writer->U.I.DstReg.WriteMask;
-               if (d->ReaderData->InElse) {
-                       if (shared_mask & d->AliveWriteMask) {
-                               /* We set AbortOnRead here because the
-                                * destination register of d->ReaderData->Writer
-                                * is written to in both the IF and the
-                                * ELSE block of this IF/ELSE statement.
-                                * This means that readers of this
-                                * destination register that follow this IF/ELSE
-                                * statement use the value of different
-                                * instructions depending on the control flow
-                                * decisions made by the program. */
-                               d->ReaderData->AbortOnRead = 1;
+       if (index == d->DstIndex && file == d->DstFile) {
+               unsigned int shared_mask = mask & d->DstMask;
+               d->ReaderData->AbortOnRead &= ~shared_mask;
+               d->AliveWriteMask &= ~shared_mask;
+       }
+
+       if(d->WriteCB)
+               d->WriteCB(d->ReaderData, inst, file, index, mask);
+}
+
+static void get_readers_for_single_write(
+       void * userdata,
+       struct rc_instruction * writer,
+       rc_register_file dst_file,
+       unsigned int dst_index,
+       unsigned int dst_mask)
+{
+       struct rc_instruction * tmp;
+       unsigned int branch_depth = 0;
+       struct get_readers_callback_data * d = userdata;
+
+       d->ReaderData->Writer = writer;
+       d->ReaderData->AbortOnRead = 0;
+       d->ReaderData->InElse = 0;
+       d->DstFile = dst_file;
+       d->DstIndex = dst_index;
+       d->DstMask = dst_mask;
+       d->AliveWriteMask = dst_mask;
+       memset(d->BranchMasks, 0, sizeof(d->BranchMasks));
+
+       if (!dst_mask)
+               return;
+
+       for(tmp = writer->Next; tmp != &d->C->Program.Instructions;
+                                                       tmp = tmp->Next){
+               rc_opcode opcode = get_flow_control_inst(tmp);
+               switch(opcode) {
+               case RC_OPCODE_BGNLOOP:
+                       /* XXX We can do better when we see a BGNLOOP if we
+                        * add a flag called AbortOnWrite to struct
+                        * rc_reader_data and leave it set until the next
+                        * ENDLOOP. */
+               case RC_OPCODE_ENDLOOP:
+                       /* XXX We can do better when we see an ENDLOOP by
+                        * searching backwards from writer and looking for
+                        * readers of writer's destination index.  If we find a
+                        * reader before we get to the BGNLOOP, we must abort
+                        * unless there is another writer between that reader
+                        * and the BGNLOOP. */
+               case RC_OPCODE_BRK:
+               case RC_OPCODE_CONT:
+                       d->ReaderData->Abort = 1;
+                       return;
+               case RC_OPCODE_IF:
+                       branch_depth++;
+                       if (branch_depth > R500_PFS_MAX_BRANCH_DEPTH_FULL) {
+                               d->ReaderData->Abort = 1;
+                               return;
+                       }
+                       d->BranchMasks[branch_depth].IfWriteMask =
+                                                       d->AliveWriteMask;
+                       break;
+               case RC_OPCODE_ELSE:
+                       if (branch_depth == 0) {
+                               d->ReaderData->InElse = 1;
+                       } else {
+                               unsigned int temp_mask = d->AliveWriteMask;
+                               d->AliveWriteMask =
+                                       d->BranchMasks[branch_depth].IfWriteMask;
+                               d->BranchMasks[branch_depth].ElseWriteMask =
+                                                               temp_mask;
+                               d->BranchMasks[branch_depth].HasElse = 1;
                        }
+                       break;
+               case RC_OPCODE_ENDIF:
+                       if (branch_depth == 0) {
+                               d->ReaderData->AbortOnRead = d->AliveWriteMask;
+                               d->ReaderData->InElse = 0;
+                       }
+                       else {
+                               struct branch_write_mask * masks =
+                                       &d->BranchMasks[branch_depth];
+
+                               if (masks->HasElse) {
+                                       d->ReaderData->AbortOnRead |=
+                                               masks->IfWriteMask
+                                                       & ~masks->ElseWriteMask;
+                                       d->AliveWriteMask = masks->IfWriteMask
+                                               ^ ((masks->IfWriteMask ^
+                                                       masks->ElseWriteMask)
+                                               & (masks->IfWriteMask
+                                                       ^ d->AliveWriteMask));
+                               } else {
+                                       d->ReaderData->AbortOnRead |=
+                                               masks->IfWriteMask
+                                                       & ~d->AliveWriteMask;
+                                       d->AliveWriteMask = masks->IfWriteMask;
+
+                               }
+                               memset(masks, 0,
+                                       sizeof(struct branch_write_mask));
+                               branch_depth--;
+                       }
+                       break;
+               default:
+                       break;
+               }
+
+               if (d->ReaderData->InElse)
+                       continue;
+
+               if (tmp->Type == RC_INSTRUCTION_NORMAL) {
+                       rc_for_all_reads_src(tmp,
+                               get_readers_normal_read_callback, d);
                } else {
-                       d->AliveWriteMask &= ~shared_mask;
+                       rc_pair_for_all_reads_arg(tmp,
+                               get_readers_pair_read_callback, d);
                }
-       }
+               rc_for_all_writes_mask(tmp, get_readers_write_callback, d);
 
-       d->WriteCB(d->ReaderData, inst, file, index, mask);
+               if (d->ReaderData->Abort)
+                       return;
+
+               if (branch_depth == 0 && !d->AliveWriteMask)
+                       return;
+       }
 }
 
 /**
@@ -578,83 +792,26 @@ static void get_readers_write_callback(
  * @param write_cb This function will be called for every instruction after
  * writer.
  */
-void  rc_get_readers_normal(
+void rc_get_readers(
        struct radeon_compiler * c,
        struct rc_instruction * writer,
        struct rc_reader_data * data,
-       rc_read_src_fn read_cb,
+       rc_read_src_fn read_normal_cb,
+       rc_pair_read_arg_fn read_pair_cb,
        rc_read_write_mask_fn write_cb)
 {
-       struct rc_instruction * tmp;
        struct get_readers_callback_data d;
-       unsigned int branch_depth = 0;
 
-       data->Writer = writer;
        data->Abort = 0;
-       data->AbortOnRead = 0;
-       data->InElse = 0;
        data->ReaderCount = 0;
        data->ReadersReserved = 0;
        data->Readers = NULL;
 
        d.C = c;
-       d.AliveWriteMask = writer->U.I.DstReg.WriteMask;
        d.ReaderData = data;
-       d.ReadCB = read_cb;
+       d.ReadNormalCB = read_normal_cb;
+       d.ReadPairCB = read_pair_cb;
        d.WriteCB = write_cb;
 
-       if (!writer->U.I.DstReg.WriteMask)
-               return;
-
-       for(tmp = writer->Next; tmp != &c->Program.Instructions;
-                                                       tmp = tmp->Next){
-               rc_opcode opcode = get_flow_control_inst(tmp);
-               switch(opcode) {
-               case RC_OPCODE_BGNLOOP:
-                       /* XXX We can do better when we see a BGNLOOP if we
-                        * add a flag called AbortOnWrite to struct
-                        * rc_reader_data and leave it set until the next
-                        * ENDLOOP. */
-               case RC_OPCODE_ENDLOOP:
-                       /* XXX We can do better when we see an ENDLOOP by
-                        * searching backwards from writer and looking for
-                        * readers of writer's destination index.  If we find a
-                        * reader before we get to the BGNLOOP, we must abort
-                        * unless there is another writer between that reader
-                        * and the BGNLOOP. */
-                       data->Abort = 1;
-                       return;
-               case RC_OPCODE_IF:
-                       /* XXX We can do better here, but this will have to
-                        * do until this dataflow analysis is more mature. */
-                       data->Abort = 1;
-                       branch_depth++;
-                       break;
-               case RC_OPCODE_ELSE:
-                       if (branch_depth == 0)
-                               data->InElse = 1;
-                       break;
-               case RC_OPCODE_ENDIF:
-                       if (branch_depth == 0) {
-                               data->AbortOnRead = 1;
-                               data->InElse = 0;
-                       }
-                       else {
-                               branch_depth--;
-                       }
-                       break;
-               default:
-                       break;
-               }
-
-               if (!data->InElse)
-                       rc_for_all_reads_src(tmp, get_readers_normal_read_callback, &d);
-               rc_for_all_writes_mask(tmp, get_readers_write_callback, &d);
-
-               if (data->Abort)
-                       return;
-
-               if (!d.AliveWriteMask)
-                       return;
-       }
+       rc_for_all_writes_mask(writer, get_readers_for_single_write, &d);
 }
index 7de6b98f763c45fd0fa1b0afcbe3e8f1a224619d..ef971c5b23456d73553222b99bef616d852c0f40 100644 (file)
@@ -36,6 +36,7 @@ struct rc_instruction;
 struct rc_swizzle_caps;
 struct rc_src_register;
 struct rc_pair_instruction_arg;
+struct rc_pair_instruction_source;
 struct rc_compiler;
 
 
@@ -59,7 +60,8 @@ void rc_for_all_reads_src(struct rc_instruction * inst, rc_read_src_fn cb,
                        void * userdata);
 
 typedef void (*rc_pair_read_arg_fn)(void * userdata,
-       struct rc_instruction * inst, struct rc_pair_instruction_arg * arg);
+       struct rc_instruction * inst, struct rc_pair_instruction_arg * arg,
+       struct rc_pair_instruction_source * src);
 void rc_pair_for_all_reads_arg(struct rc_instruction * inst,
                                        rc_pair_read_arg_fn cb, void * userdata);
 
@@ -71,7 +73,10 @@ void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, v
 struct rc_reader {
        struct rc_instruction * Inst;
        unsigned int WriteMask;
-       struct rc_src_register * Src;
+       union {
+               struct rc_src_register * Src;
+               struct rc_pair_instruction_arg * Arg;
+       } U;
 };
 
 struct rc_reader_data {
@@ -87,14 +92,13 @@ struct rc_reader_data {
        void * CbData;
 };
 
-void rc_get_readers_normal(
+void rc_get_readers(
        struct radeon_compiler * c,
-       struct rc_instruction * inst,
+       struct rc_instruction * writer,
        struct rc_reader_data * data,
-       /*XXX: These should be their own function types. */
-       rc_read_src_fn read_cb,
+       rc_read_src_fn read_normal_cb,
+       rc_pair_read_arg_fn read_pair_cb,
        rc_read_write_mask_fn write_cb);
-
 /**
  * Compiler passes based on dataflow analysis.
  */
index da495a3afaa7d9eb0b666456646e8454f562be9e..25afd272beefd397326c360882ddeeb3311a171c 100644 (file)
@@ -66,6 +66,13 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
                .HasDstReg = 1,
                .IsComponentwise = 1
        },
+       {
+               .Opcode = RC_OPCODE_CLAMP,
+               .Name = "CLAMP",
+               .NumSrcRegs = 3,
+               .HasDstReg = 1,
+               .IsComponentwise = 1
+       },
        {
                .Opcode = RC_OPCODE_CMP,
                .Name = "CMP",
@@ -453,6 +460,7 @@ void rc_compute_sources_for_writemask(
                        srcmasks[1] |= RC_MASK_XY;
                        break;
                case RC_OPCODE_DP3:
+               case RC_OPCODE_XPD:
                        srcmasks[0] |= RC_MASK_XYZ;
                        srcmasks[1] |= RC_MASK_XYZ;
                        break;
@@ -460,6 +468,10 @@ void rc_compute_sources_for_writemask(
                        srcmasks[0] |= RC_MASK_XYZW;
                        srcmasks[1] |= RC_MASK_XYZW;
                        break;
+               case RC_OPCODE_DPH:
+                       srcmasks[0] |= RC_MASK_XYZ;
+                       srcmasks[1] |= RC_MASK_XYZW;
+                       break;
                case RC_OPCODE_TXB:
                case RC_OPCODE_TXP:
                        srcmasks[0] |= RC_MASK_W;
index d3f639c87012fc0d8268e52c484879db5c5798a5..7e666101276a2ed96269e324f91777281bbcf5f9 100644 (file)
@@ -50,6 +50,9 @@ typedef enum {
        /** vec4 instruction: dst.c = ceil(src0.c) */
        RC_OPCODE_CEIL,
 
+       /** vec4 instruction: dst.c = clamp(src0.c, src1.c, src2.c) */
+       RC_OPCODE_CLAMP,
+
        /** vec4 instruction: dst.c = src0.c < 0.0 ? src1.c : src2.c */
        RC_OPCODE_CMP,
 
index 15b9c5e7dc3eb39aef889772d1ecf3e44ac0173a..44f4c0fbdc74b4a119bcdcdfff1e5f225deb3149 100644 (file)
@@ -54,12 +54,7 @@ static struct rc_src_register chain_srcregs(struct rc_src_register outer, struct
                combine.Negate = outer.Negate;
        } else {
                combine.Abs = inner.Abs;
-               combine.Negate = 0;
-               for(unsigned int chan = 0; chan < 4; ++chan) {
-                       unsigned int swz = GET_SWZ(outer.Swizzle, chan);
-                       if (swz < 4)
-                               combine.Negate |= GET_BIT(inner.Negate, swz) << chan;
-               }
+               combine.Negate = swizzle_mask(outer.Swizzle, inner.Negate);
                combine.Negate ^= outer.Negate;
        }
        combine.Swizzle = combine_swizzles(inner.Swizzle, outer.Swizzle);
@@ -71,12 +66,13 @@ static void copy_propagate_scan_read(void * data, struct rc_instruction * inst,
 {
        rc_register_file file = src->File;
        struct rc_reader_data * reader_data = data;
-       const struct rc_opcode_info * info = rc_get_opcode_info(inst->U.I.Opcode);
 
-       /* It is possible to do copy propigation in this situation,
-        * just not right now, see peephole_add_presub_inv() */
-       if (reader_data->Writer->U.I.PreSub.Opcode != RC_PRESUB_NONE &&
-                       (info->NumSrcRegs > 2 || info->HasTexture)) {
+       if(!rc_inst_can_use_presub(inst,
+                               reader_data->Writer->U.I.PreSub.Opcode,
+                               rc_swizzle_to_writemask(src->Swizzle),
+                               *src,
+                               reader_data->Writer->U.I.PreSub.SrcReg[0],
+                               reader_data->Writer->U.I.PreSub.SrcReg[1])) {
                reader_data->Abort = 1;
                return;
        }
@@ -112,11 +108,11 @@ static void src_clobbered_reads_cb(
            && src->Index == sc_data->Index
            && (rc_swizzle_to_writemask(src->Swizzle) & sc_data->Mask)) {
 
-               sc_data->ReaderData->AbortOnRead = 1;
+               sc_data->ReaderData->AbortOnRead = RC_MASK_XYZW;
        }
 
        if (src->RelAddr && sc_data->File == RC_FILE_ADDRESS) {
-               sc_data->ReaderData->AbortOnRead = 1;
+               sc_data->ReaderData->AbortOnRead = RC_MASK_XYZW;
        }
 }
 
@@ -149,8 +145,9 @@ static void copy_propagate(struct radeon_compiler * c, struct rc_instruction * i
                return;
 
        /* Get a list of all the readers of this MOV instruction. */
-       rc_get_readers_normal(c, inst_mov, &reader_data,
-                       copy_propagate_scan_read, is_src_clobbered_scan_write);
+       rc_get_readers(c, inst_mov, &reader_data,
+                      copy_propagate_scan_read, NULL,
+                      is_src_clobbered_scan_write);
 
        if (reader_data.Abort || reader_data.ReaderCount == 0)
                return;
@@ -158,7 +155,7 @@ static void copy_propagate(struct radeon_compiler * c, struct rc_instruction * i
        /* Propagate the MOV instruction. */
        for (i = 0; i < reader_data.ReaderCount; i++) {
                struct rc_instruction * inst = reader_data.Readers[i].Inst;
-               *reader_data.Readers[i].Src = chain_srcregs(*reader_data.Readers[i].Src, inst_mov->U.I.SrcReg[0]);
+               *reader_data.Readers[i].U.Src = chain_srcregs(*reader_data.Readers[i].U.Src, inst_mov->U.I.SrcReg[0]);
 
                if (inst_mov->U.I.SrcReg[0].File == RC_FILE_PRESUB)
                        inst->U.I.PreSub = inst_mov->U.I.PreSub;
@@ -423,24 +420,13 @@ static void presub_scan_read(
        struct rc_src_register * src)
 {
        struct rc_reader_data * reader_data = data;
-       const struct rc_opcode_info * info =
-                                       rc_get_opcode_info(inst->U.I.Opcode);
-       /* XXX: There are some situations where instructions
-        * with more than 2 src registers can use the
-        * presubtract select, but to keep things simple we
-        * will disable presubtract on these instructions for
-        * now. */
-       if (info->NumSrcRegs > 2 || info->HasTexture) {
-               reader_data->Abort = 1;
-               return;
-       }
+       rc_presubtract_op * presub_opcode = reader_data->CbData;
 
-       /* We can't use more than one presubtract value in an
-        * instruction, unless the two prsubtract operations
-        * are the same and read from the same registers.
-        * XXX For now we will limit instructions to only one presubtract
-        * value.*/
-       if (inst->U.I.PreSub.Opcode != RC_PRESUB_NONE) {
+       if (!rc_inst_can_use_presub(inst, *presub_opcode,
+                       reader_data->Writer->U.I.DstReg.WriteMask,
+                       *src,
+                       reader_data->Writer->U.I.SrcReg[0],
+                       reader_data->Writer->U.I.SrcReg[1])) {
                reader_data->Abort = 1;
                return;
        }
@@ -454,8 +440,10 @@ static int presub_helper(
 {
        struct rc_reader_data reader_data;
        unsigned int i;
+       rc_presubtract_op cb_op = presub_opcode;
 
-       rc_get_readers_normal(c, inst_add, &reader_data, presub_scan_read,
+       reader_data.CbData = &cb_op;
+       rc_get_readers(c, inst_add, &reader_data, presub_scan_read, NULL,
                                                is_src_clobbered_scan_write);
 
        if (reader_data.Abort || reader_data.ReaderCount == 0)
@@ -468,7 +456,7 @@ static int presub_helper(
                                rc_get_opcode_info(reader.Inst->U.I.Opcode);
 
                for (src_index = 0; src_index < info->NumSrcRegs; src_index++) {
-                       if (&reader.Inst->U.I.SrcReg[src_index] == reader.Src)
+                       if (&reader.Inst->U.I.SrcReg[src_index] == reader.U.Src)
                                presub_replace(inst_add, reader.Inst, src_index);
                }
        }
@@ -505,7 +493,9 @@ static void presub_replace_add(
        inst_reader->U.I.SrcReg[src_index].Index = presub_opcode;
 }
 
-static int is_presub_candidate(struct rc_instruction * inst)
+static int is_presub_candidate(
+       struct radeon_compiler * c,
+       struct rc_instruction * inst)
 {
        const struct rc_opcode_info * info = rc_get_opcode_info(inst->U.I.Opcode);
        unsigned int i;
@@ -514,7 +504,12 @@ static int is_presub_candidate(struct rc_instruction * inst)
                return 0;
 
        for(i = 0; i < info->NumSrcRegs; i++) {
-               if (src_reads_dst_mask(inst->U.I.SrcReg[i], inst->U.I.DstReg))
+               struct rc_src_register src = inst->U.I.SrcReg[i];
+               if (src_reads_dst_mask(src, inst->U.I.DstReg))
+                       return 0;
+
+               src.File = RC_FILE_PRESUB;
+               if (!c->SwizzleCaps->IsNative(inst->U.I.Opcode, src))
                        return 0;
        }
        return 1;
@@ -528,7 +523,7 @@ static int peephole_add_presub_add(
        struct rc_src_register * src1 = NULL;
        unsigned int i;
 
-       if (!is_presub_candidate(inst_add))
+       if (!is_presub_candidate(c, inst_add))
                return 0;
 
        if (inst_add->U.I.SrcReg[0].Swizzle != inst_add->U.I.SrcReg[1].Swizzle)
@@ -592,7 +587,7 @@ static int peephole_add_presub_inv(
 {
        unsigned int i, swz, mask;
 
-       if (!is_presub_candidate(inst_add))
+       if (!is_presub_candidate(c, inst_add))
                return 0;
 
        mask = inst_add->U.I.DstReg.WriteMask;
index 91524f5ec6863c5f5e2edd897e0922659e720722..d53181e1f75646ff6e0513a16c18a81986f4008f 100644 (file)
@@ -66,10 +66,13 @@ struct regalloc_state {
        struct hardware_register * HwTemporary;
        unsigned int NumHwTemporaries;
        /**
-        * If an instruction is inside of a loop, end_loop will be the
-        * IP of the ENDLOOP instruction, otherwise end_loop will be 0
+        * If an instruction is inside of a loop, EndLoop will be the
+        * IP of the ENDLOOP instruction, and BeginLoop will be the IP
+        * of the BGNLOOP instruction.  Otherwise, EndLoop and BeginLoop
+        * will be -1.
         */
-       int end_loop;
+       int EndLoop;
+       int BeginLoop;
 };
 
 static void print_live_intervals(struct live_intervals * src)
@@ -180,11 +183,13 @@ static void scan_callback(void * data, struct rc_instruction * inst,
                reg->Used = 1;
                if (file == RC_FILE_INPUT)
                        reg->Live.Start = -1;
+               else if (s->BeginLoop >= 0)
+                       reg->Live.Start = s->BeginLoop;
                else
                        reg->Live.Start = inst->IP;
                reg->Live.End = inst->IP;
-       } else if (s->end_loop)
-               reg->Live.End = s->end_loop;
+       } else if (s->EndLoop >= 0)
+               reg->Live.End = s->EndLoop;
        else if (inst->IP > reg->Live.End)
                reg->Live.End = inst->IP;
 }
@@ -195,6 +200,8 @@ static void compute_live_intervals(struct radeon_compiler *c,
        memset(s, 0, sizeof(*s));
        s->C = c;
        s->NumHwTemporaries = c->max_temp_regs;
+       s->BeginLoop = -1;
+       s->EndLoop = -1;
        s->HwTemporary =
                memory_pool_malloc(&c->Pool,
                                   s->NumHwTemporaries * sizeof(struct hardware_register));
@@ -207,10 +214,12 @@ static void compute_live_intervals(struct radeon_compiler *c,
            inst = inst->Next) {
 
                /* For all instructions inside of a loop, the ENDLOOP
-                * instruction is used as the end of the live interval. */
-               if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && !s->end_loop) {
+                * instruction is used as the end of the live interval and
+                * the BGNLOOP instruction is used as the beginning. */
+               if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && s->EndLoop < 0) {
                        int loops = 1;
                        struct rc_instruction * tmp;
+                       s->BeginLoop = inst->IP;
                        for(tmp = inst->Next;
                                        tmp != &s->C->Program.Instructions;
                                        tmp = tmp->Next) {
@@ -219,15 +228,17 @@ static void compute_live_intervals(struct radeon_compiler *c,
                                } else if (tmp->U.I.Opcode
                                                        == RC_OPCODE_ENDLOOP) {
                                        if(!--loops) {
-                                               s->end_loop = tmp->IP;
+                                               s->EndLoop = tmp->IP;
                                                break;
                                        }
                                }
                        }
                }
 
-               if (inst->IP == s->end_loop)
-                       s->end_loop = 0;
+               if (inst->IP == s->EndLoop) {
+                       s->EndLoop = -1;
+                       s->BeginLoop = -1;
+               }
 
                rc_for_all_reads_mask(inst, scan_callback, s);
                rc_for_all_writes_mask(inst, scan_callback, s);
index 553e9dcf7c1e2098b394cff94c229f9682861fca..9beb5d6357996c9651796742c6e3fba6ea55ecdb 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 
 #include "radeon_compiler.h"
+#include "radeon_compiler_util.h"
 #include "radeon_dataflow.h"
 
 
@@ -54,6 +55,11 @@ struct schedule_instruction {
         * this instruction can be scheduled.
         */
        unsigned int NumDependencies:5;
+
+       /** List of all readers (see rc_get_readers() for the definition of
+        * "all readers"), even those outside the basic block this instruction
+        * lives in. */
+       struct rc_reader_data GlobalReaders;
 };
 
 
@@ -94,6 +100,16 @@ struct register_state {
        struct reg_value * Values[4];
 };
 
+struct remap_reg {
+       struct rc_instruciont * Inst;
+       unsigned int OldIndex:(RC_REGISTER_INDEX_BITS+1);
+       unsigned int OldSwizzle:3;
+       unsigned int NewIndex:(RC_REGISTER_INDEX_BITS+1);
+       unsigned int NewSwizzle:3;
+       unsigned int OnlyTexReads:1;
+       struct remap_reg * Next;
+};
+
 struct schedule_state {
        struct radeon_compiler * C;
        struct schedule_instruction * Current;
@@ -126,15 +142,6 @@ static struct reg_value ** get_reg_valuep(struct schedule_state * s,
        return &s->Temporary[index].Values[chan];
 }
 
-static struct reg_value * get_reg_value(struct schedule_state * s,
-               rc_register_file file, unsigned int index, unsigned int chan)
-{
-       struct reg_value ** pv = get_reg_valuep(s, file, index, chan);
-       if (!pv)
-               return 0;
-       return *pv;
-}
-
 static void add_inst_to_list(struct schedule_instruction ** list, struct schedule_instruction * inst)
 {
        inst->NextReady = *list;
@@ -295,12 +302,12 @@ static int merge_presub_sources(
        assert(dst_full->Alpha.Opcode == RC_OPCODE_NOP);
 
        switch(type) {
-       case RC_PAIR_SOURCE_RGB:
+       case RC_SOURCE_RGB:
                is_rgb = 1;
                is_alpha = 0;
                dst_sub = &dst_full->RGB;
                break;
-       case RC_PAIR_SOURCE_ALPHA:
+       case RC_SOURCE_ALPHA:
                is_rgb = 0;
                is_alpha = 1;
                dst_sub = &dst_full->Alpha;
@@ -341,6 +348,8 @@ static int merge_presub_sources(
                                continue;
                        free_source = rc_pair_alloc_source(dst_full, is_rgb,
                                        is_alpha, temp.File, temp.Index);
+                       if (free_source < 0)
+                               return 0;
                        one_way = 1;
                } else {
                        dst_sub->Src[free_source] = temp;
@@ -356,11 +365,11 @@ static int merge_presub_sources(
                for(arg = 0; arg < info->NumSrcRegs; arg++) {
                        /*If this arg does not read from an rgb source,
                         * do nothing. */
-                       if (!(rc_source_type_that_arg_reads(
-                               dst_full->RGB.Arg[arg].Source,
-                               dst_full->RGB.Arg[arg].Swizzle) & type)) {
+                       if (!(rc_source_type_swz(dst_full->RGB.Arg[arg].Swizzle,
+                                                               3) & type)) {
                                continue;
                        }
+
                        if (dst_full->RGB.Arg[arg].Source == srcp_src)
                                dst_full->RGB.Arg[arg].Source = free_source;
                        /* We need to do this just in case register
@@ -392,13 +401,13 @@ static int destructive_merge_instructions(
 
        /* Merge the rgb presubtract registers. */
        if (alpha->RGB.Src[RC_PAIR_PRESUB_SRC].Used) {
-               if (!merge_presub_sources(rgb, alpha->RGB, RC_PAIR_SOURCE_RGB)) {
+               if (!merge_presub_sources(rgb, alpha->RGB, RC_SOURCE_RGB)) {
                        return 0;
                }
        }
        /* Merge the alpha presubtract registers */
        if (alpha->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) {
-               if(!merge_presub_sources(rgb,  alpha->Alpha, RC_PAIR_SOURCE_ALPHA)){
+               if(!merge_presub_sources(rgb,  alpha->Alpha, RC_SOURCE_ALPHA)){
                        return 0;
                }
        }
@@ -525,6 +534,222 @@ static void presub_nop(struct rc_instruction * emitted) {
                }
        }
 }
+
+static void rgb_to_alpha_remap (
+       struct rc_instruction * inst,
+       struct rc_pair_instruction_arg * arg,
+       rc_register_file old_file,
+       rc_swizzle old_swz,
+       unsigned int new_index)
+{
+       int new_src_index;
+       unsigned int i;
+       struct rc_pair_instruction_source * old_src =
+                                       rc_pair_get_src(&inst->U.P, arg);
+       if (!old_src) {
+               return;
+       }
+
+       for (i = 0; i < 3; i++) {
+               if (get_swz(arg->Swizzle, i) == old_swz) {
+                       SET_SWZ(arg->Swizzle, i, RC_SWIZZLE_W);
+               }
+       }
+       memset(old_src, 0, sizeof(struct rc_pair_instruction_source));
+       new_src_index = rc_pair_alloc_source(&inst->U.P, 0, 1,
+                                                       old_file, new_index);
+       /* This conversion is not possible, we must have made a mistake in
+        * is_rgb_to_alpha_possible. */
+       if (new_src_index < 0) {
+               assert(0);
+               return;
+       }
+
+       arg->Source = new_src_index;
+}
+
+static int can_remap(unsigned int opcode)
+{
+       switch(opcode) {
+       case RC_OPCODE_DDX:
+       case RC_OPCODE_DDY:
+               return 0;
+       default:
+               return 1;
+       }
+}
+
+static int can_convert_opcode_to_alpha(unsigned int opcode)
+{
+       switch(opcode) {
+       case RC_OPCODE_DDX:
+       case RC_OPCODE_DDY:
+       case RC_OPCODE_DP2:
+       case RC_OPCODE_DP3:
+       case RC_OPCODE_DP4:
+       case RC_OPCODE_DPH:
+               return 0;
+       default:
+               return 1;
+       }
+}
+
+static void is_rgb_to_alpha_possible(
+       void * userdata,
+       struct rc_instruction * inst,
+       struct rc_pair_instruction_arg * arg,
+       struct rc_pair_instruction_source * src)
+{
+       unsigned int chan_count = 0;
+       unsigned int alpha_sources = 0;
+       unsigned int i;
+       struct rc_reader_data * reader_data = userdata;
+
+       if (!can_remap(inst->U.P.RGB.Opcode)
+           || !can_remap(inst->U.P.Alpha.Opcode)) {
+               reader_data->Abort = 1;
+               return;
+       }
+
+       if (!src)
+               return;
+
+       /* XXX There are some cases where we can still do the conversion if
+        * a reader reads from a presubtract source, but for now we'll prevent
+        * it. */
+       if (arg->Source == RC_PAIR_PRESUB_SRC) {
+               reader_data->Abort = 1;
+               return;
+       }
+
+       /* Make sure the source only reads from one component.
+        * XXX We should allow the source to read from the same component twice.
+        * XXX If the index we will be converting to is the same as the
+        * current index, then it is OK to read from more than one component.
+        */
+       for (i = 0; i < 3; i++) {
+               rc_swizzle swz = get_swz(arg->Swizzle, i);
+               switch(swz) {
+               case RC_SWIZZLE_X:
+               case RC_SWIZZLE_Y:
+               case RC_SWIZZLE_Z:
+               case RC_SWIZZLE_W:
+                       chan_count++;
+                       break;
+               default:
+                       break;
+               }
+       }
+       if (chan_count > 1) {
+               reader_data->Abort = 1;
+               return;
+       }
+
+       /* Make sure there are enough alpha sources.
+        * XXX If we know what register all the readers are going
+        * to be remapped to, then in some situations we can still do
+        * the subsitution, even if all 3 alpha sources are being used.*/
+       for (i = 0; i < 3; i++) {
+               if (inst->U.P.Alpha.Src[i].Used) {
+                       alpha_sources++;
+               }
+       }
+       if (alpha_sources > 2) {
+               reader_data->Abort = 1;
+               return;
+       }
+}
+
+static int convert_rgb_to_alpha(
+       struct schedule_state * s,
+       struct schedule_instruction * sched_inst)
+{
+       struct rc_pair_instruction * pair_inst = &sched_inst->Instruction->U.P;
+       unsigned int old_mask = pair_inst->RGB.WriteMask;
+       unsigned int old_swz = rc_mask_to_swizzle(old_mask);
+       const struct rc_opcode_info * info =
+                               rc_get_opcode_info(pair_inst->RGB.Opcode);
+       int new_index = -1;
+       unsigned int i;
+
+       if (sched_inst->GlobalReaders.Abort)
+               return 0;
+
+       if (!pair_inst->RGB.WriteMask)
+               return 0;
+
+       if (!can_convert_opcode_to_alpha(pair_inst->RGB.Opcode)
+           || !can_convert_opcode_to_alpha(pair_inst->Alpha.Opcode)) {
+               return 0;
+       }
+
+       assert(sched_inst->NumWriteValues == 1);
+
+       if (!sched_inst->WriteValues[0]) {
+               assert(0);
+               return 0;
+       }
+
+       /* We start at the old index, because if we can reuse the same
+        * register and just change the swizzle then it is more likely we
+        * will be able to convert all the readers. */
+       for (i = pair_inst->RGB.DestIndex; i < RC_REGISTER_MAX_INDEX; i++) {
+               struct reg_value ** new_regvalp = get_reg_valuep(
+                                               s, RC_FILE_TEMPORARY, i, 3);
+               if (!*new_regvalp) {
+                       struct reg_value ** old_regvalp =
+                               get_reg_valuep(s,
+                                       RC_FILE_TEMPORARY,
+                                       pair_inst->RGB.DestIndex,
+                                       rc_mask_to_swizzle(old_mask));
+                       new_index = i;
+                       *new_regvalp = *old_regvalp;
+                       *old_regvalp = NULL;
+                       new_regvalp = get_reg_valuep(s, RC_FILE_TEMPORARY, i, 3);
+                       break;
+               }
+       }
+       if (new_index < 0) {
+               return 0;
+       }
+
+       pair_inst->Alpha.Opcode = pair_inst->RGB.Opcode;
+       pair_inst->Alpha.DestIndex = new_index;
+       pair_inst->Alpha.WriteMask = 1;
+       pair_inst->Alpha.Target = pair_inst->RGB.Target;
+       pair_inst->Alpha.OutputWriteMask = pair_inst->RGB.OutputWriteMask;
+       pair_inst->Alpha.DepthWriteMask = pair_inst->RGB.DepthWriteMask;
+       pair_inst->Alpha.Saturate = pair_inst->RGB.Saturate;
+       memcpy(pair_inst->Alpha.Arg, pair_inst->RGB.Arg,
+                                               sizeof(pair_inst->Alpha.Arg));
+       /* Move the swizzles into the first chan */
+       for (i = 0; i < info->NumSrcRegs; i++) {
+               unsigned int j;
+               for (j = 0; j < 3; j++) {
+                       unsigned int swz = get_swz(pair_inst->Alpha.Arg[i].Swizzle, j);
+                       if (swz != RC_SWIZZLE_UNUSED) {
+                               pair_inst->Alpha.Arg[i].Swizzle = swz;
+                               break;
+                       }
+               }
+       }
+       pair_inst->RGB.Opcode = RC_OPCODE_NOP;
+       pair_inst->RGB.DestIndex = 0;
+       pair_inst->RGB.WriteMask = 0;
+       pair_inst->RGB.Target = 0;
+       pair_inst->RGB.OutputWriteMask = 0;
+       pair_inst->RGB.DepthWriteMask = 0;
+       pair_inst->RGB.Saturate = 0;
+       memset(pair_inst->RGB.Arg, 0, sizeof(pair_inst->RGB.Arg));
+
+       for(i = 0; i < sched_inst->GlobalReaders.ReaderCount; i++) {
+               struct rc_reader reader = sched_inst->GlobalReaders.Readers[i];
+               rgb_to_alpha_remap(reader.Inst, reader.U.Arg,
+                                       RC_FILE_TEMPORARY, old_swz, new_index);
+       }
+       return 1;
+}
+
 /**
  * Find a good ALU instruction or pair of ALU instruction and emit it.
  *
@@ -536,24 +761,16 @@ static void emit_one_alu(struct schedule_state *s, struct rc_instruction * befor
 {
        struct schedule_instruction * sinst;
 
-       if (s->ReadyFullALU || !(s->ReadyRGB && s->ReadyAlpha)) {
-               if (s->ReadyFullALU) {
-                       sinst = s->ReadyFullALU;
-                       s->ReadyFullALU = s->ReadyFullALU->NextReady;
-               } else if (s->ReadyRGB) {
-                       sinst = s->ReadyRGB;
-                       s->ReadyRGB = s->ReadyRGB->NextReady;
-               } else {
-                       sinst = s->ReadyAlpha;
-                       s->ReadyAlpha = s->ReadyAlpha->NextReady;
-               }
-
+       if (s->ReadyFullALU) {
+               sinst = s->ReadyFullALU;
+               s->ReadyFullALU = s->ReadyFullALU->NextReady;
                rc_insert_instruction(before->Prev, sinst->Instruction);
                commit_alu_instruction(s, sinst);
        } else {
                struct schedule_instruction **prgb;
                struct schedule_instruction **palpha;
-
+               struct schedule_instruction *prev;
+pair:
                /* Some pairings might fail because they require too
                 * many source slots; try all possible pairings if necessary */
                for(prgb = &s->ReadyRGB; *prgb; prgb = &(*prgb)->NextReady) {
@@ -572,10 +789,43 @@ static void emit_one_alu(struct schedule_state *s, struct rc_instruction * befor
                                goto success;
                        }
                }
-
-               /* No success in pairing; just take the first RGB instruction */
-               sinst = s->ReadyRGB;
-               s->ReadyRGB = s->ReadyRGB->NextReady;
+               prev = NULL;
+               /* No success in pairing, now try to convert one of the RGB
+                * instructions to an Alpha so we can pair it with another RGB.
+                */
+               if (s->ReadyRGB && s->ReadyRGB->NextReady) {
+               for(prgb = &s->ReadyRGB; *prgb; prgb = &(*prgb)->NextReady) {
+                       if ((*prgb)->NumWriteValues == 1) {
+                               struct schedule_instruction * prgb_next;
+                               if (!convert_rgb_to_alpha(s, *prgb))
+                                       goto cont_loop;
+                               prgb_next = (*prgb)->NextReady;
+                               /* Add instruction to the Alpha ready list. */
+                               (*prgb)->NextReady = s->ReadyAlpha;
+                               s->ReadyAlpha = *prgb;
+                               /* Remove instruction from the RGB ready list.*/
+                               if (prev)
+                                       prev->NextReady = prgb_next;
+                               else
+                                       s->ReadyRGB = prgb_next;
+                               goto pair;
+                       }
+cont_loop:
+                       prev = *prgb;
+               }
+               }
+               /* Still no success in pairing, just take the first RGB
+                * or alpha instruction. */
+               if (s->ReadyRGB) {
+                       sinst = s->ReadyRGB;
+                       s->ReadyRGB = s->ReadyRGB->NextReady;
+               } else if (s->ReadyAlpha) {
+                       sinst = s->ReadyAlpha;
+                       s->ReadyAlpha = s->ReadyAlpha->NextReady;
+               } else {
+                       /*XXX Something real bad has happened. */
+                       assert(0);
+               }
 
                rc_insert_instruction(before->Prev, sinst->Instruction);
                commit_alu_instruction(s, sinst);
@@ -591,13 +841,13 @@ static void scan_read(void * data, struct rc_instruction * inst,
                rc_register_file file, unsigned int index, unsigned int chan)
 {
        struct schedule_state * s = data;
-       struct reg_value * v = get_reg_value(s, file, index, chan);
+       struct reg_value ** v = get_reg_valuep(s, file, index, chan);
        struct reg_value_reader * reader;
 
        if (!v)
                return;
 
-       if (v->Writer == s->Current) {
+       if (*v && (*v)->Writer == s->Current) {
                /* The instruction reads and writes to a register component.
                 * In this case, we only want to increment dependencies by one.
                 */
@@ -608,16 +858,28 @@ static void scan_read(void * data, struct rc_instruction * inst,
 
        reader = memory_pool_malloc(&s->C->Pool, sizeof(*reader));
        reader->Reader = s->Current;
-       reader->Next = v->Readers;
-       v->Readers = reader;
-       v->NumReaders++;
-
-       s->Current->NumDependencies++;
+       if (!*v) {
+               /* In this situation, the instruction reads from a register
+                * that hasn't been written to or read from in the current
+                * block. */
+               *v = memory_pool_malloc(&s->C->Pool, sizeof(struct reg_value));
+               memset(*v, 0, sizeof(struct reg_value));
+               (*v)->Readers = reader;
+       } else {
+               reader->Next = (*v)->Readers;
+               (*v)->Readers = reader;
+               /* Only update the current instruction's dependencies if the
+                * register it reads from has been written to in this block. */
+               if ((*v)->Writer) {
+                       s->Current->NumDependencies++;
+               }
+       }
+       (*v)->NumReaders++;
 
        if (s->Current->NumReadValues >= 12) {
                rc_error(s->C, "%s: NumReadValues overflow\n", __FUNCTION__);
        } else {
-               s->Current->ReadValues[s->Current->NumReadValues++] = v;
+               s->Current->ReadValues[s->Current->NumReadValues++] = *v;
        }
 }
 
@@ -652,6 +914,16 @@ static void scan_write(void * data, struct rc_instruction * inst,
        }
 }
 
+static void is_rgb_to_alpha_possible_normal(
+       void * userdata,
+       struct rc_instruction * inst,
+       struct rc_src_register * src)
+{
+       struct rc_reader_data * reader_data = userdata;
+       reader_data->Abort = 1;
+
+}
+
 static void schedule_block(struct r300_fragment_program_compiler * c,
                struct rc_instruction * begin, struct rc_instruction * end)
 {
@@ -683,6 +955,11 @@ static void schedule_block(struct r300_fragment_program_compiler * c,
 
                if (!s.Current->NumDependencies)
                        instruction_ready(&s, s.Current);
+
+               /* Get global readers for possible RGB->Alpha conversion. */
+               rc_get_readers(s.C, inst, &s.Current->GlobalReaders,
+                               is_rgb_to_alpha_possible_normal,
+                               is_rgb_to_alpha_possible, NULL);
        }
 
        /* Temporarily unlink all instructions */
@@ -711,8 +988,13 @@ static int is_controlflow(struct rc_instruction * inst)
 
 void rc_pair_schedule(struct radeon_compiler *cc, void *user)
 {
+       struct schedule_state s;
+
        struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
        struct rc_instruction * inst = c->Base.Program.Instructions.Next;
+
+       memset(&s, 0, sizeof(s));
+       s.C = &c->Base;
        while(inst != &c->Base.Program.Instructions) {
                struct rc_instruction * first;
 
index c549be52183891867e2153b783a78aacef853f5f..fc05366f50ee3d8bfb45af2991dbe90696a8e295 100644 (file)
@@ -280,9 +280,12 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
                        pair->RGB.DestIndex = inst->DstReg.Index;
                        pair->RGB.WriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ;
                }
+
                if (needalpha) {
-                       pair->Alpha.DestIndex = inst->DstReg.Index;
                        pair->Alpha.WriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
+                       if (pair->Alpha.WriteMask) {
+                               pair->Alpha.DestIndex = inst->DstReg.Index;
+                       }
                }
        }
 
index 24b685fbeb4a4cd51df2067b0223cb9f2ba7fb03..fe5756ebc45deb990ab2636d3b522ee2749ae7f0 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 
 #include "radeon_compiler.h"
+#include "radeon_dataflow.h"
 
 
 /**
@@ -70,58 +71,98 @@ void rc_local_transform(
        }
 }
 
+struct get_used_temporaries_data {
+       unsigned char * Used;
+       unsigned int UsedLength;
+};
+
+static void get_used_temporaries_cb(
+       void * userdata,
+       struct rc_instruction * inst,
+       rc_register_file file,
+       unsigned int index,
+       unsigned int mask)
+{
+       struct get_used_temporaries_data * d = userdata;
+
+       if (file != RC_FILE_TEMPORARY)
+               return;
+
+       if (index >= d->UsedLength)
+               return;
+
+       d->Used[index] |= mask;
+}
+
 /**
- * Left multiplication of a register with a swizzle
+ * This function fills in the parameter 'used' with a writemask that
+ * represent which components of each temporary register are used by the
+ * program.  This is meant to be combined with rc_find_free_temporary_list as a
+ * more efficient version of rc_find_free_temporary.
+ * @param used The function does not initialize this parameter.
  */
-struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg)
+void rc_get_used_temporaries(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length)
+{
+       struct rc_instruction * inst;
+       struct get_used_temporaries_data d;
+       d.Used = used;
+       d.UsedLength = used_length;
+
+       for(inst = c->Program.Instructions.Next;
+                       inst != &c->Program.Instructions; inst = inst->Next) {
+
+               rc_for_all_reads_mask(inst, get_used_temporaries_cb, &d);
+               rc_for_all_writes_mask(inst, get_used_temporaries_cb, &d);
+       }
+}
+
+/* Search a list of used temporaries for a free one
+ * \sa rc_get_used_temporaries
+ * @note If this functions finds a free temporary, it will mark it as used
+ * in the used temporary list (param 'used')
+ * @param used list of used temporaries
+ * @param used_length number of items in param 'used'
+ * @param mask which components must be free in the temporary index that is
+ * returned.
+ * @return -1 If there are no more free temporaries, otherwise the index of
+ * a temporary register where the components specified in param 'mask' are
+ * not being used.
+ */
+int rc_find_free_temporary_list(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length,
+       unsigned int mask)
 {
-       struct rc_src_register tmp = srcreg;
        int i;
-       tmp.Swizzle = 0;
-       tmp.Negate = 0;
-       for(i = 0; i < 4; ++i) {
-               rc_swizzle swz = GET_SWZ(swizzle, i);
-               if (swz < 4) {
-                       tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
-                       tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
-               } else {
-                       tmp.Swizzle |= swz << (i*3);
+       for(i = 0; i < used_length; i++) {
+               if ((~used[i] & mask) == mask) {
+                       used[i] |= mask;
+                       return i;
                }
        }
-       return tmp;
+       return -1;
 }
 
 unsigned int rc_find_free_temporary(struct radeon_compiler * c)
 {
-       char used[RC_REGISTER_MAX_INDEX];
-       unsigned int i;
-       struct rc_instruction * rcinst;
+       unsigned char used[RC_REGISTER_MAX_INDEX];
+       int free;
 
        memset(used, 0, sizeof(used));
 
-       for (rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
-               const struct rc_sub_instruction *inst = &rcinst->U.I;
-               const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
-               unsigned int k;
-
-               for (k = 0; k < opcode->NumSrcRegs; k++) {
-                       if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
-                               used[inst->SrcReg[k].Index] = 1;
-               }
-
-               if (opcode->HasDstReg) {
-                       if (inst->DstReg.File == RC_FILE_TEMPORARY)
-                               used[inst->DstReg.Index] = 1;
-               }
-       }
+       rc_get_used_temporaries(c, used, RC_REGISTER_MAX_INDEX);
 
-       for (i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
-               if (!used[i])
-                       return i;
+       free = rc_find_free_temporary_list(c, used, RC_REGISTER_MAX_INDEX,
+                                                               RC_MASK_XYZW);
+       if (free < 0) {
+               rc_error(c, "Ran out of temporary registers\n");
+               return 0;
        }
-
-       rc_error(c, "Ran out of temporary registers\n");
-       return 0;
+       return free;
 }
 
 
index f0a77d7b53967ecb2962c7c19fd571e699dbbb80..df6c94b35f9ba07bbd1ef0aa76b1028ad3adb113 100644 (file)
@@ -159,47 +159,6 @@ struct rc_program {
        struct rc_constant_list Constants;
 };
 
-static inline rc_swizzle get_swz(unsigned int swz, rc_swizzle idx)
-{
-       if (idx & 0x4)
-               return idx;
-       return GET_SWZ(swz, idx);
-}
-
-static inline unsigned int combine_swizzles4(unsigned int src,
-               rc_swizzle swz_x, rc_swizzle swz_y, rc_swizzle swz_z, rc_swizzle swz_w)
-{
-       unsigned int ret = 0;
-
-       ret |= get_swz(src, swz_x);
-       ret |= get_swz(src, swz_y) << 3;
-       ret |= get_swz(src, swz_z) << 6;
-       ret |= get_swz(src, swz_w) << 9;
-
-       return ret;
-}
-
-static inline unsigned int combine_swizzles(unsigned int src, unsigned int swz)
-{
-       unsigned int ret = 0;
-
-       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_X));
-       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Y)) << 3;
-       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Z)) << 6;
-       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_W)) << 9;
-
-       return ret;
-}
-
-struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg);
-
-static inline void reset_srcreg(struct rc_src_register* reg)
-{
-       memset(reg, 0, sizeof(struct rc_src_register));
-       reg->Swizzle = RC_SWIZZLE_XYZW;
-}
-
-
 /**
  * A transformation that can be passed to \ref rc_local_transform.
  *
@@ -222,6 +181,17 @@ void rc_local_transform(
        struct radeon_compiler *c,
        void *user);
 
+void rc_get_used_temporaries(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length);
+
+int rc_find_free_temporary_list(
+       struct radeon_compiler * c,
+       unsigned char * used,
+       unsigned int used_length,
+       unsigned int mask);
+
 unsigned int rc_find_free_temporary(struct radeon_compiler * c);
 
 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
@@ -233,4 +203,5 @@ unsigned int rc_recompute_ips(struct radeon_compiler * c);
 
 void rc_print_program(const struct rc_program *prog);
 
+rc_swizzle rc_mask_to_swizzle(unsigned int mask);
 #endif
index 39408845d5ad80f69d3efe0ae9d4b2bac4beb3df..58977a40c7c2ca71a4351c8b06bd786a848e48eb 100644 (file)
@@ -36,6 +36,7 @@
 #include "radeon_program_alu.h"
 
 #include "radeon_compiler.h"
+#include "radeon_compiler_util.h"
 
 
 static struct rc_instruction *emit1(
@@ -84,16 +85,6 @@ static struct rc_instruction *emit3(
        return fpi;
 }
 
-static struct rc_dst_register dstreg(int file, int index)
-{
-       struct rc_dst_register dst;
-       dst.File = file;
-       dst.Index = index;
-       dst.WriteMask = RC_MASK_XYZW;
-       dst.RelAddr = 0;
-       return dst;
-}
-
 static struct rc_dst_register dstregtmpmask(int index, int mask)
 {
        struct rc_dst_register dst = {0};
@@ -186,6 +177,38 @@ static struct rc_src_register swizzle_wwww(struct rc_src_register reg)
        return swizzle_smear(reg, RC_SWIZZLE_W);
 }
 
+static int is_dst_safe_to_reuse(struct rc_instruction *inst)
+{
+       const struct rc_opcode_info *info = rc_get_opcode_info(inst->U.I.Opcode);
+       unsigned i;
+
+       assert(info->HasDstReg);
+
+       if (inst->U.I.DstReg.File != RC_FILE_TEMPORARY)
+               return 0;
+
+       for (i = 0; i < info->NumSrcRegs; i++) {
+               if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY &&
+                   inst->U.I.SrcReg[i].Index == inst->U.I.DstReg.Index)
+                       return 0;
+       }
+
+       return 1;
+}
+
+static struct rc_dst_register try_to_reuse_dst(struct radeon_compiler *c,
+                                              struct rc_instruction *inst)
+{
+       unsigned tmp;
+
+       if (is_dst_safe_to_reuse(inst))
+               tmp = inst->U.I.DstReg.Index;
+       else
+               tmp = rc_find_free_temporary(c);
+
+       return dstregtmpmask(tmp, inst->U.I.DstReg.WriteMask);
+}
+
 static void transform_ABS(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
@@ -209,10 +232,26 @@ static void transform_CEIL(struct radeon_compiler* c,
         *     ceil(x) = x+frac(-x)
         */
 
-       int tempreg = rc_find_free_temporary(c);
-       emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstreg(RC_FILE_TEMPORARY, tempreg), negate(inst->U.I.SrcReg[0]));
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
+       emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dst, negate(inst->U.I.SrcReg[0]));
        emit2(c, inst->Prev, RC_OPCODE_ADD, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, tempreg));
+               inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, dst.Index));
+       rc_remove_instruction(inst);
+}
+
+static void transform_CLAMP(struct radeon_compiler *c,
+       struct rc_instruction *inst)
+{
+       /* CLAMP dst, src, min, max
+        *    into:
+        * MIN tmp, src, max
+        * MAX dst, tmp, min
+        */
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
+       emit2(c, inst->Prev, RC_OPCODE_MIN, 0, dst,
+               inst->U.I.SrcReg[0], inst->U.I.SrcReg[2]);
+       emit2(c, inst->Prev, RC_OPCODE_MAX, inst->U.I.SaturateMode, inst->U.I.DstReg,
+               srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[1]);
        rc_remove_instruction(inst);
 }
 
@@ -258,10 +297,10 @@ static void transform_DST(struct radeon_compiler* c,
 static void transform_FLR(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
-       emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->U.I.SrcReg[0]);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
+       emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dst, inst->U.I.SrcReg[0]);
        emit2(c, inst->Prev, RC_OPCODE_ADD, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               inst->U.I.SrcReg[0], negate(srcreg(RC_FILE_TEMPORARY, tempreg)));
+               inst->U.I.SrcReg[0], negate(srcreg(RC_FILE_TEMPORARY, dst.Index)));
        rc_remove_instruction(inst);
 }
 
@@ -351,14 +390,14 @@ static void transform_LIT(struct radeon_compiler* c,
 static void transform_LRP(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
        emit2(c, inst->Prev, RC_OPCODE_ADD, 0,
-               dstreg(RC_FILE_TEMPORARY, tempreg),
+               dst,
                inst->U.I.SrcReg[1], negate(inst->U.I.SrcReg[2]));
        emit3(c, inst->Prev, RC_OPCODE_MAD, inst->U.I.SaturateMode,
                inst->U.I.DstReg,
-               inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, tempreg), inst->U.I.SrcReg[2]);
+               inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[2]);
 
        rc_remove_instruction(inst);
 }
@@ -366,9 +405,8 @@ static void transform_LRP(struct radeon_compiler* c,
 static void transform_POW(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
-       struct rc_dst_register tempdst = dstreg(RC_FILE_TEMPORARY, tempreg);
-       struct rc_src_register tempsrc = srcreg(RC_FILE_TEMPORARY, tempreg);
+       struct rc_dst_register tempdst = try_to_reuse_dst(c, inst);
+       struct rc_src_register tempsrc = srcreg(RC_FILE_TEMPORARY, tempdst.Index);
        tempdst.WriteMask = RC_MASK_W;
        tempsrc.Swizzle = RC_SWIZZLE_WWWW;
 
@@ -388,11 +426,11 @@ static void transform_RSQ(struct radeon_compiler* c,
 static void transform_SEQ(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
+       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
        emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               negate(absolute(srcreg(RC_FILE_TEMPORARY, tempreg))), builtin_zero, builtin_one);
+               negate(absolute(srcreg(RC_FILE_TEMPORARY, dst.Index))), builtin_zero, builtin_one);
 
        rc_remove_instruction(inst);
 }
@@ -407,11 +445,11 @@ static void transform_SFL(struct radeon_compiler* c,
 static void transform_SGE(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
+       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
        emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               srcreg(RC_FILE_TEMPORARY, tempreg), builtin_zero, builtin_one);
+               srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_zero, builtin_one);
 
        rc_remove_instruction(inst);
 }
@@ -419,11 +457,11 @@ static void transform_SGE(struct radeon_compiler* c,
 static void transform_SGT(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), negate(inst->U.I.SrcReg[0]), inst->U.I.SrcReg[1]);
+       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, negate(inst->U.I.SrcReg[0]), inst->U.I.SrcReg[1]);
        emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               srcreg(RC_FILE_TEMPORARY, tempreg), builtin_one, builtin_zero);
+               srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_one, builtin_zero);
 
        rc_remove_instruction(inst);
 }
@@ -431,11 +469,11 @@ static void transform_SGT(struct radeon_compiler* c,
 static void transform_SLE(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), negate(inst->U.I.SrcReg[0]), inst->U.I.SrcReg[1]);
+       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, negate(inst->U.I.SrcReg[0]), inst->U.I.SrcReg[1]);
        emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               srcreg(RC_FILE_TEMPORARY, tempreg), builtin_zero, builtin_one);
+               srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_zero, builtin_one);
 
        rc_remove_instruction(inst);
 }
@@ -443,11 +481,11 @@ static void transform_SLE(struct radeon_compiler* c,
 static void transform_SLT(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
+       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
        emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               srcreg(RC_FILE_TEMPORARY, tempreg), builtin_one, builtin_zero);
+               srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_one, builtin_zero);
 
        rc_remove_instruction(inst);
 }
@@ -455,11 +493,11 @@ static void transform_SLT(struct radeon_compiler* c,
 static void transform_SNE(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
+       emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1]));
        emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode, inst->U.I.DstReg,
-               negate(absolute(srcreg(RC_FILE_TEMPORARY, tempreg))), builtin_one, builtin_zero);
+               negate(absolute(srcreg(RC_FILE_TEMPORARY, dst.Index))), builtin_one, builtin_zero);
 
        rc_remove_instruction(inst);
 }
@@ -473,12 +511,13 @@ static void transform_SSG(struct radeon_compiler* c,
         *   CMP tmp1, x, 1, 0
         *   ADD result, tmp0, -tmp1;
         */
-       unsigned tmp0, tmp1;
+       struct rc_dst_register dst0;
+       unsigned tmp1;
 
        /* 0 < x */
-       tmp0 = rc_find_free_temporary(c);
+       dst0 = try_to_reuse_dst(c, inst);
        emit3(c, inst->Prev, RC_OPCODE_CMP, 0,
-             dstregtmpmask(tmp0, inst->U.I.DstReg.WriteMask),
+             dst0,
              negate(inst->U.I.SrcReg[0]),
              builtin_one,
              builtin_zero);
@@ -495,7 +534,7 @@ static void transform_SSG(struct radeon_compiler* c,
        /* result = tmp0 - tmp1 */
        emit2(c, inst->Prev, RC_OPCODE_ADD, 0,
              inst->U.I.DstReg,
-             srcreg(RC_FILE_TEMPORARY, tmp0),
+             srcreg(RC_FILE_TEMPORARY, dst0.Index),
              negate(srcreg(RC_FILE_TEMPORARY, tmp1)));
 
        rc_remove_instruction(inst);
@@ -517,15 +556,15 @@ static void transform_SWZ(struct radeon_compiler* c,
 static void transform_XPD(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
-       emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dstreg(RC_FILE_TEMPORARY, tempreg),
+       emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dst,
                swizzle(inst->U.I.SrcReg[0], RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_W),
                swizzle(inst->U.I.SrcReg[1], RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_W));
        emit3(c, inst->Prev, RC_OPCODE_MAD, inst->U.I.SaturateMode, inst->U.I.DstReg,
                swizzle(inst->U.I.SrcReg[0], RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_W),
                swizzle(inst->U.I.SrcReg[1], RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_W),
-               negate(srcreg(RC_FILE_TEMPORARY, tempreg)));
+               negate(srcreg(RC_FILE_TEMPORARY, dst.Index)));
 
        rc_remove_instruction(inst);
 }
@@ -553,6 +592,7 @@ int radeonTransformALU(
        switch(inst->U.I.Opcode) {
        case RC_OPCODE_ABS: transform_ABS(c, inst); return 1;
        case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
+       case RC_OPCODE_CLAMP: transform_CLAMP(c, inst); return 1;
        case RC_OPCODE_DP2: transform_DP2(c, inst); return 1;
        case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
        case RC_OPCODE_DST: transform_DST(c, inst); return 1;
@@ -592,7 +632,7 @@ static void transform_r300_vertex_CMP(struct radeon_compiler* c,
 {
        /* There is no decent CMP available, so let's rig one up.
         * CMP is defined as dst = src0 < 0.0 ? src1 : src2
-        * The following sequence consumes two temps and two extra slots
+        * The following sequence consumes zero to two temps and two extra slots
         * (the second temp and the second slot is consumed by transform_LRP),
         * but should be equivalent:
         *
@@ -600,18 +640,18 @@ static void transform_r300_vertex_CMP(struct radeon_compiler* c,
         * LRP dst, tmp0, src1, src2
         *
         * Yes, I know, I'm a mad scientist. ~ C. & M. */
-       int tempreg0 = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
 
        /* SLT tmp0, src0, 0.0 */
        emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
-               dstreg(RC_FILE_TEMPORARY, tempreg0),
+               dst,
                inst->U.I.SrcReg[0], builtin_zero);
 
        /* LRP dst, tmp0, src1, src2 */
        transform_LRP(c,
                emit3(c, inst->Prev, RC_OPCODE_LRP, 0,
                      inst->U.I.DstReg,
-                     srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1],  inst->U.I.SrcReg[2]));
+                     srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[1],  inst->U.I.SrcReg[2]));
 
        rc_remove_instruction(inst);
 }
@@ -642,7 +682,7 @@ static void transform_r300_vertex_DP3(struct radeon_compiler* c,
 static void transform_r300_vertex_fix_LIT(struct radeon_compiler* c,
        struct rc_instruction* inst)
 {
-       int tempreg = rc_find_free_temporary(c);
+       struct rc_dst_register dst = try_to_reuse_dst(c, inst);
        unsigned constant_swizzle;
        int constant = rc_constants_add_immediate_scalar(&c->Program.Constants,
                                                         0.0000000000000000001,
@@ -650,16 +690,16 @@ static void transform_r300_vertex_fix_LIT(struct radeon_compiler* c,
 
        /* MOV dst, src */
        emit1(c, inst->Prev, RC_OPCODE_MOV, 0,
-               dstreg(RC_FILE_TEMPORARY, tempreg),
+               dst,
                inst->U.I.SrcReg[0]);
 
        /* MAX dst.z, src, 0.00...001 */
        emit2(c, inst->Prev, RC_OPCODE_MAX, 0,
-               dstregtmpmask(tempreg, RC_MASK_Y),
-               srcreg(RC_FILE_TEMPORARY, tempreg),
+               dstregtmpmask(dst.Index, RC_MASK_Y),
+               srcreg(RC_FILE_TEMPORARY, dst.Index),
                srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle));
 
-       inst->U.I.SrcReg[0] = srcreg(RC_FILE_TEMPORARY, tempreg);
+       inst->U.I.SrcReg[0] = srcreg(RC_FILE_TEMPORARY, dst.Index);
 }
 
 static void transform_r300_vertex_SEQ(struct radeon_compiler *c,
@@ -743,12 +783,13 @@ static void transform_r300_vertex_SSG(struct radeon_compiler* c,
         *   SLT tmp1, x, 0;
         *   ADD result, tmp0, -tmp1;
         */
-       unsigned tmp0, tmp1;
+       struct rc_dst_register dst0 = try_to_reuse_dst(c, inst);
+       unsigned tmp1;
 
        /* 0 < x */
-       tmp0 = rc_find_free_temporary(c);
+       dst0 = try_to_reuse_dst(c, inst);
        emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
-             dstregtmpmask(tmp0, inst->U.I.DstReg.WriteMask),
+             dst0,
              builtin_zero,
              inst->U.I.SrcReg[0]);
 
@@ -763,7 +804,7 @@ static void transform_r300_vertex_SSG(struct radeon_compiler* c,
        /* result = tmp0 - tmp1 */
        emit2(c, inst->Prev, RC_OPCODE_ADD, 0,
              inst->U.I.DstReg,
-             srcreg(RC_FILE_TEMPORARY, tmp0),
+             srcreg(RC_FILE_TEMPORARY, dst0.Index),
              negate(srcreg(RC_FILE_TEMPORARY, tmp1)));
 
        rc_remove_instruction(inst);
@@ -781,6 +822,7 @@ int r300_transform_vertex_alu(
        switch(inst->U.I.Opcode) {
        case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
        case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
+       case RC_OPCODE_CLAMP: transform_CLAMP(c, inst); return 1;
        case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1;
        case RC_OPCODE_DP2: transform_r300_vertex_DP2(c, inst); return 1;
        case RC_OPCODE_DP3: transform_r300_vertex_DP3(c, inst); return 1;
index 9dcd44c522dbc24a72ded4df6bddd5f4caf917de..45f79ece5bad4f8f9bc98c04859e7d37fe408eb5 100644 (file)
@@ -181,4 +181,9 @@ static inline int rc_presubtract_src_reg_count(rc_presubtract_op op){
                return 0;
        }
 }
+
+#define RC_SOURCE_NONE  0x0
+#define RC_SOURCE_RGB   0x1
+#define RC_SOURCE_ALPHA 0x2
+
 #endif /* RADEON_PROGRAM_CONSTANTS_H */
index a21fe8d3df8ac0c15b4cc4ff4be611863752ca1e..5905d26e521b087550dd1b8fe32d01037a17ffc4 100644 (file)
@@ -27,6 +27,9 @@
 
 #include "radeon_program_pair.h"
 
+#include "radeon_compiler_util.h"
+
+#include <stdlib.h>
 
 /**
  * Return the source slot where we installed the given register access,
@@ -204,24 +207,37 @@ void rc_pair_foreach_source_that_rgb_reads(
        }
 }
 
-/*return 0 for rgb, 1 for alpha -1 for error. */
-
-unsigned int rc_source_type_that_arg_reads(
-       unsigned int source,
-       unsigned int swizzle)
+struct rc_pair_instruction_source * rc_pair_get_src(
+       struct rc_pair_instruction * pair_inst,
+       struct rc_pair_instruction_arg * arg)
 {
-       unsigned int chan;
-       unsigned int swz = RC_SWIZZLE_UNUSED;
-       unsigned int ret = RC_PAIR_SOURCE_NONE;
-
-       for(chan = 0; chan < 3; chan++) {
-               swz = GET_SWZ(swizzle, chan);
-               if (swz == RC_SWIZZLE_W) {
-                       ret |= RC_PAIR_SOURCE_ALPHA;
-               } else if (swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y
-                                               || swz == RC_SWIZZLE_Z) {
-                       ret |= RC_PAIR_SOURCE_RGB;
+       unsigned int i, type;
+       unsigned int channels = 0;
+
+       for(i = 0; i < 3; i++) {
+               if (arg == pair_inst->RGB.Arg + i) {
+                       channels = 3;
+                       break;
                }
        }
-       return ret;
+
+       if (channels == 0) {
+               for (i = 0; i < 3; i++) {
+                       if (arg == pair_inst->Alpha.Arg + i) {
+                               channels = 1;
+                               break;
+                       }
+               }
+       }
+
+       assert(channels > 0);
+       type = rc_source_type_swz(arg->Swizzle, channels);
+
+       if (type & RC_SOURCE_RGB) {
+               return &pair_inst->RGB.Src[arg->Source];
+       } else if (type & RC_SOURCE_ALPHA) {
+               return &pair_inst->Alpha.Src[arg->Source];
+       } else {
+               return NULL;
+       }
 }
index 54d44a2098b02459d0bc4aa6e4deba251b2db1ec..ccf7a0070cdae07ebd7e6f845216e5c257c9a49f 100644 (file)
@@ -55,10 +55,6 @@ struct radeon_compiler;
  */
 #define RC_PAIR_PRESUB_SRC 3
 
-#define RC_PAIR_SOURCE_NONE  0x0
-#define RC_PAIR_SOURCE_RGB   0x1
-#define RC_PAIR_SOURCE_ALPHA 0x2
-
 struct rc_pair_instruction_source {
        unsigned int Used:1;
        unsigned int File:3;
@@ -115,9 +111,9 @@ void rc_pair_foreach_source_that_rgb_reads(
        void * data,
        rc_pair_foreach_src_fn cb);
 
-unsigned int rc_source_type_that_arg_reads(
-       unsigned int source,
-       unsigned int swizzle);
+struct rc_pair_instruction_source * rc_pair_get_src(
+       struct rc_pair_instruction * pair_inst,
+       struct rc_pair_instruction_arg * arg);
 /*@}*/
 
 
index 618ab5a099bf6111aff7c6fa6d6cf3a4d04290a6..ae13f6742f881a4e53533fc471ea3321e0f758de 100644 (file)
@@ -129,6 +129,7 @@ static char rc_swizzle_char(unsigned int swz)
        case RC_SWIZZLE_HALF: return 'H';
        case RC_SWIZZLE_UNUSED: return '_';
        }
+       fprintf(stderr, "bad swz: %u\n", swz);
        return '?';
 }
 
index 530afa5e08e245984a7acee765f8523b7ad2201a..f9d9f34b6ad9f7e25629450df2ee144f88f0b779 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "radeon_program_tex.h"
 
+#include "radeon_compiler_util.h"
+
 /* Series of transformations to be done on textures. */
 
 static struct rc_src_register shadow_ambient(struct r300_fragment_program_compiler *compiler,
index 5f67f536f61ae29e75aff97d7f8177551f2953ee..7d76585a593b6b822bd48b1d12a5477e947019b1 100644 (file)
@@ -87,8 +87,9 @@ void rc_remove_unused_constants(struct radeon_compiler *c, void *user)
                rc_for_all_reads_src(inst, mark_used, &d);
        }
 
-       /* Pass 2: If there is relative addressing, mark all externals as used. */
-       if (has_rel_addr) {
+       /* Pass 2: If there is relative addressing or dead constant elimination
+        * is disabled, mark all externals as used. */
+       if (has_rel_addr || !c->remove_unused_constants) {
                for (unsigned i = 0; i < c->Program.Constants.Count; i++)
                        if (constants[i].Type == RC_CONSTANT_EXTERNAL)
                                const_used[i] = 1;
@@ -119,7 +120,7 @@ void rc_remove_unused_constants(struct radeon_compiler *c, void *user)
        /*  is_identity ==> new_count == old_count
         * !is_identity ==> new_count <  old_count */
        assert( is_identity || new_count <  c->Program.Constants.Count);
-       assert(!(has_rel_addr && are_externals_remapped));
+       assert(!((has_rel_addr || !c->remove_unused_constants) && are_externals_remapped));
 
        /* Pass 4: Redirect reads of all constants to their new locations. */
        if (!is_identity) {
@@ -127,7 +128,6 @@ void rc_remove_unused_constants(struct radeon_compiler *c, void *user)
                     inst != &c->Program.Instructions; inst = inst->Next) {
                        rc_remap_registers(inst, remap_regs, inv_remap_table);
                }
-
        }
 
        /* Set the new constant count. Note that new_count may be less than
index 60e228be5bd8115607c800d7e76bd8a305e6f7bc..88165f78953e456c80ed2672cf289c0967a1391c 100644 (file)
 
 #include "radeon_compiler.h"
 #include "radeon_dataflow.h"
-
-struct reg_rename {
-       int old_index;
-       int new_index;
-       int temp_index;
-};
-
-static void rename_reg(void * data, struct rc_instruction * inst,
-                       rc_register_file * file, unsigned int * index)
-{
-       struct reg_rename *r = data;
-
-       if(r->old_index == *index && *file == RC_FILE_TEMPORARY) {
-               *index = r->new_index;
-       }
-       else if(r->new_index == *index && *file == RC_FILE_TEMPORARY) {
-               *index = r->temp_index;
-       }
-}
-
-static void rename_all(
-       struct radeon_compiler *c,
-       struct rc_instruction * start,
-       unsigned int old,
-       unsigned int new,
-       unsigned int temp)
-{
-       struct rc_instruction * inst;
-       struct reg_rename r;
-       r.old_index = old;
-       r.new_index = new;
-       r.temp_index = temp;
-       for(inst = start; inst != &c->Program.Instructions;
-                                               inst = inst->Next) {
-               rc_remap_registers(inst, rename_reg, &r);
-       }
-}
+#include "radeon_program.h"
 
 /**
  * This function renames registers in an attempt to get the code close to
  * SSA form.  After this function has completed, most of the register are only
- * written to one time, with a few exceptions.  For example, this block of code
- * will not be modified by this function:
- * Mov Temp[0].x Const[0].x
- * Mov Temp[0].y Const[0].y
- * Basically, destination registers will be renamed if:
- * 1. There have been no previous writes to that register
- * or
- * 2. If the instruction is writting to the exact components (no more, no less)
- * of a register that has been written to by previous instructions.
+ * written to one time, with a few exceptions.
  *
  * This function assumes all the instructions are still of type
  * RC_INSTRUCTION_NORMAL.
  */
 void rc_rename_regs(struct radeon_compiler *c, void *user)
 {
-       unsigned int cur_index = 0;
-       unsigned int icount;
+       unsigned int i, used_length;
+       int new_index;
        struct rc_instruction * inst;
-       unsigned int * masks;
+       struct rc_reader_data reader_data;
+       unsigned char * used;
 
-       /* The number of instructions in the program is also the maximum
-        * number of temp registers that could potentially be used. */
-       icount = rc_recompute_ips(c);
-       masks = memory_pool_malloc(&c->Pool, icount * sizeof(unsigned int));
-       memset(masks, 0, icount * sizeof(unsigned int));
+       used_length = 2 * rc_recompute_ips(c);
+       used = memory_pool_malloc(&c->Pool, sizeof(unsigned char) * used_length);
+       memset(used, 0, sizeof(unsigned char) * used_length);
 
+       rc_get_used_temporaries(c, used, used_length);
        for(inst = c->Program.Instructions.Next;
                                        inst != &c->Program.Instructions;
                                        inst = inst->Next) {
-               const struct rc_opcode_info * info;
-               unsigned int old_index, temp_index;
-               struct rc_dst_register * dst;
-               if(inst->Type != RC_INSTRUCTION_NORMAL) {
-                       rc_error(c, "%s only works with normal instructions.",
-                                                               __FUNCTION__);
-                       return;
-               }
-               dst = &inst->U.I.DstReg;
-               info = rc_get_opcode_info(inst->U.I.Opcode);
-               if(!info->HasDstReg || dst->File != RC_FILE_TEMPORARY) {
+
+               if (inst->U.I.DstReg.File != RC_FILE_TEMPORARY)
                        continue;
+
+               rc_get_readers(c, inst, &reader_data, NULL, NULL, NULL);
+
+               if (reader_data.Abort || reader_data.ReaderCount == 0)
+                       continue;
+
+               new_index = rc_find_free_temporary_list(c, used, used_length,
+                                               RC_MASK_XYZW);
+               if (new_index < 0) {
+                       rc_error(c, "Ran out of temporary registers\n");
+                       return;
                }
-               if(dst->Index >= icount || !masks[dst->Index] ||
-                                       masks[dst->Index] == dst->WriteMask) {
-                       old_index = dst->Index;
-                       /* We need to set dst->Index here so get free temporary
-                        * will work. */
-                       dst->Index = cur_index++;
-                       temp_index = rc_find_free_temporary(c);
-                       rename_all(c, inst->Next, old_index,
-                                               dst->Index, temp_index);
+
+               reader_data.Writer->U.I.DstReg.Index = new_index;
+               for(i = 0; i < reader_data.ReaderCount; i++) {
+                       reader_data.Readers[i].U.Src->Index = new_index;
                }
-               assert(dst->Index < icount);
-               masks[dst->Index] |= dst->WriteMask;
        }
 }
index 2c9e4e2b8448283c4c147f0879505aa85b001968..53dacbfdf391286e04203e5fe37a474956279e92 100644 (file)
@@ -286,7 +286,11 @@ static void evergreenSetupVTXConstants(struct gl_context  * ctx,
     if (!paos->bo)
            return;
 
-       r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
+    if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_CEDAR) ||
+       (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_PALM))
+           r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit);
+    else
+           r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
 
     //uSQ_VTX_CONSTANT_WORD0_0
     uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
index a77be183a1212e28dacd1177bc04c28313d37211..076a608573ced0ac605bfcafc4c62ee5c68d7043 100644 (file)
@@ -1461,6 +1461,14 @@ static void evergreenInitSQConfig(struct gl_context * ctx)
         uMaxThreads = 248;
         uMaxStackEntries = 512;
            break;
+    case CHIP_FAMILY_PALM:
+           uSqNumCfInsts       = 1;
+        bVC_ENABLE = GL_FALSE;
+        uMaxGPRs = 256;
+        uPSThreadCount = 96;
+        uMaxThreads = 192;
+        uMaxStackEntries = 256;
+           break;
     default:
         uSqNumCfInsts       = 2;
         bVC_ENABLE = GL_TRUE;
index 2f4c92d6767f00e05c936ba105d6732a961963e9..3b5448a0e4e4f55c2f9626508c20873f49b0ce75 100644 (file)
@@ -31,7 +31,6 @@
 #include "main/enums.h"
 #include "main/image.h"
 #include "main/teximage.h"
-#include "main/mipmap.h"
 #include "main/simple_list.h"
 #include "main/texobj.h"
 
index b6443bf0c535153b5335154f729448157e74074d..aa1891eac320d05fe3ef0a5613c2e77e99b8a3c8 100644 (file)
@@ -259,7 +259,7 @@ static void r600InitConstValues(struct gl_context *ctx, radeonScreenPtr screen)
     R700_CHIP_CONTEXT *r700    = (R700_CHIP_CONTEXT*)(&context->hw);
 
     if(  (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_CEDAR)
-       &&(context->radeon.radeonScreen->chip_family <= CHIP_FAMILY_HEMLOCK) )
+       &&(context->radeon.radeonScreen->chip_family <= CHIP_FAMILY_PALM) )
     {
         r700->bShaderUseMemConstant = GL_TRUE;
     }
@@ -285,8 +285,13 @@ static void r600InitConstValues(struct gl_context *ctx, radeonScreenPtr screen)
        ctx->Const.MaxTextureMaxAnisotropy = 16.0;
        ctx->Const.MaxTextureLodBias = 16.0;
 
-       ctx->Const.MaxTextureLevels = 13; /* hw support 14 */
-       ctx->Const.MaxTextureRectSize = 4096; /* hw support 8192 */
+       if (screen->chip_family >= CHIP_FAMILY_CEDAR) {
+               ctx->Const.MaxTextureLevels = 15;
+               ctx->Const.MaxTextureRectSize = 16384;
+       } else {
+               ctx->Const.MaxTextureLevels = 14;
+               ctx->Const.MaxTextureRectSize = 8192;
+       }
 
        ctx->Const.MinPointSize   = 0x0001 / 8.0;
        ctx->Const.MinPointSizeAA = 0x0001 / 8.0;
index 2bf24096a0dbe8324d5d318cd016b9518cfbc868..1fa559cec1a45e97e1bbbc5f3930d560f6386082 100644 (file)
@@ -3334,7 +3334,14 @@ GLboolean assemble_CMP(r700_AssemblerBase *pAsm)
         return GL_FALSE;
     }
 
-    pAsm->D.dst.opcode = SQ_OP3_INST_CNDGE;
+    if(8 == pAsm->unAsic)
+    {
+       pAsm->D.dst.opcode = EG_OP3_INST_CNDGE;
+    }
+    else
+    {
+       pAsm->D.dst.opcode = SQ_OP3_INST_CNDGE;
+    }
     pAsm->D.dst.op3     = 1;  
 
     tmp = (-1);
@@ -3416,8 +3423,14 @@ GLboolean assemble_TRIG(r700_AssemblerBase *pAsm, BITS opcode)
     checkop1(pAsm);
 
     tmp = gethelpr(pAsm);
-
-    pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    if(8 == pAsm->unAsic)
+    {
+        pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+    }
+    else
+    {
+        pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    }
     pAsm->D.dst.op3    = 1;
 
     setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -3457,7 +3470,14 @@ GLboolean assemble_TRIG(r700_AssemblerBase *pAsm, BITS opcode)
     {
         return GL_FALSE;
     }
-    pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    if(8 == pAsm->unAsic)
+    {
+        pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+    }
+    else
+    {
+        pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    }
     pAsm->D.dst.op3    = 1;
 
     setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -4742,7 +4762,14 @@ GLboolean assemble_SCS(r700_AssemblerBase *pAsm)
 
     tmp = gethelpr(pAsm);
 
-    pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    if(8 == pAsm->unAsic)
+    {
+        pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+    }
+    else
+    {
+        pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    }
     pAsm->D.dst.op3    = 1;
 
     setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -4782,7 +4809,14 @@ GLboolean assemble_SCS(r700_AssemblerBase *pAsm)
     {
         return GL_FALSE;
     }
-    pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    if(8 == pAsm->unAsic)
+    {
+        pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+    }
+    else
+    {
+        pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+    }
     pAsm->D.dst.op3    = 1;
 
     setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -5010,7 +5044,14 @@ GLboolean assemble_SSG(r700_AssemblerBase *pAsm)
     
     GLuint tmp = gethelpr(pAsm);
     /* tmp = (src > 0 ? 1 : src) */
-    pAsm->D.dst.opcode = SQ_OP3_INST_CNDGT;
+    if(8 == pAsm->unAsic)
+    {
+        pAsm->D.dst.opcode = EG_OP3_INST_CNDGT;
+    }
+    else
+    {
+        pAsm->D.dst.opcode = SQ_OP3_INST_CNDGT;
+    }
     pAsm->D.dst.op3    = 1;
     pAsm->D.dst.rtype = DST_REG_TEMPORARY;
     pAsm->D.dst.reg   = tmp;
@@ -5033,7 +5074,14 @@ GLboolean assemble_SSG(r700_AssemblerBase *pAsm)
     }
 
     /* dst = (-tmp > 0 ? -1 : tmp) */
-    pAsm->D.dst.opcode = SQ_OP3_INST_CNDGT;
+    if(8 == pAsm->unAsic)
+    {
+        pAsm->D.dst.opcode = EG_OP3_INST_CNDGT;
+    }
+    else
+    {
+        pAsm->D.dst.opcode = SQ_OP3_INST_CNDGT;
+    }
     pAsm->D.dst.op3    = 1;
 
     if( GL_FALSE == assemble_dst(pAsm) )
index 61106fbc43f5b6777a9ecae5baa09d802270c75d..82789cec5ed4b3def8b00f0e7b04ae345e32e7d9 100644 (file)
 #define PCI_CHIP_HEMLOCK_689C           0x689C
 #define PCI_CHIP_HEMLOCK_689D           0x689D
 
+#define PCI_CHIP_PALM_9802              0x9802
+#define PCI_CHIP_PALM_9803              0x9803
+#define PCI_CHIP_PALM_9804              0x9804
+#define PCI_CHIP_PALM_9805              0x9805
+
 enum {
    CHIP_FAMILY_R100,
    CHIP_FAMILY_RV100,
@@ -483,6 +488,7 @@ enum {
    CHIP_FAMILY_JUNIPER,
    CHIP_FAMILY_CYPRESS,
    CHIP_FAMILY_HEMLOCK,
+   CHIP_FAMILY_PALM,
    CHIP_FAMILY_LAST
 };
 
index fecdd11905902220e7aef154777347e1e200823c..ca6ab46ca436cd3644591581f07e6c56ddaeee13 100644 (file)
@@ -99,6 +99,7 @@ static const char* get_chip_family_name(int chip_family)
        case CHIP_FAMILY_JUNIPER: return "JUNIPER";
        case CHIP_FAMILY_CYPRESS: return "CYPRESS";
        case CHIP_FAMILY_HEMLOCK: return "HEMLOCK";
+       case CHIP_FAMILY_PALM: return "PALM";
        default: return "unknown";
        }
 }
index 088f97017223dcd6222afe7591ca838c46c6e48d..a68a97687799562b15d9dfcb0234544a7bc86bf1 100644 (file)
@@ -49,7 +49,7 @@ struct _radeon_mipmap_level {
 };
 
 /* store the max possible in the miptree */
-#define RADEON_MIPTREE_MAX_TEXTURE_LEVELS 13
+#define RADEON_MIPTREE_MAX_TEXTURE_LEVELS 15
 
 /**
  * A mipmap tree contains texture images in the layout that the hardware
index b379240579d49ecbfab965c15612b013235865af..94e56c2ade6d482b159baba517ee799ecb994228 100644 (file)
@@ -1155,6 +1155,14 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
        screen->chip_flags = RADEON_CHIPSET_TCL;
        break;
 
+    case PCI_CHIP_PALM_9802:
+    case PCI_CHIP_PALM_9803:
+    case PCI_CHIP_PALM_9804:
+    case PCI_CHIP_PALM_9805:
+       screen->chip_family = CHIP_FAMILY_PALM;
+       screen->chip_flags = RADEON_CHIPSET_TCL;
+       break;
+
    default:
       fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
              device_id);
index f0171f3c0f804a8a995233a0bd16afe84cd628ed..7d8f507115d5696540d59b18cf277f4c10d71810 100644 (file)
@@ -72,13 +72,4 @@ typedef struct {
   int dummy;
 } SISDRIContextRec, *SISDRIContextPtr;
 
-#ifdef XFree86Server
-
-#include "screenint.h"
-
-Bool SISDRIScreenInit(ScreenPtr pScreen);
-void SISDRICloseScreen(ScreenPtr pScreen);
-Bool SISDRIFinishScreenInit(ScreenPtr pScreen);
-
-#endif
 #endif
index fb38419dcdd2c390b436a1c509c94f91e5f7e6c6..7e2f0e00a8e2ef90e1492719dfc8ee008ae419dd 100644 (file)
 
 #include <sys/time.h>
 #include "dri_util.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#else
 #include "main/glheader.h"
-#endif
 #if defined(__linux__)
 #include <signal.h>
 #endif
index b47397d5728e510ff0a65afc0dc7b28b5a309848..c6eed03c1c93c74d4388a7aca9953aac40387a29 100644 (file)
@@ -35,9 +35,7 @@
 #define VIA_DRIDDX_VERSION_MINOR  0
 #define VIA_DRIDDX_VERSION_PATCH  0
 
-#ifndef XFree86Server
 typedef int Bool;
-#endif
 
 typedef struct {
     drm_handle_t handle;
index 7145bffa510d0b0e33eb0d337cbd329fb7381bdf..69f03b8e47c81480387067efc13cbecdda9f70ea 100644 (file)
@@ -1,7 +1,8 @@
 #include "glapi.h"
 #include "glThread.h"
 
-#ifdef WIN32_THREADS
+#ifdef WIN32
+
 extern "C" _glthread_Mutex OneTimeLock;
 extern "C" _glthread_Mutex GenTexturesLock;
 
@@ -29,4 +30,4 @@ public:
 _CriticalSectionInit _CriticalSectionInit::m_inst;
 
 
-#endif
+#endif /* WIN32 */
index d88afba20e7c42aa2710e59e87f251c86c575c88..ee002191bc06d6ba9179892b67f53dc9c94d6206 100644 (file)
 
 #include "main/glheader.h"
 
-#ifdef XFree86Server
-
-# include "xorg-server.h"
-# include "resource.h"
-# include "windowstr.h"
-
-#else
 
 # include <X11/Xlib.h>
 # include <X11/Xlibint.h>
@@ -51,7 +44,6 @@
 # include <GL/glx.h>
 # include <sys/time.h>
 
-#endif
 
 
 
index 00ceb960c624932dac0ddf6198debd49f294838d..b5eabadf486b5158f1efb3cbc38b332af2b1f962 100644 (file)
@@ -158,14 +158,12 @@ static short hpcr_rgbTbl[3][256] = {
 /**
  * Return the host's byte order as LSBFirst or MSBFirst ala X.
  */
-#ifndef XFree86Server
 static int host_byte_order( void )
 {
    int i = 1;
    char *cptr = (char *) &i;
    return (*cptr==1) ? LSBFirst : MSBFirst;
 }
-#endif
 
 
 /**
@@ -176,7 +174,7 @@ static int host_byte_order( void )
  */
 static int check_for_xshm( XMesaDisplay *display )
 {
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
    int major, minor, ignore;
    Bool pixmaps;
 
@@ -227,16 +225,6 @@ gamma_adjust( GLfloat gamma, GLint value, GLint max )
 static int
 bits_per_pixel( XMesaVisual xmv )
 {
-#ifdef XFree86Server
-   const int depth = xmv->nplanes;
-   int i;
-   assert(depth > 0);
-   for (i = 0; i < screenInfo.numPixmapFormats; i++) {
-      if (screenInfo.formats[i].depth == depth)
-         return screenInfo.formats[i].bitsPerPixel;
-   }
-   return depth;  /* should never get here, but this should be safe */
-#else
    XMesaDisplay *dpy = xmv->display;
    XMesaVisualInfo visinfo = xmv->visinfo;
    XMesaImage *img;
@@ -257,7 +245,6 @@ bits_per_pixel( XMesaVisual xmv )
    img->data = NULL;
    XMesaDestroyImage( img );
    return bitsPerPixel;
-#endif
 }
 
 
@@ -271,7 +258,6 @@ bits_per_pixel( XMesaVisual xmv )
  * Return:  GL_TRUE - window exists
  *          GL_FALSE - window doesn't exist
  */
-#ifndef XFree86Server
 static GLboolean WindowExistsFlag;
 
 static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
@@ -306,7 +292,6 @@ get_drawable_size( XMesaDisplay *dpy, Drawable d, GLuint *width, GLuint *height
    *height = h;
    return stat;
 }
-#endif
 
 
 /**
@@ -319,10 +304,6 @@ void
 xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
                       GLuint *width, GLuint *height)
 {
-#ifdef XFree86Server
-   *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
-   *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
-#else
    Status stat;
 
    _glthread_LOCK_MUTEX(_xmesa_lock);
@@ -335,7 +316,6 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
       _mesa_warning(NULL, "XGetGeometry failed!\n");
       *width = *height = 1;
    }
-#endif
 }
 
 
@@ -549,16 +529,11 @@ noFaultXAllocColor( int client,
                     XMesaColor *color,
                     int *exact, int *alloced )
 {
-#ifdef XFree86Server
-   Pixel *ppixIn;
-   xrgb *ctable;
-#else
    /* we'll try to cache ctable for better remote display performance */
    static Display *prevDisplay = NULL;
    static XMesaColormap prevCmap = 0;
    static int prevCmapSize = 0;
    static XMesaColor *ctable = NULL;
-#endif
    XMesaColor subColor;
    int i, bestmatch;
    double mindist;       /* 3*2^16^2 exceeds long int precision. */
@@ -566,14 +541,7 @@ noFaultXAllocColor( int client,
    (void) client;
 
    /* First try just using XAllocColor. */
-#ifdef XFree86Server
-   if (AllocColor(cmap,
-                 &color->red, &color->green, &color->blue,
-                 &color->pixel,
-                 client) == Success)
-#else
    if (XAllocColor(dpy, cmap, color))
-#endif
    {
       *exact = 1;
       *alloced = 1;
@@ -584,14 +552,6 @@ noFaultXAllocColor( int client,
 
    /* Retrieve color table entries. */
    /* XXX alloca candidate. */
-#ifdef XFree86Server
-   ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel));
-   ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb));
-   for (i = 0; i < cmapSize; i++) {
-      ppixIn[i] = i;
-   }
-   QueryColors(cmap, cmapSize, ppixIn, ctable);
-#else
    if (prevDisplay != dpy || prevCmap != cmap
        || prevCmapSize != cmapSize || !ctable) {
       /* free previously cached color table */
@@ -608,7 +568,6 @@ noFaultXAllocColor( int client,
       prevCmap = cmap;
       prevCmapSize = cmapSize;
    }
-#endif
 
    /* Find best match. */
    bestmatch = -1;
@@ -632,14 +591,7 @@ noFaultXAllocColor( int client,
     * fail if the cell is read/write.  Otherwise, we're incrementing
     * the cell's reference count.
     */
-#ifdef XFree86Server
-   if (AllocColor(cmap,
-                 &subColor.red, &subColor.green, &subColor.blue,
-                 &subColor.pixel,
-                 client) == Success) {
-#else
    if (XAllocColor(dpy, cmap, &subColor)) {
-#endif
       *alloced = 1;
    }
    else {
@@ -651,12 +603,7 @@ noFaultXAllocColor( int client,
       subColor.flags = DoRed | DoGreen | DoBlue;
       *alloced = 0;
    }
-#ifdef XFree86Server
-   free(ppixIn);
-   free(ctable);
-#else
    /* don't free table, save it for next time */
-#endif
 
    *color = subColor;
    *exact = 0;
@@ -873,10 +820,8 @@ setup_8bit_hpcr(XMesaVisual v)
       v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display,
                                                DefaultRootWindow(v->display),
                                                16, 2, 8);
-#ifndef XFree86Server
       v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap,
                                        0, 0, 16, 2, AllPlanes, ZPixmap);
-#endif
    }
 }
 
@@ -1049,9 +994,6 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
    int client = 0;
    const int xclass = v->visualType;
 
-#ifdef XFree86Server
-   client = (window) ? CLIENT_ID(window->id) : 0;
-#endif
 
    ASSERT(!b || b->xm_visual == v);
 
@@ -1120,40 +1062,23 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
       }
 
       /* X11 graphics contexts */
-#ifdef XFree86Server
-      b->gc = CreateScratchGC(v->display, window->depth);
-#else
       b->gc = XCreateGC( v->display, window, 0, NULL );
-#endif
       XMesaSetFunction( v->display, b->gc, GXcopy );
 
       /* cleargc - for glClear() */
-#ifdef XFree86Server
-      b->cleargc = CreateScratchGC(v->display, window->depth);
-#else
       b->cleargc = XCreateGC( v->display, window, 0, NULL );
-#endif
       XMesaSetFunction( v->display, b->cleargc, GXcopy );
 
       /*
        * Don't generate Graphics Expose/NoExpose events in swapbuffers().
        * Patch contributed by Michael Pichler May 15, 1995.
        */
-#ifdef XFree86Server
-      b->swapgc = CreateScratchGC(v->display, window->depth);
-      {
-         CARD32 v[1];
-         v[0] = FALSE;
-         dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
-      }
-#else
       {
          XGCValues gcvalues;
          gcvalues.graphics_exposures = False;
          b->swapgc = XCreateGC(v->display, window,
                                GCGraphicsExposures, &gcvalues);
       }
-#endif
       XMesaSetFunction( v->display, b->swapgc, GXcopy );
       /*
        * Set fill style and tile pixmap once for all for HPCR stuff
@@ -1175,9 +1100,6 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
 
       /* Initialize the row buffer XImage for use in write_color_span() */
       data = (char*) MALLOC(MAX_WIDTH*4);
-#ifdef XFree86Server
-      b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, data);
-#else
       b->rowimage = XCreateImage( v->display,
                                   v->visinfo->visual,
                                   v->visinfo->depth,
@@ -1186,7 +1108,6 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
                                   MAX_WIDTH, 1,         /*width, height*/
                                   32,                   /*bitmap_pad*/
                                   0                     /*bytes_per_line*/ );
-#endif
       if (!b->rowimage)
          return GL_FALSE;
    }
@@ -1334,7 +1255,6 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
    XMesaVisual v;
    GLint red_bits, green_bits, blue_bits, alpha_bits;
 
-#ifndef XFree86Server
    /* For debugging only */
    if (_mesa_getenv("MESA_XSYNC")) {
       /* This makes debugging X easier.
@@ -1343,7 +1263,6 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
        */
       XSynchronize( display, 1 );
    }
-#endif
 
    /* Color-index rendering not supported. */
    if (!rgb_flag)
@@ -1360,14 +1279,12 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
     * the struct but we may need some of the information contained in it
     * at a later time.
     */
-#ifndef XFree86Server
    v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
    if(!v->visinfo) {
       free(v);
       return NULL;
    }
    memcpy(v->visinfo, visinfo, sizeof(*visinfo));
-#endif
 
    /* check for MESA_GAMMA environment variable */
    gamma = _mesa_getenv("MESA_GAMMA");
@@ -1384,30 +1301,13 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
 
    v->ximage_flag = ximage_flag;
 
-#ifdef XFree86Server
-   /* We could calculate these values by ourselves.  nplanes is either the sum
-    * of the red, green, and blue bits or the number index bits.
-    * ColormapEntries is either (1U << index_bits) or
-    * (1U << max(redBits, greenBits, blueBits)).
-    */
-   assert(visinfo->nplanes > 0);
-   v->nplanes = visinfo->nplanes;
-   v->ColormapEntries = visinfo->ColormapEntries;
-
-   v->mesa_visual.redMask = visinfo->redMask;
-   v->mesa_visual.greenMask = visinfo->greenMask;
-   v->mesa_visual.blueMask = visinfo->blueMask;
-   v->visualID = visinfo->vid;
-   v->screen = 0; /* FIXME: What should be done here? */
-#else
    v->mesa_visual.redMask = visinfo->red_mask;
    v->mesa_visual.greenMask = visinfo->green_mask;
    v->mesa_visual.blueMask = visinfo->blue_mask;
    v->visualID = visinfo->visualid;
    v->screen = visinfo->screen;
-#endif
 
-#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus))
+#if !(defined(__cplusplus) || defined(c_plusplus))
    v->visualType = xmesa_convert_from_x_visual_type(visinfo->class);
 #else
    v->visualType = xmesa_convert_from_x_visual_type(visinfo->c_class);
@@ -1461,9 +1361,7 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
 PUBLIC
 void XMesaDestroyVisual( XMesaVisual v )
 {
-#ifndef XFree86Server
    free(v->visinfo);
-#endif
    free(v);
 }
 
@@ -1532,12 +1430,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
     _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query");
 #endif
 
-#ifdef XFree86Server
-   /* If we're running in the X server, do bounds checking to prevent
-    * segfaults and server crashes!
-    */
-   mesaCtx->Const.CheckArrayBounds = GL_TRUE;
-#endif
 
    /* finish up xmesa context initializations */
    c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE;
@@ -1602,9 +1494,7 @@ void XMesaDestroyContext( XMesaContext c )
 PUBLIC XMesaBuffer
 XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
 {
-#ifndef XFree86Server
    XWindowAttributes attr;
-#endif
    XMesaBuffer b;
    XMesaColormap cmap;
    int depth;
@@ -1613,12 +1503,8 @@ XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
    assert(w);
 
    /* Check that window depth matches visual depth */
-#ifdef XFree86Server
-   depth = ((XMesaDrawable)w)->depth;
-#else
    XGetWindowAttributes( v->display, w, &attr );
    depth = attr.depth;
-#endif
    if (GET_VISUAL_DEPTH(v) != depth) {
       _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
                     GET_VISUAL_DEPTH(v), depth);
@@ -1626,9 +1512,6 @@ XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
    }
 
    /* Find colormap */
-#ifdef XFree86Server
-   cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
-#else
    if (attr.colormap) {
       cmap = attr.colormap;
    }
@@ -1638,7 +1521,6 @@ XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
       /* OK, let's just allocate a new one and hope for the best */
       cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
    }
-#endif
 
    b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
    if (!b)
@@ -1748,7 +1630,6 @@ XMesaBuffer
 XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
                    unsigned int width, unsigned int height)
 {
-#ifndef XFree86Server
    XMesaWindow root;
    XMesaDrawable drawable;  /* X Pixmap Drawable */
    XMesaBuffer b;
@@ -1770,9 +1651,6 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
    }
 
    return b;
-#else
-   return 0;
-#endif
 }
 
 
@@ -1931,40 +1809,6 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
 }
 
 
-#ifdef XFree86Server
-PUBLIC
-GLboolean XMesaForceCurrent(XMesaContext c)
-{
-   if (c) {
-      _glapi_set_dispatch(c->mesa.CurrentDispatch);
-
-      if (&(c->mesa) != _mesa_get_current_context()) {
-        _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
-      }
-   }
-   else {
-      _mesa_make_current(NULL, NULL, NULL);
-   }
-   return GL_TRUE;
-}
-
-
-PUBLIC
-GLboolean XMesaLoseCurrent(XMesaContext c)
-{
-   (void) c;
-   _mesa_make_current(NULL, NULL, NULL);
-   return GL_TRUE;
-}
-
-
-PUBLIC
-GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask )
-{
-   _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
-   return GL_TRUE;
-}
-#endif /* XFree86Server */
 
 
 #ifndef FX
@@ -2004,7 +1848,7 @@ void XMesaSwapBuffers( XMesaBuffer b )
 #endif
       if (b->backxrb->ximage) {
         /* Copy Ximage (back buf) from client memory to server window */
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
         if (b->shm) {
             /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
            XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
@@ -2041,9 +1885,7 @@ void XMesaSwapBuffers( XMesaBuffer b )
       if (b->swAlpha)
          _mesa_copy_soft_alpha_renderbuffers(ctx, &b->mesa_buffer);
    }
-#if !defined(XFree86Server)
    XSync( b->xm_visual->display, False );
-#endif
 }
 
 
@@ -2074,7 +1916,7 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
 #endif
       if (b->backxrb->ximage) {
          /* Copy Ximage from host's memory to server's window */
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
          if (b->shm) {
             /* XXX assuming width and height aren't too large! */
             XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
@@ -2116,7 +1958,6 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
  * Return:  GL_TRUE = context is double buffered
  *          GL_FALSE = context is single buffered
  */
-#ifndef XFree86Server
 GLboolean XMesaGetBackBuffer( XMesaBuffer b,
                               XMesaPixmap *pixmap,
                               XMesaImage **ximage )
@@ -2134,7 +1975,6 @@ GLboolean XMesaGetBackBuffer( XMesaBuffer b,
       return GL_FALSE;
    }
 }
-#endif /* XFree86Server */
 
 
 /*
@@ -2171,11 +2011,7 @@ GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
 void XMesaFlush( XMesaContext c )
 {
    if (c && c->xm_visual) {
-#ifdef XFree86Server
-      /* NOT_NEEDED */
-#else
       XSync( c->xm_visual->display, False );
-#endif
    }
 }
 
@@ -2234,15 +2070,11 @@ void XMesaGarbageCollect( void )
    for (b=XMesaBufferList; b; b=next) {
       next = b->Next;
       if (b->display && b->frontxrb->drawable && b->type == WINDOW) {
-#ifdef XFree86Server
-        /* NOT_NEEDED */
-#else
          XSync(b->display, False);
          if (!window_exists( b->display, b->frontxrb->drawable )) {
             /* found a dead window, free the ancillary info */
             XMesaDestroyBuffer( b );
          }
-#endif
       }
    }
 }
index 2683bd44d196899fc50294fcd4eddf588d82d0fb..10829b4284fd714f3f4f6d6db00bbc51fdb97a30 100644 (file)
@@ -37,7 +37,7 @@
 #include "main/renderbuffer.h"
 
 
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
 static volatile int mesaXErrorFlag = 0;
 
 /**
@@ -170,7 +170,7 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
    if (b->db_mode == BACK_XIMAGE) {
       /* Deallocate the old backxrb->ximage, if any */
       if (b->backxrb->ximage) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
         if (b->shm) {
            XShmDetach(b->xm_visual->display, &b->shminfo);
            XDestroyImage(b->backxrb->ximage);
@@ -188,10 +188,6 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
       /* Allocate new back buffer */
       if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) {
         /* Allocate a regular XImage for the back buffer. */
-#ifdef XFree86Server
-        b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
-                                               width, height, NULL);
-#else
         b->backxrb->ximage = XCreateImage(b->xm_visual->display,
                                       b->xm_visual->visinfo->visual,
                                       GET_VISUAL_DEPTH(b->xm_visual),
@@ -199,7 +195,6 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
                                      NULL,
                                       width, height,
                                      8, 0);  /* pad, bytes_per_line */
-#endif
         if (!b->backxrb->ximage) {
            _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
             return;
@@ -359,16 +354,8 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb)
    if (b->num_alloced > 0) {
       /* If no other buffer uses this X colormap then free the colors. */
       if (!xmesa_find_buffer(b->display, b->cmap, b)) {
-#ifdef XFree86Server
-         int client = 0;
-         if (b->frontxrb->drawable)
-            client = CLIENT_ID(b->frontxrb->drawable->id);
-         (void)FreeColors(b->cmap, client,
-                          b->num_alloced, b->alloced_colors, 0);
-#else
          XFreeColors(b->display, b->cmap,
                      b->alloced_colors, b->num_alloced, 0);
-#endif
       }
    }
 
@@ -382,7 +369,7 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb)
    if (fb->Visual.doubleBufferMode) {
       /* free back ximage/pixmap/shmregion */
       if (b->backxrb->ximage) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
          if (b->shm) {
             XShmDetach( b->display, &b->shminfo );
             XDestroyImage( b->backxrb->ximage );
index acece2025cfa8a97d7c035d7666867c3d4b590cb..b8d9e20c4267ed1d30b6b51d9b0a19d31964b65b 100644 (file)
@@ -93,16 +93,12 @@ const int xmesa_kernel1[16] = {
 static void
 finish_or_flush( struct gl_context *ctx )
 {
-#ifdef XFree86Server
-      /* NOT_NEEDED */
-#else
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    if (xmesa) {
       _glthread_LOCK_MUTEX(_xmesa_lock);
       XSync( xmesa->display, False );
       _glthread_UNLOCK_MUTEX(_xmesa_lock);
    }
-#endif
 }
 
 
@@ -388,7 +384,6 @@ clear_buffers(struct gl_context *ctx, GLbitfield buffers)
 }
 
 
-#ifndef XFree86Server
 /* XXX these functions haven't been tested in the Xserver environment */
 
 
@@ -731,7 +726,6 @@ xmesa_CopyPixels( struct gl_context *ctx,
    }
 }
 
-#endif /* XFree86Server */
 
 
 
@@ -745,17 +739,9 @@ get_string( struct gl_context *ctx, GLenum name )
    (void) ctx;
    switch (name) {
       case GL_RENDERER:
-#ifdef XFree86Server
-         return (const GLubyte *) "Mesa GLX Indirect";
-#else
          return (const GLubyte *) "Mesa X11";
-#endif
       case GL_VENDOR:
-#ifdef XFree86Server
-         return (const GLubyte *) "Mesa project: www.mesa3d.org";
-#else
          return NULL;
-#endif
       default:
          return NULL;
    }
@@ -947,43 +933,6 @@ xmesa_update_state( struct gl_context *ctx, GLbitfield new_state )
 
 
 
-/**
- * Called via ctx->Driver.TestProxyTeximage().  Normally, we'd just use
- * the _mesa_test_proxy_teximage() fallback function, but we're going to
- * special-case the 3D texture case to allow textures up to 512x512x32
- * texels.
- */
-static GLboolean
-test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
-                    GLint internalFormat, GLenum format, GLenum type,
-                    GLint width, GLint height, GLint depth, GLint border)
-{
-   if (target == GL_PROXY_TEXTURE_3D) {
-      /* special case for 3D textures */
-      if (width * height * depth > 512 * 512 * 64 ||
-          width  < 2 * border ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width  - 2 * border) != 1) ||
-          height < 2 * border ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(height - 2 * border) != 1) ||
-          depth  < 2 * border ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(depth  - 2 * border) != 1)) {
-         /* Bad size, or too many texels */
-         return GL_FALSE;
-      }
-      return GL_TRUE;
-   }
-   else {
-      /* use the fallback routine for 1D, 2D, cube and rect targets */
-      return _mesa_test_proxy_teximage(ctx, target, level, internalFormat,
-                                       format, type, width, height, depth,
-                                       border);
-   }
-}
-
-
 /**
  * In SW, we don't really compress GL_COMPRESSED_RGB[A] textures!
  */
@@ -1124,7 +1073,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
    }
    else {
       driver->Clear = clear_buffers;
-#ifndef XFree86Server
       driver->CopyPixels = xmesa_CopyPixels;
       if (xmvisual->undithered_pf == PF_8R8G8B &&
           xmvisual->dithered_pf == PF_8R8G8B &&
@@ -1134,9 +1082,8 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
       else if (xmvisual->undithered_pf == PF_5R6G5B) {
          driver->DrawPixels = xmesa_DrawPixels_5R6G5B;
       }
-#endif
    }
-   driver->TestProxyTexImage = test_proxy_teximage;
+
 #if ENABLE_EXT_texure_compression_s3tc
    driver->ChooseTextureFormat = choose_tex_format;
 #else
index cbd69b011a1d15e7dcc33013ab43d5a3c1101f51..d8a0e6de6d0b2f13c0f81b1e952bee0ab1a068a2 100644 (file)
@@ -140,16 +140,8 @@ static void FXgetImage( XMesaBuffer b )
    GLuint x, y;
    GLuint width, height;
 
-#ifdef XFree86Server
-   x = b->frontxrb->pixmap->x;
-   y = b->frontxrb->pixmap->y;
-   width = b->frontxrb->pixmap->width;
-   height = b->frontxrb->pixmap->height;
-   depth = b->frontxrb->pixmap->depth;
-#else
    xmesa_get_window_size(b->display, b, &width, &height);
    x = y = 0;
-#endif
    if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
       b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
       b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
index 087b4e4c3a7c81f02c4049c625ce981cde94eb76..12fef7dad345cecb9e8374fae58a0a979fcdf440 100644 (file)
@@ -37,97 +37,3 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "glxheader.h"
 #include "xmesaP.h"
 
-#ifdef XFree86Server
-
-#ifdef ROUNDUP
-#undef ROUNDUP
-#endif
-
-#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
-
-XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data)
-{
-    XMesaImage *image;
-
-    image = (XMesaImage *)xalloc(sizeof(XMesaImage));
-
-    if (image) {
-       image->width = width;
-       image->height = height;
-       image->data = data;
-       /* Always pad to 32 bits */
-       image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32);
-       image->bits_per_pixel = bitsPerPixel;
-    }
-
-    return image;
-}
-
-void XMesaDestroyImage(XMesaImage *image)
-{
-    if (image->data)
-       free(image->data);
-    xfree(image);
-}
-
-unsigned long XMesaGetPixel(XMesaImage *image, int x, int y)
-{
-    CARD8  *row = (CARD8 *)(image->data + y*image->bytes_per_line);
-    CARD8  *i8;
-    CARD16 *i16;
-    CARD32 *i32;
-    switch (image->bits_per_pixel) {
-    case 8:
-       i8 = (CARD8 *)row;
-       return i8[x];
-       break;
-    case 15:
-    case 16:
-       i16 = (CARD16 *)row;
-       return i16[x];
-       break;
-    case 24: /* WARNING: architecture specific code */
-       i8 = (CARD8 *)row;
-       return (((CARD32)i8[x*3]) |
-               (((CARD32)i8[x*3+1])<<8) |
-               (((CARD32)i8[x*3+2])<<16));
-       break;
-    case 32:
-       i32 = (CARD32 *)row;
-       return i32[x];
-       break;
-    }
-    return 0;
-}
-
-#ifndef XMESA_USE_PUTPIXEL_MACRO
-void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel)
-{
-    CARD8  *row = (CARD8 *)(image->data + y*image->bytes_per_line);
-    CARD8  *i8;
-    CARD16 *i16;
-    CARD32 *i32;
-    switch (image->bits_per_pixel) {
-    case 8:
-       i8 = (CARD8 *)row;
-       i8[x] = (CARD8)pixel;
-       break;
-    case 15:
-    case 16:
-       i16 = (CARD16 *)row;
-       i16[x] = (CARD16)pixel;
-       break;
-    case 24: /* WARNING: architecture specific code */
-       i8 = (CARD8 *)__row;
-       i8[x*3]   = (CARD8)(p);
-       i8[x*3+1] = (CARD8)(p>>8);
-       i8[x*3+2] = (CARD8)(p>>16);
-    case 32:
-       i32 = (CARD32 *)row;
-       i32[x] = (CARD32)pixel;
-       break;
-    }
-}
-#endif
-
-#endif /* XFree86Server */
index f03f99f918f629b66fbd1fd098e2ac08052c241e..04cedcd4ec09431e5e968b531221bf73a67a064a 100644 (file)
@@ -537,7 +537,6 @@ void xmesa_choose_point( struct gl_context *ctx )
 
 
 
-#ifndef XFree86Server
 /**
  * Draw fast, XOR line with XDrawLine in front color buffer.
  * WARNING: this isn't fully OpenGL conformant because different pixels
@@ -567,7 +566,6 @@ xor_line(struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1)
    XDrawLine(dpy, xrb->pixmap, gc, x0, y0, x1, y1);
    XMesaSetFunction(dpy, gc, GXcopy);  /* this gc is used elsewhere */
 }
-#endif /* XFree86Server */
 
 
 #endif /* CHAN_BITS == 8 */
@@ -660,7 +658,6 @@ get_line_func(struct gl_context *ctx)
       }
    }
 
-#ifndef XFree86Server
    if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
        && ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT
        && swrast->_RasterMask == LOGIC_OP_BIT
@@ -669,7 +666,6 @@ get_line_func(struct gl_context *ctx)
        && !ctx->Line.SmoothFlag) {
       return xor_line;
    }
-#endif /* XFree86Server */
 
 #endif /* CHAN_BITS == 8 */
    return (swrast_line_func) NULL;
index ab66c5e1f12f9fd71cd4c8a727d843db92aeab97..294b93a57ccafc8a9a6432547a09b98a3819aa10 100644 (file)
@@ -42,7 +42,6 @@
  * generate BadMatch errors if the drawable isn't mapped.
  */
 
-#ifndef XFree86Server
 static int caught_xgetimage_error = 0;
 static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );
 static unsigned long xgetimage_serial;
@@ -87,7 +86,6 @@ static int check_xgetimage_errors( void )
    /* return 0=no error, 1=error caught */
    return caught_xgetimage_error;
 }
-#endif
 
 
 /*
@@ -97,7 +95,6 @@ static unsigned long read_pixel( XMesaDisplay *dpy,
                                  XMesaDrawable d, int x, int y )
 {
    unsigned long p;
-#ifndef XFree86Server
    XMesaImage *pixel = NULL;
    int error;
 
@@ -113,9 +110,6 @@ static unsigned long read_pixel( XMesaDisplay *dpy,
    if (pixel) {
       XMesaDestroyImage( pixel );
    }
-#else
-   (*dpy->GetImage)(d, x, y, 1, 1, ZPixmap, ~0L, (pointer)&p);
-#endif
    return p;
 }
 
@@ -3763,7 +3757,6 @@ static void put_values_ci_ximage( PUT_VALUES_ARGS )
 /*****                      Pixel reading                         *****/
 /**********************************************************************/
 
-#ifndef XFree86Server
 /**
  * Do clip testing prior to calling XGetImage.  If any of the region lies
  * outside the screen's bounds, XGetImage will return NULL.
@@ -3806,7 +3799,6 @@ clip_for_xgetimage(struct gl_context *ctx, XMesaPixmap pixmap, GLuint *n, GLint
    }
    return 0;
 }
-#endif
 
 
 /*
@@ -3824,7 +3816,6 @@ get_row_ci(struct gl_context *ctx, struct gl_renderbuffer *rb,
    y = YFLIP(xrb, y);
 
    if (xrb->pixmap) {
-#ifndef XFree86Server
       XMesaImage *span = NULL;
       int error;
       int k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
@@ -3850,11 +3841,6 @@ get_row_ci(struct gl_context *ctx, struct gl_renderbuffer *rb,
       if (span) {
         XMesaDestroyImage( span );
       }
-#else
-      (*xmesa->display->GetImage)(xrb->drawable,
-                                 x, y, n, 1, ZPixmap,
-                                 ~0L, (pointer)index);
-#endif
    }
    else if (xrb->ximage) {
       XMesaImage *img = xrb->ximage;
@@ -3882,14 +3868,6 @@ get_row_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
       /* Read from Pixmap or Window */
       XMesaImage *span = NULL;
       int error;
-#ifdef XFree86Server
-      span = XMesaCreateImage(xmesa->xm_visual->BitsPerPixel, n, 1, NULL);
-      span->data = (char *)MALLOC(span->height * span->bytes_per_line);
-      error = (!span->data);
-      (*xmesa->display->GetImage)(xrb->drawable,
-                                 x, YFLIP(xrb, y), n, 1, ZPixmap,
-                                 ~0L, (pointer)span->data);
-#else
       int k;
       y = YFLIP(xrb, y);
       k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
@@ -3900,7 +3878,6 @@ get_row_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
       span = XGetImage( xmesa->display, xrb->pixmap,
                        x, y, n, 1, AllPlanes, ZPixmap );
       error = check_xgetimage_errors();
-#endif
       if (span && !error) {
         switch (xmesa->pixelformat) {
            case PF_Truecolor:
index f63626a97026b77c7ddfd5a363ba62bfe0e42bc9..98737fab248e06ebcbfe83bc91829d1721a4d9f7 100644 (file)
@@ -72,13 +72,9 @@ and create a window, you must do the following to use the X/Mesa interface:
 extern "C" {
 #endif
 
-#ifdef XFree86Server
-#include "xmesa_xf86.h"
-#else
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include "xmesa_x.h"
-#endif
 #include "GL/gl.h"
 
 #ifdef AMIWIN
@@ -180,19 +176,6 @@ extern XMesaContext XMesaCreateContext( XMesaVisual v,
 extern void XMesaDestroyContext( XMesaContext c );
 
 
-#ifdef XFree86Server
-/*
- * These are the extra routines required for integration with XFree86.
- * None of these routines should be user visible. -KEM
- */
-extern GLboolean XMesaForceCurrent( XMesaContext c );
-
-extern GLboolean XMesaLoseCurrent( XMesaContext c );
-
-extern GLboolean XMesaCopyContext( XMesaContext src,
-                                  XMesaContext dst,
-                                  GLuint mask );
-#endif /* XFree86Server */
 
 
 /*
index 5d34b430cb6dd5d0502862d68fc1ddfe41ea8cc4..63e3e211bf624b102d7cc5b7a57f7eb18cf9496e 100644 (file)
@@ -33,9 +33,6 @@
 #include "fxmesa.h"
 #include "xm_glide.h"
 #endif
-#ifdef XFree86Server
-#include "xm_image.h"
-#endif
 
 
 extern _glthread_Mutex _xmesa_lock;
@@ -88,13 +85,8 @@ struct xmesa_visual {
    XMesaDisplay *display;      /* The X11 display */
    int screen, visualID;
    int visualType;
-#ifdef XFree86Server
-   GLint ColormapEntries;
-   GLint nplanes;
-#else
    XMesaVisualInfo visinfo;    /* X's visual info (pointer to private copy) */
    XVisualInfo *vishandle;     /* Only used in fakeglx.c */
-#endif
    GLint BitsPerPixel;         /* True bits per pixel for XImages */
 
    GLboolean ximage_flag;      /* Use XImage for back buffer (not pixmap)? */
@@ -233,7 +225,7 @@ struct xmesa_buffer {
                                /*    0 = not available                 */
                                /*    1 = XImage support available      */
                                /*    2 = Pixmap support available too  */
-#if defined(USE_XSHM) && !defined(XFree86Server)
+#if defined(USE_XSHM) 
    XShmSegmentInfo shminfo;
 #endif
 
@@ -259,11 +251,7 @@ struct xmesa_buffer {
 
    /* Used to do XAllocColor/XFreeColors accounting: */
    int num_alloced;
-#if defined(XFree86Server)
-   Pixel alloced_colors[256];
-#else
    unsigned long alloced_colors[256];
-#endif
 
 #if defined( FX )
    /* For 3Dfx Glide only */
@@ -578,9 +566,7 @@ extern void xmesa_register_swrast_functions( struct gl_context *ctx );
 
 #define ENABLE_EXT_texure_compression_s3tc 0 /* SW texture compression */
 
-#ifdef XFree86Server
-#define ENABLE_EXT_timer_query 0
-#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#if   defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 #define ENABLE_EXT_timer_query 1 /* should have 64-bit GLuint64EXT */
 #else
 #define ENABLE_EXT_timer_query 0 /* may not have 64-bit GLuint64EXT */
index 4dc0b0d485194b69a1fb3ab0eff900a0b32e4d25..16d0c9413d07ecf2d6197029b7962c4c990c7812 100644 (file)
 <api name="mesa" implementation="true">
        <category name="MESA"/>
 
-       <function name="Color4f"  default_prefix="_vbo_" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/>
+       <function name="Color4f"  default_prefix="_es_" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/>
        <function name="ClipPlane" template="ClipPlane" gltype="GLdouble"/>
        <function name="CullFace" template="CullFace"/>
 
 
        <function name="LineWidth" template="LineWidth" gltype="GLfloat"/>
 
-       <function name="Materialf" default_prefix="_vbo_" template="Material" gltype="GLfloat" expand_vector="true"/>
-       <function name="Materialfv" default_prefix="_vbo_" template="Material" gltype="GLfloat"/>
+       <function name="Materialf" default_prefix="_es_" template="Material" gltype="GLfloat" expand_vector="true"/>
+       <function name="Materialfv" default_prefix="_es_" template="Material" gltype="GLfloat"/>
 
        <function name="PointSize" template="PointSize" gltype="GLfloat"/>
        <function name="PointSizePointer" template="PointSizePointer"/>
        <function name="EnableClientState" template="EnableClientState"/>
 
        <function name="GetPointerv" template="GetPointer"/>
-       <function name="Normal3f" default_prefix="_vbo_" template="Normal" gltype="GLfloat" expand_vector="true"/>
+       <function name="Normal3f" default_prefix="_es_" template="Normal" gltype="GLfloat" expand_vector="true"/>
        <function name="NormalPointer" template="NormalPointer"/>
        <function name="TexCoordPointer" template="TexCoordPointer"/>
        <function name="VertexPointer" template="VertexPointer"/>
        <function name="ActiveTextureARB" template="ActiveTexture"/>
        <function name="ClientActiveTextureARB" template="ClientActiveTexture"/>
 
-       <function name="MultiTexCoord4f" default_prefix="_vbo_" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/>
+       <function name="MultiTexCoord4f" default_prefix="_es_" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/>
 
        <function name="SampleCoverageARB" template="SampleCoverage" gltype="GLclampf"/>
 
        <function name="PointParameterf" template="PointParameter" gltype="GLfloat" expand_vector="true"/>
        <function name="PointParameterfv" template="PointParameter" gltype="GLfloat"/>
 
-       <function name="VertexAttrib1f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/>
-       <function name="VertexAttrib2f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/>
-       <function name="VertexAttrib3f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/>
-       <function name="VertexAttrib4f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/>
-       <function name="VertexAttrib1fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="1"/>
-       <function name="VertexAttrib2fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="2"/>
-       <function name="VertexAttrib3fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="3"/>
-       <function name="VertexAttrib4fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="4"/>
+       <function name="VertexAttrib1f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/>
+       <function name="VertexAttrib2f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/>
+       <function name="VertexAttrib3f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/>
+       <function name="VertexAttrib4f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/>
+       <function name="VertexAttrib1fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="1"/>
+       <function name="VertexAttrib2fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="2"/>
+       <function name="VertexAttrib3fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="3"/>
+       <function name="VertexAttrib4fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="4"/>
 
        <function name="VertexAttribPointerARB" template="VertexAttribPointer"/>
        <function name="EnableVertexAttribArrayARB" template="EnableVertexAttribArray"/>
 
        <category name="OES_matrix_palette"/>
 
-       <function name="Color4f" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/>
+       <function name="Color4f" external="true" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/>
        <function name="Color4ub" template="Color" gltype="GLubyte" vector_size="4" expand_vector="true"/>
        <function name="Color4x" template="Color" gltype="GLfixed" vector_size="4" expand_vector="true"/>
 
        <function name="LineWidth" template="LineWidth" gltype="GLfloat"/>
        <function name="LineWidthx" template="LineWidth" gltype="GLfixed"/>
 
-       <function name="Materialf" template="Material" gltype="GLfloat" expand_vector="true"/>
-       <function name="Materialfv" template="Material" gltype="GLfloat"/>
+       <function name="Materialf" external="true" template="Material" gltype="GLfloat" expand_vector="true"/>
+       <function name="Materialfv" external="true" template="Material" gltype="GLfloat"/>
        <function name="Materialx" template="Material" gltype="GLfixed" expand_vector="true"/>
        <function name="Materialxv" template="Material" gltype="GLfixed"/>
 
 
        <function name="GetPointerv" template="GetPointer"/>
 
-       <function name="Normal3f" template="Normal" gltype="GLfloat" expand_vector="true"/>
+       <function name="Normal3f" external="true" template="Normal" gltype="GLfloat" expand_vector="true"/>
        <function name="Normal3x" template="Normal" gltype="GLfixed" expand_vector="true"/>
        <function name="NormalPointer" template="NormalPointer"/>
        <function name="TexCoordPointer" template="TexCoordPointer"/>
        <function name="ActiveTexture" template="ActiveTexture"/>
        <function name="ClientActiveTexture" template="ClientActiveTexture"/>
 
-       <function name="MultiTexCoord4f" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/>
+       <function name="MultiTexCoord4f" external="true" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/>
 
        <function name="SampleCoverage" template="SampleCoverage" gltype="GLclampf"/>
        <function name="SampleCoveragex" template="SampleCoverage" gltype="GLclampx"/>
 
        <function name="BlendFuncSeparate" template="BlendFuncSeparate"/>
 
-       <function name="VertexAttrib1f" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/>
-       <function name="VertexAttrib2f" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/>
-       <function name="VertexAttrib3f" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/>
-       <function name="VertexAttrib4f" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/>
-       <function name="VertexAttrib1fv" template="VertexAttrib" gltype="GLfloat" vector_size="1"/>
-       <function name="VertexAttrib2fv" template="VertexAttrib" gltype="GLfloat" vector_size="2"/>
-       <function name="VertexAttrib3fv" template="VertexAttrib" gltype="GLfloat" vector_size="3"/>
-       <function name="VertexAttrib4fv" template="VertexAttrib" gltype="GLfloat" vector_size="4"/>
+       <function name="VertexAttrib1f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/>
+       <function name="VertexAttrib2f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/>
+       <function name="VertexAttrib3f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/>
+       <function name="VertexAttrib4f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/>
+       <function name="VertexAttrib1fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="1"/>
+       <function name="VertexAttrib2fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="2"/>
+       <function name="VertexAttrib3fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="3"/>
+       <function name="VertexAttrib4fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="4"/>
 
        <function name="VertexAttribPointer" template="VertexAttribPointer"/>
 
index 800eb839005bebadf19e15da34a13f31a224370a..5557a3b5cb5ac4ffd804bb27d84ee22d389dc6c6 100644 (file)
@@ -358,6 +358,10 @@ static INLINE GLuint CPU_TO_LE32(GLuint x)
 #define M_E (2.7182818284590452354)
 #endif
 
+#ifndef M_LOG2E
+#define M_LOG2E     (1.4426950408889634074)
+#endif
+
 #ifndef ONE_DIV_LN2
 #define ONE_DIV_LN2 (1.442695040888963456)
 #endif
index 0f2d1a8f8da5993220f870180817f0f8570721c2..fffb1a7d2ececba81d37aeaf4a22d30963b75fd5 100644 (file)
 /** Max texture palette / color table size */
 #define MAX_COLOR_TABLE_SIZE 256
 
+/** Max memory to allow for a single texture image (in megabytes) */
+#define MAX_TEXTURE_MBYTES 1024
+
 /** Number of 1D/2D texture mipmap levels */
-#define MAX_TEXTURE_LEVELS 13
+#define MAX_TEXTURE_LEVELS 15
 
 /** Number of 3D texture mipmap levels */
-#define MAX_3D_TEXTURE_LEVELS 9
+#define MAX_3D_TEXTURE_LEVELS 15
 
 /** Number of cube texture mipmap levels - GL_ARB_texture_cube_map */
-#define MAX_CUBE_TEXTURE_LEVELS 13
+#define MAX_CUBE_TEXTURE_LEVELS 15
 
 /** Maximum rectangular texture size - GL_NV_texture_rectangle */
-#define MAX_TEXTURE_RECT_SIZE 4096
+#define MAX_TEXTURE_RECT_SIZE 16384
 
 /** Maximum number of layers in a 1D or 2D array texture - GL_MESA_texture_array */
 #define MAX_ARRAY_TEXTURE_LAYERS 64
  */
 
 #ifndef MAX_WIDTH
-#   define MAX_WIDTH 4096
+#   define MAX_WIDTH 16384
 #endif
 /** Maximum viewport/image height */
 #ifndef MAX_HEIGHT
-#   define MAX_HEIGHT 4096
+#   define MAX_HEIGHT 16384
+#endif
+
+/* XXX: hack to prevent stack overflow on windows until all temporary arrays
+ * [MAX_WIDTH] are allocated from the heap */
+#ifdef WIN32
+#undef MAX_TEXTURE_LEVELS
+#undef MAX_3D_TEXTURE_LEVELS
+#undef MAX_CUBE_TEXTURE_LEVELS
+#undef MAX_TEXTURE_RECT_SIZE
+#undef MAX_WIDTH
+#undef MAX_HEIGHT
+#define MAX_TEXTURE_LEVELS 13
+#define MAX_3D_TEXTURE_LEVELS 9
+#define MAX_CUBE_TEXTURE_LEVELS 13
+#define MAX_TEXTURE_RECT_SIZE 4096
+#define MAX_WIDTH 4096
+#define MAX_HEIGHT 4096
 #endif
 
 /** Maxmimum size for CVA.  May be overridden by the drivers.  */
 #define MAX_TEXTURE_MAX_ANISOTROPY 16.0
 
 /** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
-#define MAX_TEXTURE_LOD_BIAS 12.0
+#define MAX_TEXTURE_LOD_BIAS 14.0
 
 /** For any program target/extension */
 /*@{*/
index b132030b9b1a10ffdaf70606023abc387382436e..f42a566c30228ac7b5d1535cc6aa99dbbde31845 100644 (file)
@@ -535,6 +535,7 @@ _mesa_init_constants(struct gl_context *ctx)
    assert(ctx);
 
    /* Constants, may be overriden (usually only reduced) by device drivers */
+   ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES;
    ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
    ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
    ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
@@ -1399,6 +1400,8 @@ _mesa_make_current( struct gl_context *newCtx,
                     struct gl_framebuffer *drawBuffer,
                     struct gl_framebuffer *readBuffer )
 {
+   GET_CURRENT_CONTEXT(curCtx);
+
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(newCtx, "_mesa_make_current()\n");
 
@@ -1419,6 +1422,11 @@ _mesa_make_current( struct gl_context *newCtx,
       }
    }
 
+   if (curCtx && 
+      (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */
+      curCtx != newCtx)
+      _mesa_flush(curCtx);
+
    /* We used to call _glapi_check_multithread() here.  Now do it in drivers */
    _glapi_set_context((void *) newCtx);
    ASSERT(_mesa_get_current_context() == newCtx);
@@ -1822,7 +1830,7 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
 #ifdef DEBUG
    if (ctx->Shader.Flags & GLSL_LOG) {
       struct gl_shader_program *shProg[MESA_SHADER_TYPES];
-      unsigned i;
+      gl_shader_type i;
 
       shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram;
       shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram;
index 3d5830c01ccde17e44157a01ddd40cfc5eed12b8..b71afdd61f35323c2530ead1bc68cde13af62b7b 100644 (file)
@@ -873,8 +873,12 @@ make_extension_string_es2(const struct gl_context *ctx, GLubyte *str)
    if (ctx->Extensions.ARB_vertex_buffer_object)
       len += append_extension(&str, "GL_OES_mapbuffer");
 
+#if 0
+   /* disabled because of missing GLSL support */
    if (ctx->Extensions.EXT_texture3D)
       len += append_extension(&str, "GL_OES_texture_3D");
+#endif
+
    if (ctx->Extensions.ARB_texture_non_power_of_two)
       len += append_extension(&str, "GL_OES_texture_npot");
    if (ctx->Extensions.EXT_texture_filter_anisotropic)
index 7c3357043faf3b1efc372a120eaaf45fb96a2a1a..975063d0d78584719fcdde282008b8d78cb38554 100644 (file)
@@ -2014,7 +2014,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
 
    switch (pname) {
    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
-      *params = att->Type;
+      *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
       return;
    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
       if (att->Type == GL_RENDERBUFFER_EXT) {
@@ -2024,8 +2024,8 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
         *params = att->Texture->Name;
       }
       else {
-        _mesa_error(ctx, GL_INVALID_ENUM,
-                    "glGetFramebufferAttachmentParameterivEXT(pname)");
+         assert(att->Type == GL_NONE);
+         *params = 0;
       }
       return;
    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
@@ -2146,6 +2146,7 @@ _mesa_GenerateMipmapEXT(GLenum target)
       /* OK, legal value */
       break;
    default:
+      /* XXX need to implement GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY */
       _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
       return;
    }
@@ -2157,6 +2158,13 @@ _mesa_GenerateMipmapEXT(GLenum target)
       return;
    }
 
+   if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
+       !_mesa_cube_complete(texObj)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGenerateMipmap(incomplete cube map)");
+      return;
+   }
+
    _mesa_lock_texture(ctx, texObj);
    if (target == GL_TEXTURE_CUBE_MAP) {
       GLuint face;
index 88a04e888e407a6a1628babecb0a99db407befaf..cd9eb81852fbae6526e6cf7cf115dd5357c8e75f 100644 (file)
@@ -1057,11 +1057,12 @@ _mesa_format_image_size(gl_format format, GLsizei width,
    const struct gl_format_info *info = _mesa_get_format_info(format);
    /* Strictly speaking, a conditional isn't needed here */
    if (info->BlockWidth > 1 || info->BlockHeight > 1) {
-      /* compressed format */
+      /* compressed format (2D only for now) */
       const GLuint bw = info->BlockWidth, bh = info->BlockHeight;
       const GLuint wblocks = (width + bw - 1) / bw;
       const GLuint hblocks = (height + bh - 1) / bh;
       const GLuint sz = wblocks * hblocks * info->BytesPerBlock;
+      assert(depth == 1);
       return sz;
    }
    else {
@@ -1072,6 +1073,36 @@ _mesa_format_image_size(gl_format format, GLsizei width,
 }
 
 
+/**
+ * Same as _mesa_format_image_size() but returns a 64-bit value to
+ * accomodate very large textures.
+ */
+uint64_t
+_mesa_format_image_size64(gl_format format, GLsizei width,
+                          GLsizei height, GLsizei depth)
+{
+   const struct gl_format_info *info = _mesa_get_format_info(format);
+   /* Strictly speaking, a conditional isn't needed here */
+   if (info->BlockWidth > 1 || info->BlockHeight > 1) {
+      /* compressed format (2D only for now) */
+      const uint64_t bw = info->BlockWidth, bh = info->BlockHeight;
+      const uint64_t wblocks = (width + bw - 1) / bw;
+      const uint64_t hblocks = (height + bh - 1) / bh;
+      const uint64_t sz = wblocks * hblocks * info->BytesPerBlock;
+      assert(depth == 1);
+      return sz;
+   }
+   else {
+      /* non-compressed */
+      const uint64_t sz = ((uint64_t) width *
+                           (uint64_t) height *
+                           (uint64_t) depth *
+                           info->BytesPerBlock);
+      return sz;
+   }
+}
+
+
 
 GLint
 _mesa_format_row_stride(gl_format format, GLsizei width)
index eeb460dabe70fbc8fa4c172fdb26d744f215396a..997229bf9f4e271b12ff78f13a3d630b64843c78 100644 (file)
@@ -209,6 +209,10 @@ extern GLuint
 _mesa_format_image_size(gl_format format, GLsizei width,
                         GLsizei height, GLsizei depth);
 
+extern uint64_t
+_mesa_format_image_size64(gl_format format, GLsizei width,
+                          GLsizei height, GLsizei depth);
+
 extern GLint
 _mesa_format_row_stride(gl_format format, GLsizei width);
 
index b54af6ee86bce5f7022a3639aeb8355e43d21628..5ae35b868e3d30e82cef5ada61257f59f8bf7e4f 100644 (file)
@@ -314,6 +314,7 @@ EXTRA_EXT2(ARB_vertex_program, NV_vertex_program);
 EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program);
 EXTRA_EXT(ARB_vertex_buffer_object);
 EXTRA_EXT(ARB_geometry_shader4);
+EXTRA_EXT(ARB_copy_buffer);
 
 static const int
 extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
@@ -469,6 +470,10 @@ static const struct value_desc values[] = {
    { GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0,
      extra_ARB_vertex_buffer_object },
 
+   /* GL_ARB_copy_buffer */
+   { GL_COPY_READ_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer },
+   { GL_COPY_WRITE_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer },
+
    /* GL_OES_read_format */
    { GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, LOC_CUSTOM, TYPE_INT, 0,
      extra_new_buffers_OES_read_format },
@@ -700,12 +705,9 @@ static const struct value_desc values[] = {
 #if FEATURE_ES2
    /* Enums unique to OpenGL ES 2.0 */
    { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA },
-   { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT,
-     offsetof(struct gl_context, Const.FragmentProgram.MaxUniformComponents), NO_EXTRA },
-   { GL_MAX_VARYING_VECTORS, LOC_CUSTOM, TYPE_INT,
-     offsetof(struct gl_context, Const.MaxVarying), NO_EXTRA },
-   { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT,
-     offsetof(struct gl_context, Const.VertexProgram.MaxUniformComponents), NO_EXTRA },
+   { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
+   { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying), NO_EXTRA },
+   { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
    { GL_SHADER_COMPILER, CONST(1), NO_EXTRA },
    /* OES_get_program_binary */
    { GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
@@ -1112,6 +1114,14 @@ static const struct value_desc values[] = {
      extra_valid_draw_buffer },
    { GL_DRAW_BUFFER3_ARB, BUFFER_ENUM(ColorDrawBuffer[3]),
      extra_valid_draw_buffer },
+   { GL_DRAW_BUFFER4_ARB, BUFFER_ENUM(ColorDrawBuffer[4]),
+     extra_valid_draw_buffer },
+   { GL_DRAW_BUFFER5_ARB, BUFFER_ENUM(ColorDrawBuffer[5]),
+     extra_valid_draw_buffer },
+   { GL_DRAW_BUFFER6_ARB, BUFFER_ENUM(ColorDrawBuffer[6]),
+     extra_valid_draw_buffer },
+   { GL_DRAW_BUFFER7_ARB, BUFFER_ENUM(ColorDrawBuffer[7]),
+     extra_valid_draw_buffer },
 
    /* GL_ATI_fragment_shader */
    { GL_NUM_FRAGMENT_REGISTERS_ATI, CONST(6), extra_ATI_fragment_shader },
@@ -1564,6 +1574,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       v->value_int = ctx->Array.ElementArrayBufferObj->Name;
       break;
 
+   /* ARB_copy_buffer */
+   case GL_COPY_READ_BUFFER:
+      v->value_int = ctx->CopyReadBuffer->Name;
+      break;
+   case GL_COPY_WRITE_BUFFER:
+      v->value_int = ctx->CopyWriteBuffer->Name;
+      break;
+
    case GL_FRAGMENT_PROGRAM_BINDING_NV:
       v->value_int = 
         ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0;
@@ -1604,6 +1622,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
    case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
       v->value_int = ctx->Array.ArrayObj->PointSize.BufferObj->Name;
       break;
+
+   case GL_MAX_VERTEX_UNIFORM_VECTORS:
+      v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4;
+      break;
+
+   case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+      v->value_int = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
+      break;
    }   
 }
 
@@ -1733,16 +1759,18 @@ find_value(const char *func, GLenum pname, void **p, union value *v)
    hash = (pname * prime_factor);
    while (1) {
       d = &values[table[hash & mask]];
-      if (likely(d->pname == pname))
-        break;
 
       /* If the enum isn't valid, the hash walk ends with index 0,
        * which is the API mask entry at the beginning of values[]. */
-      if (d->type == TYPE_API_MASK) {
+      if (unlikely(d->type == TYPE_API_MASK)) {
         _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
                      _mesa_lookup_enum_by_nr(pname));
         return &error_value;
       }
+
+      if (likely(d->pname == pname))
+        break;
+
       hash += prime_step;
    }
 
index df1527b47f1b1ec899d58b615c92656e07618709..f9f2ed73077621c040606e665f42334d1a2376cb 100644 (file)
@@ -154,6 +154,8 @@ _mesa_sizeof_type( GLenum type )
         return sizeof(GLdouble);
       case GL_HALF_FLOAT_ARB:
         return sizeof(GLhalfARB);
+      case GL_FIXED:
+        return sizeof(GLfixed);
       default:
          return -1;
    }
index bcca4edc1aa77dd3b898a1c5ea355f93672adba0..cefbf4d8c98772c1543167e97f1523383bad4733 100644 (file)
@@ -88,7 +88,8 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment)
 #if defined(HAVE_POSIX_MEMALIGN)
    void *mem;
    int err = posix_memalign(& mem, alignment, bytes);
-   (void) err;
+   if (err)
+      return NULL;
    return mem;
 #elif defined(_WIN32) && defined(_MSC_VER)
    return _aligned_malloc(bytes, alignment);
index 87b96489dbfab5af88d8b558d81512f27207241d..1c549a8e2479d7ef3e7e400b27354c7256070445 100644 (file)
 #include "math/m_matrix.h"     /* GLmatrix */
 #include "main/simple_list.h"  /* struct simple_node */
 
-/* Shader stages. Note that these will become 5 with tessellation.
- * These MUST have the same values as PIPE_SHADER_*
- */
-#define MESA_SHADER_VERTEX   0
-#define MESA_SHADER_FRAGMENT 1
-#define MESA_SHADER_GEOMETRY 2
-#define MESA_SHADER_TYPES    3
-
 
 /**
  * Color channel data type.
@@ -129,6 +121,20 @@ struct st_context;
 
 
 
+/**
+ * Shader stages. Note that these will become 5 with tessellation.
+ * These MUST have the same values as gallium's PIPE_SHADER_*
+ */
+typedef enum
+{
+   MESA_SHADER_VERTEX = 0,
+   MESA_SHADER_FRAGMENT = 1,
+   MESA_SHADER_GEOMETRY = 2,
+   MESA_SHADER_TYPES = 3
+} gl_shader_type;
+
+
+
 /**
  * Indexes for vertex program attributes.
  * GL_NV_vertex_program aliases generic attributes over the conventional
@@ -2191,6 +2197,7 @@ struct gl_shader_compiler_options
    GLboolean EmitNoCont;                  /**< Emit CONT opcode? */
    GLboolean EmitNoMainReturn;            /**< Emit CONT/RET opcodes? */
    GLboolean EmitNoNoise;                 /**< Emit NOISE opcodes? */
+   GLboolean EmitNoPow;                   /**< Emit POW opcodes? */
 
    /**
     * \name Forms of indirect addressing the driver cannot do.
@@ -2560,6 +2567,7 @@ struct gl_program_constants
  */
 struct gl_constants
 {
+   GLint MaxTextureMbytes;      /**< Max memory per image, in MB */
    GLint MaxTextureLevels;      /**< Max mipmap levels. */ 
    GLint Max3DTextureLevels;    /**< Max mipmap levels for 3D textures */
    GLint MaxCubeTextureLevels;  /**< Max mipmap levels for cube textures */
index fdb647c7ea855a82fdb34bc1b77314f11dd491f6..6d524e64908d1c7c2b8901cb6280ac91d2bf507a 100644 (file)
@@ -484,11 +484,25 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
                            const struct gl_pixelstore_attrib *dstPacking,
                            GLbitfield transferOps)
 {
-   GLfloat luminance[MAX_WIDTH];
+   GLfloat *luminance;
    const GLint comps = _mesa_components_in_format(dstFormat);
    const GLboolean intDstFormat = _mesa_is_integer_format(dstFormat);
    GLuint i;
 
+   if (dstFormat == GL_LUMINANCE ||
+       dstFormat == GL_LUMINANCE_ALPHA ||
+       dstFormat == GL_LUMINANCE_INTEGER_EXT ||
+       dstFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT) {
+      luminance = (GLfloat *) malloc(n * sizeof(GLfloat));
+      if (!luminance) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
+         return;
+      }
+   }
+   else {
+      luminance = NULL;
+   }
+
    /* XXX
     * This test should probably go away.  Have the caller set/clear the
     * IMAGE_CLAMP_BIT as needed.
@@ -1907,6 +1921,8 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          }
       }
    }
+
+   free(luminance);
 }
 
 
@@ -3462,7 +3478,12 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
    {
       GLint dstComponents;
       GLint rDst, gDst, bDst, aDst, lDst, iDst;
-      GLfloat rgba[MAX_WIDTH][4];
+      GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+
+      if (!rgba) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+         return;
+      }
 
       dstComponents = _mesa_components_in_format( dstFormat );
       /* source & dest image formats should have been error checked by now */
@@ -3471,9 +3492,14 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
       /*
        * Extract image data and convert to RGBA floats
        */
-      assert(n <= MAX_WIDTH);
       if (srcFormat == GL_COLOR_INDEX) {
-         GLuint indexes[MAX_WIDTH];
+         GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+
+         if (!indexes) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+            return;
+         }
+
          extract_uint_indexes(n, indexes, srcFormat, srcType, source,
                               srcPacking);
 
@@ -3484,6 +3510,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
             for (i = 0; i < n; i++) {
                dest[i] = (GLchan) (indexes[i] & 0xff);
             }
+            free(indexes);
+            free(rgba);
             return;
          }
          else {
@@ -3498,6 +3526,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
           * with color indexes.
           */
          transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
+
+         free(indexes);
       }
       else {
          /* non-color index data */
@@ -3575,6 +3605,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
             dst += dstComponents;
          }
       }
+
+      free(rgba);
    }
 }
 
@@ -3652,7 +3684,12 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
    {
       GLint dstComponents;
       GLint rDst, gDst, bDst, aDst, lDst, iDst;
-      GLfloat rgba[MAX_WIDTH][4];
+      GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+
+      if (!rgba) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+         return;
+      }
 
       dstComponents = _mesa_components_in_format( dstFormat );
       /* source & dest image formats should have been error checked by now */
@@ -3661,9 +3698,15 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
       /*
        * Extract image data and convert to RGBA floats
        */
-      assert(n <= MAX_WIDTH);
       if (srcFormat == GL_COLOR_INDEX) {
-         GLuint indexes[MAX_WIDTH];
+         GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+
+         if (!indexes) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+            free(rgba);
+            return;
+         }
+
          extract_uint_indexes(n, indexes, srcFormat, srcType, source,
                               srcPacking);
 
@@ -3674,6 +3717,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
             for (i = 0; i < n; i++) {
                dest[i] = (GLchan) (indexes[i] & 0xff);
             }
+            free(indexes);
+            free(rgba);
             return;
          }
          else {
@@ -3688,6 +3733,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
           * with color indexes.
           */
          transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
+
+         free(indexes);
       }
       else {
          /* non-color index data */
@@ -3760,6 +3807,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
             dst += dstComponents;
          }
       }
+
+      free(rgba);
    }
 }
 
@@ -3776,9 +3825,12 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx,
                              const GLvoid *source,
                              const struct gl_pixelstore_attrib *srcPacking)
 {
-   GLuint rgba[MAX_WIDTH][4];
+   GLuint (*rgba)[4] = (GLuint (*)[4]) malloc(n * 4 * sizeof(GLfloat));
 
-   ASSERT(n <= MAX_WIDTH);
+   if (!rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+      return;
+   }
 
    ASSERT(dstFormat == GL_ALPHA ||
           dstFormat == GL_LUMINANCE ||
@@ -3912,6 +3964,8 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx,
          }
       }
    }
+
+   free(rgba);
 }
 
 
@@ -3943,9 +3997,14 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx,
    /* general solution */
    {
       GLint dstComponents;
-      GLfloat rgba[MAX_WIDTH][4];
       GLbyte *dst = dest;
       GLuint i;
+      GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+
+      if (!rgba) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+         return;
+      }
 
       dstComponents = _mesa_components_in_format( dstFormat );
       /* source & dest image formats should have been error checked by now */
@@ -3954,7 +4013,6 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx,
       /*
        * Extract image data and convert to RGBA floats
        */
-      assert(n <= MAX_WIDTH);
       extract_float_rgba(n, rgba, srcFormat, srcType, source,
                          srcPacking->SwapBytes);
 
@@ -3970,6 +4028,8 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx,
          dst[1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
          dst += dstComponents;
       }
+
+      free(rgba);
    }
 }
 
@@ -3988,7 +4048,7 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx,
  *        transferOps - the pixel transfer operations to apply
  */
 void
-_mesa_unpack_index_span( const struct gl_context *ctx, GLuint n,
+_mesa_unpack_index_span( struct gl_context *ctx, GLuint n,
                          GLenum dstType, GLvoid *dest,
                          GLenum srcType, const GLvoid *source,
                          const struct gl_pixelstore_attrib *srcPacking,
@@ -4026,8 +4086,12 @@ _mesa_unpack_index_span( const struct gl_context *ctx, GLuint n,
       /*
        * general solution
        */
-      GLuint indexes[MAX_WIDTH];
-      assert(n <= MAX_WIDTH);
+      GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+
+      if (!indexes) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+         return;
+      }
 
       extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
                            srcPacking);
@@ -4061,19 +4125,24 @@ _mesa_unpack_index_span( const struct gl_context *ctx, GLuint n,
          default:
             _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span");
       }
+
+      free(indexes);
    }
 }
 
 
 void
-_mesa_pack_index_span( const struct gl_context *ctx, GLuint n,
+_mesa_pack_index_span( struct gl_context *ctx, GLuint n,
                        GLenum dstType, GLvoid *dest, const GLuint *source,
                        const struct gl_pixelstore_attrib *dstPacking,
                        GLbitfield transferOps )
 {
-   GLuint indexes[MAX_WIDTH];
+   GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
 
-   ASSERT(n <= MAX_WIDTH);
+   if (!indexes) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
+      return;
+   }
 
    transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
 
@@ -4178,6 +4247,8 @@ _mesa_pack_index_span( const struct gl_context *ctx, GLuint n,
    default:
       _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
    }
+
+   free(indexes);
 }
 
 
@@ -4196,7 +4267,7 @@ _mesa_pack_index_span( const struct gl_context *ctx, GLuint n,
  *        transferOps - apply offset/bias/lookup ops?
  */
 void
-_mesa_unpack_stencil_span( const struct gl_context *ctx, GLuint n,
+_mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
                            GLenum dstType, GLvoid *dest,
                            GLenum srcType, const GLvoid *source,
                            const struct gl_pixelstore_attrib *srcPacking,
@@ -4240,8 +4311,12 @@ _mesa_unpack_stencil_span( const struct gl_context *ctx, GLuint n,
       /*
        * general solution
        */
-      GLuint indexes[MAX_WIDTH];
-      assert(n <= MAX_WIDTH);
+      GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+
+      if (!indexes) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking");
+         return;
+      }
 
       extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
                            srcPacking);
@@ -4286,18 +4361,23 @@ _mesa_unpack_stencil_span( const struct gl_context *ctx, GLuint n,
          default:
             _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
       }
+
+      free(indexes);
    }
 }
 
 
 void
-_mesa_pack_stencil_span( const struct gl_context *ctx, GLuint n,
+_mesa_pack_stencil_span( struct gl_context *ctx, GLuint n,
                          GLenum dstType, GLvoid *dest, const GLstencil *source,
                          const struct gl_pixelstore_attrib *dstPacking )
 {
-   GLstencil stencil[MAX_WIDTH];
+   GLstencil *stencil = (GLstencil *) malloc(n * sizeof(GLstencil));
 
-   ASSERT(n <= MAX_WIDTH);
+   if (!stencil) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing");
+      return;
+   }
 
    if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
        ctx->Pixel.MapStencilFlag) {
@@ -4436,6 +4516,8 @@ _mesa_pack_stencil_span( const struct gl_context *ctx, GLuint n,
    default:
       _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
    }
+
+   free(stencil);
 }
 
 #define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT)                              \
@@ -4466,12 +4548,12 @@ _mesa_pack_stencil_span( const struct gl_context *ctx, GLuint n,
  *                  (ignored for GLfloat).
  */
 void
-_mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n,
+_mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
                          GLenum dstType, GLvoid *dest, GLuint depthMax,
                          GLenum srcType, const GLvoid *source,
                          const struct gl_pixelstore_attrib *srcPacking )
 {
-   GLfloat depthTemp[MAX_WIDTH], *depthValues;
+   GLfloat *depthTemp, *depthValues;
    GLboolean needClamp = GL_FALSE;
 
    /* Look for special cases first.
@@ -4517,6 +4599,12 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n,
 
    /* general case path follows */
 
+   depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat));
+   if (!depthTemp) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+      return;
+   }
+
    if (dstType == GL_FLOAT) {
       depthValues = (GLfloat *) dest;
    }
@@ -4599,6 +4687,7 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n,
          break;
       default:
          _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
+         free(depthTemp);
          return;
    }
 
@@ -4658,6 +4747,8 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n,
       ASSERT(dstType == GL_FLOAT);
       /*ASSERT(depthMax == 1.0F);*/
    }
+
+   free(depthTemp);
 }
 
 
@@ -4665,13 +4756,15 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n,
  * Pack an array of depth values.  The values are floats in [0,1].
  */
 void
-_mesa_pack_depth_span( const struct gl_context *ctx, GLuint n, GLvoid *dest,
+_mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
                        GLenum dstType, const GLfloat *depthSpan,
                        const struct gl_pixelstore_attrib *dstPacking )
 {
-   GLfloat depthCopy[MAX_WIDTH];
-
-   ASSERT(n <= MAX_WIDTH);
+   GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat));
+   if (!depthCopy) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
+      return;
+   }
 
    if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
       memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
@@ -4773,6 +4866,8 @@ _mesa_pack_depth_span( const struct gl_context *ctx, GLuint n, GLvoid *dest,
    default:
       _mesa_problem(ctx, "bad type in _mesa_pack_depth_span");
    }
+
+   free(depthCopy);
 }
 
 
@@ -4781,16 +4876,21 @@ _mesa_pack_depth_span( const struct gl_context *ctx, GLuint n, GLvoid *dest,
  * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8.
  */
 void
-_mesa_pack_depth_stencil_span(const struct gl_context *ctx, GLuint n, GLuint *dest,
+_mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest,
                               const GLfloat *depthVals,
                               const GLstencil *stencilVals,
                               const struct gl_pixelstore_attrib *dstPacking)
 {
-   GLfloat depthCopy[MAX_WIDTH];
-   GLstencil stencilCopy[MAX_WIDTH];
+   GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat));
+   GLstencil *stencilCopy = (GLstencil *) malloc(n * sizeof(GLstencil));
    GLuint i;
 
-   ASSERT(n <= MAX_WIDTH);
+   if (!depthCopy || !stencilCopy) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
+      free(depthCopy);
+      free(stencilCopy);
+      return;
+   }
 
    if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
       memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
@@ -4814,6 +4914,9 @@ _mesa_pack_depth_stencil_span(const struct gl_context *ctx, GLuint n, GLuint *de
    if (dstPacking->SwapBytes) {
       _mesa_swap4(dest, n);
    }
+
+   free(depthCopy);
+   free(stencilCopy);
 }
 
 
index 65d3f7a0fb2dbbd90c53b1c28616ab7374333a44..78238ea5839566088ff813a7800878884d260a84 100644 (file)
@@ -90,7 +90,7 @@ _mesa_unpack_dudv_span_byte(struct gl_context *ctx,
                             GLbitfield transferOps);
 
 extern void
-_mesa_unpack_index_span(const struct gl_context *ctx, GLuint n,
+_mesa_unpack_index_span(struct gl_context *ctx, GLuint n,
                         GLenum dstType, GLvoid *dest,
                         GLenum srcType, const GLvoid *source,
                         const struct gl_pixelstore_attrib *srcPacking,
@@ -98,39 +98,39 @@ _mesa_unpack_index_span(const struct gl_context *ctx, GLuint n,
 
 
 extern void
-_mesa_pack_index_span(const struct gl_context *ctx, GLuint n,
+_mesa_pack_index_span(struct gl_context *ctx, GLuint n,
                       GLenum dstType, GLvoid *dest, const GLuint *source,
                       const struct gl_pixelstore_attrib *dstPacking,
                       GLbitfield transferOps);
 
 
 extern void
-_mesa_unpack_stencil_span(const struct gl_context *ctx, GLuint n,
+_mesa_unpack_stencil_span(struct gl_context *ctx, GLuint n,
                           GLenum dstType, GLvoid *dest,
                           GLenum srcType, const GLvoid *source,
                           const struct gl_pixelstore_attrib *srcPacking,
                           GLbitfield transferOps);
 
 extern void
-_mesa_pack_stencil_span(const struct gl_context *ctx, GLuint n,
+_mesa_pack_stencil_span(struct gl_context *ctx, GLuint n,
                         GLenum dstType, GLvoid *dest, const GLstencil *source,
                         const struct gl_pixelstore_attrib *dstPacking);
 
 
 extern void
-_mesa_unpack_depth_span(const struct gl_context *ctx, GLuint n,
+_mesa_unpack_depth_span(struct gl_context *ctx, GLuint n,
                         GLenum dstType, GLvoid *dest, GLuint depthMax,
                         GLenum srcType, const GLvoid *source,
                         const struct gl_pixelstore_attrib *srcPacking);
 
 extern void
-_mesa_pack_depth_span(const struct gl_context *ctx, GLuint n, GLvoid *dest,
+_mesa_pack_depth_span(struct gl_context *ctx, GLuint n, GLvoid *dest,
                       GLenum dstType, const GLfloat *depthSpan,
                       const struct gl_pixelstore_attrib *dstPacking);
 
 
 extern void
-_mesa_pack_depth_stencil_span(const struct gl_context *ctx,
+_mesa_pack_depth_stencil_span(struct gl_context *ctx,
                               GLuint n, GLuint *dest,
                               const GLfloat *depthVals,
                               const GLstencil *stencilVals,
index 030236e7350b296e5b4b77b4079b78be91e3edb9..96df58d35c241b9cb80772264c19fdb748656fe5 100644 (file)
@@ -95,7 +95,7 @@ _mesa_init_shader_state(struct gl_context *ctx)
     * are generated by the GLSL compiler.
     */
    struct gl_shader_compiler_options options;
-   GLuint i;
+   gl_shader_type sh;
 
    memset(&options, 0, sizeof(options));
    options.MaxUnrollIterations = 32;
@@ -103,8 +103,8 @@ _mesa_init_shader_state(struct gl_context *ctx)
    /* Default pragma settings */
    options.DefaultPragmas.Optimize = GL_TRUE;
 
-   for(i = 0; i < MESA_SHADER_TYPES; ++i)
-      memcpy(&ctx->ShaderCompilerOptions[i], &options, sizeof(options));
+   for (sh = 0; sh < MESA_SHADER_TYPES; ++sh)
+      memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
 
    ctx->Shader.Flags = get_shader_flags();
 }
index b6594cbe6f0704ee8e4ec1928c807360f0df7442..216bbce003299a4501b0a259726f3606c2cf4d5e 100644 (file)
@@ -291,6 +291,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx,
                                struct gl_shader_program *shProg)
 {
    GLuint i;
+   gl_shader_type sh;
 
    assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
 
@@ -326,10 +327,10 @@ _mesa_free_shader_program_data(struct gl_context *ctx,
    shProg->TransformFeedback.NumVarying = 0;
 
 
-   for (i = 0; i < MESA_SHADER_TYPES; i++) {
-      if (shProg->_LinkedShaders[i] != NULL) {
-        ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[i]);
-        shProg->_LinkedShaders[i] = NULL;
+   for (sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+      if (shProg->_LinkedShaders[sh] != NULL) {
+        ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]);
+        shProg->_LinkedShaders[sh] = NULL;
       }
    }
 }
index 346a5b75175da10f34fc3bb73ee5568e356634ce..de7c998cf0e4b3543cab00e90fb04c4c7a0ec738 100644 (file)
@@ -98,7 +98,7 @@ extern void
 _mesa_free_shader_state(struct gl_context *ctx);
 
 
-static INLINE GLuint
+static INLINE gl_shader_type
 _mesa_shader_type_to_index(GLenum v)
 {
    switch (v) {
@@ -110,7 +110,7 @@ _mesa_shader_type_to_index(GLenum v)
       return MESA_SHADER_GEOMETRY;
    default:
       ASSERT(0 && "bad value in _mesa_shader_type_to_index()");
-      return ~0;
+      return MESA_SHADER_TYPES;
    }
 }
 
index f3c0046cf3d4dcae424438ba40361951b139ac57..51de9bf480948fb5aa50f75b909c3372cbcd8a12 100644 (file)
 #ifndef SYNCOBJ_H
 #define SYNCOBJ_H
 
-#include "main/mtypes.h"
+#include "glheader.h"
+#include "mfeatures.h"
 
+struct _glapi_table;
 struct dd_function_table;
+struct gl_context;
+struct gl_sync_object;
 
 #if FEATURE_ARB_sync
 
index 83856429c54cb987547edf8fde867200e4ffebef..19b08bbadf62ae3d8e9746fae46ec5e06d298fe9 100644 (file)
 #ifndef TEXCOMPRESS_H
 #define TEXCOMPRESS_H
 
-#include "mtypes.h"
 #include "formats.h"
+#include "glheader.h"
+#include "mfeatures.h"
+
+struct gl_context;
 
 #if _HAVE_FULL_GL
 
index d0a5b186b719b5a6f7b1d2c564e4a816f5f8ee59..74a0343b9b99032363b867d4636ff88248db397a 100644 (file)
 #ifndef TEXCOMPRESS_S3TC_H
 #define TEXCOMPRESS_S3TC_H
 
-#include "main/mtypes.h"
+#include "compiler.h"
+#include "glheader.h"
+#include "mfeatures.h"
 #include "texstore.h"
 
+struct gl_context;
+struct gl_texture_image;
 
 #if FEATURE_texture_s3tc
 
index abfb916d21ba0257f7873d3cc718f11df73b5c63..22e30a519439efbb0ebeb1bc61a9531f35fb39da 100644 (file)
@@ -27,7 +27,7 @@
 #define TEXENVPROGRAM_H
 
 
-#include "mtypes.h"
+struct gl_context;
 
 extern struct gl_fragment_program *
 _mesa_get_fixed_func_fragment_program(struct gl_context *ctx);
index 8bd1507675343755d94d134d31c6f9ebb8a1e96e..3cf09213ac49725435754599e94c6e4d9b283469 100644 (file)
@@ -27,9 +27,9 @@
 #define TEXFORMAT_H
 
 
-#include "mtypes.h"
 #include "formats.h"
 
+struct gl_context;
 
 extern gl_format
 _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
index 879ac529a01cd52faaa42d1f3bbcad3ed7bf3fd1..c94f88e16e68e8f7a81447d2b01b47f5f1cf6931 100644 (file)
@@ -120,10 +120,15 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
    const GLint height = texImage->Height;
    const GLint depth = texImage->Depth;
    GLint img, row, col;
+   GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat));
+
+   if (!depthRow) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+      return;
+   }
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
-         GLfloat depthRow[MAX_WIDTH];
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
@@ -135,6 +140,8 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
          _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack);
       }
    }
+
+   free(depthRow);
 }
 
 
@@ -244,6 +251,12 @@ get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
    const GLint depth = texImage->Depth;
    const GLbitfield transferOps = 0x0;
    GLint img, row;
+   GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+
+   if (!rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+      return;
+   }
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
@@ -251,7 +264,6 @@ get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
                                           width, height, format, type,
                                           img, row, 0);
 
-         GLfloat rgba[MAX_WIDTH][4];
          GLint col;
 
          /* convert row to RGBA format */
@@ -279,6 +291,8 @@ get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
                                     &ctx->Pack, transferOps);
       }
    }
+
+   free(rgba);
 }
 
 
@@ -314,13 +328,18 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
     */
    GLbitfield transferOps = 0x0;
    GLint img, row;
+   GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+
+   if (!rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+      return;
+   }
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
-         GLfloat rgba[MAX_WIDTH][4];
          GLint col;
          GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
 
@@ -364,6 +383,8 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
                                     &ctx->Pack, transferOps);
       }
    }
+
+   free(rgba);
 }
 
 
index 81a3bbbd9a77471bf7e7cbf5057af5fd2e98c73d..ef420ddabf5fbcca55cc3e92c7a28a74467878b2 100644 (file)
 #ifndef TEXGETIMAGE_H
 #define TEXGETIMAGE_H
 
-#include "mtypes.h"
+#include "glheader.h"
+
+struct gl_context;
+struct gl_texture_image;
+struct gl_texture_object;
 
 extern void
 _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
index 060f34b7f9766ca89fbd5389185d3c9a12231b5c..c5ae63052a740e12bf7ea2659805fd29fcd03206 100644 (file)
@@ -635,6 +635,47 @@ _mesa_is_proxy_texture(GLenum target)
 }
 
 
+/**
+ * Return the proxy target which corresponds to the given texture target
+ */
+static GLenum
+get_proxy_target(GLenum target)
+{
+   switch (target) {
+   case GL_TEXTURE_1D:
+   case GL_PROXY_TEXTURE_1D:
+      return GL_PROXY_TEXTURE_1D;
+   case GL_TEXTURE_2D:
+   case GL_PROXY_TEXTURE_2D:
+      return GL_PROXY_TEXTURE_2D;
+   case GL_TEXTURE_3D:
+   case GL_PROXY_TEXTURE_3D:
+      return GL_PROXY_TEXTURE_3D;
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+   case GL_TEXTURE_CUBE_MAP_ARB:
+   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+      return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
+   case GL_TEXTURE_RECTANGLE_NV:
+   case GL_PROXY_TEXTURE_RECTANGLE_NV:
+      return GL_PROXY_TEXTURE_RECTANGLE_NV;
+   case GL_TEXTURE_1D_ARRAY_EXT:
+   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+      return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
+   case GL_TEXTURE_2D_ARRAY_EXT:
+   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+      return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
+   default:
+      _mesa_problem(NULL, "unexpected target in get_proxy_target()");
+      return 0;
+   }
+}
+
+
 /**
  * Get the texture object that corresponds to the target of the given
  * texture unit.
@@ -1178,94 +1219,110 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
    switch (target) {
    case GL_PROXY_TEXTURE_1D:
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
-      if (width < 2 * border || width > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width >0 && !_mesa_is_pow_two(width - 2 * border)) ||
-          level >= ctx->Const.MaxTextureLevels) {
-         /* bad width or level */
+      if (width < 2 * border || width > 2 + maxSize)
+         return GL_FALSE;
+      if (level >= ctx->Const.MaxTextureLevels)
          return GL_FALSE;
+      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+            return GL_FALSE;
       }
       return GL_TRUE;
+
    case GL_PROXY_TEXTURE_2D:
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
-      if (width < 2 * border || width > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
-          height < 2 * border || height > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
-          level >= ctx->Const.MaxTextureLevels) {
-         /* bad width or height or level */
+      if (width < 2 * border || width > 2 + maxSize)
+         return GL_FALSE;
+      if (height < 2 * border || height > 2 + maxSize)
+         return GL_FALSE;
+      if (level >= ctx->Const.MaxTextureLevels)
          return GL_FALSE;
+      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+            return GL_FALSE;
+         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+            return GL_FALSE;
       }
       return GL_TRUE;
+
    case GL_PROXY_TEXTURE_3D:
       maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
-      if (width < 2 * border || width > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
-          height < 2 * border || height > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
-          depth < 2 * border || depth > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) ||
-          level >= ctx->Const.Max3DTextureLevels) {
-         /* bad width or height or depth or level */
+      if (width < 2 * border || width > 2 + maxSize)
+         return GL_FALSE;
+      if (height < 2 * border || height > 2 + maxSize)
+         return GL_FALSE;
+      if (depth < 2 * border || depth > 2 + maxSize)
          return GL_FALSE;
+      if (level >= ctx->Const.Max3DTextureLevels)
+         return GL_FALSE;
+      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+            return GL_FALSE;
+         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+            return GL_FALSE;
+         if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
+            return GL_FALSE;
       }
       return GL_TRUE;
+
    case GL_PROXY_TEXTURE_RECTANGLE_NV:
-      if (width < 0 || width > ctx->Const.MaxTextureRectSize ||
-          height < 0 || height > ctx->Const.MaxTextureRectSize ||
-          level != 0) {
-         /* bad width or height or level */
+      maxSize = ctx->Const.MaxTextureRectSize;
+      if (width < 0 || width > maxSize)
+         return GL_FALSE;
+      if (height < 0 || height > maxSize)
+         return GL_FALSE;
+      if (level != 0)
          return GL_FALSE;
-      }
       return GL_TRUE;
+
    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
-      if (width < 2 * border || width > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
-          height < 2 * border || height > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
-          level >= ctx->Const.MaxCubeTextureLevels) {
-         /* bad width or height */
+      if (width < 2 * border || width > 2 + maxSize)
+         return GL_FALSE;
+      if (height < 2 * border || height > 2 + maxSize)
          return GL_FALSE;
+      if (level >= ctx->Const.MaxCubeTextureLevels)
+         return GL_FALSE;
+      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+            return GL_FALSE;
+         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+            return GL_FALSE;
       }
       return GL_TRUE;
+
    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
-      if (width < 2 * border || width > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
-          level >= ctx->Const.MaxTextureLevels) {
-         /* bad width or level */
+      if (width < 2 * border || width > 2 + maxSize)
          return GL_FALSE;
-      }
-
-      if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) {
+      if (height < 1 || height > ctx->Const.MaxArrayTextureLayers)
+         return GL_FALSE;
+      if (level >= ctx->Const.MaxTextureLevels)
          return GL_FALSE;
+      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+            return GL_FALSE;
       }
       return GL_TRUE;
+
    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
-      if (width < 2 * border || width > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
-          height < 2 * border || height > 2 + maxSize ||
-          (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
-          level >= ctx->Const.MaxTextureLevels) {
-         /* bad width or height or level */
+      if (width < 2 * border || width > 2 + maxSize)
          return GL_FALSE;
-      }
-      if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) {
+      if (height < 2 * border || height > 2 + maxSize)
+         return GL_FALSE;
+      if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers)
+         return GL_FALSE;
+      if (level >= ctx->Const.MaxTextureLevels)
          return GL_FALSE;
+      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+            return GL_FALSE;
+         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+            return GL_FALSE;
       }
       return GL_TRUE;
+
    default:
       _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
       return GL_FALSE;
@@ -1274,15 +1331,37 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
 
 
 /**
- * Helper function to determine whether a target supports compressed textures
+ * Check if the memory used by the texture would exceed the driver's limit.
+ * This lets us support a max 3D texture size of 8K (for example) but
+ * prevents allocating a full 8K x 8K x 8K texture.
+ * XXX this could be rolled into the proxy texture size test (above) but
+ * we don't have the actual texture internal format at that point.
+ */
+static GLboolean
+legal_texture_size(struct gl_context *ctx, gl_format format,
+                   GLint width, GLint height, GLint depth)
+{
+   uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
+   uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
+   return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
+}
+
+
+
+/**
+ * Helper function to determine whether a target and specific compression
+ * format are supported.
  */
 static GLboolean
-target_can_be_compressed(struct gl_context *ctx, GLenum target)
+target_can_be_compressed(const struct gl_context *ctx, GLenum target,
+                         GLenum intFormat)
 {
+   (void) intFormat;  /* not used yet */
+
    switch (target) {
    case GL_TEXTURE_2D:
    case GL_PROXY_TEXTURE_2D:
-      return GL_TRUE;
+      return GL_TRUE; /* true for any compressed format so far */
    case GL_PROXY_TEXTURE_CUBE_MAP:
    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
@@ -1300,6 +1379,109 @@ target_can_be_compressed(struct gl_context *ctx, GLenum target)
 }
 
 
+/**
+ * Check if the given texture target value is legal for a
+ * glTexImage1/2/3D call.
+ */
+static GLboolean
+legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
+{
+   switch (dims) {
+   case 1:
+      switch (target) {
+      case GL_TEXTURE_1D:
+      case GL_PROXY_TEXTURE_1D:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+      }
+   case 2:
+      switch (target) {
+      case GL_TEXTURE_2D:
+      case GL_PROXY_TEXTURE_2D:
+         return GL_TRUE;
+      case GL_PROXY_TEXTURE_CUBE_MAP:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+         return ctx->Extensions.ARB_texture_cube_map;
+      case GL_TEXTURE_RECTANGLE_NV:
+      case GL_PROXY_TEXTURE_RECTANGLE_NV:
+         return ctx->Extensions.NV_texture_rectangle;
+      case GL_TEXTURE_1D_ARRAY_EXT:
+      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+         return ctx->Extensions.MESA_texture_array;
+      default:
+         return GL_FALSE;
+      }
+   case 3:
+      switch (target) {
+      case GL_TEXTURE_3D:
+      case GL_PROXY_TEXTURE_3D:
+         return GL_TRUE;
+      case GL_TEXTURE_2D_ARRAY_EXT:
+      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+         return ctx->Extensions.MESA_texture_array;
+      default:
+         return GL_FALSE;
+      }
+   default:
+      _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Check if the given texture target value is legal for a
+ * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
+ * The difference compared to legal_teximage_target() above is that
+ * proxy targets are not supported.
+ */
+static GLboolean
+legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
+{
+   switch (dims) {
+   case 1:
+      return target == GL_TEXTURE_1D;
+   case 2:
+      switch (target) {
+      case GL_TEXTURE_2D:
+         return GL_TRUE;
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+         return ctx->Extensions.ARB_texture_cube_map;
+      case GL_TEXTURE_RECTANGLE_NV:
+         return ctx->Extensions.NV_texture_rectangle;
+      case GL_TEXTURE_1D_ARRAY_EXT:
+         return ctx->Extensions.MESA_texture_array;
+      default:
+         return GL_FALSE;
+      }
+   case 3:
+      switch (target) {
+      case GL_TEXTURE_3D:
+         return GL_TRUE;
+      case GL_TEXTURE_2D_ARRAY_EXT:
+         return ctx->Extensions.MESA_texture_array;
+      default:
+         return GL_FALSE;
+      }
+   default:
+      _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
+                    dims);
+      return GL_FALSE;
+   }
+}
+
+
 /**
  * Test the glTexImage[123]D() parameters for errors.
  * 
@@ -1329,10 +1511,10 @@ texture_error_check( struct gl_context *ctx,
                      GLint width, GLint height,
                      GLint depth, GLint border )
 {
-   const GLboolean isProxy = _mesa_is_proxy_texture(target);
+   const GLenum proxyTarget = get_proxy_target(target);
+   const GLboolean isProxy = target == proxyTarget;
    GLboolean sizeOK = GL_TRUE;
    GLboolean colorFormat, indexFormat;
-   GLenum proxy_target;
 
    /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
@@ -1362,71 +1544,16 @@ texture_error_check( struct gl_context *ctx,
       return GL_TRUE;
    }
 
-   /* Check target and call ctx->Driver.TestProxyTexImage() to check the
-    * level, width, height and depth.
-    */
-   if (dimensions == 1) {
-      if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
-         proxy_target = GL_PROXY_TEXTURE_1D;
-         height = 1;
-         depth = 1;
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 2) {
-      depth = 1;
-      if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
-         proxy_target = GL_PROXY_TEXTURE_2D;
-      }
-      else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
-               (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
-            return GL_TRUE;
-         }
-         proxy_target = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
-         sizeOK = (width == height);
-      }
-      else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
-               target == GL_TEXTURE_RECTANGLE_NV) {
-         if (!ctx->Extensions.NV_texture_rectangle) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
-            return GL_TRUE;
-         }
-         proxy_target = GL_PROXY_TEXTURE_RECTANGLE_NV;
-      }
-      else if (target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
-               target == GL_TEXTURE_1D_ARRAY_EXT) {
-         proxy_target = GL_PROXY_TEXTURE_1D_ARRAY_EXT;
-      }
-      else {
-         _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 3) {
-      if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
-         proxy_target = GL_PROXY_TEXTURE_3D;
-      }
-      else if (target == GL_PROXY_TEXTURE_2D_ARRAY_EXT ||
-               target == GL_TEXTURE_2D_ARRAY_EXT) {
-         proxy_target = GL_PROXY_TEXTURE_2D_ARRAY_EXT;
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else {
-      _mesa_problem( ctx, "bad dims in texture_error_check" );
-      return GL_TRUE;
+   /* Do this simple check before calling the TestProxyTexImage() function */
+   if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+      sizeOK = (width == height);
    }
 
-   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxy_target, level,
+   /*
+    * Use the proxy texture driver hook to see if the size/level/etc are
+    * legal.
+    */
+   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
                                                     internalFormat, format,
                                                     type, width, height,
                                                     depth, border);
@@ -1531,9 +1658,10 @@ texture_error_check( struct gl_context *ctx,
 
    /* additional checks for compressed textures */
    if (_mesa_is_compressed_format(ctx, internalFormat)) {
-      if (!target_can_be_compressed(ctx, target) && !isProxy) {
-         _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glTexImage%dD(target)", dimensions);
+      if (!target_can_be_compressed(ctx, target, internalFormat)) {
+         if (!isProxy)
+            _mesa_error(ctx, GL_INVALID_ENUM,
+                        "glTexImage%dD(target)", dimensions);
          return GL_TRUE;
       }
       if (border != 0) {
@@ -1591,61 +1719,13 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
                         GLint width, GLint height, GLint depth,
                         GLenum format, GLenum type )
 {
-   /* Check target */
-   if (dimensions == 1) {
-      if (target != GL_TEXTURE_1D) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 2) {
-      if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-          target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
-            return GL_TRUE;
-         }
-      }
-      else if (target == GL_TEXTURE_RECTANGLE_NV) {
-         if (!ctx->Extensions.NV_texture_rectangle) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
-            return GL_TRUE;
-         }
-      }
-      else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
-        if (!ctx->Extensions.MESA_texture_array) {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
-           return GL_TRUE;
-        }
-      }
-      else if (target != GL_TEXTURE_2D) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 3) {
-      if (target == GL_TEXTURE_2D_ARRAY_EXT) {
-         if (!ctx->Extensions.MESA_texture_array) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
-            return GL_TRUE;
-         }
-      }
-      else if (target != GL_TEXTURE_3D) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else {
-      _mesa_problem( ctx, "invalid dims in texture_error_check" );
-      return GL_TRUE;
-   }
-
    /* Basic level check */
    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
       return GL_TRUE;
    }
 
+   /* Check for negative sizes */
    if (width < 0) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glTexSubImage%dD(width=%d)", dimensions, width);
@@ -1732,13 +1812,6 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
    if (_mesa_is_format_compressed(destTex->TexFormat)) {
       GLuint bw, bh;
 
-      if (!target_can_be_compressed(ctx, target)) {
-         _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glTexSubImage%dD(target=%s)", dimensions,
-                     _mesa_lookup_enum_by_nr(target));
-         return GL_TRUE;
-      }
-
       /* do tests which depend on compression block size */
       _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
 
@@ -1789,10 +1862,18 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
                          GLenum target, GLint level, GLint internalFormat,
                          GLint width, GLint height, GLint border )
 {
-   GLenum type;
+   const GLenum proxyTarget = get_proxy_target(target);
+   const GLenum type = GL_FLOAT;
    GLboolean sizeOK;
    GLint format;
 
+   /* check target */
+   if (!legal_texsubimage_target(ctx, dimensions, target)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
+                  dimensions, _mesa_lookup_enum_by_nr(target));
+      return GL_TRUE;
+   }       
+
    /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
       _mesa_error(ctx, GL_INVALID_VALUE,
@@ -1830,75 +1911,14 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   /* NOTE: the format and type aren't really significant for
-    * TestProxyTexImage().  Only the internalformat really matters.
-    */
-   type = GL_FLOAT;
+   /* Do size, level checking */
+   sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
+      ? (width == height) : 1;
 
-   /* Check target and call ctx->Driver.TestProxyTexImage() to check the
-    * level, width, height and depth.
-    */
-   if (dimensions == 1) {
-      if (target == GL_TEXTURE_1D) {
-         sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
-                                                level, internalFormat,
-                                                format, type,
-                                                width, 1, 1, border);
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 2) {
-      if (target == GL_TEXTURE_2D) {
-         sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
-                                                level, internalFormat,
-                                                format, type,
-                                                width, height, 1, border);
-      }
-      else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-               target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
-            return GL_TRUE;
-         }
-         sizeOK = (width == height) &&
-            ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
-                                          level, internalFormat, format, type,
-                                          width, height, 1, border);
-      }
-      else if (target == GL_TEXTURE_RECTANGLE_NV) {
-         if (!ctx->Extensions.NV_texture_rectangle) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
-            return GL_TRUE;
-         }
-         sizeOK = ctx->Driver.TestProxyTexImage(ctx,
-                                                GL_PROXY_TEXTURE_RECTANGLE_NV,
-                                                level, internalFormat,
-                                                format, type,
-                                                width, height, 1, border);
-      }
-      else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
-         if (!ctx->Extensions.MESA_texture_array) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)");
-            return GL_TRUE;
-         }
-         sizeOK = ctx->Driver.TestProxyTexImage(ctx,
-                                                GL_PROXY_TEXTURE_1D_ARRAY_EXT,
-                                                level, internalFormat,
-                                                format, type,
-                                                width, height, 1, border);
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else {
-      _mesa_problem(ctx, "invalid dimensions in copytexture_error_check");
-      return GL_TRUE;
-   }
+   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
+                                                    internalFormat, format,
+                                                    type, width, height,
+                                                    1, border);
 
    if (!sizeOK) {
       if (dimensions == 1) {
@@ -1914,7 +1934,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
    }
 
    if (_mesa_is_compressed_format(ctx, internalFormat)) {
-      if (!target_can_be_compressed(ctx, target)) {
+      if (!target_can_be_compressed(ctx, target, internalFormat)) {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glCopyTexImage%dD(target)", dimensions);
          return GL_TRUE;
@@ -1973,45 +1993,11 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
       }
    }
 
-   /* Check target */
-   if (dimensions == 1) {
-      if (target != GL_TEXTURE_1D) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 2) {
-      if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-          target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
-            return GL_TRUE;
-         }
-      }
-      else if (target == GL_TEXTURE_RECTANGLE_NV) {
-         if (!ctx->Extensions.NV_texture_rectangle) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
-            return GL_TRUE;
-         }
-      }
-      else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
-         if (!ctx->Extensions.MESA_texture_array) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
-            return GL_TRUE;
-         }
-      }
-      else if (target != GL_TEXTURE_2D) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
-         return GL_TRUE;
-      }
-   }
-   else if (dimensions == 3) {
-      if (((target != GL_TEXTURE_2D_ARRAY_EXT) ||
-          (!ctx->Extensions.MESA_texture_array))
-         && (target != GL_TEXTURE_3D)) {
-        _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
-        return GL_TRUE;
-      }
+   /* check target (proxies not allowed) */
+   if (!legal_texsubimage_target(ctx, dimensions, target)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
+                  dimensions, _mesa_lookup_enum_by_nr(target));
+      return GL_TRUE;
    }
 
    /* Check level */
@@ -2100,11 +2086,6 @@ copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
    }
 
    if (_mesa_is_format_compressed(teximage->TexFormat)) {
-      if (!target_can_be_compressed(ctx, target)) {
-         _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glCopyTexSubImage%dD(target)", dimensions);
-         return GL_TRUE;
-      }
       /* offset must be multiple of 4 */
       if ((xoffset & 3) || (yoffset & 3)) {
          _mesa_error(ctx, GL_INVALID_VALUE,
@@ -2337,89 +2318,48 @@ _mesa_choose_texture_format(struct gl_context *ctx,
 }
 
 
-
-/*
- * Called from the API.  Note that width includes the border.
+/**
+ * Common code to implement all the glTexImage1D/2D/3D functions.
  */
-void GLAPIENTRY
-_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
-                  GLsizei width, GLint border, GLenum format,
-                  GLenum type, const GLvoid *pixels )
+static void
+teximage(struct gl_context *ctx, GLuint dims,
+         GLenum target, GLint level, GLint internalFormat,
+         GLsizei width, GLsizei height, GLsizei depth,
+         GLint border, GLenum format, GLenum type,
+         const GLvoid *pixels)
 {
-   GET_CURRENT_CONTEXT(ctx);
+   GLboolean error;
+
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n",
+      _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
+                  dims,
                   _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat), width, border,
+                  _mesa_lookup_enum_by_nr(internalFormat),
+                  width, height, depth, border,
                   _mesa_lookup_enum_by_nr(format),
                   _mesa_lookup_enum_by_nr(type), pixels);
 
-   internalFormat = override_internal_format(internalFormat, width, 1);
+   internalFormat = override_internal_format(internalFormat, width, height);
 
-   if (target == GL_TEXTURE_1D) {
-      /* non-proxy target */
-      struct gl_texture_object *texObj;
-      struct gl_texture_image *texImage;
-      const GLuint face = _mesa_tex_target_to_face(target);
+   /* target error checking */
+   if (!legal_teximage_target(ctx, dims, target)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
+                  dims, _mesa_lookup_enum_by_nr(target));
+      return;
+   }
 
-      if (texture_error_check(ctx, 1, target, level, internalFormat,
-                              format, type, width, 1, 1, border)) {
-         return;   /* error was recorded */
-      }
+   /* general error checking */
+   error = texture_error_check(ctx, dims, target, level, internalFormat,
+                               format, type, width, height, depth, border);
 
-      if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
-        _mesa_update_state(ctx);
+   if (_mesa_is_proxy_texture(target)) {
+      /* Proxy texture: just clear or set state depending on error checking */
+      struct gl_texture_image *texImage =
+         _mesa_get_proxy_tex_image(ctx, target, level);
 
-      texObj = _mesa_get_current_tex_object(ctx, target);
-      _mesa_lock_texture(ctx, texObj);
-      {
-        texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-        if (!texImage) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
-        }
-         else {
-            gl_format texFormat;
-
-            if (texImage->Data) {
-               ctx->Driver.FreeTexImageData( ctx, texImage );
-            }
-
-            ASSERT(texImage->Data == NULL);
-
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, format,
-                                                    type);
-
-            _mesa_init_teximage_fields(ctx, target, texImage,
-                                       width, 1, 1,
-                                       border, internalFormat,
-                                       texFormat);
-
-            /* Give the texture to the driver.  <pixels> may be null. */
-            ASSERT(ctx->Driver.TexImage1D);
-            ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
-                                   width, border, format, type, pixels,
-                                   &ctx->Unpack, texObj, texImage);
-
-            check_gen_mipmap(ctx, target, texObj, level);
-
-            update_fbo_texture(ctx, texObj, face, level);
-
-            /* state update */
-            texObj->_Complete = GL_FALSE;
-            ctx->NewState |= _NEW_TEXTURE;
-         }
-      }
-      _mesa_unlock_texture(ctx, texObj);
-   }
-   else if (target == GL_PROXY_TEXTURE_1D) {
-      /* Proxy texture: check for errors and update proxy state */
-      struct gl_texture_image *texImage;
-      texImage = _mesa_get_proxy_tex_image(ctx, target, level);
-      if (texture_error_check(ctx, 1, target, level, internalFormat,
-                              format, type, width, 1, 1, border)) {
+      if (error) {
          /* when error, clear all proxy texture image parameters */
          if (texImage)
             clear_teximage_fields(texImage);
@@ -2428,54 +2368,28 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
          /* no error, set the tex image parameters */
          struct gl_texture_object *texObj =
             _mesa_get_current_tex_object(ctx, target);
-         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, target,
-                                                           level,
+         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
+                                                           target, level,
                                                            internalFormat,
                                                            format, type);
-         _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
-                                    border, internalFormat, texFormat);
+
+         if (legal_texture_size(ctx, texFormat, width, height, depth)) {
+            _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+                                       depth, border, internalFormat,
+                                       texFormat);
+         }
+         else if (texImage) {
+            clear_teximage_fields(texImage);
+         }
       }
    }
    else {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
-      return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
-                  GLsizei width, GLsizei height, GLint border,
-                  GLenum format, GLenum type,
-                  const GLvoid *pixels )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat), width, height,
-                  border, _mesa_lookup_enum_by_nr(format),
-                  _mesa_lookup_enum_by_nr(type), pixels);
-
-   internalFormat = override_internal_format(internalFormat, width, height);
-
-   if (target == GL_TEXTURE_2D ||
-       (ctx->Extensions.ARB_texture_cube_map &&
-        target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) ||
-       (ctx->Extensions.NV_texture_rectangle &&
-        target == GL_TEXTURE_RECTANGLE_NV) ||
-       (ctx->Extensions.MESA_texture_array &&
-        target == GL_TEXTURE_1D_ARRAY_EXT)) {
       /* non-proxy target */
+      const GLuint face = _mesa_tex_target_to_face(target);
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      const GLuint face = _mesa_tex_target_to_face(target);
 
-      if (texture_error_check(ctx, 2, target, level, internalFormat,
-                              format, type, width, height, 1, border)) {
+      if (error) {
          return;   /* error was recorded */
       }
 
@@ -2483,11 +2397,13 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
         _mesa_update_state(ctx);
 
       texObj = _mesa_get_current_tex_object(ctx, target);
+
       _mesa_lock_texture(ctx, texObj);
       {
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+
         if (!texImage) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
         }
          else {
             gl_format texFormat;
@@ -2497,63 +2413,81 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
             }
 
             ASSERT(texImage->Data == NULL);
-
             texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
                                                     internalFormat, format,
                                                     type);
 
-            _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                       border, internalFormat, texFormat);
-
-            /* Give the texture to the driver.  <pixels> may be null. */
-            ASSERT(ctx->Driver.TexImage2D);
-            ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
-                                   width, height, border, format, type,
-                                   pixels, &ctx->Unpack, texObj, texImage);
+            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
+               _mesa_init_teximage_fields(ctx, target, texImage,
+                                          width, height, depth,
+                                          border, internalFormat, texFormat);
+
+               /* Give the texture to the driver.  <pixels> may be null. */
+               ASSERT(ctx->Driver.TexImage3D);
+               switch (dims) {
+               case 1:
+                  ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+                                         width, border, format,
+                                         type, pixels, &ctx->Unpack, texObj,
+                                         texImage);
+                  break;
+               case 2:
+                  ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+                                         width, height, border, format,
+                                         type, pixels, &ctx->Unpack, texObj,
+                                         texImage);
+                  break;
+               case 3:
+                  ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
+                                         width, height, depth, border, format,
+                                         type, pixels, &ctx->Unpack, texObj,
+                                         texImage);
+                  break;
+               default:
+                  _mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
+               }
 
-            check_gen_mipmap(ctx, target, texObj, level);
+               check_gen_mipmap(ctx, target, texObj, level);
 
-            update_fbo_texture(ctx, texObj, face, level);
+               update_fbo_texture(ctx, texObj, face, level);
 
-            /* state update */
-            texObj->_Complete = GL_FALSE;
-            ctx->NewState |= _NEW_TEXTURE;
+               /* state update */
+               texObj->_Complete = GL_FALSE;
+               ctx->NewState |= _NEW_TEXTURE;
+            }
+            else {
+               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
+            }
          }
       }
       _mesa_unlock_texture(ctx, texObj);
    }
-   else if (target == GL_PROXY_TEXTURE_2D ||
-            (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
-             ctx->Extensions.ARB_texture_cube_map) ||
-            (target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
-             ctx->Extensions.NV_texture_rectangle) ||
-            (ctx->Extensions.MESA_texture_array &&
-             target == GL_PROXY_TEXTURE_1D_ARRAY_EXT)) {
-      /* Proxy texture: check for errors and update proxy state */
-      struct gl_texture_image *texImage;
-      texImage = _mesa_get_proxy_tex_image(ctx, target, level);
-      if (texture_error_check(ctx, 2, target, level, internalFormat,
-                              format, type, width, height, 1, border)) {
-         /* when error, clear all proxy texture image parameters */
-         if (texImage)
-            clear_teximage_fields(texImage);
-      }
-      else {
-         /* no error, set the tex image parameters */
-         struct gl_texture_object *texObj =
-            _mesa_get_current_tex_object(ctx, target);
-         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
-                                                           target, level,
-                                                           internalFormat,
-                                                           format, type);
-         _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                    border, internalFormat, texFormat);
-      }
-   }
-   else {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
-      return;
-   }
+}
+
+
+/*
+ * Called from the API.  Note that width includes the border.
+ */
+void GLAPIENTRY
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
+                  GLsizei width, GLint border, GLenum format,
+                  GLenum type, const GLvoid *pixels )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
+            border, format, type, pixels);
+}
+
+
+void GLAPIENTRY
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
+                  GLsizei width, GLsizei height, GLint border,
+                  GLenum format, GLenum type,
+                  const GLvoid *pixels )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   teximage(ctx, 2, target, level, internalFormat, width, height, 1,
+            border, format, type, pixels);
 }
 
 
@@ -2568,100 +2502,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
                   const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat), width, height,
-                  depth, border, _mesa_lookup_enum_by_nr(format),
-                  _mesa_lookup_enum_by_nr(type), pixels);
-
-   internalFormat = override_internal_format(internalFormat, width, height);
-
-   if (target == GL_TEXTURE_3D ||
-       (ctx->Extensions.MESA_texture_array &&
-        target == GL_TEXTURE_2D_ARRAY_EXT)) {
-      /* non-proxy target */
-      struct gl_texture_object *texObj;
-      struct gl_texture_image *texImage;
-      const GLuint face = _mesa_tex_target_to_face(target);
-
-      if (texture_error_check(ctx, 3, target, level, (GLint) internalFormat,
-                              format, type, width, height, depth, border)) {
-         return;   /* error was recorded */
-      }
-
-      if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
-        _mesa_update_state(ctx);
-
-      texObj = _mesa_get_current_tex_object(ctx, target);
-      _mesa_lock_texture(ctx, texObj);
-      {
-        texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-        if (!texImage) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
-        }
-         else {
-            gl_format texFormat;
-
-            if (texImage->Data) {
-               ctx->Driver.FreeTexImageData( ctx, texImage );
-            }
-
-            ASSERT(texImage->Data == NULL);
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, format,
-                                                    type);
-            _mesa_init_teximage_fields(ctx, target, texImage,
-                                       width, height, depth,
-                                       border, internalFormat, texFormat);
-
-            /* Give the texture to the driver.  <pixels> may be null. */
-            ASSERT(ctx->Driver.TexImage3D);
-            ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
-                                   width, height, depth, border, format, type,
-                                   pixels, &ctx->Unpack, texObj, texImage);
-
-            check_gen_mipmap(ctx, target, texObj, level);
-
-            update_fbo_texture(ctx, texObj, face, level);
-
-            /* state update */
-            texObj->_Complete = GL_FALSE;
-            ctx->NewState |= _NEW_TEXTURE;
-         }
-      }
-      _mesa_unlock_texture(ctx, texObj);
-   }
-   else if (target == GL_PROXY_TEXTURE_3D ||
-       (ctx->Extensions.MESA_texture_array &&
-        target == GL_PROXY_TEXTURE_2D_ARRAY_EXT)) {
-      /* Proxy texture: check for errors and update proxy state */
-      struct gl_texture_image *texImage;
-      texImage = _mesa_get_proxy_tex_image(ctx, target, level);
-      if (texture_error_check(ctx, 3, target, level, internalFormat,
-                              format, type, width, height, depth, border)) {
-         /* when error, clear all proxy texture image parameters */
-         if (texImage)
-            clear_teximage_fields(texImage);
-      }
-      else {
-         /* no error, set the tex image parameters */
-         struct gl_texture_object *texObj =
-            _mesa_get_current_tex_object(ctx, target);
-         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
-                                                           target, level,
-                                                           internalFormat,
-                                                           format, type);
-         _mesa_init_teximage_fields(ctx, target, texImage, width, height,
-                                    depth, border, internalFormat, texFormat);
-      }
-   }
-   else {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
-      return;
-   }
+   teximage(ctx, 3, target, level, internalFormat, width, height, depth,
+            border, format, type, pixels);
 }
 
 
@@ -2724,141 +2566,40 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
 #endif
 
 
-void GLAPIENTRY
-_mesa_TexSubImage1D( GLenum target, GLint level,
-                     GLint xoffset, GLsizei width,
-                     GLenum format, GLenum type,
-                     const GLvoid *pixels )
-{
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  xoffset, width, _mesa_lookup_enum_by_nr(format),
-                  _mesa_lookup_enum_by_nr(type), pixels);
-
-   if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
-      _mesa_update_state(ctx);
-
-   if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
-                              width, 1, 1, format, type)) {
-      return;   /* error was detected */
-   }
-
-
-   texObj = _mesa_get_current_tex_object(ctx, target);
-   assert(texObj);
-
-   _mesa_lock_texture(ctx, texObj);
-   {
-      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
-      if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0,
-                                 width, 1, 1, format, type, texImage)) {
-         /* error was recorded */
-      }
-      else if (width > 0) {
-         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-         xoffset += texImage->Border;
-
-         ASSERT(ctx->Driver.TexSubImage1D);
-         ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
-                                   format, type, pixels, &ctx->Unpack,
-                                   texObj, texImage);
-
-         check_gen_mipmap(ctx, target, texObj, level);
-
-         ctx->NewState |= _NEW_TEXTURE;
-      }
-   }
-   _mesa_unlock_texture(ctx, texObj);
-}
-
 
-void GLAPIENTRY
-_mesa_TexSubImage2D( GLenum target, GLint level,
-                     GLint xoffset, GLint yoffset,
-                     GLsizei width, GLsizei height,
-                     GLenum format, GLenum type,
-                     const GLvoid *pixels )
+/**
+ * Implement all the glTexSubImage1/2/3D() functions.
+ */
+static void
+texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
+            GLint xoffset, GLint yoffset, GLint zoffset,
+            GLsizei width, GLsizei height, GLsizei depth,
+            GLenum format, GLenum type, const GLvoid *pixels )
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  xoffset, yoffset, width, height,
-                  _mesa_lookup_enum_by_nr(format),
-                  _mesa_lookup_enum_by_nr(type), pixels);
-
-   if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
-      _mesa_update_state(ctx);
-
-   if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
-                             width, height, 1, format, type)) {
-      return;   /* error was detected */
-   }
-
-   texObj = _mesa_get_current_tex_object(ctx, target);
-
-   _mesa_lock_texture(ctx, texObj);
-   {
-      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
-      if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
-                                 width, height, 1, format, type, texImage)) {
-        /* error was recorded */
-      }
-      else if (width > 0 && height >= 0) {
-         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-         xoffset += texImage->Border;
-         yoffset += texImage->Border;
-
-         ASSERT(ctx->Driver.TexSubImage2D);
-         ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
-                                   width, height, format, type, pixels,
-                                   &ctx->Unpack, texObj, texImage);
 
-         check_gen_mipmap(ctx, target, texObj, level);
-
-         ctx->NewState |= _NEW_TEXTURE;
-      }
-   }
-   _mesa_unlock_texture(ctx, texObj);
-}
-
-
-
-void GLAPIENTRY
-_mesa_TexSubImage3D( GLenum target, GLint level,
-                     GLint xoffset, GLint yoffset, GLint zoffset,
-                     GLsizei width, GLsizei height, GLsizei depth,
-                     GLenum format, GLenum type,
-                     const GLvoid *pixels )
-{
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n",
+      _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
+                  dims,
                   _mesa_lookup_enum_by_nr(target), level,
                   xoffset, yoffset, zoffset, width, height, depth,
                   _mesa_lookup_enum_by_nr(format),
                   _mesa_lookup_enum_by_nr(type), pixels);
 
+   /* check target (proxies not allowed) */
+   if (!legal_texsubimage_target(ctx, dims, target)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
+                  dims, _mesa_lookup_enum_by_nr(target));
+      return;
+   }       
+
    if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-   if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
+   if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
                               width, height, depth, format, type)) {
       return;   /* error was detected */
    }
@@ -2869,24 +2610,48 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
-      if (subtexture_error_check2(ctx, 3, target, level,
+      if (subtexture_error_check2(ctx, dims, target, level,
                                   xoffset, yoffset, zoffset,
                                  width, height, depth,
                                   format, type, texImage)) {
          /* error was recorded */
       }
       else if (width > 0 && height > 0 && height > 0) {
-         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-         xoffset += texImage->Border;
-         yoffset += texImage->Border;
-         zoffset += texImage->Border;
-
-         ASSERT(ctx->Driver.TexSubImage3D);
-         ctx->Driver.TexSubImage3D(ctx, target, level,
-                                   xoffset, yoffset, zoffset,
-                                   width, height, depth,
-                                   format, type, pixels,
-                                   &ctx->Unpack, texObj, texImage );
+         /* If we have a border, offset=-1 is legal.  Bias by border width. */
+         switch (dims) {
+         case 3:
+            zoffset += texImage->Border;
+            /* fall-through */
+         case 2:
+            yoffset += texImage->Border;
+            /* fall-through */
+         case 1:
+            xoffset += texImage->Border;
+         }
+
+         switch (dims) {
+         case 1:
+            ctx->Driver.TexSubImage1D(ctx, target, level,
+                                      xoffset, width,
+                                      format, type, pixels,
+                                      &ctx->Unpack, texObj, texImage );
+            break;
+         case 2:
+            ctx->Driver.TexSubImage2D(ctx, target, level,
+                                      xoffset, yoffset, width, height,
+                                      format, type, pixels,
+                                      &ctx->Unpack, texObj, texImage );
+            break;
+         case 3:
+            ctx->Driver.TexSubImage3D(ctx, target, level,
+                                      xoffset, yoffset, zoffset,
+                                      width, height, depth,
+                                      format, type, pixels,
+                                      &ctx->Unpack, texObj, texImage );
+            break;
+         default:
+            _mesa_problem(ctx, "unexpected dims in subteximage()");
+         }
 
          check_gen_mipmap(ctx, target, texObj, level);
 
@@ -2897,87 +2662,69 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
 }
 
 
-
 void GLAPIENTRY
-_mesa_CopyTexImage1D( GLenum target, GLint level,
-                      GLenum internalFormat,
-                      GLint x, GLint y,
-                      GLsizei width, GLint border )
+_mesa_TexSubImage1D( GLenum target, GLint level,
+                     GLint xoffset, GLsizei width,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels )
 {
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   const GLuint face = _mesa_tex_target_to_face(target);
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat),
-                  x, y, width, border);
-
-   if (ctx->NewState & NEW_COPY_TEX_STATE)
-      _mesa_update_state(ctx);
-
-   if (copytexture_error_check(ctx, 1, target, level, internalFormat,
-                               width, 1, border))
-      return;
-
-   texObj = _mesa_get_current_tex_object(ctx, target);
-
-   _mesa_lock_texture(ctx, texObj);
-   {
-      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-      if (!texImage) {
-        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
-      }
-      else {
-         gl_format texFormat;
-
-         if (texImage->Data) {
-            ctx->Driver.FreeTexImageData( ctx, texImage );
-         }
-
-         ASSERT(texImage->Data == NULL);
-
-         texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                 internalFormat, GL_NONE,
-                                                 GL_NONE);
+   texsubimage(ctx, 1, target, level,
+               xoffset, 0, 0,
+               width, 1, 1,
+               format, type, pixels);
+}
 
-         _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
-                                    border, internalFormat, texFormat);
 
-         ASSERT(ctx->Driver.CopyTexImage1D);
-         ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
-                                    x, y, width, border);
+void GLAPIENTRY
+_mesa_TexSubImage2D( GLenum target, GLint level,
+                     GLint xoffset, GLint yoffset,
+                     GLsizei width, GLsizei height,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   texsubimage(ctx, 2, target, level,
+               xoffset, yoffset, 0,
+               width, height, 1,
+               format, type, pixels);
+}
 
-         check_gen_mipmap(ctx, target, texObj, level);
 
-         update_fbo_texture(ctx, texObj, face, level);
 
-         /* state update */
-         texObj->_Complete = GL_FALSE;
-         ctx->NewState |= _NEW_TEXTURE;
-      }
-   }
-   _mesa_unlock_texture(ctx, texObj);
+void GLAPIENTRY
+_mesa_TexSubImage3D( GLenum target, GLint level,
+                     GLint xoffset, GLint yoffset, GLint zoffset,
+                     GLsizei width, GLsizei height, GLsizei depth,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   texsubimage(ctx, 3, target, level,
+               xoffset, yoffset, zoffset,
+               width, height, depth,
+               format, type, pixels);
 }
 
 
 
-void GLAPIENTRY
-_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
-                      GLint x, GLint y, GLsizei width, GLsizei height,
-                      GLint border )
+/**
+ * Implement the glCopyTexImage1/2D() functions.
+ */
+static void
+copyteximage(struct gl_context *ctx, GLuint dims,
+             GLenum target, GLint level, GLenum internalFormat,
+             GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    const GLuint face = _mesa_tex_target_to_face(target);
-   GET_CURRENT_CONTEXT(ctx);
+
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n",
+      _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
+                  dims,
                   _mesa_lookup_enum_by_nr(target), level,
                   _mesa_lookup_enum_by_nr(internalFormat),
                   x, y, width, height, border);
@@ -2985,7 +2732,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
-   if (copytexture_error_check(ctx, 2, target, level, internalFormat,
+   if (copytexture_error_check(ctx, dims, target, level, internalFormat,
                                width, height, border))
       return;
 
@@ -2996,7 +2743,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
       texImage = _mesa_get_tex_image(ctx, texObj, target, level);
 
       if (!texImage) {
-        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
+        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
       }
       else {
          gl_format texFormat;
@@ -3011,99 +2758,83 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
                                                  internalFormat, GL_NONE,
                                                  GL_NONE);
 
-         _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                    border, internalFormat, texFormat);
+         if (legal_texture_size(ctx, texFormat, width, height, 1)) {
+            _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+                                       border, internalFormat, texFormat);
 
-         ASSERT(ctx->Driver.CopyTexImage2D);
-         ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
-                                    x, y, width, height, border);
+            ASSERT(ctx->Driver.CopyTexImage2D);
+            if (dims == 1)
+               ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
+                                          x, y, width, border);
+            else
+               ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
+                                          x, y, width, height, border);
 
-         check_gen_mipmap(ctx, target, texObj, level);
+            check_gen_mipmap(ctx, target, texObj, level);
 
-         update_fbo_texture(ctx, texObj, face, level);
+            update_fbo_texture(ctx, texObj, face, level);
 
-         /* state update */
-         texObj->_Complete = GL_FALSE;
-         ctx->NewState |= _NEW_TEXTURE;
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+         else {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
+         }
       }
    }
    _mesa_unlock_texture(ctx, texObj);
 }
 
 
+
 void GLAPIENTRY
-_mesa_CopyTexSubImage1D( GLenum target, GLint level,
-                         GLint xoffset, GLint x, GLint y, GLsizei width )
+_mesa_CopyTexImage1D( GLenum target, GLint level,
+                      GLenum internalFormat,
+                      GLint x, GLint y,
+                      GLsizei width, GLint border )
 {
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   GLint yoffset = 0;
-   GLsizei height = 1;
-
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n",
-                  _mesa_lookup_enum_by_nr(target),
-                  level, xoffset, x, y, width);
-
-   if (ctx->NewState & NEW_COPY_TEX_STATE)
-      _mesa_update_state(ctx);
-
-   if (copytexsubimage_error_check1(ctx, 1, target, level))
-      return;
-
-   texObj = _mesa_get_current_tex_object(ctx, target);
-
-   _mesa_lock_texture(ctx, texObj);
-   {
-      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
-      if (copytexsubimage_error_check2(ctx, 1, target, level,
-                                      xoffset, 0, 0, width, 1, texImage)) {
-         /* error was recorded */
-      }
-      else {
-         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-         xoffset += texImage->Border;
+   copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
+}
 
-         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
-                                        &width, &height)) {
-            ASSERT(ctx->Driver.CopyTexSubImage1D);
-            ctx->Driver.CopyTexSubImage1D(ctx, target, level,
-                                          xoffset, x, y, width);
 
-            check_gen_mipmap(ctx, target, texObj, level);
 
-            ctx->NewState |= _NEW_TEXTURE;
-         }
-      }
-   }
-   _mesa_unlock_texture(ctx, texObj);
+void GLAPIENTRY
+_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
+                      GLint x, GLint y, GLsizei width, GLsizei height,
+                      GLint border )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   copyteximage(ctx, 2, target, level, internalFormat,
+                x, y, width, height, border);
 }
 
 
 
-void GLAPIENTRY
-_mesa_CopyTexSubImage2D( GLenum target, GLint level,
-                         GLint xoffset, GLint yoffset,
-                         GLint x, GLint y, GLsizei width, GLsizei height )
+/**
+ * Implementation for glCopyTexSubImage1/2/3D() functions.
+ */
+static void
+copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
+                GLint xoffset, GLint yoffset, GLint zoffset,
+                GLint x, GLint y, GLsizei width, GLsizei height)
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GET_CURRENT_CONTEXT(ctx);
+
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n",
+      _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
+                  dims,
                   _mesa_lookup_enum_by_nr(target),
-                  level, xoffset, yoffset, x, y, width, height);
+                  level, xoffset, yoffset, zoffset, x, y, width, height);
 
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
-   if (copytexsubimage_error_check1(ctx, 2, target, level))
+   if (copytexsubimage_error_check1(ctx, dims, target, level))
       return;
 
    texObj = _mesa_get_current_tex_object(ctx, target);
@@ -3112,21 +2843,43 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
-      if (copytexsubimage_error_check2(ctx, 2, target, level,
-                                       xoffset, yoffset, 0,
-                                      width, height, texImage)) {
-         /* error was recorded */
+      if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
+                                      zoffset, width, height, texImage)) {
+         /* error was recored */
       }
       else {
-         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-         xoffset += texImage->Border;
-         yoffset += texImage->Border;
+         /* If we have a border, offset=-1 is legal.  Bias by border width. */
+         switch (dims) {
+         case 3:
+            zoffset += texImage->Border;
+            /* fall-through */
+         case 2:
+            yoffset += texImage->Border;
+            /* fall-through */
+         case 1:
+            xoffset += texImage->Border;
+         }
 
          if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
                                         &width, &height)) {
-            ASSERT(ctx->Driver.CopyTexSubImage2D);
-            ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset,
-                                          x, y, width, height);
+            switch (dims) {
+            case 1:
+               ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+                                             xoffset, x, y, width);
+               break;
+            case 2:
+               ctx->Driver.CopyTexSubImage2D(ctx, target, level,
+                                             xoffset, yoffset,
+                                             x, y, width, height);
+               break;
+            case 3:
+               ctx->Driver.CopyTexSubImage3D(ctx, target, level,
+                                             xoffset, yoffset, zoffset,
+                                             x, y, width, height);
+               break;
+            default:
+               _mesa_problem(ctx, "bad dims in copytexsubimage()");
+            }
 
             check_gen_mipmap(ctx, target, texObj, level);
 
@@ -3138,58 +2891,36 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
 }
 
 
-
 void GLAPIENTRY
-_mesa_CopyTexSubImage3D( GLenum target, GLint level,
-                         GLint xoffset, GLint yoffset, GLint zoffset,
-                         GLint x, GLint y, GLsizei width, GLsizei height )
+_mesa_CopyTexSubImage1D( GLenum target, GLint level,
+                         GLint xoffset, GLint x, GLint y, GLsizei width )
 {
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n",
-                  _mesa_lookup_enum_by_nr(target),
-                  level, xoffset, yoffset, zoffset, x, y, width, height);
-
-   if (ctx->NewState & NEW_COPY_TEX_STATE)
-      _mesa_update_state(ctx);
-
-   if (copytexsubimage_error_check1(ctx, 3, target, level))
-      return;
+   copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
+}
 
-   texObj = _mesa_get_current_tex_object(ctx, target);
 
-   _mesa_lock_texture(ctx, texObj);
-   {
-      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
-      if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
-                                      zoffset, width, height, texImage)) {
-         /* error was recored */
-      }
-      else {
-         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-         xoffset += texImage->Border;
-         yoffset += texImage->Border;
-         zoffset += texImage->Border;
+void GLAPIENTRY
+_mesa_CopyTexSubImage2D( GLenum target, GLint level,
+                         GLint xoffset, GLint yoffset,
+                         GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
+                   width, height);
+}
 
-         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
-                                        &width, &height)) {
-            ASSERT(ctx->Driver.CopyTexSubImage3D);
-            ctx->Driver.CopyTexSubImage3D(ctx, target, level,
-                                          xoffset, yoffset, zoffset,
-                                          x, y, width, height);
 
-            check_gen_mipmap(ctx, target, texObj, level);
 
-            ctx->NewState |= _NEW_TEXTURE;
-         }
-      }
-   }
-   _mesa_unlock_texture(ctx, texObj);
+void GLAPIENTRY
+_mesa_CopyTexSubImage3D( GLenum target, GLint level,
+                         GLint xoffset, GLint yoffset, GLint zoffset,
+                         GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
+                   x, y, width, height);
 }
 
 
@@ -3224,55 +2955,28 @@ get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
 
 
 /**
- * Error checking for glCompressedTexImage[123]D().
- * \return error code or GL_NO_ERROR.
- */
-static GLenum
-compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
-                               GLenum target, GLint level,
-                               GLenum internalFormat, GLsizei width,
-                               GLsizei height, GLsizei depth, GLint border,
-                               GLsizei imageSize)
-{
-   GLint expectedSize, maxLevels = 0, maxTextureSize;
-
-   if (dimensions == 1) {
-      /* 1D compressed textures not allowed */
-      return GL_INVALID_ENUM;
-   }
-   else if (dimensions == 2) {
-      if (target == GL_PROXY_TEXTURE_2D) {
-         maxLevels = ctx->Const.MaxTextureLevels;
-      }
-      else if (target == GL_TEXTURE_2D) {
-         maxLevels = ctx->Const.MaxTextureLevels;
-      }
-      else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
-         if (!ctx->Extensions.ARB_texture_cube_map)
-            return GL_INVALID_ENUM; /*target*/
-         maxLevels = ctx->Const.MaxCubeTextureLevels;
-      }
-      else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-               target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
-         if (!ctx->Extensions.ARB_texture_cube_map)
-            return GL_INVALID_ENUM; /*target*/
-         maxLevels = ctx->Const.MaxCubeTextureLevels;
-      }
-      else {
-         return GL_INVALID_ENUM; /*target*/
-      }
-   }
-   else if (dimensions == 3) {
-      /* 3D compressed textures not allowed */
-      return GL_INVALID_ENUM;
-   }
-   else {
-      assert(0);
+ * Error checking for glCompressedTexImage[123]D().
+ * \return error code or GL_NO_ERROR.
+ */
+static GLenum
+compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
+                               GLenum target, GLint level,
+                               GLenum internalFormat, GLsizei width,
+                               GLsizei height, GLsizei depth, GLint border,
+                               GLsizei imageSize)
+{
+   const GLenum proxyTarget = get_proxy_target(target);
+   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
+   GLint expectedSize;
+
+   /* check level */
+   if (level < 0 || level >= maxLevels)
+      return GL_INVALID_VALUE;
+
+   if (!target_can_be_compressed(ctx, target, internalFormat)) {
       return GL_INVALID_ENUM;
    }
 
-   maxTextureSize = 1 << (maxLevels - 1);
-
    /* This will detect any invalid internalFormat value */
    if (!_mesa_is_compressed_format(ctx, internalFormat))
       return GL_INVALID_ENUM;
@@ -3281,47 +2985,51 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
    if (_mesa_base_tex_format(ctx, internalFormat) < 0)
       return GL_INVALID_ENUM;
 
+   /* No compressed formats support borders at this time */
    if (border != 0)
       return GL_INVALID_VALUE;
 
-   /*
-    * XXX We should probably use the proxy texture error check function here.
-    */
-   if (width < 1 || width > maxTextureSize ||
-       (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width)))
-      return GL_INVALID_VALUE;
-
-   if ((height < 1 || height > maxTextureSize ||
-       (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height)))
-       && dimensions > 1)
-      return GL_INVALID_VALUE;
-
-   if ((depth < 1 || depth > maxTextureSize ||
-       (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth)))
-       && dimensions > 2)
-      return GL_INVALID_VALUE;
-
    /* For cube map, width must equal height */
    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
       return GL_INVALID_VALUE;
 
-   if (level < 0 || level >= maxLevels)
-      return GL_INVALID_VALUE;
+   /* check image size against compression block size */
+   {
+      gl_format texFormat =
+         ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+                                         GL_NONE, GL_NONE);
+      GLuint bw, bh;
 
-   expectedSize = compressed_tex_size(width, height, depth, internalFormat);
-   if (expectedSize != imageSize)
-      return GL_INVALID_VALUE;
+      _mesa_get_format_block_size(texFormat, &bw, &bh);
+      if ((width > bw && width % bw > 0) ||
+          (height > bh && height % bh > 0)) {
+         /*
+          * Per GL_ARB_texture_compression:  GL_INVALID_OPERATION is
+          * generated [...] if any parameter combinations are not
+          * supported by the specific compressed internal format. 
+          */
+         return GL_INVALID_OPERATION;
+      }
+   }
 
-#if FEATURE_EXT_texture_sRGB
-   if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
-        internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
-        internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
-        internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)
-       && border != 0) {
+   /* check image sizes */
+   if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
+                                      internalFormat, GL_NONE, GL_NONE,
+                                      width, height, depth, border)) {
+      /* See error comment above */
       return GL_INVALID_OPERATION;
    }
-#endif
+
+   /* check image size in bytes */
+   expectedSize = compressed_tex_size(width, height, depth, internalFormat);
+   if (expectedSize != imageSize) {
+      /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
+       * if <imageSize> is not consistent with the format, dimensions, and
+       * contents of the specified image.
+       */
+      return GL_INVALID_VALUE;
+   }
 
    return GL_NO_ERROR;
 }
@@ -3463,159 +3171,101 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
 }
 
 
-
-void GLAPIENTRY
-_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
-                              GLenum internalFormat, GLsizei width,
-                              GLint border, GLsizei imageSize,
-                              const GLvoid *data)
+/**
+ * Implementation of the glCompressedTexImage1/2/3D() functions.
+ */
+static void
+compressedteximage(struct gl_context *ctx, GLuint dims,
+                   GLenum target, GLint level,
+                   GLenum internalFormat, GLsizei width,
+                   GLsizei height, GLsizei depth, GLint border,
+                   GLsizei imageSize, const GLvoid *data)
 {
-   GET_CURRENT_CONTEXT(ctx);
+   GLenum error;
+
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n",
+      _mesa_debug(ctx,
+                  "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
+                  dims,
                   _mesa_lookup_enum_by_nr(target), level,
                   _mesa_lookup_enum_by_nr(internalFormat),
-                  width, border, imageSize, data);
-
-   if (target == GL_TEXTURE_1D) {
-      /* non-proxy target */
-      struct gl_texture_object *texObj;
-      struct gl_texture_image *texImage;
-      GLenum error = compressed_texture_error_check(ctx, 1, target, level,
-                               internalFormat, width, 1, 1, border, imageSize);
-      if (error) {
-         _mesa_error(ctx, error, "glCompressedTexImage1D");
-         return;
-      }
-
-      texObj = _mesa_get_current_tex_object(ctx, target);
-
-      _mesa_lock_texture(ctx, texObj);
-      {
-        texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-        if (!texImage) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
-        }
-         else {
-            gl_format texFormat;
-
-            if (texImage->Data) {
-               ctx->Driver.FreeTexImageData( ctx, texImage );
-            }
-            ASSERT(texImage->Data == NULL);
-
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, GL_NONE,
-                                                    GL_NONE);
+                  width, height, depth, border, imageSize, data);
 
-            _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
-                                       border, internalFormat, texFormat);
+   /* check target */
+   if (!legal_teximage_target(ctx, dims, target)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
+                  dims, _mesa_lookup_enum_by_nr(target));
+      return;
+   }
 
-            ASSERT(ctx->Driver.CompressedTexImage1D);
-            ctx->Driver.CompressedTexImage1D(ctx, target, level,
-                                             internalFormat, width, border,
-                                             imageSize, data,
-                                             texObj, texImage);
+   error = compressed_texture_error_check(ctx, dims, target, level,
+                                          internalFormat, width, height, depth,
+                                          border, imageSize);
 
-            check_gen_mipmap(ctx, target, texObj, level);
+#if FEATURE_ES
+   /* XXX this is kind of a hack */
+   if (error) {
+      _mesa_error(ctx, error, "glTexImage2D");
+      return;
+   }
 
-            /* state update */
-            texObj->_Complete = GL_FALSE;
-            ctx->NewState |= _NEW_TEXTURE;
-         }
+   if (dims == 2) {
+      switch (internalFormat) {
+      case GL_PALETTE4_RGB8_OES:
+      case GL_PALETTE4_RGBA8_OES:
+      case GL_PALETTE4_R5_G6_B5_OES:
+      case GL_PALETTE4_RGBA4_OES:
+      case GL_PALETTE4_RGB5_A1_OES:
+      case GL_PALETTE8_RGB8_OES:
+      case GL_PALETTE8_RGBA8_OES:
+      case GL_PALETTE8_R5_G6_B5_OES:
+      case GL_PALETTE8_RGBA4_OES:
+      case GL_PALETTE8_RGB5_A1_OES:
+         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
+                                          width, height, imageSize, data);
+         return;
       }
-      _mesa_unlock_texture(ctx, texObj);
    }
-   else if (target == GL_PROXY_TEXTURE_1D) {
-      /* Proxy texture: check for errors and update proxy state */
-      GLenum error = compressed_texture_error_check(ctx, 1, target, level,
-                               internalFormat, width, 1, 1, border, imageSize);
+#endif
+
+   if (_mesa_is_proxy_texture(target)) {
+      /* Proxy texture: just check for errors and update proxy state */
+      struct gl_texture_image *texImage;
+
       if (!error) {
-         ASSERT(ctx->Driver.TestProxyTexImage);
-         error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
-                                             internalFormat, GL_NONE, GL_NONE,
-                                             width, 1, 1, border);
-      }
-      if (error) {
-         /* if error, clear all proxy texture image parameters */
-         struct gl_texture_image *texImage;
-         texImage = _mesa_get_proxy_tex_image(ctx, target, level);
-         if (texImage)
-            clear_teximage_fields(texImage);
+         struct gl_texture_object *texObj =
+            _mesa_get_current_tex_object(ctx, target);
+         gl_format texFormat =
+            _mesa_choose_texture_format(ctx, texObj, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
+         if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
+            error = GL_OUT_OF_MEMORY;
+         }
       }
-      else {
-         /* store the teximage parameters */
-         struct gl_texture_object *texObj;
-         struct gl_texture_image *texImage;
-         gl_format texFormat;
 
-         texObj = _mesa_get_current_tex_object(ctx, target);
-
-        _mesa_lock_texture(ctx, texObj);
-        {
-           texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, GL_NONE,
-                                                    GL_NONE);
-           _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
-                                      border, internalFormat, texFormat);
-        }
-        _mesa_unlock_texture(ctx, texObj);
+      texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+      if (texImage) {
+         if (error) {
+            /* if error, clear all proxy texture image parameters */
+            clear_teximage_fields(texImage);
+         }
+         else {
+            /* no error: store the teximage parameters */
+            _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+                                       depth, border, internalFormat,
+                                       MESA_FORMAT_NONE);
+         }
       }
    }
    else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)");
-      return;
-   }
-}
-
-void GLAPIENTRY
-_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
-                              GLenum internalFormat, GLsizei width,
-                              GLsizei height, GLint border, GLsizei imageSize,
-                              const GLvoid *data)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat),
-                  width, height, border, imageSize, data);
-
-#if FEATURE_ES
-   switch (internalFormat) {
-   case GL_PALETTE4_RGB8_OES:
-   case GL_PALETTE4_RGBA8_OES:
-   case GL_PALETTE4_R5_G6_B5_OES:
-   case GL_PALETTE4_RGBA4_OES:
-   case GL_PALETTE4_RGB5_A1_OES:
-   case GL_PALETTE8_RGB8_OES:
-   case GL_PALETTE8_RGBA8_OES:
-   case GL_PALETTE8_R5_G6_B5_OES:
-   case GL_PALETTE8_RGBA4_OES:
-   case GL_PALETTE8_RGB5_A1_OES:
-      _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
-                                      width, height, imageSize, data);
-      return;
-   }
-#endif
-
-   if (target == GL_TEXTURE_2D ||
-       (ctx->Extensions.ARB_texture_cube_map &&
-        target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
-        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
       /* non-proxy target */
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
 
-      GLenum error = compressed_texture_error_check(ctx, 2, target, level,
-                          internalFormat, width, height, 1, border, imageSize);
       if (error) {
-         _mesa_error(ctx, error, "glCompressedTexImage2D");
+         _mesa_error(ctx, error, "glCompressedTexImage%uD", dims);
          return;
       }
 
@@ -3625,7 +3275,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
       {
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+           _mesa_error(ctx, GL_OUT_OF_MEMORY,
+                        "glCompressedTexImage%uD", dims);
         }
          else {
             gl_format texFormat;
@@ -3639,67 +3290,78 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
                                                     internalFormat, GL_NONE,
                                                     GL_NONE);
 
-            _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                       border, internalFormat, texFormat);
-
-            ASSERT(ctx->Driver.CompressedTexImage2D);
-            ctx->Driver.CompressedTexImage2D(ctx, target, level,
-                                             internalFormat, width, height,
-                                             border, imageSize, data,
-                                             texObj, texImage);
+            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
+               _mesa_init_teximage_fields(ctx, target, texImage,
+                                          width, height, depth,
+                                          border, internalFormat, texFormat);
+
+               switch (dims) {
+               case 1:
+                  ASSERT(ctx->Driver.CompressedTexImage1D);
+                  ctx->Driver.CompressedTexImage1D(ctx, target, level,
+                                                   internalFormat,
+                                                   width,
+                                                   border, imageSize, data,
+                                                   texObj, texImage);
+                  break;
+               case 2:
+                  ASSERT(ctx->Driver.CompressedTexImage2D);
+                  ctx->Driver.CompressedTexImage2D(ctx, target, level,
+                                                   internalFormat,
+                                                   width, height,
+                                                   border, imageSize, data,
+                                                   texObj, texImage);
+                  break;
+               case 3:
+                  ASSERT(ctx->Driver.CompressedTexImage3D);
+                  ctx->Driver.CompressedTexImage3D(ctx, target, level,
+                                                   internalFormat,
+                                                   width, height, depth,
+                                                   border, imageSize, data,
+                                                   texObj, texImage);
+                  break;
+               default:
+                  _mesa_problem(ctx, "bad dims in compressedteximage");
+               }
 
-            check_gen_mipmap(ctx, target, texObj, level);
+               check_gen_mipmap(ctx, target, texObj, level);
 
-            /* state update */
-            texObj->_Complete = GL_FALSE;
-            ctx->NewState |= _NEW_TEXTURE;
+               /* state update */
+               texObj->_Complete = GL_FALSE;
+               ctx->NewState |= _NEW_TEXTURE;
+            }
+            else {
+               _mesa_error(ctx, GL_OUT_OF_MEMORY,
+                           "glCompressedTexImage%uD", dims);
+            }
          }
       }
       _mesa_unlock_texture(ctx, texObj);
    }
-   else if (target == GL_PROXY_TEXTURE_2D ||
-            (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
-             ctx->Extensions.ARB_texture_cube_map)) {
-      /* Proxy texture: check for errors and update proxy state */
-      GLenum error = compressed_texture_error_check(ctx, 2, target, level,
-                          internalFormat, width, height, 1, border, imageSize);
-      if (!error) {
-         ASSERT(ctx->Driver.TestProxyTexImage);
-         error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
-                                              internalFormat, GL_NONE, GL_NONE,
-                                              width, height, 1, border);
-      }
-      if (error) {
-         /* if error, clear all proxy texture image parameters */
-         struct gl_texture_image *texImage;
-         texImage = _mesa_get_proxy_tex_image(ctx, target, level);
-         if (texImage)
-            clear_teximage_fields(texImage);
-      }
-      else {
-         /* store the teximage parameters */
-         struct gl_texture_object *texObj;
-         struct gl_texture_image *texImage;
-         gl_format texFormat;
+}
 
-         texObj = _mesa_get_current_tex_object(ctx, target);
 
-        _mesa_lock_texture(ctx, texObj);
-        {
-           texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, GL_NONE,
-                                                    GL_NONE);
-           _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                      border, internalFormat, texFormat);
-        }
-        _mesa_unlock_texture(ctx, texObj);
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)");
-      return;
-   }
+void GLAPIENTRY
+_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
+                              GLenum internalFormat, GLsizei width,
+                              GLint border, GLsizei imageSize,
+                              const GLvoid *data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   compressedteximage(ctx, 1, target, level, internalFormat,
+                      width, 1, 1, border, imageSize, data);
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
+                              GLenum internalFormat, GLsizei width,
+                              GLsizei height, GLint border, GLsizei imageSize,
+                              const GLvoid *data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   compressedteximage(ctx, 2, target, level, internalFormat,
+                      width, height, 1, border, imageSize, data);
 }
 
 
@@ -3710,107 +3372,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
                               GLsizei imageSize, const GLvoid *data)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n",
-                  _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat),
-                  width, height, depth, border, imageSize, data);
-
-   if (target == GL_TEXTURE_3D) {
-      /* non-proxy target */
-      struct gl_texture_object *texObj;
-      struct gl_texture_image *texImage;
-      GLenum error = compressed_texture_error_check(ctx, 3, target, level,
-                      internalFormat, width, height, depth, border, imageSize);
-      if (error) {
-         _mesa_error(ctx, error, "glCompressedTexImage3D");
-         return;
-      }
-
-      texObj = _mesa_get_current_tex_object(ctx, target);
-
-      _mesa_lock_texture(ctx, texObj);
-      {
-        texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-        if (!texImage) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
-        }
-         else {
-            gl_format texFormat;
-
-            if (texImage->Data) {
-               ctx->Driver.FreeTexImageData( ctx, texImage );
-            }
-            ASSERT(texImage->Data == NULL);
-
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, GL_NONE,
-                                                    GL_NONE);
-
-            _mesa_init_teximage_fields(ctx, target, texImage,
-                                       width, height, depth,
-                                       border, internalFormat, texFormat);
-
-            ASSERT(ctx->Driver.CompressedTexImage3D);
-            ctx->Driver.CompressedTexImage3D(ctx, target, level,
-                                             internalFormat,
-                                             width, height, depth,
-                                             border, imageSize, data,
-                                             texObj, texImage);
-
-            check_gen_mipmap(ctx, target, texObj, level);
-
-            /* state update */
-            texObj->_Complete = GL_FALSE;
-            ctx->NewState |= _NEW_TEXTURE;
-         }
-      }
-      _mesa_unlock_texture(ctx, texObj);
-   }
-   else if (target == GL_PROXY_TEXTURE_3D) {
-      /* Proxy texture: check for errors and update proxy state */
-      GLenum error = compressed_texture_error_check(ctx, 3, target, level,
-                      internalFormat, width, height, depth, border, imageSize);
-      if (!error) {
-         ASSERT(ctx->Driver.TestProxyTexImage);
-         error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
-                                             internalFormat, GL_NONE, GL_NONE,
-                                             width, height, depth, border);
-      }
-      if (error) {
-         /* if error, clear all proxy texture image parameters */
-         struct gl_texture_image *texImage;
-         texImage = _mesa_get_proxy_tex_image(ctx, target, level);
-         if (texImage)
-            clear_teximage_fields(texImage);
-      }
-      else {
-         /* store the teximage parameters */
-         struct gl_texture_object *texObj;
-         struct gl_texture_image *texImage;
-         gl_format texFormat;
-
-         texObj = _mesa_get_current_tex_object(ctx, target);
-
-        _mesa_lock_texture(ctx, texObj);
-        {
-           texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, GL_NONE,
-                                                    GL_NONE);
-           _mesa_init_teximage_fields(ctx, target, texImage, width, height,
-                                      depth, border, internalFormat,
-                                       texFormat);
-        }
-        _mesa_unlock_texture(ctx, texObj);
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)");
-      return;
-   }
+   compressedteximage(ctx, 3, target, level, internalFormat,
+                      width, height, depth, border, imageSize, data);
 }
 
 
index 72dbf10cc4b40e3cd8b85cbaa24070548e99f784..5bc5639dbf725dff01601ebb3d3b1e6985b1f7fa 100644 (file)
@@ -372,15 +372,12 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
 
 
 /**
- * Report why a texture object is incomplete.  
- *
- * \param t texture object.
- * \param why string describing why it's incomplete.
- *
- * \note For debug purposes only.
+ * Mark a texture object as incomplete.
+ * \param t  texture object
+ * \param fmt...  string describing why it's incomplete (for debugging).
  */
 static void
-incomplete(const struct gl_texture_object *t, const char *fmt, ...)
+incomplete(struct gl_texture_object *t, const char *fmt, ...)
 {
 #if 0
    va_list args;
@@ -392,6 +389,7 @@ incomplete(const struct gl_texture_object *t, const char *fmt, ...)
 
    printf("Texture Obj %d incomplete because: %s\n", t->Name, s);
 #endif
+   t->_Complete = GL_FALSE;
 }
 
 
@@ -421,14 +419,12 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
     */
    if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
       incomplete(t, "base level = %d is invalid", baseLevel);
-      t->_Complete = GL_FALSE;
       return;
    }
 
    /* Always need the base level image */
    if (!t->Image[0][baseLevel]) {
       incomplete(t, "Image[baseLevel=%d] == NULL", baseLevel);
-      t->_Complete = GL_FALSE;
       return;
    }
 
@@ -437,7 +433,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
        t->Image[0][baseLevel]->Height == 0 ||
        t->Image[0][baseLevel]->Depth == 0) {
       incomplete(t, "texture width = 0");
-      t->_Complete = GL_FALSE;
       return;
    }
 
@@ -491,7 +486,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
          if (t->Image[face][baseLevel] == NULL ||
              t->Image[face][baseLevel]->Width2 != w ||
              t->Image[face][baseLevel]->Height2 != h) {
-            t->_Complete = GL_FALSE;
             incomplete(t, "Cube face missing or mismatched size");
             return;
          }
@@ -508,7 +502,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
       GLint maxLevel = t->_MaxLevel;
 
       if (minLevel > maxLevel) {
-         t->_Complete = GL_FALSE;
          incomplete(t, "minLevel > maxLevel");
          return;
       }
@@ -517,12 +510,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
       for (i = minLevel; i <= maxLevel; i++) {
          if (t->Image[0][i]) {
             if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
-               t->_Complete = GL_FALSE;
                incomplete(t, "Format[i] != Format[baseLevel]");
                return;
             }
             if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
-               t->_Complete = GL_FALSE;
                incomplete(t, "Border[i] != Border[baseLevel]");
                return;
             }
@@ -540,12 +531,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
             }
             if (i >= minLevel && i <= maxLevel) {
                if (!t->Image[0][i]) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "1D Image[0][i] == NULL");
                   return;
                }
                if (t->Image[0][i]->Width2 != width ) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "1D Image[0][i] bad width");
                   return;
                }
@@ -569,17 +558,14 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
             }
             if (i >= minLevel && i <= maxLevel) {
                if (!t->Image[0][i]) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "2D Image[0][i] == NULL");
                   return;
                }
                if (t->Image[0][i]->Width2 != width) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "2D Image[0][i] bad width");
                   return;
                }
                if (t->Image[0][i]->Height2 != height) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "2D Image[0][i] bad height");
                   return;
                }
@@ -607,26 +593,21 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
             if (i >= minLevel && i <= maxLevel) {
                if (!t->Image[0][i]) {
                   incomplete(t, "3D Image[0][i] == NULL");
-                  t->_Complete = GL_FALSE;
                   return;
                }
                if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
                   return;
                }
                if (t->Image[0][i]->Width2 != width) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "3D Image[0][i] bad width");
                   return;
                }
                if (t->Image[0][i]->Height2 != height) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "3D Image[0][i] bad height");
                   return;
                }
                if (t->Image[0][i]->Depth2 != depth) {
-                  t->_Complete = GL_FALSE;
                   incomplete(t, "3D Image[0][i] bad depth");
                   return;
                }
@@ -652,20 +633,17 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
               for (face = 0; face < 6; face++) {
                  /* check that we have images defined */
                  if (!t->Image[face][i]) {
-                    t->_Complete = GL_FALSE;
                     incomplete(t, "CubeMap Image[n][i] == NULL");
                     return;
                  }
                  /* Don't support GL_DEPTH_COMPONENT for cube maps */
                  if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
-                    t->_Complete = GL_FALSE;
                     incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
                     return;
                  }
                  /* check that all six images have same size */
                   if (t->Image[face][i]->Width2 != width || 
                       t->Image[face][i]->Height2 != height) {
-                    t->_Complete = GL_FALSE;
                     incomplete(t, "CubeMap Image[n][i] bad size");
                     return;
                  }
@@ -687,6 +665,44 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
 }
 
 
+/**
+ * Check if the given cube map texture is "cube complete" as defined in
+ * the OpenGL specification.
+ */
+GLboolean
+_mesa_cube_complete(const struct gl_texture_object *texObj)
+{
+   const GLint baseLevel = texObj->BaseLevel;
+   const struct gl_texture_image *img0, *img;
+   GLuint face;
+
+   if (texObj->Target != GL_TEXTURE_CUBE_MAP)
+      return GL_FALSE;
+
+   if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS))
+      return GL_FALSE;
+
+   /* check first face */
+   img0 = texObj->Image[0][baseLevel];
+   if (!img0 ||
+       img0->Width < 1 ||
+       img0->Width != img0->Height)
+      return GL_FALSE;
+
+   /* check remaining faces vs. first face */
+   for (face = 1; face < 6; face++) {
+      img = texObj->Image[face][baseLevel];
+      if (!img ||
+          img->Width != img0->Width ||
+          img->Height != img0->Height ||
+          img->TexFormat != img0->TexFormat)
+         return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+
 /**
  * Mark a texture object dirty.  It forces the object to be incomplete
  * and optionally forces the context to re-validate its state.
index 821b35caa366f1ad790bd908af85831179e866ee..2461b063efdc97a9676ba67d6c8e63839e0890bd 100644 (file)
@@ -32,8 +32,9 @@
 #define TEXTOBJ_H
 
 
-#include "mtypes.h"
+#include "glheader.h"
 
+struct gl_context;
 
 /**
  * \name Internal functions
@@ -68,6 +69,9 @@ extern void
 _mesa_test_texobj_completeness( const struct gl_context *ctx,
                                 struct gl_texture_object *obj );
 
+extern GLboolean
+_mesa_cube_complete(const struct gl_texture_object *texObj);
+
 extern void
 _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj,
                    GLboolean invalidate_state);
index 5e68fb03b5784184ba659de13f771dff22771449..cacd091160e77d83662516c3cdc27c80bf1dd474 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef TEXRENDER_H
 #define TEXRENDER_H
 
-#include "mtypes.h"
+struct gl_context;
+struct gl_framebuffer;
+struct gl_renderbuffer_attachment;
 
 extern void
 _mesa_render_texture(struct gl_context *ctx,
index 752cd4e201f012e773a21ca37a93d26a42488bc5..b0d5b70f2b7104878ef262c984a730953f151b84 100644 (file)
 #ifndef TRANSFORM_FEEDBACK_H
 #define TRANSFORM_FEEDBACK_H
 
-#include "main/mtypes.h"
+#include "compiler.h"
+#include "glheader.h"
+#include "mfeatures.h"
 
+struct _glapi_table;
+struct dd_function_table;
+struct gl_context;
 
 extern void
 _mesa_init_transform_feedback(struct gl_context *ctx);
index 340c3fe1d39bfe9bd33f57dc51ab264b2cabcede..32bf95e3ed1009a4b4779ea4f980492b3b88a801 100644 (file)
@@ -127,8 +127,8 @@ update_array(struct gl_context *ctx,
    GLsizei elementSize;
    GLenum format = GL_RGBA;
 
-   if (ctx->API != API_OPENGLES) {
-      /* fixed point arrays / data is only allowed with OpenGL ES 1.x */
+   if (ctx->API != API_OPENGLES && ctx->API != API_OPENGLES2) {
+      /* fixed point arrays / data is only allowed with OpenGL ES 1.x/2.0 */
       legalTypesMask &= ~FIXED_BIT;
    }
 
@@ -297,7 +297,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
                       const GLvoid *ptr)
 {
    GLbitfield legalTypes = (SHORT_BIT | INT_BIT |
-                            HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
+                            HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+                            FIXED_BIT);
    GET_CURRENT_CONTEXT(ctx);
    const GLuint unit = ctx->Array.ActiveTexture;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
index fb96478cfc33dd2aec161a9a6f55bd6af4643386..af9324134ec77b721696eee7fe6aeee5e30909ba 100644 (file)
 #define VARRAY_H
 
 
-#include "mtypes.h"
+#include "glheader.h"
+#include "mfeatures.h"
+
+struct gl_client_array;
+struct gl_context;
 
 #if _HAVE_FULL_GL
 
index ccfa37588b8059fb9782cdb071e44a1a0e25bf8e..909ff92eee549c4852bf8c49c22fccdbda028c34 100644 (file)
@@ -28,7 +28,8 @@
 #define VIEWPORT_H
 
 #include "glheader.h"
-#include "mtypes.h"
+
+struct gl_context;
 
 extern void GLAPIENTRY
 _mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
index e97afafac3cb981a200c5b2ab7a15b648194c994..bbad6ef024bb20dc606e7875efbfe730ecb2eeba 100644 (file)
@@ -208,6 +208,24 @@ ALIGN16(static GLfloat, d[TEST_COUNT][4]);
 ALIGN16(static GLfloat, r[TEST_COUNT][4]);
 
 
+/**
+ * Check if X, Y or Z component of the coordinate is close to W, in terms
+ * of the clip test.
+ */
+static GLboolean
+xyz_close_to_w(const GLfloat c[4])
+{
+   float k = 0.0001;
+   return (fabs(c[0] - c[3]) < k ||
+           fabs(c[1] - c[3]) < k ||
+           fabs(c[2] - c[3]) < k ||
+           fabs(-c[0] - c[3]) < k ||
+           fabs(-c[1] - c[3]) < k ||
+           fabs(-c[2] - c[3]) < k);
+}
+
+
+
 static int test_cliptest_function( clip_func func, int np,
                                   int psize, long *cycles )
 {
@@ -281,9 +299,18 @@ static int test_cliptest_function( clip_func func, int np,
    }
    for ( i = 0 ; i < TEST_COUNT ; i++ ) {
       if ( dm[i] != rm[i] ) {
+         GLfloat *c = source->start;
+         STRIDE_F(c, source->stride * i);
+         if (psize == 4 && xyz_close_to_w(c)) {
+            /* The coordinate is very close to the clip plane.  The clipmask
+             * may vary depending on code path, but that's OK.
+             */
+            continue;
+         }
         printf( "\n-----------------------------\n" );
-        printf( "(i = %i)\n", i );
-        printf( "dm = 0x%02x   rm = 0x%02x\n", dm[i], rm[i] );
+        printf( "mask[%d] = 0x%02x   ref mask[%d] = 0x%02x\n", i, dm[i], i,rm[i] );
+         printf(" coord = %f, %f, %f, %f\n",
+                c[0], c[1], c[2], c[3]);
         return 0;
       }
    }
index 08e25a1c168c61bf1cd6bfc3959f2201b29e3346..4c0c3007205b6bcc20798b47dd6bda0022ad7108 100644 (file)
 #ifndef ARBPROGPARSE_H
 #define ARBPROGPARSE_H
 
-#include "main/mtypes.h"
+#include "main/glheader.h"
+
+struct gl_context;
+struct gl_fragment_program;
+struct gl_vertex_program;
 
 extern void
 _mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
index 98da90d359ad0bfddaea2bb51e3feb3a523bb612..b274a961b28db5053f2563fcca437dada28e8231 100644 (file)
@@ -65,7 +65,7 @@ static int swizzle_for_size(int size);
 typedef struct ir_to_mesa_src_reg {
    ir_to_mesa_src_reg(int file, int index, const glsl_type *type)
    {
-      this->file = file;
+      this->file = (gl_register_file) file;
       this->index = index;
       if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
         this->swizzle = swizzle_for_size(type->vector_elements);
@@ -84,7 +84,7 @@ typedef struct ir_to_mesa_src_reg {
       this->reladdr = NULL;
    }
 
-   int file; /**< PROGRAM_* from Mesa */
+   gl_register_file file; /**< PROGRAM_* from Mesa */
    int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
    GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
    int negate; /**< NEGATE_XYZW mask from mesa */
@@ -133,13 +133,13 @@ public:
 
 class variable_storage : public exec_node {
 public:
-   variable_storage(ir_variable *var, int file, int index)
+   variable_storage(ir_variable *var, gl_register_file file, int index)
       : file(file), index(index), var(var)
    {
       /* empty */
    }
 
-   int file;
+   gl_register_file file;
    int index;
    ir_variable *var; /* variable that maps to this, if any */
 };
@@ -2166,9 +2166,14 @@ ir_to_mesa_visitor::visit(ir_discard *ir)
 {
    struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
 
-   assert(ir->condition == NULL); /* FINISHME */
+   if (ir->condition) {
+      ir->condition->accept(this);
+      this->result.negate = ~this->result.negate;
+      ir_to_mesa_emit_op1(ir, OPCODE_KIL, ir_to_mesa_undef_dst, this->result);
+   } else {
+      ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
+   }
 
-   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
    fp->UsesKill = GL_TRUE;
 }
 
@@ -2239,7 +2244,7 @@ mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
    struct prog_src_register mesa_reg;
 
    mesa_reg.File = reg.file;
-   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
+   assert(reg.index < (1 << INST_INDEX_BITS));
    mesa_reg.Index = reg.index;
    mesa_reg.Swizzle = reg.swizzle;
    mesa_reg.RelAddr = reg.reladdr != NULL;
@@ -2609,8 +2614,9 @@ set_uniform_initializers(struct gl_context *ctx,
 /**
  * Convert a shader's GLSL IR into a Mesa gl_program.
  */
-struct gl_program *
-get_mesa_program(struct gl_context *ctx, struct gl_shader_program *shader_program,
+static struct gl_program *
+get_mesa_program(struct gl_context *ctx,
+                 struct gl_shader_program *shader_program,
                 struct gl_shader *shader)
 {
    ir_to_mesa_visitor v;
@@ -2633,6 +2639,10 @@ get_mesa_program(struct gl_context *ctx, struct gl_shader_program *shader_progra
       target = GL_FRAGMENT_PROGRAM_ARB;
       target_string = "fragment";
       break;
+   case GL_GEOMETRY_SHADER:
+      target = GL_GEOMETRY_PROGRAM_NV;
+      target_string = "geometry";
+      break;
    default:
       assert(!"should not be reached");
       return NULL;
@@ -2756,6 +2766,15 @@ get_mesa_program(struct gl_context *ctx, struct gl_shader_program *shader_progra
 
       mesa_inst++;
       i++;
+
+      if (!shader_program->LinkStatus)
+         break;
+   }
+
+   if (!shader_program->LinkStatus) {
+      free(mesa_instructions);
+      _mesa_reference_program(ctx, &shader->Program, NULL);
+      return NULL;
    }
 
    set_branchtargets(&v, mesa_instructions, num_instructions);
@@ -2830,8 +2849,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
         /* Lowering */
         do_mat_op_to_vec(ir);
-        lower_instructions(ir, MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2
-                             | LOG_TO_LOG2);
+        lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2
+                                | LOG_TO_LOG2
+                                | ((options->EmitNoPow) ? POW_TO_EXP2 : 0)));
 
         progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
 
@@ -2839,8 +2859,10 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
         progress = lower_quadop_vector(ir, true) || progress;
 
-        if (options->EmitNoIfs)
+        if (options->EmitNoIfs) {
+           progress = lower_discard(ir) || progress;
            progress = do_if_to_cond_assign(ir) || progress;
+        }
 
         if (options->EmitNoNoise)
            progress = lower_noise(ir) || progress;
@@ -2866,30 +2888,40 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
    for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
       struct gl_program *linked_prog;
-      bool ok = true;
 
       if (prog->_LinkedShaders[i] == NULL)
         continue;
 
       linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
 
-      switch (prog->_LinkedShaders[i]->Type) {
-      case GL_VERTEX_SHADER:
-        _mesa_reference_vertprog(ctx, &prog->VertexProgram,
-                                 (struct gl_vertex_program *)linked_prog);
-        ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
-                                             linked_prog);
-        break;
-      case GL_FRAGMENT_SHADER:
-        _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
-                                 (struct gl_fragment_program *)linked_prog);
-        ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                                             linked_prog);
-        break;
-      }
-      if (!ok) {
-        return GL_FALSE;
+      if (linked_prog) {
+         bool ok = true;
+
+         switch (prog->_LinkedShaders[i]->Type) {
+         case GL_VERTEX_SHADER:
+            _mesa_reference_vertprog(ctx, &prog->VertexProgram,
+                                     (struct gl_vertex_program *)linked_prog);
+            ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+                                                 linked_prog);
+            break;
+         case GL_FRAGMENT_SHADER:
+            _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
+                                     (struct gl_fragment_program *)linked_prog);
+            ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+                                                 linked_prog);
+            break;
+         case GL_GEOMETRY_SHADER:
+            _mesa_reference_geomprog(ctx, &prog->GeometryProgram,
+                                     (struct gl_geometry_program *)linked_prog);
+            ok = ctx->Driver.ProgramStringNotify(ctx, GL_GEOMETRY_PROGRAM_NV,
+                                                 linked_prog);
+            break;
+         }
+         if (!ok) {
+            return GL_FALSE;
+         }
       }
+
       _mesa_reference_program(ctx, &linked_prog, NULL);
    }
 
@@ -3007,6 +3039,7 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
    prog->Varying = _mesa_new_parameter_list();
    _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
    _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
+   _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL);
 
    if (prog->LinkStatus) {
       link_shaders(ctx, prog);
index ca90de7ce1c6a4295e6eef1cb17c14f5017a4ca3..a383828e34425f1c65b6802f8b7f4dcd199935c6 100644 (file)
@@ -247,7 +247,7 @@ typedef enum prog_opcode {
  * Number of bits for the src/dst register Index field.
  * This limits the size of temp/uniform register files.
  */
-#define INST_INDEX_BITS 10
+#define INST_INDEX_BITS 11
 
 
 /**
index 79c01020eb24dffb52538cfeb5dfdc874d112ed2..abebf392c0ad9cc573124a8937c614db4afb18f9 100644 (file)
@@ -42,8 +42,8 @@
 /**
  * Return string name for given program/register file.
  */
-static const char *
-file_string(gl_register_file f, gl_prog_print_mode mode)
+const char *
+_mesa_register_file_name(gl_register_file f)
 {
    switch (f) {
    case PROGRAM_TEMPORARY:
@@ -275,7 +275,8 @@ reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
 
    switch (mode) {
    case PROG_PRINT_DEBUG:
-      sprintf(str, "%s[%s%d]", file_string(f, mode), addr, index);
+      sprintf(str, "%s[%s%d]",
+              _mesa_register_file_name(f), addr, index);
       if (hasIndex2) {
          int offset = strlen(str);
          const char *addr2 = relAddr2 ? "ADDR+" : "";
@@ -497,7 +498,7 @@ fprint_dst_reg(FILE * f,
 
 #if 0
    fprintf(f, "%s[%d]%s",
-          file_string((gl_register_file) dstReg->File, mode),
+          _mesa_register_file_name((gl_register_file) dstReg->File),
           dstReg->Index,
           _mesa_writemask_string(dstReg->WriteMask));
 #endif
@@ -522,7 +523,7 @@ fprint_src_reg(FILE *f,
           abs);
 #if 0
    fprintf(f, "%s[%d]%s",
-          file_string((gl_register_file) srcReg->File, mode),
+          _mesa_register_file_name((gl_register_file) srcReg->File),
           srcReg->Index,
           _mesa_swizzle_string(srcReg->Swizzle,
                                srcReg->Negate, GL_FALSE));
@@ -615,8 +616,7 @@ _mesa_fprint_instruction_opt(FILE *f,
       if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
          fprintf(f, ", ");
          fprintf(f, "%s[%d]%s",
-                file_string((gl_register_file) inst->SrcReg[0].File,
-                            mode),
+                 _mesa_register_file_name((gl_register_file) inst->SrcReg[0].File),
                 inst->SrcReg[0].Index,
                 _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
                                      inst->SrcReg[0].Negate, GL_FALSE));
@@ -632,8 +632,7 @@ _mesa_fprint_instruction_opt(FILE *f,
       fprintf(f, " ");
       fprint_dst_reg(f, &inst->DstReg, mode, prog);
       fprintf(f, ", %s[%d], %s",
-             file_string((gl_register_file) inst->SrcReg[0].File,
-                         mode),
+             _mesa_register_file_name((gl_register_file) inst->SrcReg[0].File),
              inst->SrcReg[0].Index,
              _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
                                   inst->SrcReg[0].Negate, GL_TRUE));
@@ -964,7 +963,6 @@ static void
 _mesa_fprint_parameter_list(FILE *f,
                             const struct gl_program_parameter_list *list)
 {
-   const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
    GLuint i;
 
    if (!list)
@@ -978,7 +976,7 @@ _mesa_fprint_parameter_list(FILE *f,
       const GLfloat *v = list->ParameterValues[i];
       fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}",
              i, param->Size,
-             file_string(list->Parameters[i].Type, mode),
+             _mesa_register_file_name(list->Parameters[i].Type),
              param->Name, v[0], v[1], v[2], v[3]);
       if (param->Flags & PROG_PARAM_BIT_CENTROID)
          fprintf(f, " Centroid");
index f080b3fd2e6ab95db1201b48bf31b009e6155595..d962087db3869396adb8a334c9d9378a34afe18c 100644 (file)
@@ -47,6 +47,9 @@ typedef enum {
 } gl_prog_print_mode;
 
 
+extern const char *
+_mesa_register_file_name(gl_register_file f);
+
 extern void
 _mesa_print_vp_inputs(GLbitfield inputs);
 
index baac29ff0dd5dc3d6daea105bae86c9ffb9977c1..c310acb01d4fdc619c4b9c47ebabb63ae9a2991a 100644 (file)
@@ -572,6 +572,24 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
          value[3] = 0.0F;
          return;
 
+      case STATE_FB_WPOS_Y_TRANSFORM:
+         /* A driver may negate this conditional by using ZW swizzle
+          * instead of XY (based on e.g. some other state). */
+         if (ctx->DrawBuffer->Name != 0) {
+            /* Identity (XY) followed by flipping Y upside down (ZW). */
+            value[0] = 1.0F;
+            value[1] = 0.0F;
+            value[2] = -1.0F;
+            value[3] = (GLfloat) (ctx->DrawBuffer->Height - 1);
+         } else {
+            /* Flipping Y upside down (XY) followed by identity (ZW). */
+            value[0] = -1.0F;
+            value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
+            value[2] = 1.0F;
+            value[3] = 0.0F;
+         }
+         return;
+
       case STATE_ROT_MATRIX_0:
          {
             const int unit = (int) state[2];
@@ -695,6 +713,7 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
          return _NEW_PIXEL;
 
       case STATE_FB_SIZE:
+      case STATE_FB_WPOS_Y_TRANSFORM:
          return _NEW_BUFFERS;
 
       default:
@@ -900,6 +919,9 @@ append_token(char *dst, gl_state_index k)
    case STATE_FB_SIZE:
       append(dst, "FbSize");
       break;
+   case STATE_FB_WPOS_Y_TRANSFORM:
+      append(dst, "FbWposYTransform");
+      break;
    case STATE_ROT_MATRIX_0:
       append(dst, "rotMatrixRow0");
       break;
@@ -1046,7 +1068,9 @@ _mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
  * Loop over all the parameters in a parameter list.  If the parameter
  * is a GL state reference, look up the current value of that state
  * variable and put it into the parameter's Value[4] array.
- * This would be called at glBegin time when using a fragment program.
+ * Other parameter types never change or are explicitly set by the user
+ * with glUniform() or glProgramParameter(), etc.
+ * This would be called at glBegin time.
  */
 void
 _mesa_load_state_parameters(struct gl_context *ctx,
@@ -1057,12 +1081,10 @@ _mesa_load_state_parameters(struct gl_context *ctx,
    if (!paramList)
       return;
 
-   /*assert(ctx->Driver.NeedFlush == 0);*/
-
    for (i = 0; i < paramList->NumParameters; i++) {
       if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
          _mesa_fetch_state(ctx,
-                          (gl_state_index *) paramList->Parameters[i].StateIndexes,
+                          paramList->Parameters[i].StateIndexes,
                            paramList->ParameterValues[i]);
       }
    }
index 6e5be53630c1517991c824dedc90c451437b6ae9..009ebde00128b4f8df4cdfe11d03d0def75b7f2a 100644 (file)
@@ -117,6 +117,7 @@ typedef enum gl_state_index_ {
    STATE_PT_BIAS,               /**< Pixel transfer RGBA bias */
    STATE_SHADOW_AMBIENT,        /**< ARB_shadow_ambient fail value; token[2] is texture unit index */
    STATE_FB_SIZE,               /**< (width-1, height-1, 0, 0) */
+   STATE_FB_WPOS_Y_TRANSFORM,   /**< (1, 0, -1, height-1) if a FBO is bound, (-1, height-1, 1, 0) otherwise */
    STATE_ROT_MATRIX_0,          /**< ATI_envmap_bumpmap, rot matrix row 0 */
    STATE_ROT_MATRIX_1,          /**< ATI_envmap_bumpmap, rot matrix row 1 */
    STATE_INTERNAL_DRIVER       /* first available state index for drivers (must be last) */
index 4cacde9aed14a7815cdcc01b3fabc10b357d91fe..9ffa49bb013cd81e2b63f5a2228e918d11865c15 100644 (file)
@@ -917,6 +917,103 @@ _mesa_find_free_register(const GLboolean used[],
 }
 
 
+
+/**
+ * Check if the given register index is valid (doesn't exceed implementation-
+ * dependent limits).
+ * \return GL_TRUE if OK, GL_FALSE if bad index
+ */
+GLboolean
+_mesa_valid_register_index(const struct gl_context *ctx,
+                           gl_shader_type shaderType,
+                           gl_register_file file, GLint index)
+{
+   const struct gl_program_constants *c;
+
+   switch (shaderType) {
+   case MESA_SHADER_VERTEX:
+      c = &ctx->Const.VertexProgram;
+      break;
+   case MESA_SHADER_FRAGMENT:
+      c = &ctx->Const.FragmentProgram;
+      break;
+   case MESA_SHADER_GEOMETRY:
+      c = &ctx->Const.GeometryProgram;
+      break;
+   default:
+      _mesa_problem(ctx,
+                    "unexpected shader type in _mesa_valid_register_index()");
+      return GL_FALSE;
+   }
+
+   switch (file) {
+   case PROGRAM_UNDEFINED:
+      return GL_TRUE;  /* XXX or maybe false? */
+
+   case PROGRAM_TEMPORARY:
+      return index >= 0 && index < c->MaxTemps;
+
+   case PROGRAM_ENV_PARAM:
+      return index >= 0 && index < c->MaxEnvParams;
+
+   case PROGRAM_LOCAL_PARAM:
+      return index >= 0 && index < c->MaxLocalParams;
+
+   case PROGRAM_NAMED_PARAM:
+      return index >= 0 && index < c->MaxParameters;
+
+   case PROGRAM_UNIFORM:
+   case PROGRAM_STATE_VAR:
+      /* aka constant buffer */
+      return index >= 0 && index < c->MaxUniformComponents / 4;
+
+   case PROGRAM_CONSTANT:
+      /* constant buffer w/ possible relative negative addressing */
+      return (index > (int) c->MaxUniformComponents / -4 &&
+              index < c->MaxUniformComponents / 4);
+
+   case PROGRAM_INPUT:
+      if (index < 0)
+         return GL_FALSE;
+
+      switch (shaderType) {
+      case MESA_SHADER_VERTEX:
+         return index < VERT_ATTRIB_GENERIC0 + c->MaxAttribs;
+      case MESA_SHADER_FRAGMENT:
+         return index < FRAG_ATTRIB_VAR0 + ctx->Const.MaxVarying;
+      case MESA_SHADER_GEOMETRY:
+         return index < GEOM_ATTRIB_VAR0 + ctx->Const.MaxVarying;
+      default:
+         return GL_FALSE;
+      }
+
+   case PROGRAM_OUTPUT:
+      if (index < 0)
+         return GL_FALSE;
+
+      switch (shaderType) {
+      case MESA_SHADER_VERTEX:
+         return index < VERT_RESULT_VAR0 + ctx->Const.MaxVarying;
+      case MESA_SHADER_FRAGMENT:
+         return index < FRAG_RESULT_DATA0 + ctx->Const.MaxDrawBuffers;
+      case MESA_SHADER_GEOMETRY:
+         return index < GEOM_RESULT_VAR0 + ctx->Const.MaxVarying;
+      default:
+         return GL_FALSE;
+      }
+
+   case PROGRAM_ADDRESS:
+      return index >= 0 && index < c->MaxAddressRegs;
+
+   default:
+      _mesa_problem(ctx,
+                    "unexpected register file in _mesa_valid_register_index()");
+      return GL_FALSE;
+   }
+}
+
+
+
 /**
  * "Post-process" a GPU program.  This is intended to be used for debugging.
  * Example actions include no-op'ing instructions or changing instruction
index 70cc2c3aaede6a196a586d7c6ccc3f9a60ea81bc..ce37b95bf82db8c0ac55f98575b7bd0f50922017 100644 (file)
@@ -165,6 +165,12 @@ extern GLint
 _mesa_find_free_register(const GLboolean used[],
                          GLuint maxRegs, GLuint firstReg);
 
+
+extern GLboolean
+_mesa_valid_register_index(const struct gl_context *ctx,
+                           gl_shader_type shaderType,
+                           gl_register_file file, GLint index);
+
 extern void
 _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog);
 
index 09e7cb44ef399f68e7a69117ef0e47525e479b83..004f1f8fa7b535bc399fd96425cdfc060b04e4fb 100644 (file)
@@ -336,12 +336,12 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
     check_symbol_table(table);
 
     if (hdr == NULL) {
-        hdr = calloc(1, sizeof(*hdr));
-        hdr->name = strdup(name);
+       hdr = calloc(1, sizeof(*hdr));
+       hdr->name = strdup(name);
 
-        hash_table_insert(table->ht, hdr, hdr->name);
-       hdr->next = table->hdr;
-       table->hdr = hdr;
+       hash_table_insert(table->ht, hdr, hdr->name);
+       hdr->next = table->hdr;
+       table->hdr = hdr;
     }
 
     check_symbol_table(table);
@@ -376,6 +376,81 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
 }
 
 
+int
+_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
+                                    int name_space, const char *name,
+                                    void *declaration)
+{
+    struct symbol_header *hdr;
+    struct symbol *sym;
+    struct symbol *curr;
+    struct scope_level *top_scope;
+
+    check_symbol_table(table);
+
+    hdr = find_symbol(table, name);
+
+    check_symbol_table(table);
+
+    if (hdr == NULL) {
+        hdr = calloc(1, sizeof(*hdr));
+        hdr->name = strdup(name);
+
+        hash_table_insert(table->ht, hdr, hdr->name);
+        hdr->next = table->hdr;
+        table->hdr = hdr;
+    }
+
+    check_symbol_table(table);
+
+    /* If the symbol already exists in this namespace at this scope, it cannot
+     * be added to the table.
+     */
+    for (sym = hdr->symbols
+        ; (sym != NULL) && (sym->name_space != name_space)
+        ; sym = sym->next_with_same_name) {
+       /* empty */
+    }
+
+    if (sym && sym->depth == 0)
+       return -1;
+
+    /* Find the top-level scope */
+    for (top_scope = table->current_scope
+        ; top_scope->next != NULL
+        ; top_scope = top_scope->next) {
+       /* empty */
+    }
+
+    sym = calloc(1, sizeof(*sym));
+    sym->next_with_same_scope = top_scope->symbols;
+    sym->hdr = hdr;
+    sym->name_space = name_space;
+    sym->data = declaration;
+
+    assert(sym->hdr == hdr);
+
+    /* Since next_with_same_name is ordered by scope, we need to append the
+     * new symbol to the _end_ of the list.
+     */
+    if (hdr->symbols == NULL) {
+       hdr->symbols = sym;
+    } else {
+       for (curr = hdr->symbols
+           ; curr->next_with_same_name != NULL
+           ; curr = curr->next_with_same_name) {
+         /* empty */
+       }
+       curr->next_with_same_name = sym;
+    }
+    top_scope->symbols = sym;
+
+    check_symbol_table(table);
+    return 0;
+}
+
+
+
 struct _mesa_symbol_table *
 _mesa_symbol_table_ctor(void)
 {
index 1d570fc1a09ecfe4364c832076280296c31a876d..f9d91649bbc13d1d36e87e80264941974cb7d4f2 100644 (file)
@@ -33,6 +33,10 @@ extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
 extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
     int name_space, const char *name, void *declaration);
 
+extern int _mesa_symbol_table_add_global_symbol(
+    struct _mesa_symbol_table *symtab, int name_space, const char *name,
+    void *declaration);
+
 extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
     int name_space, const char *name);
 
index 8d1dc792bc84fb525b3e07963eedcfd49fbee3e0..f1d08a3e1665e5cdb118eec3c6828193a686e971 100644 (file)
@@ -66,6 +66,11 @@ void st_upload_constants( struct st_context *st,
    if (params && params->NumParameters) {
       const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
 
+      /* Update the constants which come from fixed-function state, such as
+       * transformation matrices, fog factors, etc.  The rest of the values in
+       * the parameters list are explicitly set by the user with glUniform,
+       * glProgramParameter(), etc.
+       */
       _mesa_load_state_parameters(st->ctx, params);
 
       /* We always need to get a new buffer, to keep the drivers simple and
index 036bc60049abb044281d2a26e1a31d5b40b75fc5..2843b7b1764b321878f058bba1f833950d5eae73 100644 (file)
@@ -51,7 +51,7 @@ static void
 update_renderbuffer_surface(struct st_context *st,
                             struct st_renderbuffer *strb)
 {
-   struct pipe_screen *screen = st->pipe->screen;
+   struct pipe_context *pipe = st->pipe;
    struct pipe_resource *resource = strb->rtt->pt;
    int rtt_width = strb->Base.Width;
    int rtt_height = strb->Base.Height;
@@ -65,15 +65,19 @@ update_renderbuffer_surface(struct st_context *st,
       for (level = 0; level <= resource->last_level; level++) {
          if (u_minify(resource->width0, level) == rtt_width &&
              u_minify(resource->height0, level) == rtt_height) {
+            struct pipe_surface surf_tmpl;
+            memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+            surf_tmpl.format = resource->format;
+            surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+            surf_tmpl.u.tex.level = level;
+            surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
+            surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
 
             pipe_surface_reference(&strb->surface, NULL);
 
-            strb->surface = screen->get_tex_surface(screen,
-                                                   resource,
-                                                   strb->rtt_face,
-                                                   level,
-                                                   strb->rtt_slice,
-                                                   PIPE_BIND_RENDER_TARGET);
+            strb->surface = pipe->create_surface(pipe,
+                                                 resource,
+                                                 &surf_tmpl);
 #if 0
             printf("-- alloc new surface %d x %d into tex %p\n",
                    strb->surface->width, strb->surface->height,
index 6be03376d0177966e4bf06cc110bf8e23757c78c..378b30e57ccf406fd9f2f1037302063c8a332053 100644 (file)
@@ -122,8 +122,8 @@ load_color_map_texture(struct gl_context *ctx, struct pipe_resource *pt)
    uint i, j;
 
    transfer = pipe_get_transfer(st_context(ctx)->pipe,
-                                            pt, 0, 0, 0, PIPE_TRANSFER_WRITE,
-                                            0, 0, texSize, texSize);
+                                pt, 0, 0, PIPE_TRANSFER_WRITE,
+                                0, 0, texSize, texSize);
    dest = (uint *) pipe_transfer_map(pipe, transfer);
 
    /* Pack four 1D maps into a 2D texture:
index f147d76808469dcf86affa59d20bd90b179ae2e8..b67068df373d7a358c701a08b7714efceda81404 100644 (file)
@@ -121,6 +121,18 @@ static void
 xlate_border_color(const GLfloat *colorIn, GLenum baseFormat, GLfloat *colorOut)
 {
    switch (baseFormat) {
+   case GL_RED:
+      colorOut[0] = colorIn[0];
+      colorOut[1] = 0.0F;
+      colorOut[2] = 0.0F;
+      colorOut[3] = 1.0F;
+      break;
+   case GL_RG:
+      colorOut[0] = colorIn[0];
+      colorOut[1] = colorIn[1];
+      colorOut[2] = 0.0F;
+      colorOut[3] = 1.0F;
+      break;
    case GL_RGB:
       colorOut[0] = colorIn[0];
       colorOut[1] = colorIn[1];
index 6c5caf42e354330164671a2124b639535ed36851..a76ae92dc3db98cebc49b31ebd6a5d70cd302ceb 100644 (file)
@@ -138,10 +138,10 @@ accum_accum(struct st_context *st, GLfloat value,
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
    color_trans = pipe_get_transfer(st->pipe,
-                                               color_strb->texture,
-                                               0, 0, 0,
-                                               PIPE_TRANSFER_READ, xpos, ypos,
-                                               width, height);
+                                   color_strb->texture,
+                                   0, 0,
+                                   PIPE_TRANSFER_READ, xpos, ypos,
+                                   width, height);
 
    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
@@ -187,9 +187,9 @@ accum_load(struct st_context *st, GLfloat value,
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
    color_trans = pipe_get_transfer(st->pipe, color_strb->texture,
-                                               0, 0, 0,
-                                               PIPE_TRANSFER_READ, xpos, ypos,
-                                               width, height);
+                                   0, 0,
+                                   PIPE_TRANSFER_READ, xpos, ypos,
+                                   width, height);
 
    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
@@ -241,12 +241,12 @@ accum_return(struct gl_context *ctx, GLfloat value,
       usage = PIPE_TRANSFER_READ_WRITE;
    else
       usage = PIPE_TRANSFER_WRITE;
-   
+
    color_trans = pipe_get_transfer(st_context(ctx)->pipe,
-                                               color_strb->texture, 0, 0, 0,
-                                               usage,
-                                               xpos, ypos,
-                                               width, height);
+                                   color_strb->texture, 0, 0,
+                                   usage,
+                                   xpos, ypos,
+                                   width, height);
 
    if (usage & PIPE_TRANSFER_READ)
       pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
index 3c0ee6c288387fafb21398eeb006e5294b28514a..f08697fe23b4d58a4c3d9e90faba8b7761310817 100644 (file)
@@ -283,9 +283,9 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
       return NULL;
    }
 
-   transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0,
-                                          PIPE_TRANSFER_WRITE,
-                                          0, 0, width, height);
+   transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
+                                PIPE_TRANSFER_WRITE,
+                                0, 0, width, height);
 
    dest = pipe_transfer_map(pipe, transfer);
 
@@ -585,10 +585,10 @@ create_cache_trans(struct st_context *st)
    /* Map the texture transfer.
     * Subsequent glBitmap calls will write into the texture image.
     */
-   cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0, 0,
-                                              PIPE_TRANSFER_WRITE, 0, 0,
-                                              BITMAP_CACHE_WIDTH,
-                                              BITMAP_CACHE_HEIGHT);
+   cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0,
+                                    PIPE_TRANSFER_WRITE, 0, 0,
+                                    BITMAP_CACHE_WIDTH,
+                                    BITMAP_CACHE_HEIGHT);
    cache->buffer = pipe_transfer_map(pipe, cache->trans);
 
    /* init image to all 0xff */
index af41835326a855412f14024af6c2e34b8a36f6b6..06cee520b373566c2bb61a08745987b71af11e7c 100644 (file)
@@ -115,17 +115,14 @@ st_BlitFramebuffer(struct gl_context *ctx,
             st_texture_object(srcAtt->Texture);
          struct st_renderbuffer *dstRb =
             st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
-         struct pipe_subresource srcSub;
          struct pipe_surface *dstSurf = dstRb->surface;
 
          if (!srcObj->pt)
             return;
 
-         srcSub.face = srcAtt->CubeMapFace;
-         srcSub.level = srcAtt->TextureLevel;
-
-         util_blit_pixels(st->blit, srcObj->pt, srcSub,
-                          srcX0, srcY0, srcX1, srcY1, srcAtt->Zoffset,
+         util_blit_pixels(st->blit, srcObj->pt, srcAtt->TextureLevel,
+                          srcX0, srcY0, srcX1, srcY1,
+                          srcAtt->Zoffset + srcAtt->CubeMapFace,
                           dstSurf, dstX0, dstY0, dstX1, dstY1,
                           0.0, pFilter);
       }
@@ -136,14 +133,11 @@ st_BlitFramebuffer(struct gl_context *ctx,
             st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
          struct pipe_surface *srcSurf = srcRb->surface;
          struct pipe_surface *dstSurf = dstRb->surface;
-         struct pipe_subresource srcSub;
-
-         srcSub.face = srcSurf->face;
-         srcSub.level = srcSurf->level;
 
          util_blit_pixels(st->blit,
-                          srcRb->texture, srcSub, srcX0, srcY0, srcX1, srcY1,
-                          srcSurf->zslice,
+                          srcRb->texture, srcSurf->u.tex.level,
+                          srcX0, srcY0, srcX1, srcY1,
+                          srcSurf->u.tex.first_layer,
                           dstSurf, dstX0, dstY0, dstX1, dstY1,
                           0.0, pFilter);
       }
@@ -176,11 +170,11 @@ st_BlitFramebuffer(struct gl_context *ctx,
          /* Blitting depth and stencil values between combined
           * depth/stencil buffers.  This is the ideal case for such buffers.
           */
-         util_blit_pixels(st->blit, srcDepthRb->texture,
-                          u_subresource(srcDepthRb->surface->face,
-                                        srcDepthRb->surface->level),
+         util_blit_pixels(st->blit,
+                          srcDepthRb->texture,
+                          srcDepthRb->surface->u.tex.level,
                           srcX0, srcY0, srcX1, srcY1,
-                          srcDepthRb->surface->zslice,
+                          srcDepthRb->surface->u.tex.first_layer,
                           dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
                           0.0, pFilter);
       }
@@ -189,10 +183,9 @@ st_BlitFramebuffer(struct gl_context *ctx,
 
          if (mask & GL_DEPTH_BUFFER_BIT) {
             util_blit_pixels(st->blit, srcDepthRb->texture,
-                             u_subresource(srcDepthRb->surface->face,
-                                           srcDepthRb->surface->level),
+                             srcDepthRb->surface->u.tex.level,
                              srcX0, srcY0, srcX1, srcY1,
-                             srcDepthRb->surface->zslice,
+                             srcDepthRb->surface->u.tex.first_layer,
                              dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
                              0.0, pFilter);
          }
index 27540c36ce7013ddd56a265831ab30b01685d246..8b60f9040d00fe09e6f6e7662acf26cec2b5f9e7 100644 (file)
@@ -210,6 +210,13 @@ st_bufferobj_data(struct gl_context *ctx,
 }
 
 
+/**
+ * Dummy data whose's pointer is used for zero size buffers or ranges.
+ */
+static long st_bufferobj_zero_length = 0;
+
+
+
 /**
  * Called via glMapBufferARB().
  */
@@ -233,10 +240,16 @@ st_bufferobj_map(struct gl_context *ctx, GLenum target, GLenum access,
       break;      
    }
 
-   obj->Pointer = pipe_buffer_map(st_context(ctx)->pipe,
-                                  st_obj->buffer,
-                                  flags,
-                                  &st_obj->transfer);
+   /* Handle zero-size buffers here rather than in drivers */
+   if (obj->Size == 0) {
+      obj->Pointer = &st_bufferobj_zero_length;
+   }
+   else {
+      obj->Pointer = pipe_buffer_map(st_context(ctx)->pipe,
+                                     st_obj->buffer,
+                                     flags,
+                                     &st_obj->transfer);
+   }
 
    if (obj->Pointer) {
       obj->Offset = 0;
@@ -246,13 +259,6 @@ st_bufferobj_map(struct gl_context *ctx, GLenum target, GLenum access,
 }
 
 
-/**
- * Dummy data whose's pointer is used for zero length ranges.
- */
-static long
-st_bufferobj_zero_length_range = 0;
-
-
 /**
  * Called via glMapBufferRange().
  */
@@ -273,6 +279,12 @@ st_bufferobj_map_range(struct gl_context *ctx, GLenum target,
 
    if (access & GL_MAP_FLUSH_EXPLICIT_BIT)
       flags |= PIPE_TRANSFER_FLUSH_EXPLICIT;
+
+   if (access & GL_MAP_INVALIDATE_RANGE_BIT)
+      flags |= PIPE_TRANSFER_DISCARD;
+
+   if (access & GL_MAP_INVALIDATE_BUFFER_BIT)
+      flags |= PIPE_TRANSFER_DISCARD;
    
    if (access & GL_MAP_UNSYNCHRONIZED_BIT)
       flags |= PIPE_TRANSFER_UNSYNCHRONIZED;
@@ -293,7 +305,7 @@ st_bufferobj_map_range(struct gl_context *ctx, GLenum target,
     * length range from the pipe driver.
     */
    if (!length) {
-      obj->Pointer = &st_bufferobj_zero_length_range;
+      obj->Pointer = &st_bufferobj_zero_length;
    }
    else {
       obj->Pointer = pipe_buffer_map_range(pipe, 
index d80c068ea813546525eaa40dad34c7533521c352..c97860245750a10f48aa7e00ed17d2e4087d750f 100644 (file)
@@ -427,9 +427,9 @@ make_texture(struct st_context *st,
       /* we'll do pixel transfer in a fragment shader */
       ctx->_ImageTransferState = 0x0;
 
-      transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0,
-                                             PIPE_TRANSFER_WRITE, 0, 0,
-                                             width, height);
+      transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
+                                   PIPE_TRANSFER_WRITE, 0, 0,
+                                   width, height);
 
       /* map texture transfer */
       dest = pipe_transfer_map(pipe, transfer);
@@ -763,9 +763,9 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
    else
       usage = PIPE_TRANSFER_WRITE;
 
-   pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0, 0,
-                                      usage, x, y,
-                                      width, height);
+   pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0,
+                                     usage, x, y,
+                                     width, height);
 
    stmap = pipe_transfer_map(pipe, pt);
 
@@ -1025,15 +1025,15 @@ copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       usage = PIPE_TRANSFER_READ_WRITE;
    else
       usage = PIPE_TRANSFER_WRITE;
-   
+
    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
       dsty = rbDraw->Base.Height - dsty - height;
    }
 
    ptDraw = pipe_get_transfer(st_context(ctx)->pipe,
-                                          rbDraw->texture, 0, 0, 0,
-                                          usage, dstx, dsty,
-                                          width, height);
+                              rbDraw->texture, 0, 0,
+                              usage, dstx, dsty,
+                              width, height);
 
    assert(util_format_get_blockwidth(ptDraw->resource->format) == 1);
    assert(util_format_get_blockheight(ptDraw->resource->format) == 1);
@@ -1209,27 +1209,24 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    /* Make temporary texture which is a copy of the src region.
     */
    if (srcFormat == texFormat) {
-      struct pipe_subresource srcsub, dstsub;
-      srcsub.face = 0;
-      srcsub.level = 0;
-      dstsub.face = 0;
-      dstsub.level = 0;
-      /* copy source framebuffer surface into mipmap/texture */
+      struct pipe_box src_box;
+      u_box_2d(readX, readY, readW, readH, &src_box);
+    /* copy source framebuffer surface into mipmap/texture */
       pipe->resource_copy_region(pipe,
                                  pt,                                /* dest tex */
-                                 dstsub,
+                                 0,
                                  pack.SkipPixels, pack.SkipRows, 0, /* dest pos */
                                  rbRead->texture,                   /* src tex */
-                                 srcsub,
-                                 readX, readY, 0, readW, readH);    /* src region */
+                                 0,
+                                 &src_box);
 
    }
    else {
       /* CPU-based fallback/conversion */
       struct pipe_transfer *ptRead =
-         pipe_get_transfer(st->pipe, rbRead->texture, 0, 0, 0,
-                                        PIPE_TRANSFER_READ,
-                                        readX, readY, readW, readH);
+         pipe_get_transfer(st->pipe, rbRead->texture, 0, 0,
+                           PIPE_TRANSFER_READ,
+                           readX, readY, readW, readH);
       struct pipe_transfer *ptTex;
       enum pipe_transfer_usage transfer_usage;
 
@@ -1241,8 +1238,8 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       else
          transfer_usage = PIPE_TRANSFER_WRITE;
 
-      ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, 0, transfer_usage,
-                                             0, 0, width, height);
+      ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage,
+                                0, 0, width, height);
 
       /* copy image from ptRead surface to ptTex surface */
       if (type == GL_COLOR) {
index 9425f07aee617d753999983681e59795fd6a0c5f..cd718a31a145925712be1163d0d29352a448efb3 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "util/u_format.h"
 #include "util/u_inlines.h"
+#include "util/u_surface.h"
 
 
 /**
@@ -65,9 +66,11 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
                               GLuint width, GLuint height)
 {
    struct st_context *st = st_context(ctx);
+   struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = st->pipe->screen;
    struct st_renderbuffer *strb = st_renderbuffer(rb);
    enum pipe_format format;
+   struct pipe_surface surf_tmpl;
 
    if (strb->format != PIPE_FORMAT_NONE)
       format = strb->format;
@@ -113,6 +116,7 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
       template.width0 = width;
       template.height0 = height;
       template.depth0 = 1;
+      template.array_size = 1;
       template.last_level = 0;
       template.nr_samples = rb->NumSamples;
       if (util_format_is_depth_or_stencil(format)) {
@@ -120,7 +124,7 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
       }
       else {
          template.bind = (PIPE_BIND_DISPLAY_TARGET |
-                         PIPE_BIND_RENDER_TARGET);
+                          PIPE_BIND_RENDER_TARGET);
       }
 
       strb->texture = screen->resource_create(screen, &template);
@@ -128,10 +132,11 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
       if (!strb->texture) 
          return FALSE;
 
-      strb->surface = screen->get_tex_surface(screen,
-                                              strb->texture,
-                                              0, 0, 0,
-                                              template.bind);
+      memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+      u_surface_default_template(&surf_tmpl, strb->texture, template.bind);
+      strb->surface = pipe->create_surface(pipe,
+                                           strb->texture,
+                                           &surf_tmpl);
       if (strb->surface) {
          assert(strb->surface->texture);
          assert(strb->surface->format);
@@ -327,12 +332,12 @@ st_render_texture(struct gl_context *ctx,
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
-   struct pipe_screen *screen = pipe->screen;
    struct st_renderbuffer *strb;
    struct gl_renderbuffer *rb;
    struct pipe_resource *pt = st_get_texobj_resource(att->Texture);
    struct st_texture_object *stObj;
    const struct gl_texture_image *texImage;
+   struct pipe_surface surf_tmpl;
 
    /* When would this fail?  Perhaps assert? */
    if (!pt) 
@@ -381,12 +386,15 @@ st_render_texture(struct gl_context *ctx,
    assert(strb->rtt_level <= strb->texture->last_level);
 
    /* new surface for rendering into the texture */
-   strb->surface = screen->get_tex_surface(screen,
-                                           strb->texture,
-                                           strb->rtt_face,
-                                           strb->rtt_level,
-                                           strb->rtt_slice,
-                                           PIPE_BIND_RENDER_TARGET);
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   surf_tmpl.format = strb->texture->format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = strb->rtt_level;
+   surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
+   surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
+   strb->surface = pipe->create_surface(pipe,
+                                        strb->texture,
+                                        &surf_tmpl);
 
    strb->format = pt->format;
 
index bcd46ac9d54a5a277f37a64e44427d9051734ec9..0507be745783be12d689ce7c19eabe5d01876a63 100644 (file)
@@ -80,7 +80,7 @@ st_read_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
    /* Create a read transfer from the renderbuffer's texture */
 
    pt = pipe_get_transfer(pipe, strb->texture,
-                          0, 0, 0,  /* face, level, zslice */
+                          0, 0,
                           PIPE_TRANSFER_READ,
                           x, y, width, height);
 
@@ -236,7 +236,7 @@ st_fast_readpixels(struct gl_context *ctx, struct st_renderbuffer *strb,
       }
 
       trans = pipe_get_transfer(pipe, strb->texture,
-                                0, 0, 0,  /* face, level, zslice */
+                                0, 0,
                                 PIPE_TRANSFER_READ,
                                 x, y, width, height);
       if (!trans) {
@@ -328,7 +328,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
-   GLfloat temp[MAX_WIDTH][4];
+   GLfloat (*temp)[4];
    const GLbitfield transferOps = ctx->_ImageTransferState;
    GLsizei i, j;
    GLint yStep, dfStride;
@@ -381,6 +381,13 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       return;
    }
 
+   /* allocate temp pixel row buffer */
+   temp = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+   if (!temp) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
+      return;
+   }
+
    if (format == GL_RGBA && type == GL_FLOAT) {
       /* write tile(row) directly into user's buffer */
       df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width,
@@ -400,7 +407,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
 
    /* Create a read transfer from the renderbuffer's texture */
    trans = pipe_get_transfer(pipe, strb->texture,
-                             0, 0, 0,  /* face, level, zslice */
+                             0, 0,
                              PIPE_TRANSFER_READ,
                              x, y, width, height);
 
@@ -533,6 +540,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       }
    }
 
+   free(temp);
+
    pipe->transfer_destroy(pipe, trans);
 
    _mesa_unmap_pbo_dest(ctx, &clippedPacking);
index 15e69e1fa076e4bf776931254986adb5af8a850a..866426a75494e76e678edb53c37c218d2c78524f 100644 (file)
@@ -63,7 +63,7 @@
 #include "util/u_surface.h"
 #include "util/u_sampler.h"
 #include "util/u_math.h"
-
+#include "util/u_box.h"
 
 #define DBG if (0) printf
 
@@ -431,7 +431,7 @@ compress_with_blit(struct gl_context * ctx,
    struct pipe_resource *src_tex;
    struct pipe_sampler_view view_templ;
    struct pipe_sampler_view *src_view;
-   struct pipe_surface *dst_surface;
+   struct pipe_surface *dst_surface, surf_tmpl;
    struct pipe_transfer *tex_xfer;
    void *map;
 
@@ -441,9 +441,13 @@ compress_with_blit(struct gl_context * ctx,
    }
 
    /* get destination surface (in the compressed texture) */
-   dst_surface = screen->get_tex_surface(screen, stImage->pt,
-                                         stImage->face, stImage->level, 0,
-                                         0 /* flags */);
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   surf_tmpl.format = stImage->pt->format;
+   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+   surf_tmpl.u.tex.level = stImage->level;
+   surf_tmpl.u.tex.first_layer = stImage->face;
+   surf_tmpl.u.tex.last_layer = stImage->face;
+   dst_surface = pipe->create_surface(pipe, stImage->pt, &surf_tmpl);
    if (!dst_surface) {
       /* can't render into this format (or other problem) */
       return GL_FALSE;
@@ -464,6 +468,7 @@ compress_with_blit(struct gl_context * ctx,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.last_level = 0;
    templ.usage = PIPE_USAGE_DEFAULT;
    templ.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -475,9 +480,9 @@ compress_with_blit(struct gl_context * ctx,
    /* Put user's tex data into the temporary texture
     */
    tex_xfer = pipe_get_transfer(st_context(ctx)->pipe, src_tex,
-                                            0, 0, 0, /* face, level are zero */
-                                            PIPE_TRANSFER_WRITE,
-                                            0, 0, width, height); /* x, y, w, h */
+                                0, 0, /* layer, level are zero */
+                                PIPE_TRANSFER_WRITE,
+                                0, 0, width, height); /* x, y, w, h */
    map = pipe_transfer_map(pipe, tex_xfer);
 
    _mesa_texstore(ctx, 2, GL_RGBA, mesa_format,
@@ -857,7 +862,6 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
-   struct pipe_screen *screen = pipe->screen;
    struct st_texture_image *stImage = st_texture_image(texImage);
    struct st_texture_object *stObj = st_texture_object(texObj);
    struct pipe_sampler_view *src_view =
@@ -871,7 +875,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
                    PIPE_BIND_TRANSFER_READ);
 
    /* create temp / dest surface */
-   if (!util_create_rgba_surface(screen, width, height, bind,
+   if (!util_create_rgba_surface(pipe, width, height, bind,
                                  &dst_texture, &dst_surface)) {
       _mesa_problem(ctx, "util_create_rgba_surface() failed "
                     "in decompress_with_blit()");
@@ -891,9 +895,9 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
 
    /* map the dst_surface so we can read from it */
    tex_xfer = pipe_get_transfer(st_context(ctx)->pipe,
-                                            dst_texture, 0, 0, 0,
-                                            PIPE_TRANSFER_READ,
-                                            0, 0, width, height);
+                                dst_texture, 0, 0,
+                                PIPE_TRANSFER_READ,
+                                0, 0, width, height);
 
    pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
 
@@ -1310,7 +1314,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
    struct pipe_transfer *src_trans;
    GLvoid *texDest;
    enum pipe_transfer_usage transfer_usage;
-   
+
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
@@ -1321,11 +1325,11 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
    }
 
    src_trans = pipe_get_transfer(st_context(ctx)->pipe,
-                                              strb->texture,
-                                              0, 0, 0,
-                                              PIPE_TRANSFER_READ,
-                                              srcX, srcY,
-                                              width, height);
+                                 strb->texture,
+                                 0, 0,
+                                 PIPE_TRANSFER_READ,
+                                 srcX, srcY,
+                                 width, height);
 
    if ((baseFormat == GL_DEPTH_COMPONENT ||
         baseFormat == GL_DEPTH_STENCIL) &&
@@ -1334,7 +1338,8 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
    else
       transfer_usage = PIPE_TRANSFER_WRITE;
 
-   texDest = st_texture_image_map(st, stImage, 0, transfer_usage,
+   /* XXX this used to ignore destZ param */
+   texDest = st_texture_image_map(st, stImage, destZ, transfer_usage,
                                   destX, destY, width, height);
 
    if (baseFormat == GL_DEPTH_COMPONENT ||
@@ -1592,27 +1597,23 @@ st_copy_texsubimage(struct gl_context *ctx,
 
       if (matching_base_formats &&
           src_format == dest_format &&
-          !do_flip) 
+          !do_flip)
       {
          /* use surface_copy() / blit */
-         struct pipe_subresource subdst, subsrc;
-         subdst.face = stImage->face;
-         subdst.level = stImage->level;
-         subsrc.face = strb->surface->face;
-         subsrc.level = strb->surface->level;
+         struct pipe_box src_box;
+         u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer,
+                         width, height, &src_box);
 
          /* for resource_copy_region(), y=0=top, always */
          pipe->resource_copy_region(pipe,
                                     /* dest */
                                     stImage->pt,
-                                    subdst,
-                                    destX, destY, destZ,
+                                    stImage->level,
+                                    destX, destY, destZ + stImage->face,
                                     /* src */
                                     strb->texture,
-                                    subsrc,
-                                    srcX, srcY, strb->surface->zslice,
-                                    /* size */
-                                    width, height);
+                                    strb->surface->u.tex.level,
+                                    &src_box);
          use_fallback = GL_FALSE;
       }
       else if (format_writemask &&
@@ -1628,12 +1629,16 @@ st_copy_texsubimage(struct gl_context *ctx,
                                            0)) {
          /* draw textured quad to do the copy */
          GLint srcY0, srcY1;
-         struct pipe_subresource subsrc;
+         struct pipe_surface surf_tmpl;
+         memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+         surf_tmpl.format = stImage->pt->format;
+         surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+         surf_tmpl.u.tex.level = stImage->level;
+         surf_tmpl.u.tex.first_layer = stImage->face + destZ;
+         surf_tmpl.u.tex.last_layer = stImage->face + destZ;
 
-         dest_surface = screen->get_tex_surface(screen, stImage->pt,
-                                                stImage->face, stImage->level,
-                                                destZ,
-                                                PIPE_BIND_RENDER_TARGET);
+         dest_surface = pipe->create_surface(pipe, stImage->pt,
+                                             &surf_tmpl);
 
          if (do_flip) {
             srcY1 = strb->Base.Height - srcY - height;
@@ -1643,15 +1648,13 @@ st_copy_texsubimage(struct gl_context *ctx,
             srcY0 = srcY;
             srcY1 = srcY0 + height;
          }
-         subsrc.face = strb->surface->face;
-         subsrc.level = strb->surface->level;
 
          util_blit_pixels_writemask(st->blit,
                                     strb->texture,
-                                    subsrc,
+                                    strb->surface->u.tex.level,
                                     srcX, srcY0,
                                     srcX + width, srcY1,
-                                    strb->surface->zslice,
+                                    strb->surface->u.tex.first_layer,
                                     dest_surface,
                                     destX, destY,
                                     destX + width, destY + height,
@@ -1852,8 +1855,9 @@ st_finalize_texture(struct gl_context *ctx,
     * will match.
     */
    if (firstImage->pt &&
+       stObj->pt &&
        firstImage->pt != stObj->pt &&
-       firstImage->pt->last_level >= stObj->lastLevel) {
+       firstImage->pt->last_level >= stObj->pt->last_level) {
       pipe_resource_reference(&stObj->pt, firstImage->pt);
       pipe_sampler_view_reference(&stObj->sampler_view, NULL);
    }
index d0dcdd4e29bdce5ae3776fe3820ac61ffa2865e9..6ec9c699a26aa8dd57b6006e0e3696118dd5f994 100644 (file)
@@ -170,6 +170,11 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
    struct gl_context *shareCtx = share ? share->ctx : NULL;
    struct dd_function_table funcs;
 
+   /* Sanity checks */
+   assert(MESA_SHADER_VERTEX == PIPE_SHADER_VERTEX);
+   assert(MESA_SHADER_FRAGMENT == PIPE_SHADER_FRAGMENT);
+   assert(MESA_SHADER_GEOMETRY == PIPE_SHADER_GEOMETRY);
+
    memset(&funcs, 0, sizeof(funcs));
    st_init_driver_functions(&funcs);
 
@@ -239,8 +244,8 @@ void st_destroy_context( struct st_context *st )
    pipe->set_index_buffer(pipe, NULL);
 
    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
-      pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, NULL);
-      pipe_resource_reference(&st->state.constants[PIPE_SHADER_VERTEX], NULL);
+      pipe->set_constant_buffer(pipe, i, 0, NULL);
+      pipe_resource_reference(&st->state.constants[i], NULL);
    }
 
    _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
index 132749130af41f738ee180b9762a00811b11db5a..930b60ade2da68f9f6a04ff71fcf795350f718e0 100644 (file)
@@ -67,7 +67,7 @@ void st_init_limits(struct st_context *st)
 {
    struct pipe_screen *screen = st->pipe->screen;
    struct gl_constants *c = &st->ctx->Const;
-   unsigned i;
+   gl_shader_type sh;
 
    c->MaxTextureLevels
       = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
@@ -137,11 +137,12 @@ void st_init_limits(struct st_context *st)
    /* Quads always follow GL provoking rules. */
    c->QuadsFollowProvokingVertexConvention = GL_FALSE;
 
-   for(i = 0; i < MESA_SHADER_TYPES; ++i) {
-      struct gl_shader_compiler_options *options = &st->ctx->ShaderCompilerOptions[i];
+   for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) {
+      struct gl_shader_compiler_options *options =
+         &st->ctx->ShaderCompilerOptions[sh];
       struct gl_program_constants *pc;
-      switch(i)
-      {
+
+      switch (sh) {
       case PIPE_SHADER_FRAGMENT:
          pc = &c->FragmentProgram;
          break;
@@ -156,36 +157,37 @@ void st_init_limits(struct st_context *st)
          continue;
       }
 
-      pc->MaxNativeInstructions    = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
-      pc->MaxNativeAluInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS);
-      pc->MaxNativeTexInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS);
-      pc->MaxNativeTexIndirections = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS);
-      pc->MaxNativeAttribs         = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INPUTS);
-      pc->MaxNativeTemps           = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEMPS);
-      pc->MaxNativeAddressRegs     = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_ADDRS);
-      pc->MaxNativeParameters      = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONSTS);
+      pc->MaxNativeInstructions    = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
+      pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS);
+      pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS);
+      pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS);
+      pc->MaxNativeAttribs         = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS);
+      pc->MaxNativeTemps           = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS);
+      pc->MaxNativeAddressRegs     = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS);
+      pc->MaxNativeParameters      = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONSTS);
+      pc->MaxUniformComponents     = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS);
 
       options->EmitNoNoise = TRUE;
 
       /* TODO: make these more fine-grained if anyone needs it */
-      options->EmitNoIfs = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
-      options->EmitNoFunctions = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
-      options->EmitNoLoops = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
-      options->EmitNoMainReturn = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
+      options->EmitNoIfs = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
+      options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
+      options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
+      options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
 
-      options->EmitNoCont = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED);
+      options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED);
 
-      options->EmitNoIndirectInput = !screen->get_shader_param(screen, i,
+      options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh,
                                         PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR);
-      options->EmitNoIndirectOutput = !screen->get_shader_param(screen, i,
+      options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh,
                                         PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR);
-      options->EmitNoIndirectTemp = !screen->get_shader_param(screen, i,
+      options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh,
                                         PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR);
-      options->EmitNoIndirectUniform = !screen->get_shader_param(screen, i,
+      options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh,
                                         PIPE_SHADER_CAP_INDIRECT_CONST_ADDR);
 
       if(options->EmitNoLoops)
-         options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
+         options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
    }
 
    /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs
@@ -298,6 +300,8 @@ void st_init_extensions(struct st_context *st)
       ctx->Extensions.ARB_vertex_shader = GL_TRUE;
       ctx->Extensions.ARB_shader_objects = GL_TRUE;
       ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
+      ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
+      ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
    }
 
    if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_REPEAT) > 0) {
index 1fc4f40488f7e5940b91dcfb8d64692561ec981a..c5f6008a22224870e814db924ff9d9da262d1881 100644 (file)
@@ -79,11 +79,15 @@ st_render_mipmap(struct st_context *st,
    const uint face = _mesa_tex_target_to_face(target);
 
    assert(psv->texture == stObj->pt);
-   assert(target != GL_TEXTURE_3D); /* not done yet */
+#if 0
+   assert(target != GL_TEXTURE_3D); /* implemented but untested */
+#endif
 
    /* check if we can render in the texture's format */
-   if (!screen->is_format_supported(screen, psv->format, psv->texture->target, 0,
-                                    PIPE_BIND_RENDER_TARGET, 0)) {
+   /* XXX should probably kill this and always use util_gen_mipmap
+      since this implements a sw fallback as well */
+   if (!screen->is_format_supported(screen, psv->format, psv->texture->target,
+                                    0, PIPE_BIND_RENDER_TARGET, 0)) {
       return FALSE;
    }
 
@@ -161,12 +165,12 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
    struct pipe_resource *pt = st_get_texobj_resource(texObj);
    const uint baseLevel = texObj->BaseLevel;
    const uint lastLevel = pt->last_level;
-   const uint face = _mesa_tex_target_to_face(target), zslice = 0;
+   const uint face = _mesa_tex_target_to_face(target);
    uint dstLevel;
    GLenum datatype;
    GLuint comps;
    GLboolean compressed;
-   
+
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
@@ -198,16 +202,15 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
       ubyte *dstData;
       int srcStride, dstStride;
 
-      srcTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, face,
-                                               srcLevel, zslice,
-                                               PIPE_TRANSFER_READ, 0, 0,
-                                                srcWidth, srcHeight);
-                                               
+      srcTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, srcLevel,
+                                   face,
+                                   PIPE_TRANSFER_READ, 0, 0,
+                                   srcWidth, srcHeight);
 
-      dstTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, face,
-                                               dstLevel, zslice,
-                                               PIPE_TRANSFER_WRITE, 0, 0,
-                                               dstWidth, dstHeight);
+      dstTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, dstLevel,
+                                   face,
+                                   PIPE_TRANSFER_WRITE, 0, 0,
+                                   dstWidth, dstHeight);
 
       srcData = (ubyte *) pipe_transfer_map(pipe, srcTrans);
       dstData = (ubyte *) pipe_transfer_map(pipe, dstTrans);
@@ -215,6 +218,8 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
       srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->resource->format);
       dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->resource->format);
 
+     /* this cannot work correctly for 3d since it does
+        not respect layerStride. */
       if (compressed) {
          const enum pipe_format format = pt->format;
          const uint bw = util_format_get_blockwidth(format);
@@ -365,6 +370,12 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
 
       pt = stObj->pt;
    }
+   else {
+      /* Make sure that the base texture image data is present in the
+       * texture buffer.
+       */
+      st_finalize_texture(ctx, st->pipe, texObj);
+   }
 
    assert(pt->last_level >= lastLevel);
 
@@ -372,6 +383,8 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
     * use the software fallback.
     */
    if (!st_render_mipmap(st, target, stObj, baseLevel, lastLevel)) {
+      /* since the util code actually also has a fallback, should
+         probably make it never fail and kill this */
       fallback_generate_mipmap(ctx, target, texObj);
    }
 
index 05733e818ea1b986884a2324c25d4095c2ffa056..0307b48978b14e1c10a52b90bd3f4685a2061888 100644 (file)
@@ -34,6 +34,7 @@
 #include "util/u_pointer.h"
 #include "util/u_inlines.h"
 #include "util/u_atomic.h"
+#include "util/u_surface.h"
 
 #include "main/mtypes.h"
 #include "main/context.h"
@@ -142,7 +143,7 @@ buffer_index_to_attachment(gl_buffer_index index)
 static void
 st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
 {
-   struct pipe_screen *screen = st->pipe->screen;
+   struct pipe_context *pipe = st->pipe;
    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
    uint width, height;
    unsigned i;
@@ -160,7 +161,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
 
    for (i = 0; i < stfb->num_statts; i++) {
       struct st_renderbuffer *strb;
-      struct pipe_surface *ps;
+      struct pipe_surface *ps, surf_tmpl;
       gl_buffer_index idx;
 
       if (!textures[i])
@@ -179,8 +180,10 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
          continue;
       }
 
-      ps = screen->get_tex_surface(screen, textures[i], 0, 0, 0,
-                                  PIPE_BIND_RENDER_TARGET);
+      memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+      u_surface_default_template(&surf_tmpl, textures[i],
+                                 PIPE_BIND_RENDER_TARGET);
+      ps = pipe->create_surface(pipe, textures[i], &surf_tmpl);
       if (ps) {
          pipe_surface_reference(&strb->surface, ps);
          pipe_resource_reference(&strb->texture, ps->texture);
@@ -813,6 +816,7 @@ st_manager_flush_frontbuffer(struct st_context *st)
 
 /**
  * Return the surface of an EGLImage.
+ * FIXME: I think this should operate on resources, not surfaces
  */
 struct pipe_surface *
 st_manager_get_egl_image_surface(struct st_context *st,
@@ -821,7 +825,7 @@ st_manager_get_egl_image_surface(struct st_context *st,
    struct st_manager *smapi =
       (struct st_manager *) st->iface.st_context_private;
    struct st_egl_image stimg;
-   struct pipe_surface *ps;
+   struct pipe_surface *ps, surf_tmpl;
 
    if (!smapi || !smapi->get_egl_image)
       return NULL;
@@ -830,8 +834,13 @@ st_manager_get_egl_image_surface(struct st_context *st,
    if (!smapi->get_egl_image(smapi, eglimg, &stimg))
       return NULL;
 
-   ps = smapi->screen->get_tex_surface(smapi->screen,
-         stimg.texture, stimg.face, stimg.level, stimg.zslice, usage);
+   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+   surf_tmpl.format = stimg.texture->format;
+   surf_tmpl.usage = usage;
+   surf_tmpl.u.tex.level = stimg.level;
+   surf_tmpl.u.tex.first_layer = stimg.layer;
+   surf_tmpl.u.tex.last_layer = stimg.layer;
+   ps = st->pipe->create_surface(st->pipe, stimg.texture, &surf_tmpl);
    pipe_resource_reference(&stimg.texture, NULL);
 
    return ps;
index c5c239b2c954874c6612cb1a34657ba50f67f84b..f848462310eb83c41089508d899c13d288cf4d10 100644 (file)
@@ -760,10 +760,13 @@ emit_adjusted_wpos( struct st_translate *t,
 
 /**
  * Emit the TGSI instructions for inverting the WPOS y coordinate.
+ * This code is unavoidable because it also depends on whether
+ * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
  */
 static void
-emit_inverted_wpos( struct st_translate *t,
-                    const struct gl_program *program )
+emit_wpos_inversion( struct st_translate *t,
+                     const struct gl_program *program,
+                     boolean invert)
 {
    struct ureg_program *ureg = t->ureg;
 
@@ -771,17 +774,17 @@ emit_inverted_wpos( struct st_translate *t,
     * Need to replace instances of INPUT[WPOS] with temp T
     * where T = INPUT[WPOS] by y is inverted.
     */
-   static const gl_state_index winSizeState[STATE_LENGTH]
-      = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 };
+   static const gl_state_index wposTransformState[STATE_LENGTH]
+      = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0 };
    
    /* XXX: note we are modifying the incoming shader here!  Need to
     * do this before emitting the constant decls below, or this
     * will be missed:
     */
-   unsigned winHeightConst = _mesa_add_state_reference(program->Parameters,
-                                                       winSizeState);
+   unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
+                                                       wposTransformState);
 
-   struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst );
+   struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
    struct ureg_dst wpos_temp;
    struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
 
@@ -794,12 +797,23 @@ emit_inverted_wpos( struct st_translate *t,
       ureg_MOV( ureg, wpos_temp, wpos_input );
    }
 
-   /* SUB wpos_temp.y, winsize_const, wpos_input
-    */
-   ureg_SUB( ureg,
-             ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
-             winsize,
-             wpos_input);
+   if (invert) {
+      /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
+       */
+      ureg_MAD( ureg,
+                ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+                wpos_input,
+                ureg_scalar(wpostrans, 0),
+                ureg_scalar(wpostrans, 1));
+   } else {
+      /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
+       */
+      ureg_MAD( ureg,
+                ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+                wpos_input,
+                ureg_scalar(wpostrans, 2),
+                ureg_scalar(wpostrans, 3));
+   }
 
    /* Use wpos_temp as position input from here on:
     */
@@ -861,8 +875,7 @@ emit_wpos(struct st_context *st,
 
    /* we invert after adjustment so that we avoid the MOV to temporary,
     * and reuse the adjustment ADD instead */
-   if (invert)
-      emit_inverted_wpos(t, program);
+   emit_wpos_inversion(t, program, invert);
 }
 
 
index 76799287fe12dff9c69de2254f87eae223596f74..aae2913c202c57345eca76d3ecc8679c75ee8e79 100644 (file)
@@ -216,6 +216,8 @@ st_translate_vertex_program(struct st_context *st,
       return NULL;
    }
 
+   vpv->key = *key;
+
    vpv->num_inputs = stvp->num_inputs;
    num_outputs = stvp->num_outputs;
    if (key->passthrough_edgeflags) {
index c6cf2ba061b4cceb11d159b1834e033e3e7fa457..155ea39f18c07d9537b0c45355c69329f974b81f 100644 (file)
@@ -84,6 +84,7 @@ st_texture_create(struct st_context *st,
    pt.width0 = width0;
    pt.height0 = height0;
    pt.depth0 = depth0;
+   pt.array_size = (target == PIPE_TEXTURE_CUBE ? 6 : 1);
    pt.usage = PIPE_USAGE_DEFAULT;
    pt.bind = bind;
    pt.flags = 0;
@@ -136,7 +137,7 @@ st_texture_match_image(const struct pipe_resource *pt,
  */
 GLubyte *
 st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
-                    GLuint zoffset, enum pipe_transfer_usage usage,
+                     GLuint zoffset, enum pipe_transfer_usage usage,
                      GLuint x, GLuint y, GLuint w, GLuint h)
 {
    struct pipe_context *pipe = st->pipe;
@@ -144,9 +145,9 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
 
    DBG("%s \n", __FUNCTION__);
 
-   stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->face,
-                                                   stImage->level, zoffset,
-                                                   usage, x, y, w, h);
+   stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->level,
+                                         stImage->face + zoffset,
+                                         usage, x, y, w, h);
 
    if (stImage->transfer)
       return pipe_transfer_map(pipe, stImage->transfer);
@@ -219,10 +220,10 @@ st_texture_image_data(struct st_context *st,
    DBG("%s\n", __FUNCTION__);
 
    for (i = 0; i < depth; i++) {
-      dst_transfer = pipe_get_transfer(st->pipe, dst, face, level, i,
-                                                 PIPE_TRANSFER_WRITE, 0, 0,
-                                                 u_minify(dst->width0, level),
-                                                  u_minify(dst->height0, level));
+      dst_transfer = pipe_get_transfer(st->pipe, dst, level, face + i,
+                                       PIPE_TRANSFER_WRITE, 0, 0,
+                                       u_minify(dst->width0, level),
+                                       u_minify(dst->height0, level));
 
       st_surface_data(pipe, dst_transfer,
                      0, 0,                             /* dstx, dsty */
@@ -230,7 +231,7 @@ st_texture_image_data(struct st_context *st,
                      src_row_stride,
                      0, 0,                             /* source x, y */
                      u_minify(dst->width0, level),
-                      u_minify(dst->height0, level));      /* width, height */
+                      u_minify(dst->height0, level));    /* width, height */
 
       pipe->transfer_destroy(pipe, dst_transfer);
 
@@ -245,14 +246,10 @@ st_texture_image_data(struct st_context *st,
 static void
 print_center_pixel(struct pipe_context *pipe, struct pipe_resource *src)
 {
-   struct pipe_subresource rect;
    struct pipe_transfer *xfer;
    struct pipe_box region;
    ubyte *map;
 
-   rect.face = 0;
-   rect.level = 0;
-
    region.x = src->width0 / 2;
    region.y = src->height0 / 2;
    region.z = 0;
@@ -260,7 +257,7 @@ print_center_pixel(struct pipe_context *pipe, struct pipe_resource *src)
    region.height = 1;
    region.depth = 1;
 
-   xfer = pipe->get_transfer(pipe, src, rect, PIPE_TRANSFER_READ, &region);
+   xfer = pipe->get_transfer(pipe, src, 0, PIPE_TRANSFER_READ, &region);
    map = pipe->transfer_map(pipe, xfer);
 
    printf("center pixel: %d %d %d %d\n", map[0], map[1], map[2], map[3]);
@@ -282,22 +279,26 @@ st_texture_image_copy(struct pipe_context *pipe,
                       struct pipe_resource *src, GLuint srcLevel,
                       GLuint face)
 {
-   GLuint width = u_minify(dst->width0, dstLevel); 
-   GLuint height = u_minify(dst->height0, dstLevel); 
-   GLuint depth = u_minify(dst->depth0, dstLevel); 
-   struct pipe_subresource dstsub, srcsub;
+   GLuint width = u_minify(dst->width0, dstLevel);
+   GLuint height = u_minify(dst->height0, dstLevel);
+   GLuint depth = u_minify(dst->depth0, dstLevel);
+   struct pipe_box src_box;
    GLuint i;
 
    assert(u_minify(src->width0, srcLevel) == width);
    assert(u_minify(src->height0, srcLevel) == height);
    assert(u_minify(src->depth0, srcLevel) == depth);
 
-   dstsub.face = face;
-   dstsub.level = dstLevel;
-   srcsub.face = face;
-   srcsub.level = srcLevel;
+   src_box.x = 0;
+   src_box.y = 0;
+   src_box.width = width;
+   src_box.height = height;
+   src_box.depth = 1;
    /* Loop over 3D image slices */
-   for (i = 0; i < depth; i++) {
+   /* could (and probably should) use "true" 3d box here -
+      but drivers can't quite handle it yet */
+   for (i = face; i < face + depth; i++) {
+      src_box.z = i;
 
       if (0)  {
          print_center_pixel(pipe, src);
@@ -305,12 +306,11 @@ st_texture_image_copy(struct pipe_context *pipe,
 
       pipe->resource_copy_region(pipe,
                                  dst,
-                                 dstsub,
+                                 dstLevel,
                                  0, 0, i,/* destX, Y, Z */
                                  src,
-                                 srcsub,
-                                 0, 0, i,/* srcX, Y, Z */
-                                 width, height);
+                                 srcLevel,
+                                 &src_box);
    }
 }
 
index 1a550c445d3c60543d757858c06303393b395a2f..d61baba0f33bbcf944cacb19fc75afe2e6e7bb0f 100644 (file)
@@ -819,7 +819,16 @@ static void
 blend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[],
               void *src, const void *dst, GLenum chanType)
 {
-   GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4];
+   GLfloat (*rgbaF)[4], (*destF)[4];
+
+   rgbaF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+   destF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+   if (!rgbaF || !destF) {
+      free(rgbaF);
+      free(destF);
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "blending");
+      return;
+   }
 
    if (chanType == GL_UNSIGNED_BYTE) {
       GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
@@ -883,6 +892,9 @@ blend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[],
       blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src,
                           (GLfloat (*)[4]) dst, chanType);
    }
+
+   free(rgbaF);
+   free(destF);
 }
 
 
index 4e9b5307cc7f0a4ea5da1ae3fbcd785ef4a58151..4d0666898b47d28fe07fa3c0d906df46370e49e6 100644 (file)
@@ -720,13 +720,16 @@ _swrast_DrawPixels( struct gl_context *ctx,
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
-    pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
-    if (!pixels) {
-       swrast_render_finish(ctx);
-       _mesa_set_vp_override(ctx, save_vp_override);
-       return;
-    }
+   pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
+   if (!pixels) {
+      swrast_render_finish(ctx);
+      _mesa_set_vp_override(ctx, save_vp_override);
+      return;
+   }
 
+   /*
+    * By time we get here, all error checking should have been done.
+    */
    switch (format) {
    case GL_STENCIL_INDEX:
       draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels );
@@ -734,27 +737,12 @@ _swrast_DrawPixels( struct gl_context *ctx,
    case GL_DEPTH_COMPONENT:
       draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels );
       break;
-   case GL_COLOR_INDEX:
-   case GL_RED:
-   case GL_GREEN:
-   case GL_BLUE:
-   case GL_ALPHA:
-   case GL_LUMINANCE:
-   case GL_LUMINANCE_ALPHA:
-   case GL_RGB:
-   case GL_BGR:
-   case GL_RGBA:
-   case GL_BGRA:
-   case GL_ABGR_EXT:
-      draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
-      break;
    case GL_DEPTH_STENCIL_EXT:
-      draw_depth_stencil_pixels(ctx, x, y, width, height,
-                                type, unpack, pixels);
+      draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels);
       break;
    default:
-      _mesa_problem(ctx, "unexpected format 0x%x in _swrast_DrawPixels", format);
-      /* don't return yet, clean-up */
+      /* all other formats should be color formats */
+      draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
    }
 
    swrast_render_finish(ctx);
index 5e6356c0d549e14b62915a69c8a419e0f2c89c3a..9fe0752a37f1ef28f35d046f60efd49a8517a7ec 100644 (file)
@@ -476,49 +476,33 @@ _swrast_ReadPixels( struct gl_context *ctx,
       _swrast_validate_derived( ctx );
 
    /* Do all needed clipping here, so that we can forget about it later */
-   if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
-      /* The ReadPixels region is totally outside the window bounds */
-      swrast_render_finish(ctx);
-      return;
-   }
-
-   pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
-   if (!pixels)
-      return;
-  
-   switch (format) {
-      case GL_STENCIL_INDEX:
-        read_stencil_pixels(ctx, x, y, width, height, type, pixels,
+   if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
+
+      pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
+
+      if (pixels) {
+         switch (format) {
+         case GL_STENCIL_INDEX:
+            read_stencil_pixels(ctx, x, y, width, height, type, pixels,
+                                &clippedPacking);
+            break;
+         case GL_DEPTH_COMPONENT:
+            read_depth_pixels(ctx, x, y, width, height, type, pixels,
+                              &clippedPacking);
+            break;
+         case GL_DEPTH_STENCIL_EXT:
+            read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
+                                      &clippedPacking);
+            break;
+         default:
+            /* all other formats should be color formats */
+            read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
                              &clippedPacking);
-         break;
-      case GL_DEPTH_COMPONENT:
-        read_depth_pixels(ctx, x, y, width, height, type, pixels,
-                           &clippedPacking);
-        break;
-      case GL_RED:
-      case GL_GREEN:
-      case GL_BLUE:
-      case GL_ALPHA:
-      case GL_RGB:
-      case GL_LUMINANCE:
-      case GL_LUMINANCE_ALPHA:
-      case GL_RGBA:
-      case GL_BGR:
-      case GL_BGRA:
-      case GL_ABGR_EXT:
-         read_rgba_pixels(ctx, x, y, width, height,
-                          format, type, pixels, &clippedPacking);
-        break;
-      case GL_DEPTH_STENCIL_EXT:
-         read_depth_stencil_pixels(ctx, x, y, width, height,
-                                   type, pixels, &clippedPacking);
-         break;
-      default:
-        _mesa_problem(ctx, "unexpected format 0x%x in _swrast_ReadPixels", format);
-         /* don't return yet, clean-up */
+         }
+
+         _mesa_unmap_pbo_dest(ctx, &clippedPacking);
+      }
    }
 
    swrast_render_finish(ctx);
-
-   _mesa_unmap_pbo_dest(ctx, &clippedPacking);
 }
index 1836d074aee9ceb2610d8c6ae8188aa9264dcf25..99c44413fbe80dd3d47337744344aeffcfc1b5c9 100644 (file)
@@ -86,10 +86,28 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
    const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA);
    const GLuint numArgsRGB = combine->_NumArgsRGB;
    const GLuint numArgsA = combine->_NumArgsA;
-   GLfloat ccolor[MAX_COMBINER_TERMS][MAX_WIDTH][4]; /* temp color buffers */
-   GLfloat rgba[MAX_WIDTH][4];
+   float4_array ccolor[4], rgba;
    GLuint i, term;
 
+   /* alloc temp pixel buffers */
+   rgba = (float4_array) malloc(4 * n * sizeof(GLfloat));
+   if (!rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
+      return;
+   }
+
+   for (i = 0; i < numArgsRGB || i < numArgsA; i++) {
+      ccolor[i] = (float4_array) malloc(4 * n * sizeof(GLfloat));
+      if (!ccolor[i]) {
+         while (i) {
+            free(ccolor[i]);
+            i--;
+         }
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
+         return;
+      }
+   }
+
    for (i = 0; i < n; i++) {
       rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);
       rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]);
@@ -163,7 +181,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
                const GLuint srcUnit = srcRGB - GL_TEXTURE0;
                ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
                if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
-                  return;
+                  goto end;
                argRGB[term] = get_texel_array(swrast, srcUnit);
             }
       }
@@ -253,7 +271,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
                const GLuint srcUnit = srcA - GL_TEXTURE0;
                ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
                if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
-                  return;
+                  goto end;
                argA[term] = get_texel_array(swrast, srcUnit);
             }
       }
@@ -411,7 +429,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
             rgba[i][BCOMP] = 0.0;
             rgba[i][ACOMP] = 1.0;
         }
-         return; /* no alpha processing */
+         goto end; /* no alpha processing */
       default:
          _mesa_problem(ctx, "invalid combine mode");
       }
@@ -519,6 +537,12 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
       UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);
       UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);
    }
+
+end:
+   for (i = 0; i < numArgsRGB || i < numArgsA; i++) {
+      free(ccolor[i]);
+   }
+   free(rgba);
 }
 
 
@@ -559,9 +583,16 @@ void
 _swrast_texture_span( struct gl_context *ctx, SWspan *span )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   GLfloat primary_rgba[MAX_WIDTH][4];
+   float4_array primary_rgba;
    GLuint unit;
 
+   primary_rgba = (float4_array) malloc(span->end * 4 * sizeof(GLfloat));
+
+   if (!primary_rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span");
+      return;
+   }
+
    ASSERT(span->end <= MAX_WIDTH);
 
    /*
@@ -706,4 +737,6 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
                           span->array->rgba );
       }
    }
+
+   free(primary_rgba);
 }
index ec281776d0d1f998fffc9a36bd8d7cdf464fa7ac..539d878ddb46483ca497bfd877288029fb83a56d 100644 (file)
@@ -1371,6 +1371,7 @@ opt_sample_rgb_2d(struct gl_context *ctx,
       rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
       rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
       rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
+      rgba[k][ACOMP] = 1.0F;
    }
 }
 
index 7b8da8eb8437eefbf1e5288b4d187b112a45c562..79f76655354b57da212f54923549c3a34f283cfe 100644 (file)
@@ -40,7 +40,8 @@ struct _mesa_prim {
    GLuint begin:1;
    GLuint end:1;
    GLuint weak:1;
-   GLuint pad:20;
+   GLuint no_current_update:1;
+   GLuint pad:19;
 
    GLuint start;
    GLuint count;
@@ -128,42 +129,42 @@ void vbo_set_draw_func(struct gl_context *ctx, vbo_draw_func func);
 
 
 void GLAPIENTRY
-_vbo_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+_es_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
 void GLAPIENTRY
-_vbo_Normal3f(GLfloat x, GLfloat y, GLfloat z);
+_es_Normal3f(GLfloat x, GLfloat y, GLfloat z);
 
 void GLAPIENTRY
-_vbo_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+_es_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
 
 void GLAPIENTRY
-_vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params);
+_es_Materialfv(GLenum face, GLenum pname, const GLfloat *params);
 
 void GLAPIENTRY
-_vbo_Materialf(GLenum face, GLenum pname, GLfloat param);
+_es_Materialf(GLenum face, GLenum pname, GLfloat param);
 
 void GLAPIENTRY
-_vbo_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+_es_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 
 void GLAPIENTRY
-_vbo_VertexAttrib1f(GLuint indx, GLfloat x);
+_es_VertexAttrib1f(GLuint indx, GLfloat x);
 
 void GLAPIENTRY
-_vbo_VertexAttrib1fv(GLuint indx, const GLfloat* values);
+_es_VertexAttrib1fv(GLuint indx, const GLfloat* values);
 
 void GLAPIENTRY
-_vbo_VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+_es_VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
 
 void GLAPIENTRY
-_vbo_VertexAttrib2fv(GLuint indx, const GLfloat* values);
+_es_VertexAttrib2fv(GLuint indx, const GLfloat* values);
 
 void GLAPIENTRY
-_vbo_VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+_es_VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
 
 void GLAPIENTRY
-_vbo_VertexAttrib3fv(GLuint indx, const GLfloat* values);
+_es_VertexAttrib3fv(GLuint indx, const GLfloat* values);
 
 void GLAPIENTRY
-_vbo_VertexAttrib4fv(GLuint indx, const GLfloat* values);
+_es_VertexAttrib4fv(GLuint indx, const GLfloat* values);
 
 #endif
index 9b2d59f9e4ce9fad0ec7c068be9c0537e52607b8..fb981ccc3bccc4e659cebdcdfd96694abffcdafc 100644 (file)
@@ -369,8 +369,6 @@ static void vbo_exec_fixup_vertex( struct gl_context *ctx,
 }
 
 
-#if FEATURE_beginend
-
 /* 
  */
 #define ATTR( A, N, V0, V1, V2, V3 )                           \
@@ -411,7 +409,7 @@ do {                                                                \
 #include "vbo_attrib_tmp.h"
 
 
-
+#if FEATURE_beginend
 
 
 #if FEATURE_evaluators
@@ -706,30 +704,6 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
 #else /* FEATURE_beginend */
 
 
-#define ATTR( A, N, V0, V1, V2, V3 )                           \
-do {                                                           \
-   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;    \
-                                                               \
-   /* FLUSH_UPDATE_CURRENT needs to be set manually */         \
-   exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;                \
-                                                               \
-   if (exec->vtx.active_sz[A] != N)                            \
-      vbo_exec_fixup_vertex(ctx, A, N);                                \
-                                                               \
-   {                                                           \
-      GLfloat *dest = exec->vtx.attrptr[A];                    \
-      if (N>0) dest[0] = V0;                                   \
-      if (N>1) dest[1] = V1;                                   \
-      if (N>2) dest[2] = V2;                                   \
-      if (N>3) dest[3] = V3;                                   \
-   }                                                           \
-} while (0)
-
-#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ )
-#define TAG(x) vbo_##x
-
-#include "vbo_attrib_tmp.h"
-
 static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
 {
    /* silence warnings */
@@ -998,35 +972,35 @@ static void reset_attrfv( struct vbo_exec_context *exec )
       
 
 void GLAPIENTRY
-_vbo_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+_es_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
 {
    vbo_Color4f(r, g, b, a);
 }
 
 
 void GLAPIENTRY
-_vbo_Normal3f(GLfloat x, GLfloat y, GLfloat z)
+_es_Normal3f(GLfloat x, GLfloat y, GLfloat z)
 {
    vbo_Normal3f(x, y, z);
 }
 
 
 void GLAPIENTRY
-_vbo_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+_es_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
 {
    vbo_MultiTexCoord4f(target, s, t, r, q);
 }
 
 
 void GLAPIENTRY
-_vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+_es_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
 {
    vbo_Materialfv(face, pname, params);
 }
 
 
 void GLAPIENTRY
-_vbo_Materialf(GLenum face, GLenum pname, GLfloat param)
+_es_Materialf(GLenum face, GLenum pname, GLfloat param)
 {
    GLfloat p[4];
    p[0] = param;
@@ -1035,57 +1009,71 @@ _vbo_Materialf(GLenum face, GLenum pname, GLfloat param)
 }
 
 
+/**
+ * A special version of glVertexAttrib4f that does not treat index 0 as
+ * VBO_ATTRIB_POS.
+ */
+static void
+VertexAttrib4f_nopos(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
+      ATTR(VBO_ATTRIB_GENERIC0 + index, 4, x, y, z, w);
+   else
+      ERROR();
+}
+
 void GLAPIENTRY
-_vbo_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+_es_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
-   vbo_VertexAttrib4fARB(index, x, y, z, w);
+   VertexAttrib4f_nopos(index, x, y, z, w);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib1f(GLuint indx, GLfloat x)
+_es_VertexAttrib1f(GLuint indx, GLfloat x)
 {
-   vbo_VertexAttrib1fARB(indx, x);
+   VertexAttrib4f_nopos(indx, x, 0.0f, 0.0f, 1.0f);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib1fv(GLuint indx, const GLfloat* values)
+_es_VertexAttrib1fv(GLuint indx, const GLfloat* values)
 {
-   vbo_VertexAttrib1fvARB(indx, values);
+   VertexAttrib4f_nopos(indx, values[0], 0.0f, 0.0f, 1.0f);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+_es_VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
 {
-   vbo_VertexAttrib2fARB(indx, x, y);
+   VertexAttrib4f_nopos(indx, x, y, 0.0f, 1.0f);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib2fv(GLuint indx, const GLfloat* values)
+_es_VertexAttrib2fv(GLuint indx, const GLfloat* values)
 {
-   vbo_VertexAttrib2fvARB(indx, values);
+   VertexAttrib4f_nopos(indx, values[0], values[1], 0.0f, 1.0f);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+_es_VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
 {
-   vbo_VertexAttrib3fARB(indx, x, y, z);
+   VertexAttrib4f_nopos(indx, x, y, z, 1.0f);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib3fv(GLuint indx, const GLfloat* values)
+_es_VertexAttrib3fv(GLuint indx, const GLfloat* values)
 {
-   vbo_VertexAttrib3fvARB(indx, values);
+   VertexAttrib4f_nopos(indx, values[0], values[1], values[2], 1.0f);
 }
 
 
 void GLAPIENTRY
-_vbo_VertexAttrib4fv(GLuint indx, const GLfloat* values)
+_es_VertexAttrib4fv(GLuint indx, const GLfloat* values)
 {
-   vbo_VertexAttrib4fvARB(indx, values);
+   VertexAttrib4f_nopos(indx, values[0], values[1], values[2], values[3]);
 }
index f5a407ced14f6f971861b8678778087a224bc5a0..23cbea2afc18066da3df88bcda8861288d8095dd 100644 (file)
@@ -96,7 +96,9 @@ struct vbo_save_vertex_list {
  */
 #define VBO_SAVE_BUFFER_SIZE (8*1024) /* dwords */
 #define VBO_SAVE_PRIM_SIZE   128
-#define VBO_SAVE_PRIM_WEAK 0x40
+#define VBO_SAVE_PRIM_MODE_MASK         0x3f
+#define VBO_SAVE_PRIM_WEAK              0x40
+#define VBO_SAVE_PRIM_NO_CURRENT_UPDATE 0x80
 
 #define VBO_SAVE_FALLBACK    0x10000000
 
index 817d478e2acf41258ec2074e314747cc5d5774e4..bf5ceda78f8b7281b54e6bc15ad987c210f6cd69 100644 (file)
@@ -294,26 +294,30 @@ static void _save_compile_vertex_list( struct gl_context *ctx )
    node->vertex_store->refcount++;
    node->prim_store->refcount++;
 
-
-   node->current_size = node->vertex_size - node->attrsz[0];
-   node->current_data = NULL;
-
-   if (node->current_size) {
-      /* If the malloc fails, we just pull the data out of the VBO
-       * later instead.
-       */
-      node->current_data = MALLOC( node->current_size * sizeof(GLfloat) );
-      if (node->current_data) {
-         const char *buffer = (const char *)save->vertex_store->buffer;
-         unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
-         unsigned vertex_offset = 0;
-
-         if (node->count)
-            vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat);
-
-         memcpy( node->current_data,
-                 buffer + node->buffer_offset + vertex_offset + attr_offset,
-                 node->current_size * sizeof(GLfloat) );
+   if (node->prim[0].no_current_update) {
+      node->current_size = 0;
+      node->current_data = NULL;
+   } else {
+      node->current_size = node->vertex_size - node->attrsz[0];
+      node->current_data = NULL;
+     
+      if (node->current_size) {
+         /* If the malloc fails, we just pull the data out of the VBO
+          * later instead.
+          */
+         node->current_data = MALLOC( node->current_size * sizeof(GLfloat) );
+         if (node->current_data) {
+            const char *buffer = (const char *)save->vertex_store->buffer;
+            unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
+            unsigned vertex_offset = 0;
+            
+            if (node->count)
+               vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat);
+         
+            memcpy( node->current_data,
+                    buffer + node->buffer_offset + vertex_offset + attr_offset,
+                    node->current_size * sizeof(GLfloat) );
+         }
       }
    }
 
@@ -397,6 +401,7 @@ static void _save_wrap_buffers( struct gl_context *ctx )
    GLint i = save->prim_count - 1;
    GLenum mode;
    GLboolean weak;
+   GLboolean no_current_update;
 
    assert(i < (GLint) save->prim_max);
    assert(i >= 0);
@@ -407,6 +412,7 @@ static void _save_wrap_buffers( struct gl_context *ctx )
                          save->prim[i].start);
    mode = save->prim[i].mode;
    weak = save->prim[i].weak;
+   no_current_update = save->prim[i].no_current_update;
    
    /* store the copied vertices, and allocate a new list.
     */
@@ -416,6 +422,7 @@ static void _save_wrap_buffers( struct gl_context *ctx )
     */
    save->prim[0].mode = mode;
    save->prim[0].weak = weak;
+   save->prim[0].no_current_update = no_current_update;
    save->prim[0].begin = 0;
    save->prim[0].end = 0;
    save->prim[0].pad = 0;
@@ -770,10 +777,11 @@ GLboolean vbo_save_NotifyBegin( struct gl_context *ctx, GLenum mode )
    GLuint i = save->prim_count++;
 
    assert(i < save->prim_max);
-   save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK;
+   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
    save->prim[i].begin = 1;
    save->prim[i].end = 0;
    save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
+   save->prim[i].no_current_update = (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
    save->prim[i].pad = 0;
    save->prim[i].start = save->vert_count;
    save->prim[i].count = 0;   
@@ -934,7 +942,7 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co
 
    _ae_map_vbos( ctx );
 
-   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
+   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE);
 
    for (i = 0; i < count; i++)
        CALL_ArrayElement(GET_DISPATCH(), (start + i));
@@ -960,7 +968,7 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
    if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
       indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
 
-   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
+   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE );
 
    switch (type) {
    case GL_UNSIGNED_BYTE: