summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2010-03-30 21:10:33 -0400
committerZack Rusin <[email protected]>2010-03-30 21:10:33 -0400
commit880e3fb09b538f6f0b6fad2db7e0e10e9df43555 (patch)
treee6cc8c691974e679ead73c3731c49a874019c8ba /src/gallium
parent93e342574f5fc95789028dbe7cf637257562e9bb (diff)
parent4afed821baa6993d85a07c67d42ea40d4e9a600a (diff)
Merge remote branch 'origin/master' into gallium_draw_llvm
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/Makefile.template7
-rw-r--r--src/gallium/SConscript2
-rw-r--r--src/gallium/auxiliary/Makefile14
-rw-r--r--src/gallium/auxiliary/SConscript13
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c252
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h47
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c58
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c58
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c37
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c37
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c39
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c29
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.c37
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.h35
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld.h (renamed from src/gallium/auxiliary/os/os_llvm.h)8
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_alpha.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c60
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_blend.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.c8
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.h10
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_conv.c34
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_conv.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_depth.c608
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_depth.h19
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format_soa.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_interp.c6
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_interp.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_intr.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.h7
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_pack.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_pack.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_printf.c113
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_printf.h39
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c6
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c38
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_struct.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c30
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.h4
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c9
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c2
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.h6
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c4
-rw-r--r--src/gallium/auxiliary/util/u_blit.c60
-rw-r--r--src/gallium/auxiliary/util/u_blit.h4
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c36
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h24
-rw-r--r--src/gallium/auxiliary/util/u_format.csv27
-rw-r--r--src/gallium/auxiliary/util/u_format.h20
-rw-r--r--src/gallium/auxiliary/util/u_format_tests.c7
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c14
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.h2
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h10
-rw-r--r--src/gallium/auxiliary/util/u_pack_color.h19
-rw-r--r--src/gallium/auxiliary/util/u_sampler.c100
-rw-r--r--src/gallium/auxiliary/util/u_sampler.h57
-rw-r--r--src/gallium/auxiliary/util/u_tile.c118
-rw-r--r--src/gallium/auxiliary/util/u_tile.h14
-rw-r--r--src/gallium/docs/d3d11ddi.txt492
-rw-r--r--src/gallium/docs/source/context.rst39
-rw-r--r--src/gallium/docs/source/cso/rasterizer.rst76
-rw-r--r--src/gallium/docs/source/cso/velems.rst2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c47
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c27
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.h18
-rw-r--r--src/gallium/drivers/failover/fo_state.c106
-rw-r--r--src/gallium/drivers/failover/fo_state_emit.c24
-rw-r--r--src/gallium/drivers/i915/i915_batch.h10
-rw-r--r--src/gallium/drivers/i915/i915_batchbuffer.h (renamed from src/gallium/drivers/i915/intel_batchbuffer.h)50
-rw-r--r--src/gallium/drivers/i915/i915_blit.c12
-rw-r--r--src/gallium/drivers/i915/i915_blit.h6
-rw-r--r--src/gallium/drivers/i915/i915_buffer.c4
-rw-r--r--src/gallium/drivers/i915/i915_context.h20
-rw-r--r--src/gallium/drivers/i915/i915_debug.c2
-rw-r--r--src/gallium/drivers/i915/i915_debug.h4
-rw-r--r--src/gallium/drivers/i915/i915_prim_emit.c7
-rw-r--r--src/gallium/drivers/i915/i915_prim_vbuf.c16
-rw-r--r--src/gallium/drivers/i915/i915_screen.c10
-rw-r--r--src/gallium/drivers/i915/i915_screen.h4
-rw-r--r--src/gallium/drivers/i915/i915_state.c55
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c8
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c11
-rw-r--r--src/gallium/drivers/i915/i915_state_immediate.c6
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c26
-rw-r--r--src/gallium/drivers/i915/i915_texture.c26
-rw-r--r--src/gallium/drivers/i915/i915_winsys.h (renamed from src/gallium/drivers/i915/intel_winsys.h)107
-rw-r--r--src/gallium/drivers/i965/SConscript1
-rw-r--r--src/gallium/drivers/i965/brw_context.c1
-rw-r--r--src/gallium/drivers/i965/brw_context.h4
-rw-r--r--src/gallium/drivers/i965/brw_pipe_sampler.c54
-rw-r--r--src/gallium/drivers/i965/brw_screen_texture.c4
-rw-r--r--src/gallium/drivers/i965/brw_wm.c4
-rw-r--r--src/gallium/drivers/i965/brw_wm_sampler_state.c8
-rw-r--r--src/gallium/drivers/i965/brw_wm_surface_state.c6
-rw-r--r--src/gallium/drivers/identity/SConscript3
-rw-r--r--src/gallium/drivers/identity/id_context.c93
-rw-r--r--src/gallium/drivers/identity/id_drm.c1
-rw-r--r--src/gallium/drivers/identity/id_objects.h26
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_fence.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_fence.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c49
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h51
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c55
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c53
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h26
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c17
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c162
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c65
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_format.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_printf.c162
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c48
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c4
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h22
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c282
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h4
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c71
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c202
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h32
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c2
-rw-r--r--src/gallium/drivers/nvfx/nv40_fragtex.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_draw.c6
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragprog.c3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c5
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c37
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.c45
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_viewport.c11
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.c22
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c2
-rw-r--r--src/gallium/drivers/r300/SConscript1
-rw-r--r--src/gallium/drivers/r300/r300_blit.c7
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c7
-rw-r--r--src/gallium/drivers/r300/r300_context.c31
-rw-r--r--src/gallium/drivers/r300/r300_context.h20
-rw-r--r--src/gallium/drivers/r300/r300_cs.h3
-rw-r--r--src/gallium/drivers/r300/r300_debug.c12
-rw-r--r--src/gallium/drivers/r300/r300_defines.h47
-rw-r--r--src/gallium/drivers/r300/r300_emit.c59
-rw-r--r--src/gallium/drivers/r300/r300_fs.c5
-rw-r--r--src/gallium/drivers/r300/r300_query.c8
-rw-r--r--src/gallium/drivers/r300/r300_render.c64
-rw-r--r--src/gallium/drivers/r300/r300_screen.c10
-rw-r--r--src/gallium/drivers/r300/r300_screen.h6
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c2
-rw-r--r--src/gallium/drivers/r300/r300_state.c312
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c147
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h38
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c2
-rw-r--r--src/gallium/drivers/r300/r300_texture.c75
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c19
-rw-r--r--src/gallium/drivers/r300/r300_vs.c2
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h9
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c10
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h8
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c259
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h147
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h21
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c89
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c33
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h10
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c54
-rw-r--r--src/gallium/drivers/svga/svga_context.h4
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c59
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c4
-rw-r--r--src/gallium/drivers/svga/svga_state_constants.c2
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c9
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c22
-rw-r--r--src/gallium/drivers/sw/Makefile10
-rw-r--r--src/gallium/drivers/sw/SConscript42
-rw-r--r--src/gallium/drivers/sw/sw.c59
-rw-r--r--src/gallium/drivers/sw/sw_public.h13
-rw-r--r--src/gallium/drivers/trace/tr_context.c135
-rw-r--r--src/gallium/drivers/trace/tr_context.h10
-rw-r--r--src/gallium/drivers/trace/tr_rbug.c8
-rw-r--r--src/gallium/drivers/trace/tr_texture.h17
-rw-r--r--src/gallium/include/pipe/p_context.h21
-rw-r--r--src/gallium/include/pipe/p_defines.h11
-rw-r--r--src/gallium/include/pipe/p_format.h1
-rw-r--r--src/gallium/include/pipe/p_state.h18
-rw-r--r--src/gallium/include/state_tracker/dri1_api.h8
-rw-r--r--src/gallium/include/state_tracker/drisw_api.h35
-rw-r--r--src/gallium/include/state_tracker/drm_api.h1
-rw-r--r--src/gallium/include/state_tracker/graw.h36
-rw-r--r--src/gallium/include/state_tracker/st_api.h407
-rw-r--r--src/gallium/include/state_tracker/sw_winsys.h21
-rw-r--r--src/gallium/state_trackers/dri/Makefile32
-rw-r--r--src/gallium/state_trackers/dri/SConscript25
-rw-r--r--src/gallium/state_trackers/dri/common/dri1_helper.c129
-rw-r--r--src/gallium/state_trackers/dri/common/dri1_helper.h61
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c (renamed from src/gallium/state_trackers/dri/dri_context.c)129
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.h (renamed from src/gallium/state_trackers/dri/dri_context.h)41
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c94
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h (renamed from src/gallium/state_trackers/dri/dri_drawable.h)45
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c (renamed from src/gallium/state_trackers/dri/dri_screen.c)302
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.h (renamed from src/gallium/state_trackers/dri/dri_screen.h)49
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.c263
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.h55
-rw-r--r--src/gallium/state_trackers/dri/common/dri_wrapper.h10
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c765
-rw-r--r--src/gallium/state_trackers/dri/drm/Makefile32
-rw-r--r--src/gallium/state_trackers/dri/drm/SConscript27
-rw-r--r--src/gallium/state_trackers/dri/drm/dri1.c522
-rw-r--r--src/gallium/state_trackers/dri/drm/dri1.h59
l---------src/gallium/state_trackers/dri/drm/dri1_helper.c1
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c416
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.h (renamed from src/gallium/state_trackers/dri/dri_extensions.c)30
l---------src/gallium/state_trackers/dri/drm/dri_context.c1
l---------src/gallium/state_trackers/dri/drm/dri_drawable.c1
l---------src/gallium/state_trackers/dri/drm/dri_screen.c1
l---------src/gallium/state_trackers/dri/drm/dri_st_api.c1
-rw-r--r--src/gallium/state_trackers/dri/sw/Makefile26
-rw-r--r--src/gallium/state_trackers/dri/sw/SConscript28
l---------src/gallium/state_trackers/dri/sw/dri1_helper.c1
l---------src/gallium/state_trackers/dri/sw/dri_context.c1
l---------src/gallium/state_trackers/dri/sw/dri_drawable.c1
l---------src/gallium/state_trackers/dri/sw/dri_screen.c1
l---------src/gallium/state_trackers/dri/sw/dri_st_api.c1
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c298
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.h54
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c586
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h25
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c227
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.h (renamed from src/gallium/state_trackers/egl/common/egl_st.h)86
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.c131
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h20
-rw-r--r--src/gallium/state_trackers/es/Makefile2
-rw-r--r--src/gallium/state_trackers/es/st_es1.c7
-rw-r--r--src/gallium/state_trackers/es/st_es2.c7
-rw-r--r--src/gallium/state_trackers/glx/xlib/Makefile5
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript1
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c9
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c348
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h55
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_public.h12
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c332
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.h51
-rw-r--r--src/gallium/state_trackers/python/SConscript3
-rw-r--r--src/gallium/state_trackers/python/gallium.i1
-rw-r--r--src/gallium/state_trackers/python/p_context.i320
-rw-r--r--src/gallium/state_trackers/python/p_texture.i228
-rw-r--r--src/gallium/state_trackers/python/st_device.c54
-rw-r--r--src/gallium/state_trackers/python/st_device.h4
-rw-r--r--src/gallium/state_trackers/python/st_sample.c29
-rw-r--r--src/gallium/state_trackers/python/st_sample.h7
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c2
-rw-r--r--src/gallium/state_trackers/vega/Makefile1
-rw-r--r--src/gallium/state_trackers/vega/api_context.c3
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c73
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c4
-rw-r--r--src/gallium/state_trackers/vega/image.c37
-rw-r--r--src/gallium/state_trackers/vega/image.h4
-rw-r--r--src/gallium/state_trackers/vega/mask.c66
-rw-r--r--src/gallium/state_trackers/vega/mask.h2
-rw-r--r--src/gallium/state_trackers/vega/paint.c62
-rw-r--r--src/gallium/state_trackers/vega/paint.h2
-rw-r--r--src/gallium/state_trackers/vega/renderer.c37
-rw-r--r--src/gallium/state_trackers/vega/renderer.h3
-rw-r--r--src/gallium/state_trackers/vega/shader.c34
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c19
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h12
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c373
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.h40
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c58
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c29
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c21
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c42
-rw-r--r--src/gallium/targets/Makefile.dri (renamed from src/gallium/winsys/drm/Makefile.template)7
-rw-r--r--src/gallium/targets/Makefile.egl (renamed from src/gallium/winsys/drm/Makefile.egl)8
-rw-r--r--src/gallium/targets/SConscript21
-rw-r--r--src/gallium/targets/SConscript.dri96
-rw-r--r--src/gallium/targets/dri-i915/Makefile (renamed from src/gallium/winsys/drm/intel/dri/Makefile)14
-rw-r--r--src/gallium/targets/dri-i915/SConscript26
-rw-r--r--src/gallium/targets/dri-i915/dummy.c0
-rw-r--r--src/gallium/targets/dri-i965/Makefile (renamed from src/gallium/winsys/drm/i965/dri/Makefile)16
-rw-r--r--src/gallium/targets/dri-i965/SConscript26
-rw-r--r--src/gallium/targets/dri-i965/dummy.c0
-rw-r--r--src/gallium/targets/dri-nouveau/Makefile (renamed from src/gallium/winsys/drm/nouveau/dri/Makefile)10
-rw-r--r--src/gallium/targets/dri-radeong/Makefile (renamed from src/gallium/winsys/drm/radeon/dri/Makefile)11
-rw-r--r--src/gallium/targets/dri-radeong/SConscript26
-rw-r--r--src/gallium/targets/dri-radeong/dummy.c0
-rw-r--r--src/gallium/targets/dri-swrast/Makefile30
-rw-r--r--src/gallium/targets/dri-swrast/SConscript42
-rw-r--r--src/gallium/targets/dri-swrast/swrast_drm_api.c147
-rw-r--r--src/gallium/targets/dri-vmwgfx/Makefile (renamed from src/gallium/winsys/drm/vmware/dri/Makefile)9
-rw-r--r--src/gallium/targets/dri-vmwgfx/SConscript24
-rw-r--r--src/gallium/targets/dri-vmwgfx/dummy.c0
-rw-r--r--src/gallium/targets/egl-i915/Makefile (renamed from src/gallium/winsys/drm/intel/egl/Makefile)7
-rw-r--r--src/gallium/targets/egl-i915/dummy.c (renamed from src/gallium/winsys/drm/i965/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-i965/Makefile16
-rw-r--r--src/gallium/targets/egl-i965/dummy.c (renamed from src/gallium/winsys/drm/intel/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-nouveau/Makefile (renamed from src/gallium/winsys/drm/nouveau/egl/Makefile)9
-rw-r--r--src/gallium/targets/egl-nouveau/dummy.c (renamed from src/gallium/winsys/drm/nouveau/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-radeon/Makefile (renamed from src/gallium/winsys/drm/radeon/egl/Makefile)7
-rw-r--r--src/gallium/targets/egl-radeon/dummy.c (renamed from src/gallium/winsys/drm/radeon/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-swrast/Makefile12
-rw-r--r--src/gallium/targets/egl-swrast/swrast_glue.c (renamed from src/gallium/winsys/drm/swrast/core/swrast_drm_api.c)4
-rw-r--r--src/gallium/targets/egl-vmwgfx/Makefile (renamed from src/gallium/winsys/drm/vmware/egl/Makefile)7
-rw-r--r--src/gallium/targets/egl-vmwgfx/dummy.c (renamed from src/gallium/winsys/drm/swrast/egl/dummy.c)0
-rw-r--r--src/gallium/targets/graw-xlib/SConscript57
-rw-r--r--src/gallium/targets/graw-xlib/graw.h36
-rw-r--r--src/gallium/targets/graw-xlib/graw_xlib.c181
-rw-r--r--src/gallium/targets/libgl-gdi/SConscript1
-rw-r--r--src/gallium/targets/libgl-xlib/Makefile2
-rw-r--r--src/gallium/targets/libgl-xlib/xlib.c95
-rw-r--r--src/gallium/targets/xorg-i915/Makefile (renamed from src/gallium/winsys/drm/intel/xorg/Makefile)10
-rw-r--r--src/gallium/targets/xorg-i915/intel_xorg.c (renamed from src/gallium/winsys/drm/intel/xorg/intel_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-i965/Makefile (renamed from src/gallium/winsys/drm/i965/xorg/Makefile)22
-rw-r--r--src/gallium/targets/xorg-i965/intel_xorg.c (renamed from src/gallium/winsys/drm/i965/xorg/intel_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-nouveau/Makefile (renamed from src/gallium/winsys/drm/nouveau/xorg/Makefile)9
-rw-r--r--src/gallium/targets/xorg-nouveau/nouveau_xorg.c (renamed from src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-radeon/Makefile (renamed from src/gallium/winsys/drm/radeon/xorg/Makefile)22
-rw-r--r--src/gallium/targets/xorg-radeon/radeon_xorg.c (renamed from src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-vmwgfx/Makefile (renamed from src/gallium/winsys/drm/vmware/xorg/Makefile)5
-rw-r--r--src/gallium/targets/xorg-vmwgfx/SConscript (renamed from src/gallium/winsys/drm/vmware/xorg/SConscript)4
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_driver.h (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_driver.h)0
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_hook.h (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_hook.h)0
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_ioctl.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c)2
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_screen.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_screen.c)0
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_video.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_video.c)2
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_xorg.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c)0
-rw-r--r--src/gallium/winsys/SConscript34
-rw-r--r--src/gallium/winsys/drm/SConscript69
-rw-r--r--src/gallium/winsys/drm/i965/Makefile12
-rw-r--r--src/gallium/winsys/drm/i965/SConscript7
-rw-r--r--src/gallium/winsys/drm/i965/dri/SConscript19
-rw-r--r--src/gallium/winsys/drm/i965/egl/Makefile14
-rw-r--r--src/gallium/winsys/drm/intel/Makefile12
-rw-r--r--src/gallium/winsys/drm/intel/SConscript7
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript21
-rw-r--r--src/gallium/winsys/drm/intel/gem/SConscript17
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h77
-rw-r--r--src/gallium/winsys/drm/nouveau/Makefile12
-rw-r--r--src/gallium/winsys/drm/radeon/Makefile12
-rw-r--r--src/gallium/winsys/drm/radeon/SConscript7
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c388
-rw-r--r--src/gallium/winsys/drm/radeon/dri/SConscript17
-rw-r--r--src/gallium/winsys/drm/swrast/Makefile12
-rw-r--r--src/gallium/winsys/drm/swrast/core/Makefile10
-rw-r--r--src/gallium/winsys/drm/swrast/egl/Makefile12
-rw-r--r--src/gallium/winsys/drm/vmware/Makefile12
-rw-r--r--src/gallium/winsys/drm/vmware/SConscript11
-rw-r--r--src/gallium/winsys/drm/vmware/dri/SConscript63
-rw-r--r--src/gallium/winsys/drm/vmware/egl/dummy.c3
-rw-r--r--src/gallium/winsys/i915/drm/Makefile (renamed from src/gallium/winsys/drm/intel/gem/Makefile)14
-rw-r--r--src/gallium/winsys/i915/drm/SConscript17
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_api.c (renamed from src/gallium/winsys/drm/intel/gem/intel_drm_api.c)28
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c (renamed from src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c)78
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_buffer.c (renamed from src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c)98
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_fence.c (renamed from src/gallium/winsys/drm/intel/gem/intel_drm_fence.c)30
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_winsys.h77
-rw-r--r--src/gallium/winsys/i965/drm/Makefile (renamed from src/gallium/winsys/drm/i965/gem/Makefile)4
-rw-r--r--src/gallium/winsys/i965/drm/SConscript (renamed from src/gallium/winsys/drm/i965/gem/SConscript)2
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_api.c (renamed from src/gallium/winsys/drm/i965/gem/i965_drm_api.c)12
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_buffer.c (renamed from src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c)0
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_winsys.h (renamed from src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h)0
-rw-r--r--src/gallium/winsys/i965/xlib/Makefile (renamed from src/gallium/winsys/drm/i965/xlib/Makefile)4
-rw-r--r--src/gallium/winsys/i965/xlib/xlib_i965.c (renamed from src/gallium/winsys/drm/i965/xlib/xlib_i965.c)0
-rw-r--r--src/gallium/winsys/nouveau/drm/Makefile (renamed from src/gallium/winsys/drm/nouveau/drm/Makefile)4
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_dri.h (renamed from src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h)0
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_api.c (renamed from src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c)0
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_api.h (renamed from src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h)0
-rw-r--r--src/gallium/winsys/radeon/drm/Makefile (renamed from src/gallium/winsys/drm/radeon/core/Makefile)4
-rw-r--r--src/gallium/winsys/radeon/drm/SConscript (renamed from src/gallium/winsys/drm/radeon/core/SConscript)4
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_buffer.h)7
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.c (renamed from src/gallium/winsys/drm/radeon/core/radeon_drm.c)7
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_drm.h)0
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c (renamed from src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c)63
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c (renamed from src/gallium/winsys/drm/radeon/core/radeon_r300.c)17
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_r300.h)0
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_winsys.h)5
-rw-r--r--src/gallium/winsys/svga/drm/Makefile (renamed from src/gallium/winsys/drm/vmware/core/Makefile)12
-rw-r--r--src/gallium/winsys/svga/drm/SConscript (renamed from src/gallium/winsys/drm/vmware/core/SConscript)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_buffer.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_buffer.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_context.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_context.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_fence.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_fence.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_dri.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c)2
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_pools.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_svga.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_surface.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_surface.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_surface.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_surface.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmwgfx_drm.h (renamed from src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h)0
-rw-r--r--src/gallium/winsys/sw/Makefile (renamed from src/gallium/winsys/drm/Makefile)4
-rw-r--r--src/gallium/winsys/sw/dri/Makefile13
-rw-r--r--src/gallium/winsys/sw/dri/SConscript23
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c225
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.h38
-rw-r--r--src/gallium/winsys/sw/drm/Makefile12
-rw-r--r--src/gallium/winsys/sw/drm/sw_drm_api.c97
-rw-r--r--src/gallium/winsys/sw/drm/sw_drm_api.h34
-rw-r--r--src/gallium/winsys/sw/gdi/SConscript (renamed from src/gallium/winsys/gdi/SConscript)0
-rw-r--r--src/gallium/winsys/sw/gdi/gdi_sw_winsys.c (renamed from src/gallium/winsys/gdi/gdi_sw_winsys.c)25
-rw-r--r--src/gallium/winsys/sw/gdi/gdi_sw_winsys.h (renamed from src/gallium/winsys/gdi/gdi_sw_winsys.h)0
-rw-r--r--src/gallium/winsys/sw/null/Makefile (renamed from src/gallium/winsys/null/Makefile)4
-rw-r--r--src/gallium/winsys/sw/null/SConscript (renamed from src/gallium/winsys/null/SConscript)0
-rw-r--r--src/gallium/winsys/sw/null/null_sw_winsys.c (renamed from src/gallium/winsys/null/null_sw_winsys.c)24
-rw-r--r--src/gallium/winsys/sw/null/null_sw_winsys.h (renamed from src/gallium/winsys/null/null_sw_winsys.h)0
-rw-r--r--src/gallium/winsys/sw/wrapper/Makefile12
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c282
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h35
-rw-r--r--src/gallium/winsys/sw/xlib/Makefile (renamed from src/gallium/winsys/xlib/Makefile)6
-rw-r--r--src/gallium/winsys/sw/xlib/SConscript (renamed from src/gallium/winsys/xlib/SConscript)0
-rw-r--r--src/gallium/winsys/sw/xlib/xlib_sw_winsys.c (renamed from src/gallium/winsys/xlib/xlib_sw_winsys.c)27
443 files changed, 12285 insertions, 5665 deletions
diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template
index 91a9b54b362..b5a9938c740 100644
--- a/src/gallium/Makefile.template
+++ b/src/gallium/Makefile.template
@@ -26,7 +26,7 @@ INCLUDES = \
##### TARGETS #####
-default: depend lib$(LIBNAME).a
+default: depend lib$(LIBNAME).a $(PROGS)
lib$(LIBNAME).a: $(OBJECTS) $(EXTRA_OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
$(MKLIB) -o $(LIBNAME) -static $(OBJECTS) $(EXTRA_OBJECTS)
@@ -36,13 +36,16 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURC
touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(GENERATED_SOURCES) 2> /dev/null
+$(PROGS): % : %.o
+ $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group
+
# Emacs tags
tags:
etags `find . -name \*.[ch]` `find $(TOP)/src/gallium/include -name \*.h`
# Remove .o and backup files
clean:
- rm -f $(OBJECTS) $(GENERATED_SOURCES) lib$(LIBNAME).a depend depend.bak
+ rm -f $(OBJECTS) $(GENERATED_SOURCES) $(PROGS) lib$(LIBNAME).a depend depend.bak
# Dummy target
install:
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index c833d83e65b..b8c04f72379 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -8,7 +8,7 @@ for driver in env['drivers']:
SConscript(os.path.join('drivers', driver, 'SConscript'))
# Needed by some state trackers
-SConscript('winsys/null/SConscript')
+SConscript('winsys/sw/null/SConscript')
SConscript('state_trackers/python/SConscript')
if platform != 'embedded':
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 0ac18426d97..452eceb7f4f 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -119,6 +119,7 @@ C_SOURCES = \
util/u_mm.c \
util/u_rect.c \
util/u_ringbuffer.c \
+ util/u_sampler.c \
util/u_simple_shaders.c \
util/u_snprintf.c \
util/u_surface.c \
@@ -127,13 +128,15 @@ C_SOURCES = \
util/u_timed_winsys.c \
util/u_upload_mgr.c \
util/u_simple_screen.c \
- vl/vl_bitstream_parser.c \
- vl/vl_mpeg12_mc_renderer.c \
- vl/vl_compositor.c \
- vl/vl_csc.c \
- vl/vl_shader_build.c \
target-helpers/wrap_screen.c
+ # Disabling until pipe-video branch gets merged in
+ #vl/vl_bitstream_parser.c \
+ #vl/vl_mpeg12_mc_renderer.c \
+ #vl/vl_compositor.c \
+ #vl/vl_csc.c \
+ #vl/vl_shader_build.c \
+
GALLIVM_SOURCES = \
gallivm/lp_bld_alpha.c \
gallivm/lp_bld_arit.c \
@@ -152,6 +155,7 @@ GALLIVM_SOURCES = \
gallivm/lp_bld_intr.c \
gallivm/lp_bld_logic.c \
gallivm/lp_bld_pack.c \
+ gallivm/lp_bld_printf.c \
gallivm/lp_bld_sample.c \
gallivm/lp_bld_sample_soa.c \
gallivm/lp_bld_struct.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index b234b2f5f4e..d0785bce16b 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -162,6 +162,7 @@ source = [
'util/u_mm.c',
'util/u_rect.c',
'util/u_ringbuffer.c',
+ 'util/u_sampler.c',
'util/u_simple_shaders.c',
'util/u_snprintf.c',
'util/u_surface.c',
@@ -170,11 +171,12 @@ source = [
'util/u_timed_winsys.c',
'util/u_upload_mgr.c',
'util/u_simple_screen.c',
- 'vl/vl_bitstream_parser.c',
- 'vl/vl_mpeg12_mc_renderer.c',
- 'vl/vl_compositor.c',
- 'vl/vl_csc.c',
- 'vl/vl_shader_build.c',
+ # Disabling until pipe-video branch gets merged in
+ #'vl/vl_bitstream_parser.c',
+ #'vl/vl_mpeg12_mc_renderer.c',
+ #'vl/vl_compositor.c',
+ #'vl/vl_csc.c',
+ #'vl/vl_shader_build.c',
'target-helpers/wrap_screen.c',
]
@@ -198,6 +200,7 @@ if drawllvm:
'gallivm/lp_bld_logic.c',
'gallivm/lp_bld_init.cpp',
'gallivm/lp_bld_pack.c',
+ 'gallivm/lp_bld_printf.c',
'gallivm/lp_bld_sample.c',
'gallivm/lp_bld_sample_soa.c',
'gallivm/lp_bld_struct.c',
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 6500891a10c..6fd4bd36428 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -37,6 +37,7 @@
#include "pipe/p_state.h"
#include "util/u_inlines.h"
+#include "util/u_math.h"
#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h"
@@ -69,17 +70,17 @@ struct cso_context {
unsigned nr_vertex_samplers_saved;
void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
- uint nr_textures;
+ uint nr_fragment_sampler_views;
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
- uint nr_vertex_textures;
+ uint nr_vertex_sampler_views;
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
- uint nr_textures_saved;
- struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS];
+ uint nr_fragment_sampler_views_saved;
+ struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS];
- uint nr_vertex_textures_saved;
- struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS];
+ uint nr_vertex_sampler_views_saved;
+ struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS];
/** Current and saved state.
* The saved state is used as a 1-deep stack.
@@ -293,13 +294,13 @@ void cso_release_all( struct cso_context *ctx )
}
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->textures[i], NULL);
- pipe_texture_reference(&ctx->textures_saved[i], NULL);
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL);
+ pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL);
+ pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL);
}
free_framebuffer_state(&ctx->fb);
@@ -616,114 +617,6 @@ cso_restore_vertex_samplers(struct cso_context *ctx)
}
-enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
- uint count,
- struct pipe_texture **textures )
-{
- uint i;
-
- ctx->nr_textures = count;
-
- for (i = 0; i < count; i++)
- pipe_texture_reference(&ctx->textures[i], textures[i]);
- for ( ; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&ctx->textures[i], NULL);
-
- ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures);
-
- return PIPE_OK;
-}
-
-void cso_save_sampler_textures( struct cso_context *ctx )
-{
- uint i;
-
- ctx->nr_textures_saved = ctx->nr_textures;
- for (i = 0; i < ctx->nr_textures; i++) {
- assert(!ctx->textures_saved[i]);
- pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]);
- }
-}
-
-void cso_restore_sampler_textures( struct cso_context *ctx )
-{
- uint i;
-
- ctx->nr_textures = ctx->nr_textures_saved;
-
- for (i = 0; i < ctx->nr_textures; i++) {
- pipe_texture_reference(&ctx->textures[i], NULL);
- ctx->textures[i] = ctx->textures_saved[i];
- ctx->textures_saved[i] = NULL;
- }
- for ( ; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&ctx->textures[i], NULL);
-
- ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures);
-
- ctx->nr_textures_saved = 0;
-}
-
-
-
-enum pipe_error
-cso_set_vertex_sampler_textures(struct cso_context *ctx,
- uint count,
- struct pipe_texture **textures)
-{
- uint i;
-
- ctx->nr_vertex_textures = count;
-
- for (i = 0; i < count; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], textures[i]);
- }
- for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- }
-
- ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures);
-
- return PIPE_OK;
-}
-
-void
-cso_save_vertex_sampler_textures(struct cso_context *ctx)
-{
- uint i;
-
- ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures;
- for (i = 0; i < ctx->nr_vertex_textures; i++) {
- assert(!ctx->vertex_textures_saved[i]);
- pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]);
- }
-}
-
-void
-cso_restore_vertex_sampler_textures(struct cso_context *ctx)
-{
- uint i;
-
- ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved;
-
- for (i = 0; i < ctx->nr_vertex_textures; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- ctx->vertex_textures[i] = ctx->vertex_textures_saved[i];
- ctx->vertex_textures_saved[i] = NULL;
- }
- for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- }
-
- ctx->pipe->set_vertex_sampler_textures(ctx->pipe,
- ctx->nr_vertex_textures,
- ctx->vertex_textures);
-
- ctx->nr_vertex_textures_saved = 0;
-}
-
-
-
enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{
@@ -1261,3 +1154,122 @@ void cso_restore_vertex_elements(struct cso_context *ctx)
}
ctx->velements_saved = NULL;
}
+
+/* fragment sampler view state */
+
+void
+cso_set_fragment_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views)
+{
+ uint i;
+
+ for (i = 0; i < count; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]);
+ }
+ for (; i < cso->nr_fragment_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_fragment_sampler_views(cso->pipe,
+ MAX2(count, cso->nr_fragment_sampler_views),
+ cso->fragment_sampler_views);
+
+ cso->nr_fragment_sampler_views = count;
+}
+
+void
+cso_save_fragment_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views;
+
+ for (i = 0; i < cso->nr_fragment_sampler_views; i++) {
+ assert(!cso->fragment_sampler_views_saved[i]);
+
+ pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i],
+ cso->fragment_sampler_views[i]);
+ }
+}
+
+void
+cso_restore_fragment_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]);
+ pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL);
+ }
+ for (; i < cso->nr_fragment_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_fragment_sampler_views(cso->pipe,
+ MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved),
+ cso->fragment_sampler_views);
+
+ cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved;
+ cso->nr_fragment_sampler_views_saved = 0;
+}
+
+
+/* vertex sampler view state */
+
+void
+cso_set_vertex_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views)
+{
+ uint i;
+
+ for (i = 0; i < count; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]);
+ }
+ for (; i < cso->nr_vertex_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_vertex_sampler_views(cso->pipe,
+ MAX2(count, cso->nr_vertex_sampler_views),
+ cso->vertex_sampler_views);
+
+ cso->nr_vertex_sampler_views = count;
+}
+
+void
+cso_save_vertex_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views;
+
+ for (i = 0; i < cso->nr_vertex_sampler_views; i++) {
+ assert(!cso->vertex_sampler_views_saved[i]);
+
+ pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i],
+ cso->vertex_sampler_views[i]);
+ }
+}
+
+void
+cso_restore_vertex_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]);
+ pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL);
+ }
+ for (; i < cso->nr_vertex_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_vertex_sampler_views(cso->pipe,
+ MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved),
+ cso->vertex_sampler_views);
+
+ cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved;
+ cso->nr_vertex_sampler_views_saved = 0;
+}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 9c16abd28dd..d6bcb1fe8f7 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -103,25 +103,6 @@ void
cso_single_vertex_sampler_done(struct cso_context *cso);
-
-enum pipe_error cso_set_sampler_textures( struct cso_context *cso,
- uint count,
- struct pipe_texture **textures );
-void cso_save_sampler_textures( struct cso_context *cso );
-void cso_restore_sampler_textures( struct cso_context *cso );
-
-
-
-enum pipe_error
-cso_set_vertex_sampler_textures(struct cso_context *cso,
- uint count,
- struct pipe_texture **textures);
-void
-cso_save_vertex_sampler_textures(struct cso_context *cso);
-void
-cso_restore_vertex_sampler_textures(struct cso_context *cso);
-
-
enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned count,
const struct pipe_vertex_element *states);
@@ -198,6 +179,34 @@ void
cso_restore_clip(struct cso_context *cso);
+/* fragment sampler view state */
+
+void
+cso_set_fragment_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views);
+
+void
+cso_save_fragment_sampler_views(struct cso_context *cso);
+
+void
+cso_restore_fragment_sampler_views(struct cso_context *cso);
+
+
+/* vertex sampler view state */
+
+void
+cso_set_vertex_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views);
+
+void
+cso_save_vertex_sampler_views(struct cso_context *cso);
+
+void
+cso_restore_vertex_sampler_views(struct cso_context *cso);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 1c07ab13654..f4615064e65 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -40,6 +40,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "tgsi/tgsi_transform.h"
#include "tgsi/tgsi_dump.h"
@@ -88,8 +89,9 @@ struct aaline_stage
void *sampler_cso;
struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
uint num_samplers;
- uint num_textures;
+ uint num_sampler_views;
/*
@@ -98,7 +100,7 @@ struct aaline_stage
struct aaline_fragment_shader *fs;
struct {
void *sampler[PIPE_MAX_SAMPLERS];
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
} state;
/*
@@ -111,8 +113,9 @@ struct aaline_stage
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
void **);
- void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
- struct pipe_texture **);
+ void (*driver_set_sampler_views)(struct pipe_context *,
+ unsigned,
+ struct pipe_sampler_view **);
struct pipe_context *pipe;
};
@@ -394,6 +397,7 @@ aaline_create_texture(struct aaline_stage *aaline)
struct pipe_context *pipe = aaline->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture texTemp;
+ struct pipe_sampler_view viewTempl;
uint level;
memset(&texTemp, 0, sizeof(texTemp));
@@ -408,6 +412,16 @@ aaline_create_texture(struct aaline_stage *aaline)
if (!aaline->texture)
return FALSE;
+ u_sampler_view_default_template(&viewTempl,
+ aaline->texture,
+ aaline->texture->format);
+ aaline->sampler_view = pipe->create_sampler_view(pipe,
+ aaline->texture,
+ &viewTempl);
+ if (!aaline->sampler_view) {
+ return FALSE;
+ }
+
/* Fill in mipmap images.
* Basically each level is solid opaque, except for the outermost
* texels which are zero. Special case the 1x1 and 2x2 levels.
@@ -669,16 +683,16 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
/* how many samplers? */
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
- num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
+ num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers);
num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
- pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
- aaline->texture);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
+ aaline->sampler_view);
draw->suspend_flushing = TRUE;
aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
- aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
+ aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views);
draw->suspend_flushing = FALSE;
/* now really draw first line */
@@ -702,8 +716,9 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
aaline->state.sampler);
- aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
- aaline->state.texture);
+ aaline->driver_set_sampler_views(pipe,
+ aaline->num_sampler_views,
+ aaline->state.sampler_views);
draw->suspend_flushing = FALSE;
draw->extra_shader_outputs.slot = 0;
@@ -724,7 +739,7 @@ aaline_destroy(struct draw_stage *stage)
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&aaline->state.texture[i], NULL);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
}
if (aaline->sampler_cso)
@@ -733,6 +748,10 @@ aaline_destroy(struct draw_stage *stage)
if (aaline->texture)
pipe_texture_reference(&aaline->texture, NULL);
+ if (aaline->sampler_view) {
+ pipe_sampler_view_reference(&aaline->sampler_view, NULL);
+ }
+
draw_free_temp_verts( stage );
FREE( stage );
@@ -844,23 +863,24 @@ aaline_bind_sampler_states(struct pipe_context *pipe,
static void
-aaline_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+aaline_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
uint i;
/* save current */
for (i = 0; i < num; i++) {
- pipe_texture_reference(&aaline->state.texture[i], texture[i]);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]);
}
for ( ; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&aaline->state.texture[i], NULL);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
}
- aaline->num_textures = num;
+ aaline->num_sampler_views = num;
/* pass-through */
- aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
+ aaline->driver_set_sampler_views(aaline->pipe, num, views);
}
@@ -898,7 +918,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
aaline->driver_delete_fs_state = pipe->delete_fs_state;
aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
- aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures;
+ aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views;
/* override the driver's functions */
pipe->create_fs_state = aaline_create_fs_state;
@@ -906,7 +926,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
pipe->delete_fs_state = aaline_delete_fs_state;
pipe->bind_fragment_sampler_states = aaline_bind_sampler_states;
- pipe->set_fragment_sampler_textures = aaline_set_sampler_textures;
+ pipe->set_fragment_sampler_views = aaline_set_sampler_views;
/* Install once everything is known to be OK:
*/
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 38c22bf4e94..794fd81d70f 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -42,6 +42,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "tgsi/tgsi_transform.h"
#include "tgsi/tgsi_dump.h"
@@ -75,8 +76,9 @@ struct pstip_stage
void *sampler_cso;
struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
uint num_samplers;
- uint num_textures;
+ uint num_sampler_views;
/*
* Currently bound state
@@ -84,7 +86,7 @@ struct pstip_stage
struct pstip_fragment_shader *fs;
struct {
void *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
const struct pipe_poly_stipple *stipple;
} state;
@@ -98,8 +100,9 @@ struct pstip_stage
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **);
- void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
- struct pipe_texture **);
+ void (*driver_set_sampler_views)(struct pipe_context *,
+ unsigned,
+ struct pipe_sampler_view **);
void (*driver_set_polygon_stipple)(struct pipe_context *,
const struct pipe_poly_stipple *);
@@ -424,6 +427,7 @@ pstip_create_texture(struct pstip_stage *pstip)
struct pipe_context *pipe = pstip->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture texTemp;
+ struct pipe_sampler_view viewTempl;
memset(&texTemp, 0, sizeof(texTemp));
texTemp.target = PIPE_TEXTURE_2D;
@@ -437,6 +441,16 @@ pstip_create_texture(struct pstip_stage *pstip)
if (pstip->texture == NULL)
return FALSE;
+ u_sampler_view_default_template(&viewTempl,
+ pstip->texture,
+ pstip->texture->format);
+ pstip->sampler_view = pipe->create_sampler_view(pipe,
+ pstip->texture,
+ &viewTempl);
+ if (!pstip->sampler_view) {
+ return FALSE;
+ }
+
return TRUE;
}
@@ -515,19 +529,19 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
/* how many samplers? */
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
- num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
+ num_samplers = MAX2(pstip->num_sampler_views, pstip->num_samplers);
num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1);
/* plug in our sampler, texture */
pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso;
- pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit],
- pstip->texture);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[pstip->fs->sampler_unit],
+ pstip->sampler_view);
assert(num_samplers <= PIPE_MAX_SAMPLERS);
draw->suspend_flushing = TRUE;
pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers);
- pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures);
+ pstip->driver_set_sampler_views(pipe, num_samplers, pstip->state.sampler_views);
draw->suspend_flushing = FALSE;
/* now really draw first triangle */
@@ -551,8 +565,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags)
pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
pstip->state.samplers);
- pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
- pstip->state.textures);
+ pstip->driver_set_sampler_views(pipe,
+ pstip->num_sampler_views,
+ pstip->state.sampler_views);
draw->suspend_flushing = FALSE;
}
@@ -571,13 +586,17 @@ pstip_destroy(struct draw_stage *stage)
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&pstip->state.textures[i], NULL);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL);
}
pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso);
pipe_texture_reference(&pstip->texture, NULL);
+ if (pstip->sampler_view) {
+ pipe_sampler_view_reference(&pstip->sampler_view, NULL);
+ }
+
draw_free_temp_verts( stage );
FREE( stage );
}
@@ -682,24 +701,25 @@ pstip_bind_sampler_states(struct pipe_context *pipe,
static void
-pstip_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+pstip_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
uint i;
/* save current */
for (i = 0; i < num; i++) {
- pipe_texture_reference(&pstip->state.textures[i], texture[i]);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[i], views[i]);
}
for (; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&pstip->state.textures[i], NULL);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL);
}
- pstip->num_textures = num;
+ pstip->num_sampler_views = num;
/* pass-through */
- pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
+ pstip->driver_set_sampler_views(pstip->pipe, num, views);
}
@@ -756,7 +776,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
pstip->driver_delete_fs_state = pipe->delete_fs_state;
pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
- pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures;
+ pstip->driver_set_sampler_views = pipe->set_fragment_sampler_views;
pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
/* override the driver's functions */
@@ -765,7 +785,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
pipe->delete_fs_state = pstip_delete_fs_state;
pipe->bind_fragment_sampler_states = pstip_bind_sampler_states;
- pipe->set_fragment_sampler_textures = pstip_set_sampler_textures;
+ pipe->set_fragment_sampler_views = pstip_set_sampler_views;
pipe->set_polygon_stipple = pstip_set_polygon_stipple;
return TRUE;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 27099579618..1c7db0005a9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -238,38 +238,15 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
unsigned output_format;
unsigned src_offset = (vbuf->vinfo->attrib[i].src_index * 4 * sizeof(float) );
- switch (vbuf->vinfo->attrib[i].emit) {
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
+ output_format = draw_translate_vinfo_format(vbuf->vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vbuf->vinfo->attrib[i].emit);
+
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
+
+ if (vbuf->vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
src_buffer = 1;
src_offset = 0;
- break;
- case EMIT_4UB:
- output_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- break;
}
hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index ae357b51226..a7917f54b04 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -86,40 +86,15 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
unsigned output_format;
unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
+ output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
-
- switch (vinfo->attrib[i].emit) {
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
+
+ if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
src_buffer = 1;
src_offset = 0;
- break;
- case EMIT_4UB:
- output_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- break;
}
hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 2a604470e9a..1994ddf2bcc 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -129,41 +129,16 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
unsigned input_offset = src->src_offset;
unsigned output_format;
- switch (vinfo->attrib[i].emit) {
- case EMIT_4UB:
- output_format = PIPE_FORMAT_R8G8B8A8_UNORM;
- emit_sz = 4 * sizeof(unsigned char);
- break;
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
+ output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ if (vinfo->attrib[i].emit == EMIT_OMIT)
+ continue;
+
+ if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
input_format = PIPE_FORMAT_R32_FLOAT;
input_buffer = draw->pt.nr_vertex_buffers;
input_offset = 0;
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_OMIT:
- continue;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- continue;
}
key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index 1aecb510777..389e2b105e5 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -130,31 +130,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
unsigned dst_offset = 0;
for (i = 0; i < vinfo->num_attribs; i++) {
- unsigned emit_sz = 0;
-
- switch (vinfo->attrib[i].emit) {
- case EMIT_4F:
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_4UB:
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- break;
- }
+ unsigned emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
/* The elements in the key correspond to vertex shader output
* numbers, not to positions in the hw vertex description --
diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c
index 3214213e445..a4f5e882c0a 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.c
+++ b/src/gallium/auxiliary/draw/draw_vertex.c
@@ -48,30 +48,12 @@ draw_compute_vertex_size(struct vertex_info *vinfo)
uint i;
vinfo->size = 0;
- for (i = 0; i < vinfo->num_attribs; i++) {
- switch (vinfo->attrib[i].emit) {
- case EMIT_OMIT:
- break;
- case EMIT_4UB:
- /* fall-through */
- case EMIT_1F_PSIZE:
- /* fall-through */
- case EMIT_1F:
- vinfo->size += 1;
- break;
- case EMIT_2F:
- vinfo->size += 2;
- break;
- case EMIT_3F:
- vinfo->size += 3;
- break;
- case EMIT_4F:
- vinfo->size += 4;
- break;
- default:
- assert(0);
- }
- }
+ for (i = 0; i < vinfo->num_attribs; i++)
+ vinfo->size += draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ assert(vinfo->size % 4 == 0);
+ /* in dwords */
+ vinfo->size /= 4;
}
@@ -120,6 +102,13 @@ draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data)
debug_printf("%u ", *data++);
debug_printf("%u ", *data++);
break;
+ case EMIT_4UB_BGRA:
+ debug_printf("EMIT_4UB_BGRA:\t");
+ debug_printf("%u ", *data++);
+ debug_printf("%u ", *data++);
+ debug_printf("%u ", *data++);
+ debug_printf("%u ", *data++);
+ break;
default:
assert(0);
}
diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h
index 8c3c7befbc7..ca272371267 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.h
+++ b/src/gallium/auxiliary/draw/draw_vertex.h
@@ -54,7 +54,8 @@ enum attrib_emit {
EMIT_2F,
EMIT_3F,
EMIT_4F,
- EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */
+ EMIT_4UB, /**< is RGBA like the rest */
+ EMIT_4UB_BGRA
};
@@ -141,9 +142,11 @@ void draw_dump_emitted_vertex(const struct vertex_info *vinfo,
const uint8_t *data);
-static INLINE unsigned draw_translate_vinfo_format(unsigned format )
+static INLINE unsigned draw_translate_vinfo_format(enum attrib_emit emit)
{
- switch (format) {
+ switch (emit) {
+ case EMIT_OMIT:
+ return PIPE_FORMAT_NONE;
case EMIT_1F:
case EMIT_1F_PSIZE:
return PIPE_FORMAT_R32_FLOAT;
@@ -155,10 +158,36 @@ static INLINE unsigned draw_translate_vinfo_format(unsigned format )
return PIPE_FORMAT_R32G32B32A32_FLOAT;
case EMIT_4UB:
return PIPE_FORMAT_R8G8B8A8_UNORM;
+ case EMIT_4UB_BGRA:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
default:
+ assert(!"unexpected format");
return PIPE_FORMAT_NONE;
}
}
+static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit)
+{
+ switch (emit) {
+ case EMIT_OMIT:
+ return 0;
+ case EMIT_1F:
+ case EMIT_1F_PSIZE:
+ return 1 * sizeof(float);
+ case EMIT_2F:
+ return 2 * sizeof(float);
+ case EMIT_3F:
+ return 3 * sizeof(float);
+ case EMIT_4F:
+ return 4 * sizeof(float);
+ case EMIT_4UB:
+ return 4 * sizeof(unsigned char);
+ case EMIT_4UB_BGRA:
+ return 4 * sizeof(unsigned char);
+ default:
+ assert(!"unexpected format");
+ return 0;
+ }
+}
#endif /* DRAW_VERTEX_H */
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index ece1ddde0cb..8f8bbe7cb88 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -401,13 +401,11 @@ static boolean emit_output( struct aos_compilation *cp,
emit_store_R32G32B32A32(cp, ptr, dataXMM);
break;
case EMIT_4UB:
- if (1) {
- emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W));
- emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
- }
- else {
- emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
- }
+ emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
+ break;
+ case EMIT_4UB_BGRA:
+ emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W));
+ emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
break;
default:
AOS_ERROR(cp, "unhandled output format");
diff --git a/src/gallium/auxiliary/os/os_llvm.h b/src/gallium/auxiliary/gallivm/lp_bld.h
index d5edfbfe923..70a4960f913 100644
--- a/src/gallium/auxiliary/os/os_llvm.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld.h
@@ -31,8 +31,8 @@
*/
-#ifndef OS_LLVM_H
-#define OS_LLVM_H
+#ifndef LP_BLD_H
+#define LP_BLD_H
#include <llvm-c/Core.h>
@@ -40,8 +40,8 @@
/** Set version to 0 if missing to avoid #ifdef HAVE_LLVM everywhere */
#ifndef HAVE_LLVM
-#define HAVE_LLVM 0x0
+#define HAVE_LLVM 0x0207
#endif
-#endif /* OS_LLVM_H */
+#endif /* LP_BLD_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_alpha.h b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h
index fe3cedcc48c..0f99fec65ed 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_alpha.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h
@@ -35,7 +35,7 @@
#define LP_BLD_ALPHA_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct pipe_alpha_state;
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 233a36669d4..8e8fcccf564 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -361,12 +361,12 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
LLVMValueRef c8;
LLVMValueRef ab;
- c8 = lp_build_int_const_scalar(i16_type, 8);
+ c8 = lp_build_const_int_vec(i16_type, 8);
#if 0
/* a*b/255 ~= (a*(b + 1)) >> 256 */
- b = LLVMBuildAdd(builder, b, lp_build_int_const_scalar(i16_type, 1), "");
+ b = LLVMBuildAdd(builder, b, lp_build_const_int_vec(i16_type, 1), "");
ab = LLVMBuildMul(builder, a, b, "");
#else
@@ -374,7 +374,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_int_const_scalar(i16_type, 0x80), "");
+ ab = LLVMBuildAdd(builder, ab, lp_build_const_int_vec(i16_type, 0x80), "");
#endif
@@ -429,7 +429,7 @@ lp_build_mul(struct lp_build_context *bld,
}
if(type.fixed)
- shift = lp_build_int_const_scalar(type, type.width/2);
+ shift = lp_build_const_int_vec(type, type.width/2);
else
shift = NULL;
@@ -491,7 +491,7 @@ lp_build_mul_imm(struct lp_build_context *bld,
* for Inf and NaN.
*/
unsigned mantissa = lp_mantissa(bld->type);
- factor = lp_build_int_const_scalar(bld->type, (unsigned long long)shift << mantissa);
+ 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), "");
@@ -499,12 +499,12 @@ lp_build_mul_imm(struct lp_build_context *bld,
#endif
}
else {
- factor = lp_build_const_scalar(bld->type, shift);
+ factor = lp_build_const_vec(bld->type, shift);
return LLVMBuildShl(bld->builder, a, factor, "");
}
}
- factor = lp_build_const_scalar(bld->type, (double)b);
+ factor = lp_build_const_vec(bld->type, (double)b);
return lp_build_mul(bld, a, factor);
}
@@ -567,7 +567,7 @@ lp_build_lerp(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_int_const_scalar(bld->type, (1 << bld->type.width/2) - 1), "");
+ res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(bld->type, (1 << bld->type.width/2) - 1), "");
return res;
}
@@ -689,7 +689,7 @@ lp_build_abs(struct lp_build_context *bld,
/* vector of floats */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
unsigned long long absMask = ~(1ULL << (type.width - 1));
- LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
+ 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, "");
@@ -751,7 +751,7 @@ lp_build_sgn(struct lp_build_context *bld,
/* vector */
int_type = lp_build_int_vec_type(type);
vec_type = lp_build_vec_type(type);
- mask = lp_build_int_const_scalar(type, maskBit);
+ mask = lp_build_const_int_vec(type, maskBit);
}
/* Take the sign bit and add it to 1 constant */
@@ -763,7 +763,7 @@ lp_build_sgn(struct lp_build_context *bld,
}
else
{
- LLVMValueRef minus_one = lp_build_const_scalar(type, -1.0);
+ LLVMValueRef minus_one = lp_build_const_vec(type, -1.0);
cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero);
res = lp_build_select(bld, cond, bld->one, minus_one);
}
@@ -789,8 +789,8 @@ lp_build_set_sign(struct lp_build_context *bld,
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_int_const_scalar(type, type.width - 1);
- LLVMValueRef mask = lp_build_int_const_scalar(type,
+ LLVMValueRef shift = lp_build_const_int_vec(type, type.width - 1);
+ LLVMValueRef mask = lp_build_const_int_vec(type,
~((unsigned long long) 1 << (type.width - 1)));
LLVMValueRef val, res;
@@ -1034,7 +1034,7 @@ lp_build_iround(struct lp_build_context *bld,
}
else {
LLVMTypeRef vec_type = lp_build_vec_type(type);
- LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef sign;
LLVMValueRef half;
@@ -1043,7 +1043,7 @@ lp_build_iround(struct lp_build_context *bld,
sign = LLVMBuildAnd(bld->builder, sign, mask, "");
/* sign * 0.5 */
- half = lp_build_const_scalar(type, 0.5);
+ half = lp_build_const_vec(type, 0.5);
half = LLVMBuildBitCast(bld->builder, half, int_vec_type, "");
half = LLVMBuildOr(bld->builder, sign, half, "");
half = LLVMBuildBitCast(bld->builder, half, vec_type, "");
@@ -1086,18 +1086,18 @@ lp_build_ifloor(struct lp_build_context *bld,
/* Take the sign bit and add it to 1 constant */
LLVMTypeRef vec_type = lp_build_vec_type(type);
unsigned mantissa = lp_mantissa(type);
- LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef mask = lp_build_const_int_vec(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_int_const_scalar(type, type.width - 1), "");
+ sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "");
lp_build_name(sign, "floor.sign");
/* offset = -0.99999(9)f */
- offset = lp_build_const_scalar(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
+ offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
offset = LLVMConstBitCast(offset, int_vec_type);
/* offset = a < 0 ? -0.99999(9)f : 0.0f */
@@ -1268,7 +1268,7 @@ lp_build_exp(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log2(e) = 1/log(2) */
- LLVMValueRef log2e = lp_build_const_scalar(bld->type, 1.4426950408889634);
+ LLVMValueRef log2e = lp_build_const_vec(bld->type, 1.4426950408889634);
return lp_build_mul(bld, log2e, lp_build_exp2(bld, x));
}
@@ -1282,7 +1282,7 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log(2) */
- LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
+ LLVMValueRef log2 = lp_build_const_vec(bld->type, 0.69314718055994529);
return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
}
@@ -1318,7 +1318,7 @@ lp_build_polynomial(struct lp_build_context *bld,
if (type.length == 1)
coeff = LLVMConstReal(float_type, coeffs[i]);
else
- coeff = lp_build_const_scalar(type, coeffs[i]);
+ coeff = lp_build_const_vec(type, coeffs[i]);
if(res)
res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
@@ -1375,11 +1375,11 @@ lp_build_exp2_approx(struct lp_build_context *bld,
assert(type.floating && type.width == 32);
- x = lp_build_min(bld, x, lp_build_const_scalar(type, 129.0));
- x = lp_build_max(bld, x, lp_build_const_scalar(type, -126.99999));
+ 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));
/* ipart = int(x - 0.5) */
- ipart = LLVMBuildSub(bld->builder, x, lp_build_const_scalar(type, 0.5f), "");
+ ipart = LLVMBuildSub(bld->builder, x, lp_build_const_vec(type, 0.5f), "");
ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, "");
/* fpart = x - ipart */
@@ -1389,8 +1389,8 @@ lp_build_exp2_approx(struct lp_build_context *bld,
if(p_exp2_int_part || p_exp2) {
/* expipart = (float) (1 << ipart) */
- expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_int_const_scalar(type, 127), "");
- expipart = LLVMBuildShl(bld->builder, expipart, lp_build_int_const_scalar(type, 23), "");
+ expipart = 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, "");
}
@@ -1456,8 +1456,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- LLVMValueRef expmask = lp_build_int_const_scalar(type, 0x7f800000);
- LLVMValueRef mantmask = lp_build_int_const_scalar(type, 0x007fffff);
+ LLVMValueRef expmask = lp_build_const_int_vec(type, 0x7f800000);
+ LLVMValueRef mantmask = lp_build_const_int_vec(type, 0x007fffff);
LLVMValueRef one = LLVMConstBitCast(bld->one, int_vec_type);
LLVMValueRef i = NULL;
@@ -1482,8 +1482,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
}
if(p_floor_log2 || p_log2) {
- logexp = LLVMBuildLShr(bld->builder, exp, lp_build_int_const_scalar(type, 23), "");
- logexp = LLVMBuildSub(bld->builder, logexp, lp_build_int_const_scalar(type, 127), "");
+ logexp = 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, "");
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
index 7a10fe12209..31efa9921ce 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
@@ -37,7 +37,7 @@
#define LP_BLD_ARIT_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_blend.h b/src/gallium/auxiliary/gallivm/lp_bld_blend.h
index 5a9e1c1fb2f..ebbdb1a604c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_blend.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_blend.h
@@ -40,7 +40,7 @@
* for a standalone example.
*/
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include "pipe/p_format.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c
index 8a275fa72f3..57843e9a60c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c
@@ -263,7 +263,7 @@ lp_build_one(struct lp_type type)
if(type.sign)
/* TODO: Unfortunately this caused "Tried to create a shift operation
* on a non-integer type!" */
- vec = LLVMConstLShr(vec, lp_build_int_const_scalar(type, 1));
+ vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1));
#endif
return vec;
@@ -283,8 +283,8 @@ lp_build_one(struct lp_type type)
* Build constant-valued vector from a scalar value.
*/
LLVMValueRef
-lp_build_const_scalar(struct lp_type type,
- double val)
+lp_build_const_vec(struct lp_type type,
+ double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
@@ -309,7 +309,7 @@ lp_build_const_scalar(struct lp_type type,
LLVMValueRef
-lp_build_int_const_scalar(struct lp_type type,
+lp_build_const_int_vec(struct lp_type type,
long long val)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h
index 40786361031..9ca2f0664eb 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h
@@ -37,9 +37,9 @@
#define LP_BLD_CONST_H
-#include "os/os_llvm.h"
+#include "pipe/p_compiler.h"
+#include "gallivm/lp_bld.h"
-#include <pipe/p_compiler.h>
struct lp_type;
@@ -85,13 +85,11 @@ lp_build_one(struct lp_type type);
LLVMValueRef
-lp_build_const_scalar(struct lp_type type,
- double val);
+lp_build_const_vec(struct lp_type type, double val);
LLVMValueRef
-lp_build_int_const_scalar(struct lp_type type,
- long long val);
+lp_build_const_int_vec(struct lp_type type, long long val);
LLVMValueRef
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
index f77cf787213..3f7f2ebde9c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
@@ -114,13 +114,13 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
scale = (double)mask/ubound;
bias = (double)((unsigned long long)1 << (mantissa - n));
- res = LLVMBuildMul(builder, src, lp_build_const_scalar(src_type, scale), "");
- res = LLVMBuildAdd(builder, res, lp_build_const_scalar(src_type, bias), "");
+ res = LLVMBuildMul(builder, src, lp_build_const_vec(src_type, scale), "");
+ res = LLVMBuildAdd(builder, res, lp_build_const_vec(src_type, bias), "");
res = LLVMBuildBitCast(builder, res, int_vec_type, "");
if(dst_width > n) {
int shift = dst_width - n;
- res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), "");
+ res = LLVMBuildShl(builder, res, lp_build_const_int_vec(src_type, shift), "");
/* TODO: Fill in the empty lower bits for additional precision? */
/* YES: this fixes progs/trivial/tri-z-eq.c.
@@ -130,21 +130,21 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
#if 0
{
LLVMValueRef msb;
- msb = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, dst_width - 1), "");
- msb = LLVMBuildShl(builder, msb, lp_build_int_const_scalar(src_type, shift), "");
- msb = LLVMBuildSub(builder, msb, lp_build_int_const_scalar(src_type, 1), "");
+ msb = LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, dst_width - 1), "");
+ msb = LLVMBuildShl(builder, msb, lp_build_const_int_vec(src_type, shift), "");
+ msb = LLVMBuildSub(builder, msb, lp_build_const_int_vec(src_type, 1), "");
res = LLVMBuildOr(builder, res, msb, "");
}
#elif 0
while(shift > 0) {
- res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, n), ""), "");
+ res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, n), ""), "");
shift -= n;
n *= 2;
}
#endif
}
else
- res = LLVMBuildAnd(builder, res, lp_build_int_const_scalar(src_type, mask), "");
+ res = LLVMBuildAnd(builder, res, lp_build_const_int_vec(src_type, mask), "");
return res;
}
@@ -183,10 +183,10 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
if(src_width > mantissa) {
int shift = src_width - mantissa;
- res = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(dst_type, shift), "");
+ res = LLVMBuildLShr(builder, res, lp_build_const_int_vec(dst_type, shift), "");
}
- bias_ = lp_build_const_scalar(dst_type, bias);
+ bias_ = lp_build_const_vec(dst_type, bias);
res = LLVMBuildOr(builder,
res,
@@ -195,7 +195,7 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
res = LLVMBuildBitCast(builder, res, vec_type, "");
res = LLVMBuildSub(builder, res, bias_, "");
- res = LLVMBuildMul(builder, res, lp_build_const_scalar(dst_type, scale), "");
+ res = LLVMBuildMul(builder, res, lp_build_const_vec(dst_type, scale), "");
return res;
}
@@ -251,7 +251,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(dst_min == 0.0)
thres = bld.zero;
else
- thres = lp_build_const_scalar(src_type, dst_min);
+ thres = lp_build_const_vec(src_type, dst_min);
for(i = 0; i < num_tmps; ++i)
tmp[i] = lp_build_max(&bld, tmp[i], thres);
}
@@ -260,7 +260,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(dst_max == 1.0)
thres = bld.one;
else
- thres = lp_build_const_scalar(src_type, dst_max);
+ thres = lp_build_const_vec(src_type, dst_max);
for(i = 0; i < num_tmps; ++i)
tmp[i] = lp_build_min(&bld, tmp[i], thres);
}
@@ -288,7 +288,7 @@ lp_build_conv(LLVMBuilderRef builder,
LLVMTypeRef tmp_vec_type;
if (dst_scale != 1.0) {
- LLVMValueRef scale = lp_build_const_scalar(tmp_type, dst_scale);
+ LLVMValueRef scale = lp_build_const_vec(tmp_type, dst_scale);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
}
@@ -315,7 +315,7 @@ lp_build_conv(LLVMBuilderRef builder,
/* FIXME: compensate different offsets too */
if(src_shift > dst_shift) {
- LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, src_shift - dst_shift);
+ LLVMValueRef shift = lp_build_const_int_vec(tmp_type, src_shift - dst_shift);
for(i = 0; i < num_tmps; ++i)
if(src_type.sign)
tmp[i] = LLVMBuildAShr(builder, tmp[i], shift, "");
@@ -388,7 +388,7 @@ lp_build_conv(LLVMBuilderRef builder,
}
if (src_scale != 1.0) {
- LLVMValueRef scale = lp_build_const_scalar(tmp_type, 1.0/src_scale);
+ LLVMValueRef scale = lp_build_const_vec(tmp_type, 1.0/src_scale);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
}
@@ -400,7 +400,7 @@ lp_build_conv(LLVMBuilderRef builder,
/* FIXME: compensate different offsets too */
if(src_shift < dst_shift) {
- LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, dst_shift - src_shift);
+ LLVMValueRef shift = lp_build_const_int_vec(tmp_type, dst_shift - src_shift);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.h b/src/gallium/auxiliary/gallivm/lp_bld_conv.h
index 78e8155ff73..628831c3ada 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.h
@@ -37,7 +37,7 @@
#define LP_BLD_CONV_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
index 441ad94786f..7b010cbdb09 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
@@ -30,7 +30,7 @@
#define LP_BLD_DEBUG_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include "pipe/p_compiler.h"
#include "util/u_string.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c
index f08f8eb6d8b..4ce1a27a061 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_depth.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.c
@@ -52,7 +52,14 @@
* Z31 Z32 Z41 Z42 Z33 Z34 Z43 Z44 ...
* ... ... ... ... ... ... ... ... ...
*
- * FIXME: Code generate stencil test
+ *
+ * Stencil test:
+ * Two-sided stencil test is supported but probably not as efficient as
+ * it could be. Currently, we use if/then/else constructs to do the
+ * operations for front vs. back-facing polygons. We could probably do
+ * both the front and back arithmetic then use a Select() instruction to
+ * choose the result depending on polyon orientation. We'd have to
+ * measure performance both ways and see which is better.
*
* @author Jose Fonseca <[email protected]>
*/
@@ -61,11 +68,264 @@
#include "util/u_format.h"
#include "lp_bld_type.h"
+#include "lp_bld_arit.h"
#include "lp_bld_const.h"
#include "lp_bld_logic.h"
#include "lp_bld_flow.h"
#include "lp_bld_debug.h"
#include "lp_bld_depth.h"
+#include "lp_bld_swizzle.h"
+
+
+/** Used to select fields from pipe_stencil_state */
+enum stencil_op {
+ S_FAIL_OP,
+ Z_FAIL_OP,
+ Z_PASS_OP
+};
+
+
+
+/**
+ * Do the stencil test comparison (compare FB stencil values against ref value).
+ * This will be used twice when generating two-sided stencil code.
+ * \param stencil the front/back stencil state
+ * \param stencilRef the stencil reference value, replicated as a vector
+ * \param stencilVals vector of stencil values from framebuffer
+ * \return vector mask of pass/fail values (~0 or 0)
+ */
+static LLVMValueRef
+lp_build_stencil_test_single(struct lp_build_context *bld,
+ const struct pipe_stencil_state *stencil,
+ LLVMValueRef stencilRef,
+ LLVMValueRef stencilVals)
+{
+ const unsigned stencilMax = 255; /* XXX fix */
+ struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ assert(type.sign);
+
+ assert(stencil->enabled);
+
+ if (stencil->valuemask != stencilMax) {
+ /* compute stencilRef = stencilRef & valuemask */
+ LLVMValueRef valuemask = lp_build_const_int_vec(type, stencil->valuemask);
+ stencilRef = LLVMBuildAnd(bld->builder, stencilRef, valuemask, "");
+ /* compute stencilVals = stencilVals & valuemask */
+ stencilVals = LLVMBuildAnd(bld->builder, stencilVals, valuemask, "");
+ }
+
+ res = lp_build_cmp(bld, stencil->func, stencilVals, stencilRef);
+
+ return res;
+}
+
+
+/**
+ * Do the one or two-sided stencil test comparison.
+ * \sa lp_build_stencil_test_single
+ * \param face an integer indicating front (+) or back (-) facing polygon.
+ * If NULL, assume front-facing.
+ */
+static LLVMValueRef
+lp_build_stencil_test(struct lp_build_context *bld,
+ const struct pipe_stencil_state stencil[2],
+ LLVMValueRef stencilRefs[2],
+ LLVMValueRef stencilVals,
+ LLVMValueRef face)
+{
+ LLVMValueRef res;
+
+ assert(stencil[0].enabled);
+
+ if (stencil[1].enabled && face) {
+ /* do two-sided test */
+ struct lp_build_flow_context *flow_ctx;
+ struct lp_build_if_state if_ctx;
+ LLVMValueRef front_facing;
+ LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
+ LLVMValueRef result = bld->undef;
+
+ flow_ctx = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx);
+
+ lp_build_flow_scope_declare(flow_ctx, &result);
+
+ /* front_facing = face > 0.0 */
+ front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
+
+ lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
+ {
+ result = lp_build_stencil_test_single(bld, &stencil[0],
+ stencilRefs[0], stencilVals);
+ }
+ lp_build_else(&if_ctx);
+ {
+ result = lp_build_stencil_test_single(bld, &stencil[1],
+ stencilRefs[1], stencilVals);
+ }
+ lp_build_endif(&if_ctx);
+
+ lp_build_flow_scope_end(flow_ctx);
+ lp_build_flow_destroy(flow_ctx);
+
+ res = result;
+ }
+ else {
+ /* do single-side test */
+ res = lp_build_stencil_test_single(bld, &stencil[0],
+ stencilRefs[0], stencilVals);
+ }
+
+ return res;
+}
+
+
+/**
+ * Apply the stencil operator (add/sub/keep/etc) to the given vector
+ * of stencil values.
+ * \return new stencil values vector
+ */
+static LLVMValueRef
+lp_build_stencil_op_single(struct lp_build_context *bld,
+ const struct pipe_stencil_state *stencil,
+ enum stencil_op op,
+ LLVMValueRef stencilRef,
+ LLVMValueRef stencilVals,
+ LLVMValueRef mask)
+
+{
+ const unsigned stencilMax = 255; /* XXX fix */
+ struct lp_type type = bld->type;
+ LLVMValueRef res;
+ LLVMValueRef max = lp_build_const_int_vec(type, stencilMax);
+ unsigned stencil_op;
+
+ assert(type.sign);
+
+ switch (op) {
+ case S_FAIL_OP:
+ stencil_op = stencil->fail_op;
+ break;
+ case Z_FAIL_OP:
+ stencil_op = stencil->zfail_op;
+ break;
+ case Z_PASS_OP:
+ stencil_op = stencil->zpass_op;
+ break;
+ default:
+ assert(0 && "Invalid stencil_op mode");
+ stencil_op = PIPE_STENCIL_OP_KEEP;
+ }
+
+ switch (stencil_op) {
+ case PIPE_STENCIL_OP_KEEP:
+ res = stencilVals;
+ /* we can return early for this case */
+ return res;
+ case PIPE_STENCIL_OP_ZERO:
+ res = bld->zero;
+ break;
+ case PIPE_STENCIL_OP_REPLACE:
+ res = stencilRef;
+ break;
+ case PIPE_STENCIL_OP_INCR:
+ res = lp_build_add(bld, stencilVals, bld->one);
+ res = lp_build_min(bld, res, max);
+ break;
+ case PIPE_STENCIL_OP_DECR:
+ res = lp_build_sub(bld, stencilVals, bld->one);
+ res = lp_build_max(bld, res, bld->zero);
+ break;
+ case PIPE_STENCIL_OP_INCR_WRAP:
+ res = lp_build_add(bld, stencilVals, bld->one);
+ res = LLVMBuildAnd(bld->builder, res, max, "");
+ break;
+ case PIPE_STENCIL_OP_DECR_WRAP:
+ res = lp_build_sub(bld, stencilVals, bld->one);
+ res = LLVMBuildAnd(bld->builder, res, max, "");
+ break;
+ case PIPE_STENCIL_OP_INVERT:
+ res = LLVMBuildNot(bld->builder, stencilVals, "");
+ res = LLVMBuildAnd(bld->builder, res, max, "");
+ break;
+ default:
+ assert(0 && "bad stencil op mode");
+ res = NULL;
+ }
+
+ if (stencil->writemask != stencilMax) {
+ /* compute res = (res & mask) | (stencilVals & ~mask) */
+ LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask);
+ LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask");
+ LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1");
+ LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2");
+ res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2");
+ }
+
+ /* only the update the vector elements enabled by 'mask' */
+ res = lp_build_select(bld, mask, res, stencilVals);
+
+ return res;
+}
+
+
+/**
+ * Do the one or two-sided stencil test op/update.
+ */
+static LLVMValueRef
+lp_build_stencil_op(struct lp_build_context *bld,
+ const struct pipe_stencil_state stencil[2],
+ enum stencil_op op,
+ LLVMValueRef stencilRefs[2],
+ LLVMValueRef stencilVals,
+ LLVMValueRef mask,
+ LLVMValueRef face)
+
+{
+ assert(stencil[0].enabled);
+
+ if (stencil[1].enabled && face) {
+ /* do two-sided op */
+ struct lp_build_flow_context *flow_ctx;
+ struct lp_build_if_state if_ctx;
+ LLVMValueRef front_facing;
+ LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
+ LLVMValueRef result = bld->undef;
+
+ flow_ctx = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx);
+
+ lp_build_flow_scope_declare(flow_ctx, &result);
+
+ /* front_facing = face > 0.0 */
+ front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
+
+ lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
+ {
+ result = lp_build_stencil_op_single(bld, &stencil[0], op,
+ stencilRefs[0], stencilVals, mask);
+ }
+ lp_build_else(&if_ctx);
+ {
+ result = lp_build_stencil_op_single(bld, &stencil[1], op,
+ stencilRefs[1], stencilVals, mask);
+ }
+ lp_build_endif(&if_ctx);
+
+ lp_build_flow_scope_end(flow_ctx);
+ lp_build_flow_destroy(flow_ctx);
+
+ return result;
+ }
+ else {
+ /* do single-sided op */
+ return lp_build_stencil_op_single(bld, &stencil[0], op,
+ stencilRefs[0], stencilVals, mask);
+ }
+}
+
/**
@@ -109,105 +369,303 @@ lp_depth_type(const struct util_format_description *format_desc,
/**
- * Depth test.
+ * Compute bitmask and bit shift to apply to the incoming fragment Z values
+ * and the Z buffer values needed before doing the Z comparison.
+ *
+ * Note that we leave the Z bits in the position that we find them
+ * in the Z buffer (typically 0xffffff00 or 0x00ffffff). That lets us
+ * get by with fewer bit twiddling steps.
*/
-void
-lp_build_depth_test(LLVMBuilderRef builder,
- const struct pipe_depth_state *state,
- struct lp_type type,
- const struct util_format_description *format_desc,
- struct lp_build_mask_context *mask,
- LLVMValueRef src,
- LLVMValueRef dst_ptr)
+static boolean
+get_z_shift_and_mask(const struct util_format_description *format_desc,
+ unsigned *shift, unsigned *mask)
{
- struct lp_build_context bld;
+ const unsigned total_bits = format_desc->block.bits;
unsigned z_swizzle;
- LLVMValueRef dst;
- LLVMValueRef z_bitmask = NULL;
- LLVMValueRef test;
-
- if(!state->enabled)
- return;
-
+ int chan;
+ unsigned padding_left, padding_right;
+
assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
assert(format_desc->block.width == 1);
assert(format_desc->block.height == 1);
z_swizzle = format_desc->swizzle[0];
- if(z_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
- return;
- /* Sanity checking */
- assert(z_swizzle < 4);
- assert(format_desc->block.bits == type.width);
- if(type.floating) {
- assert(z_swizzle == 0);
- assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_FLOAT);
- assert(format_desc->channel[z_swizzle].size == format_desc->block.bits);
+ if (z_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
+ return FALSE;
+
+ padding_right = 0;
+ for (chan = 0; chan < z_swizzle; ++chan)
+ padding_right += format_desc->channel[chan].size;
+
+ padding_left =
+ total_bits - (padding_right + format_desc->channel[z_swizzle].size);
+
+ if (padding_left || padding_right) {
+ unsigned long long mask_left = (1ULL << (total_bits - padding_left)) - 1;
+ unsigned long long mask_right = (1ULL << (padding_right)) - 1;
+ *mask = mask_left ^ mask_right;
}
else {
- assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED);
- assert(format_desc->channel[z_swizzle].normalized);
- assert(!type.fixed);
- assert(!type.sign);
- assert(type.norm);
+ *mask = 0xffffffff;
+ }
+
+ *shift = padding_left;
+
+ return TRUE;
+}
+
+
+/**
+ * Compute bitmask and bit shift to apply to the framebuffer pixel values
+ * to put the stencil bits in the least significant position.
+ * (i.e. 0x000000ff)
+ */
+static boolean
+get_s_shift_and_mask(const struct util_format_description *format_desc,
+ unsigned *shift, unsigned *mask)
+{
+ unsigned s_swizzle;
+ int chan, sz;
+
+ s_swizzle = format_desc->swizzle[1];
+
+ if (s_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
+ return FALSE;
+
+ *shift = 0;
+ for (chan = 0; chan < s_swizzle; chan++)
+ *shift += format_desc->channel[chan].size;
+
+ sz = format_desc->channel[s_swizzle].size;
+ *mask = (1U << sz) - 1U;
+
+ return TRUE;
+}
+
+
+
+/**
+ * Generate code for performing depth and/or stencil tests.
+ * We operate on a vector of values (typically a 2x2 quad).
+ *
+ * \param depth the depth test state
+ * \param stencil the front/back stencil state
+ * \param type the data type of the fragment depth/stencil values
+ * \param format_desc description of the depth/stencil surface
+ * \param mask the alive/dead pixel mask for the quad (vector)
+ * \param stencil_refs the front/back stencil ref values (scalar)
+ * \param z_src the incoming depth/stencil values (a 2x2 quad)
+ * \param zs_dst_ptr pointer to depth/stencil values in framebuffer
+ * \param facing contains float value indicating front/back facing polygon
+ */
+void
+lp_build_depth_stencil_test(LLVMBuilderRef builder,
+ const struct pipe_depth_state *depth,
+ const struct pipe_stencil_state stencil[2],
+ struct lp_type type,
+ const struct util_format_description *format_desc,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef stencil_refs[2],
+ LLVMValueRef z_src,
+ LLVMValueRef zs_dst_ptr,
+ LLVMValueRef face)
+{
+ struct lp_build_context bld;
+ struct lp_build_context sbld;
+ struct lp_type s_type;
+ LLVMValueRef zs_dst, z_dst = NULL;
+ LLVMValueRef stencil_vals = NULL;
+ LLVMValueRef z_bitmask = NULL, stencil_shift = NULL;
+ LLVMValueRef z_pass = NULL, s_pass_mask = NULL;
+ LLVMValueRef orig_mask = mask->value;
+
+ /* Sanity checking */
+ {
+ const unsigned z_swizzle = format_desc->swizzle[0];
+ const unsigned s_swizzle = format_desc->swizzle[1];
+
+ assert(z_swizzle != UTIL_FORMAT_SWIZZLE_NONE ||
+ s_swizzle != UTIL_FORMAT_SWIZZLE_NONE);
+
+ assert(depth->enabled || stencil[0].enabled);
+
+ assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
+ assert(format_desc->block.width == 1);
+ assert(format_desc->block.height == 1);
+
+ if (stencil[0].enabled) {
+ assert(format_desc->format == PIPE_FORMAT_Z24S8_UNORM ||
+ format_desc->format == PIPE_FORMAT_S8Z24_UNORM);
+ }
+
+ assert(z_swizzle < 4);
+ assert(format_desc->block.bits == type.width);
+ if (type.floating) {
+ assert(z_swizzle == 0);
+ assert(format_desc->channel[z_swizzle].type ==
+ UTIL_FORMAT_TYPE_FLOAT);
+ assert(format_desc->channel[z_swizzle].size ==
+ format_desc->block.bits);
+ }
+ else {
+ assert(format_desc->channel[z_swizzle].type ==
+ UTIL_FORMAT_TYPE_UNSIGNED);
+ assert(format_desc->channel[z_swizzle].normalized);
+ assert(!type.fixed);
+ assert(!type.sign);
+ assert(type.norm);
+ }
}
- /* Setup build context */
+
+ /* Setup build context for Z vals */
lp_build_context_init(&bld, builder, type);
- dst = LLVMBuildLoad(builder, dst_ptr, "");
+ /* Setup build context for stencil vals */
+ s_type = lp_type_int_vec(type.width);
+ lp_build_context_init(&sbld, builder, s_type);
+
+ /* Load current z/stencil value from z/stencil buffer */
+ zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, "");
+
+ lp_build_name(zs_dst, "zsbufval");
- lp_build_name(dst, "zsbuf");
- /* Align the source depth bits with the destination's, and mask out any
- * stencil or padding bits from both */
- if(format_desc->channel[z_swizzle].size == format_desc->block.bits) {
- assert(z_swizzle == 0);
- /* nothing to do */
+ /* Compute and apply the Z/stencil bitmasks and shifts.
+ */
+ {
+ unsigned z_shift, z_mask;
+ unsigned s_shift, s_mask;
+
+ if (get_z_shift_and_mask(format_desc, &z_shift, &z_mask)) {
+ if (z_shift) {
+ LLVMValueRef shift = lp_build_const_int_vec(type, z_shift);
+ z_src = LLVMBuildLShr(builder, z_src, shift, "");
+ }
+
+ if (z_mask != 0xffffffff) {
+ LLVMValueRef mask = lp_build_const_int_vec(type, z_mask);
+ z_src = LLVMBuildAnd(builder, z_src, mask, "");
+ z_dst = LLVMBuildAnd(builder, zs_dst, mask, "");
+ z_bitmask = mask; /* used below */
+ }
+ else {
+ z_dst = zs_dst;
+ }
+
+ lp_build_name(z_dst, "zsbuf.z");
+ }
+
+ if (get_s_shift_and_mask(format_desc, &s_shift, &s_mask)) {
+ if (s_shift) {
+ LLVMValueRef shift = lp_build_const_int_vec(type, s_shift);
+ stencil_vals = LLVMBuildLShr(builder, zs_dst, shift, "");
+ stencil_shift = shift; /* used below */
+ }
+ else {
+ stencil_vals = zs_dst;
+ }
+
+ if (s_mask != 0xffffffff) {
+ LLVMValueRef mask = lp_build_const_int_vec(type, s_mask);
+ stencil_vals = LLVMBuildAnd(builder, stencil_vals, mask, "");
+ }
+
+ lp_build_name(stencil_vals, "stencil");
+ }
}
- else {
- unsigned padding_left;
- unsigned padding_right;
- unsigned chan;
-
- assert(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN);
- assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED);
- assert(format_desc->channel[z_swizzle].size <= format_desc->block.bits);
- assert(format_desc->channel[z_swizzle].normalized);
-
- padding_right = 0;
- for(chan = 0; chan < z_swizzle; ++chan)
- padding_right += format_desc->channel[chan].size;
- padding_left = format_desc->block.bits -
- (padding_right + format_desc->channel[z_swizzle].size);
-
- if(padding_left || padding_right) {
- const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1;
- const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1;
- z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right);
+
+
+ if (stencil[0].enabled) {
+ /* convert scalar stencil refs into vectors */
+ stencil_refs[0] = lp_build_broadcast_scalar(&bld, stencil_refs[0]);
+ stencil_refs[1] = lp_build_broadcast_scalar(&bld, stencil_refs[1]);
+
+ s_pass_mask = lp_build_stencil_test(&sbld, stencil,
+ stencil_refs, stencil_vals, face);
+
+ /* apply stencil-fail operator */
+ {
+ LLVMValueRef s_fail_mask = lp_build_andc(&bld, orig_mask, s_pass_mask);
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, S_FAIL_OP,
+ stencil_refs, stencil_vals,
+ s_fail_mask, face);
+ }
+ }
+
+ if (depth->enabled) {
+ /* compare src Z to dst Z, returning 'pass' mask */
+ z_pass = lp_build_cmp(&bld, depth->func, z_src, z_dst);
+
+ if (!stencil[0].enabled) {
+ /* We can potentially skip all remaining operations here, but only
+ * if stencil is disabled because we still need to update the stencil
+ * buffer values. Don't need to update Z buffer values.
+ */
+ lp_build_mask_update(mask, z_pass);
+ }
+
+ if (depth->writemask) {
+ if(z_bitmask)
+ z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, "");
+ else
+ z_bitmask = mask->value;
+
+ z_dst = lp_build_select(&bld, z_bitmask, z_src, z_dst);
}
- if(padding_left)
- src = LLVMBuildLShr(builder, src, lp_build_int_const_scalar(type, padding_left), "");
- if(padding_right)
- src = LLVMBuildAnd(builder, src, z_bitmask, "");
- if(padding_left || padding_right)
- dst = LLVMBuildAnd(builder, dst, z_bitmask, "");
+ if (stencil[0].enabled) {
+ /* update stencil buffer values according to z pass/fail result */
+ LLVMValueRef z_fail_mask, z_pass_mask;
+
+ /* apply Z-fail operator */
+ z_fail_mask = lp_build_andc(&bld, orig_mask, z_pass);
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_FAIL_OP,
+ stencil_refs, stencil_vals,
+ z_fail_mask, face);
+
+ /* apply Z-pass operator */
+ z_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, z_pass, "");
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP,
+ stencil_refs, stencil_vals,
+ z_pass_mask, face);
+ }
+ }
+ else {
+ /* No depth test: apply Z-pass operator to stencil buffer values which
+ * passed the stencil test.
+ */
+ s_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, s_pass_mask, "");
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP,
+ stencil_refs, stencil_vals,
+ s_pass_mask, face);
}
- lp_build_name(dst, "zsbuf.z");
+ /* The Z bits are already in the right place but we may need to shift the
+ * stencil bits before ORing Z with Stencil to make the final pixel value.
+ */
+ if (stencil_vals && stencil_shift)
+ stencil_vals = LLVMBuildShl(bld.builder, stencil_vals,
+ stencil_shift, "");
- test = lp_build_cmp(&bld, state->func, src, dst);
- lp_build_mask_update(mask, test);
+ /* Finally, merge/store the z/stencil values */
+ if ((depth->enabled && depth->writemask) ||
+ (stencil[0].enabled && stencil[0].writemask)) {
- if(state->writemask) {
- if(z_bitmask)
- z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, "");
+ if (z_dst && stencil_vals)
+ zs_dst = LLVMBuildOr(bld.builder, z_dst, stencil_vals, "");
+ else if (z_dst)
+ zs_dst = z_dst;
else
- z_bitmask = mask->value;
+ zs_dst = stencil_vals;
- dst = lp_build_select(&bld, z_bitmask, src, dst);
- LLVMBuildStore(builder, dst, dst_ptr);
+ LLVMBuildStore(builder, zs_dst, zs_dst_ptr);
}
+
+ if (s_pass_mask)
+ lp_build_mask_update(mask, s_pass_mask);
+
+ if (depth->enabled && stencil[0].enabled)
+ lp_build_mask_update(mask, z_pass);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.h b/src/gallium/auxiliary/gallivm/lp_bld_depth.h
index 8be80024ae8..27dd46b625d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_depth.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.h
@@ -36,7 +36,7 @@
#define LP_BLD_DEPTH_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct pipe_depth_state;
@@ -51,13 +51,16 @@ lp_depth_type(const struct util_format_description *format_desc,
void
-lp_build_depth_test(LLVMBuilderRef builder,
- const struct pipe_depth_state *state,
- struct lp_type type,
- const struct util_format_description *format_desc,
- struct lp_build_mask_context *mask,
- LLVMValueRef src,
- LLVMValueRef dst_ptr);
+lp_build_depth_stencil_test(LLVMBuilderRef builder,
+ const struct pipe_depth_state *depth,
+ const struct pipe_stencil_state stencil[2],
+ struct lp_type type,
+ const struct util_format_description *format_desc,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef stencil_refs[2],
+ LLVMValueRef zs_src,
+ LLVMValueRef zs_dst_ptr,
+ LLVMValueRef facing);
#endif /* !LP_BLD_DEPTH_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h
index e1588365491..c2b50e1b602 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h
@@ -35,7 +35,7 @@
#define LP_BLD_FLOW_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h
index 8972c0dc178..73ab6de3f21 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h
@@ -34,7 +34,7 @@
* Pixel format helpers.
*/
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include "pipe/p_format.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
index abb27e4c328..45ee4b12ced 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
@@ -114,10 +114,10 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
case UTIL_FORMAT_TYPE_UNSIGNED:
if(type.floating) {
if(start)
- input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), "");
+ input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(type, start), "");
if(stop < format_desc->block.bits) {
unsigned mask = ((unsigned long long)1 << width) - 1;
- input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), "");
+ input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(type, mask), "");
}
if(format_desc->channel[chan].normalized)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_interp.c b/src/gallium/auxiliary/gallivm/lp_bld_interp.c
index 2fc894017d8..09efb161217 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_interp.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.c
@@ -289,17 +289,17 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index)
/* top-right or bottom-right quad in block */
/* build x += xstep */
x = lp_build_add(&bld->base, x,
- lp_build_const_scalar(bld->base.type, xstep));
+ lp_build_const_vec(bld->base.type, xstep));
}
if (quad_index == 2) {
/* bottom-left quad in block */
/* build y += ystep */
y = lp_build_add(&bld->base, y,
- lp_build_const_scalar(bld->base.type, ystep));
+ lp_build_const_vec(bld->base.type, ystep));
/* build x -= xstep */
x = lp_build_sub(&bld->base, x,
- lp_build_const_scalar(bld->base.type, xstep));
+ lp_build_const_vec(bld->base.type, xstep));
}
lp_build_name(x, "pos.x");
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_interp.h b/src/gallium/auxiliary/gallivm/lp_bld_interp.h
index 177b5e943ee..a4937bbb048 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_interp.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.h
@@ -41,7 +41,7 @@
#define LP_BLD_INTERP_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include "tgsi/tgsi_exec.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_intr.h b/src/gallium/auxiliary/gallivm/lp_bld_intr.h
index 7d5506c7338..977f7673228 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_intr.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_intr.h
@@ -37,7 +37,7 @@
#define LP_BLD_INTR_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
/**
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
index f3df3dd1388..a3b69701162 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
@@ -193,7 +193,7 @@ lp_build_compare(LLVMBuilderRef builder,
if(table[func].gt &&
((type.width == 8 && type.sign) ||
(type.width != 8 && !type.sign))) {
- LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef msb = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
a = LLVMBuildXor(builder, a, msb, "");
b = LLVMBuildXor(builder, b, msb, "");
}
@@ -483,3 +483,13 @@ lp_build_alloca(struct lp_build_context *bld)
return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), "");
}
}
+
+
+/** Return (a & ~b) */
+LLVMValueRef
+lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
+{
+ b = LLVMBuildNot(bld->builder, b, "");
+ b = LLVMBuildAnd(bld->builder, a, b, "");
+ return b;
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
index b54ec13b701..00a8c750196 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
@@ -37,7 +37,7 @@
#define LP_BLD_LOGIC_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
@@ -79,4 +79,9 @@ lp_build_select_aos(struct lp_build_context *bld,
LLVMValueRef
lp_build_alloca(struct lp_build_context *bld);
+
+LLVMValueRef
+lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b);
+
+
#endif /* !LP_BLD_LOGIC_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
index 23398f41f99..2daa8a3b582 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
@@ -164,7 +164,7 @@ 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_int_const_scalar(src_type, src_type.width - 1), "");
+ msb = LLVMBuildAShr(builder, src, lp_build_const_int_vec(src_type, src_type.width - 1), "");
}
else
/* Most significant bits always zero */
@@ -361,7 +361,7 @@ 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_int_const_scalar(src_type, ((unsigned long long)1 << dst_bits) - 1);
+ 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);
lo = lp_build_min(&bld, lo, dst_max);
hi = lp_build_min(&bld, hi, dst_max);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.h b/src/gallium/auxiliary/gallivm/lp_bld_pack.h
index 346a17d5803..41adeed220c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.h
@@ -37,7 +37,7 @@
#define LP_BLD_PACK_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.c b/src/gallium/auxiliary/gallivm/lp_bld_printf.c
new file mode 100644
index 00000000000..78c9ec778b6
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.c
@@ -0,0 +1,113 @@
+/**************************************************************************
+ *
+ * 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 <stdio.h>
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "lp_bld_printf.h"
+
+
+static int
+lp_get_printf_arg_count(const char *fmt)
+{
+ int count =0;
+ const char *p = fmt;
+ int c;
+
+ while ((c = *p++)) {
+ if (c != '%')
+ continue;
+ switch (*p) {
+ case '\0':
+ continue;
+ case '%':
+ p++;
+ continue;
+ case '.':
+ if (p[1] == '*' && p[2] == 's') {
+ count += 2;
+ p += 3;
+ continue;
+ }
+ default:
+ count ++;
+ }
+ }
+ return count;
+}
+
+LLVMValueRef
+lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len)
+{
+ LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), len + 1), "");
+ LLVMSetGlobalConstant(string, TRUE);
+ LLVMSetLinkage(string, LLVMInternalLinkage);
+ LLVMSetInitializer(string, LLVMConstString(str, len + 1, TRUE));
+ return string;
+}
+
+
+/**
+ * lp_build_printf.
+ *
+ * Build printf call in LLVM IR. The output goes to stdout.
+ * The additional variable arguments need to have type
+ * LLVMValueRef.
+ */
+LLVMValueRef
+lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...)
+{
+ va_list arglist;
+ int i = 0;
+ int argcount = lp_get_printf_arg_count(fmt);
+ LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
+ LLVMValueRef params[50];
+ LLVMValueRef fmtarg = lp_build_const_string_variable(module, fmt, strlen(fmt) + 1);
+ LLVMValueRef int0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ LLVMValueRef index[2];
+ LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf");
+
+ assert(Elements(params) >= argcount + 1);
+
+ index[0] = index[1] = int0;
+
+ if (!func_printf) {
+ LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntType(32), NULL, 0, 1);
+ func_printf = LLVMAddFunction(module, "printf", printf_type);
+ }
+
+ params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, "");
+
+ va_start(arglist, fmt);
+ for (i = 1; i <= argcount; i++)
+ params[i] = va_arg(arglist, LLVMValueRef);
+ va_end(arglist);
+
+ return LLVMBuildCall(builder, func_printf, params, argcount + 1, "");
+}
+
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.h b/src/gallium/auxiliary/gallivm/lp_bld_printf.h
new file mode 100644
index 00000000000..83bd8f1d557
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.h
@@ -0,0 +1,39 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef LP_BLD_PRINTF_H
+#define LP_BLD_PRINTF_H
+
+
+#include "pipe/p_compiler.h"
+#include "lp_bld.h"
+
+LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len);
+LLVMValueRef lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...);
+
+#endif
+
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 2f74aa5e00a..bb76ad4c6bf 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -173,7 +173,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
LLVMValueRef x_stride;
LLVMValueRef offset;
- x_stride = lp_build_const_scalar(bld->type, format_desc->block.bits/8);
+ x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8);
if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
LLVMValueRef x_lo, x_hi;
@@ -195,9 +195,9 @@ lp_build_sample_offset(struct lp_build_context *bld,
y_hi = LLVMBuildLShr(bld->builder, y, bld->one, "");
x_stride_lo = x_stride;
- y_stride_lo = lp_build_const_scalar(bld->type, 2*format_desc->block.bits/8);
+ y_stride_lo = lp_build_const_vec(bld->type, 2*format_desc->block.bits/8);
- x_stride_hi = lp_build_const_scalar(bld->type, 4*format_desc->block.bits/8);
+ x_stride_hi = lp_build_const_vec(bld->type, 4*format_desc->block.bits/8);
y_stride_hi = LLVMBuildShl(bld->builder, y_stride, bld->one, "");
x_offset_lo = lp_build_mul(bld, x_lo, x_stride_lo);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 7f08bfaac1f..92f3c57435a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -36,7 +36,7 @@
#define LP_BLD_SAMPLE_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct pipe_texture;
struct pipe_sampler_state;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 9741dbb389c..995c016b9dd 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -292,7 +292,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
int chan;
for (chan = 0; chan < 4; chan++) {
LLVMValueRef border_chan =
- lp_build_const_scalar(bld->texel_type,
+ lp_build_const_vec(bld->texel_type,
bld->static_state->border_color[chan]);
texel[chan] = lp_build_select(&bld->texel_bld, use_border,
border_chan, texel[chan]);
@@ -457,8 +457,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;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0);
- LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5);
+ LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
+ LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
@@ -512,7 +512,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
else {
LLVMValueRef min, max;
/* clamp to [0.5, length - 0.5] */
- min = lp_build_const_scalar(coord_bld->type, 0.5F);
+ min = lp_build_const_vec(coord_bld->type, 0.5F);
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
}
@@ -533,7 +533,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
if (bld->static_state->normalized_coords) {
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
- lp_build_const_scalar(coord_bld->type, -0.5F),
+ lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = 1.0 - min */
max = lp_build_sub(coord_bld, coord_bld->one, min);
@@ -545,7 +545,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
}
else {
/* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_scalar(coord_bld->type, -0.5F);
+ min = lp_build_const_vec(coord_bld->type, -0.5F);
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
coord = lp_build_sub(coord_bld, coord, half);
@@ -620,7 +620,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
LLVMValueRef min, max;
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
- lp_build_const_scalar(coord_bld->type, -0.5F),
+ lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = 1.0 - min */
max = lp_build_sub(coord_bld, coord_bld->one, min);
@@ -665,7 +665,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;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0);
+ LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
@@ -708,7 +708,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
}
else {
/* clamp to [0.5, length - 0.5] */
- min = lp_build_const_scalar(coord_bld->type, 0.5F);
+ min = lp_build_const_vec(coord_bld->type, 0.5F);
max = lp_build_sub(coord_bld, length_f, min);
}
/* coord = clamp(coord, min, max) */
@@ -724,7 +724,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
if (bld->static_state->normalized_coords) {
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
- lp_build_const_scalar(coord_bld->type, -0.5F),
+ lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = length - min */
max = lp_build_sub(coord_bld, length_f, min);
@@ -733,7 +733,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
}
else {
/* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_scalar(coord_bld->type, -0.5F);
+ min = lp_build_const_vec(coord_bld->type, -0.5F);
max = lp_build_sub(coord_bld, length_f, min);
}
/* coord = clamp(coord, min, max) */
@@ -1226,7 +1226,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_scalar(coord_bld->type, -0.5);
+ LLVMValueRef negHalf = lp_build_const_vec(coord_bld->type, -0.5);
LLVMValueRef absCoord = lp_build_abs(coord_bld, coord);
LLVMValueRef ima = lp_build_mul(coord_bld, negHalf,
lp_build_rcp(coord_bld, absCoord));
@@ -1246,7 +1246,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_scalar(coord_bld->type, 0.5);
+ LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef res;
assert(negate_coord == +1 || negate_coord == -1);
@@ -1708,7 +1708,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
LLVMValueRef packed,
LLVMValueRef *rgba)
{
- LLVMValueRef mask = lp_build_int_const_scalar(dst_type, 0xff);
+ LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff);
unsigned chan;
/* Decode the input vector components */
@@ -1720,7 +1720,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
input = packed;
if(start)
- input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(dst_type, start), "");
+ input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(dst_type, start), "");
if(stop < 32)
input = LLVMBuildAnd(builder, input, mask, "");
@@ -1782,17 +1782,17 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
t = LLVMBuildFPToSI(builder, t, i32_vec_type, "");
/* subtract 0.5 (add -128) */
- i32_c128 = lp_build_int_const_scalar(i32.type, -128);
+ i32_c128 = lp_build_const_int_vec(i32.type, -128);
s = LLVMBuildAdd(builder, s, i32_c128, "");
t = LLVMBuildAdd(builder, t, i32_c128, "");
/* compute floor (shift right 8) */
- i32_c8 = lp_build_int_const_scalar(i32.type, 8);
+ i32_c8 = lp_build_const_int_vec(i32.type, 8);
s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
/* compute fractional part (AND with 0xff) */
- i32_c255 = lp_build_int_const_scalar(i32.type, 255);
+ i32_c255 = lp_build_const_int_vec(i32.type, 255);
s_fpart = LLVMBuildAnd(builder, s, i32_c255, "");
t_fpart = LLVMBuildAnd(builder, t, i32_c255, "");
@@ -1959,7 +1959,7 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
}
assert(res);
- res = lp_build_mul(texel_bld, res, lp_build_const_scalar(texel_bld->type, 0.25));
+ res = lp_build_mul(texel_bld, res, lp_build_const_vec(texel_bld->type, 0.25));
/* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
for(chan = 0; chan < 3; ++chan)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.h b/src/gallium/auxiliary/gallivm/lp_bld_struct.h
index 34478c10f51..147336edb4b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_struct.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.h
@@ -37,7 +37,7 @@
#define LP_BLD_STRUCT_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include <llvm-c/Target.h>
#include "util/u_debug.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
index 64e81f7b1fe..278c838eaca 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
@@ -144,9 +144,9 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
#endif
if(shift > 0)
- tmp = LLVMBuildLShr(bld->builder, a, lp_build_int_const_scalar(type4, shift*type.width), "");
+ tmp = LLVMBuildLShr(bld->builder, a, lp_build_const_int_vec(type4, shift*type.width), "");
if(shift < 0)
- tmp = LLVMBuildShl(bld->builder, a, lp_build_int_const_scalar(type4, -shift*type.width), "");
+ tmp = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type4, -shift*type.width), "");
assert(tmp);
if(tmp)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
index 57b5cc079f2..138ca620e63 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
@@ -37,7 +37,7 @@
#define LP_BLD_SWIZZLE_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index 0f2f8a65b10..63b938bfa98 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -35,7 +35,7 @@
#ifndef LP_BLD_TGSI_H
#define LP_BLD_TGSI_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct tgsi_token;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 5ec59d636cb..8901e656aed 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -475,7 +475,7 @@ emit_store(
break;
case TGSI_SAT_MINUS_PLUS_ONE:
- value = lp_build_max(&bld->base, value, lp_build_const_scalar(bld->base.type, -1.0));
+ value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
value = lp_build_min(&bld->base, value, bld->base.one);
break;
@@ -651,32 +651,40 @@ emit_declaration(
unsigned first = decl->Range.First;
unsigned last = decl->Range.Last;
unsigned idx, i;
+ LLVMBasicBlockRef current_block =
+ LLVMGetInsertBlock(bld->base.builder);
+ LLVMBasicBlockRef first_block =
+ LLVMGetEntryBasicBlock(
+ LLVMGetBasicBlockParent(current_block));
+ LLVMValueRef first_inst =
+ LLVMGetFirstInstruction(first_block);
+
+ /* we want alloca's to be the first instruction
+ * in the function so we need to rewind the builder
+ * to the very beginning */
+ LLVMPositionBuilderBefore(bld->base.builder,
+ first_inst);
for (idx = first; idx <= last; ++idx) {
- boolean ok;
-
switch (decl->Declaration.File) {
case TGSI_FILE_TEMPORARY:
for (i = 0; i < NUM_CHANNELS; i++)
bld->temps[idx][i] = lp_build_alloca(&bld->base);
- ok = TRUE;
break;
case TGSI_FILE_OUTPUT:
for (i = 0; i < NUM_CHANNELS; i++)
bld->outputs[idx][i] = lp_build_alloca(&bld->base);
- ok = TRUE;
break;
default:
/* don't need to declare other vars */
- ok = TRUE;
+ break;
}
-
- if (!ok)
- return FALSE;
}
+ LLVMPositionBuilderAtEnd(bld->base.builder,
+ current_block);
return TRUE;
}
@@ -996,7 +1004,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_scalar(bld->base.type, 0.5);
+ tmp1 = lp_build_const_vec(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 );
}
@@ -1713,7 +1721,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
assert(num_immediates < LP_MAX_IMMEDIATES);
for( i = 0; i < size; ++i )
bld.immediates[num_immediates][i] =
- lp_build_const_scalar(type, parse.FullToken.FullImmediate.u[i].Float);
+ lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
for( i = size; i < 4; ++i )
bld.immediates[num_immediates][i] = bld.base.undef;
num_immediates++;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h
index 5b351476ac2..cd59d2faa66 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -37,9 +37,9 @@
#define LP_BLD_TYPE_H
-#include "os/os_llvm.h"
+#include "pipe/p_compiler.h"
+#include "gallivm/lp_bld.h"
-#include <pipe/p_compiler.h>
/**
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
index 86f9266c95f..0f2ae05daed 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
@@ -227,6 +227,8 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf,
pb_size size,
const struct pb_desc *desc)
{
+ void *map;
+
if(buf->base.base.size < size)
return FALSE;
@@ -239,6 +241,13 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf,
if(!pb_check_usage(desc->usage, buf->base.base.usage))
return FALSE;
+
+ map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_DONTBLOCK);
+ if (!map) {
+ return FALSE;
+ }
+
+ pb_unmap(buf->buffer);
return TRUE;
}
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index f675427d987..7595214bdf2 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -87,7 +87,7 @@ void x86_print_reg( struct x86_reg reg )
foo++; \
if (*foo) \
foo++; \
- debug_printf( "\n% 4x% 15s ", p->csr - p->store, foo ); \
+ debug_printf( "\n%4x %14s ", p->csr - p->store, foo ); \
} while (0)
#define DUMP_I( I ) do { \
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
index f7612d416a0..319b836ffb1 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
@@ -102,7 +102,7 @@ enum sse_cc {
#define cc_Z cc_E
#define cc_NZ cc_NE
-/* Begin/end/retreive function creation:
+/* Begin/end/retrieve function creation:
*/
@@ -311,8 +311,8 @@ void x87_fucom( struct x86_function *p, struct x86_reg arg );
-/* Retreive a reference to one of the function arguments, taking into
- * account any push/pop activity. Note - doesn't track explict
+/* Retrieve a reference to one of the function arguments, taking into
+ * account any push/pop activity. Note - doesn't track explicit
* manipulation of ESP by other instructions.
*/
struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index f918151daaa..0b468a9184e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -55,7 +55,7 @@ static boolean is_digit_alpha_underscore( const char *cur )
return is_digit( cur ) || is_alpha_underscore( cur );
}
-static boolean uprcase( char c )
+static char uprcase( char c )
{
if (c >= 'a' && c <= 'z')
return c += 'A' - 'a';
@@ -76,7 +76,7 @@ streq_nocase_uprcase(const char *str1,
str1++;
str2++;
}
- return TRUE;
+ return *str1 == 0 && *str2 == 0;
}
static boolean str_match_no_case( const char **pcur, const char *str )
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 4d0737ccd3d..cd95f85b63b 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -45,6 +45,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
#include "util/u_surface.h"
#include "util/u_rect.h"
@@ -280,6 +281,7 @@ regions_overlap(int srcX0, int srcY0,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -290,7 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_texture *tex = NULL;
+ struct pipe_sampler_view *sampler_view = NULL;
struct pipe_framebuffer_state fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
@@ -345,6 +347,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
src->texture->last_level != 0)
{
struct pipe_texture texTemp;
+ struct pipe_texture *tex;
+ struct pipe_sampler_view sv_templ;
struct pipe_surface *texSurf;
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
@@ -376,6 +380,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
if (!tex)
return;
+ u_sampler_view_default_template(&sv_templ, tex, tex->format);
+
+ sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ);
+ if (!sampler_view) {
+ pipe_texture_reference(&tex, NULL);
+ return;
+ }
+
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -399,22 +411,25 @@ util_blit_pixels_writemask(struct blit_state *ctx,
s1 = 1.0f;
t0 = 0.0f;
t1 = 1.0f;
+
+ pipe_texture_reference(&tex, NULL);
}
else {
- pipe_texture_reference(&tex, src->texture);
- s0 = srcX0 / (float)tex->width0;
- s1 = srcX1 / (float)tex->width0;
- t0 = srcY0 / (float)tex->height0;
- t1 = srcY1 / (float)tex->height0;
+ pipe_sampler_view_reference(&sampler_view, src_sampler_view);
+ s0 = srcX0 / (float)src->texture->width0;
+ s1 = srcX1 / (float)src->texture->width0;
+ t0 = srcY0 / (float)src->texture->height0;
+ t1 = srcY1 / (float)src->texture->height0;
}
+
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(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);
@@ -447,7 +462,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_set_viewport(ctx->cso, &ctx->viewport);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view);
if (ctx->fs[writemask] == NULL)
ctx->fs[writemask] =
@@ -486,7 +501,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(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);
@@ -494,13 +509,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
- pipe_texture_reference(&tex, NULL);
+ pipe_sampler_view_reference(&sampler_view, NULL);
}
void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -508,7 +524,7 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter )
{
- util_blit_pixels_writemask( ctx, src,
+ util_blit_pixels_writemask( ctx, src, src_sampler_view,
srcX0, srcY0,
srcX1, srcY1,
dst,
@@ -539,21 +555,23 @@ void util_blit_flush( struct blit_state *ctx )
*/
void
util_blit_pixels_tex(struct blit_state *ctx,
- struct pipe_texture *tex,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, uint filter)
+ struct pipe_sampler_view *src_sampler_view,
+ int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ struct pipe_surface *dst,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1,
+ float z, uint filter)
{
struct pipe_framebuffer_state fb;
float s0, t0, s1, t1;
unsigned offset;
+ struct pipe_texture *tex = src_sampler_view->texture;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
+ assert(tex);
assert(tex->width0 != 0);
assert(tex->height0 != 0);
@@ -572,7 +590,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(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);
@@ -604,7 +622,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_viewport(ctx->cso, &ctx->viewport);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
@@ -638,7 +656,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(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);
diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
index a102021529e..1ebe65b4558 100644
--- a/src/gallium/auxiliary/util/u_blit.h
+++ b/src/gallium/auxiliary/util/u_blit.h
@@ -53,6 +53,7 @@ util_destroy_blit(struct blit_state *ctx);
extern void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -63,6 +64,7 @@ util_blit_pixels(struct blit_state *ctx,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -73,7 +75,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
extern void
util_blit_pixels_tex(struct blit_state *ctx,
- struct pipe_texture *tex,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 36d582491f3..1692987e8e3 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -45,6 +45,7 @@
#include "util/u_draw_quad.h"
#include "util/u_pack_color.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
#include "util/u_texture.h"
@@ -96,6 +97,8 @@ struct blitter_context_priv
/* Rasterizer state. */
void *rs_state;
+ struct pipe_sampler_view *sampler_view;
+
/* Viewport state. */
struct pipe_viewport_state viewport;
@@ -127,7 +130,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->blitter.saved_vs = INVALID_PTR;
ctx->blitter.saved_velem_state = INVALID_PTR;
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
- ctx->blitter.saved_num_textures = ~0;
+ ctx->blitter.saved_num_sampler_views = ~0;
ctx->blitter.saved_num_sampler_states = ~0;
/* blend state objects */
@@ -252,6 +255,10 @@ void util_blitter_destroy(struct blitter_context *blitter)
if (ctx->sampler_state[i])
pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
+ if (ctx->sampler_view) {
+ pipe_sampler_view_reference(&ctx->sampler_view, NULL);
+ }
+
pipe_buffer_reference(&ctx->vbuf, NULL);
FREE(ctx);
}
@@ -305,11 +312,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
ctx->blitter.saved_num_sampler_states = ~0;
}
- if (ctx->blitter.saved_num_textures != ~0) {
- pipe->set_fragment_sampler_textures(pipe,
- ctx->blitter.saved_num_textures,
- ctx->blitter.saved_textures);
- ctx->blitter.saved_num_textures = ~0;
+ if (ctx->blitter.saved_num_sampler_views != ~0) {
+ pipe->set_fragment_sampler_views(pipe,
+ ctx->blitter.saved_num_sampler_views,
+ ctx->blitter.saved_sampler_views);
+ ctx->blitter.saved_num_sampler_views = ~0;
}
}
@@ -621,9 +628,10 @@ static void util_blitter_do_copy(struct blitter_context *blitter,
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_framebuffer_state fb_state;
+ struct pipe_sampler_view viewTempl, *view;
assert(blitter->saved_fb_state.nr_cbufs != ~0);
- assert(blitter->saved_num_textures != ~0);
+ assert(blitter->saved_num_sampler_views != ~0);
assert(blitter->saved_num_sampler_states != ~0);
assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES);
@@ -651,12 +659,24 @@ static void util_blitter_do_copy(struct blitter_context *blitter,
fb_state.zsbuf = 0;
}
+ u_sampler_view_default_template(&viewTempl,
+ src->texture,
+ src->texture->format);
+ view = pipe->create_sampler_view(pipe,
+ src->texture,
+ &viewTempl);
+
+ if (ctx->sampler_view) {
+ pipe_sampler_view_reference(&ctx->sampler_view, NULL);
+ }
+ ctx->sampler_view = view;
+
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs_tex);
pipe->bind_fragment_sampler_states(pipe, 1,
blitter_get_sampler_state(ctx, src->level));
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
- pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
+ pipe->set_fragment_sampler_views(pipe, 1, &view);
pipe->set_framebuffer_state(pipe, &fb_state);
/* set texture coordinates */
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index ecafdabafae..2ad7201a29d 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -53,10 +53,10 @@ struct blitter_context
struct pipe_clip_state saved_clip;
int saved_num_sampler_states;
- void *saved_sampler_states[32];
+ void *saved_sampler_states[PIPE_MAX_SAMPLERS];
- int saved_num_textures;
- struct pipe_texture *saved_textures[32]; /* is 32 enough? */
+ int saved_num_sampler_views;
+ struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
};
/**
@@ -242,17 +242,17 @@ void util_blitter_save_fragment_sampler_states(
num_sampler_states * sizeof(void *));
}
-static INLINE
-void util_blitter_save_fragment_sampler_textures(
- struct blitter_context *blitter,
- int num_textures,
- struct pipe_texture **textures)
+static INLINE void
+util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
+ int num_views,
+ struct pipe_sampler_view **views)
{
- assert(num_textures <= Elements(blitter->saved_textures));
+ assert(num_views <= Elements(blitter->saved_sampler_views));
- blitter->saved_num_textures = num_textures;
- memcpy(blitter->saved_textures, textures,
- num_textures * sizeof(struct pipe_texture *));
+ blitter->saved_num_sampler_views = num_views;
+ memcpy(blitter->saved_sampler_views,
+ views,
+ num_views * sizeof(struct pipe_sampler_view *));
}
#ifdef __cplusplus
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 96a0fa65507..d819bbbde1c 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -47,9 +47,9 @@
# - color space: rgb, yub, sz
#
# See also:
-# - http://msdn.microsoft.com/en-us/library/ee416489.aspx (D3D9)
-# - http://msdn.microsoft.com/en-us/library/ee415668.aspx (D3D9 -> D3D10)
-# - http://msdn.microsoft.com/en-us/library/ee418116.aspx (D3D10)
+# - http://msdn.microsoft.com/en-us/library/bb172558.aspx (D3D9)
+# - http://msdn.microsoft.com/en-us/library/bb205073.aspx#mapping_texture_formats (D3D9 -> D3D10)
+# - http://msdn.microsoft.com/en-us/library/bb173059.aspx (D3D10)
#
# Note that GL doesn't really specify the layout of internal formats. See
# OpenGL 2.1 specification, Table 3.16, on the "Correspondence of sized
@@ -63,6 +63,7 @@ PIPE_FORMAT_A8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, r
PIPE_FORMAT_X8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb
PIPE_FORMAT_A8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb
PIPE_FORMAT_X8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzy1, rgb
+PIPE_FORMAT_B5G5R5X1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyx1, rgb
PIPE_FORMAT_B5G5R5A1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
PIPE_FORMAT_B4G4R4A4_UNORM , plain, 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb
PIPE_FORMAT_B5G6R5_UNORM , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb
@@ -109,14 +110,18 @@ PIPE_FORMAT_UYVY , subsampled, 2, 1, x32 , , , , xyz
PIPE_FORMAT_YUYV , subsampled, 2, 1, x32 , , , , xyz1, yuv
# Compressed formats
-PIPE_FORMAT_DXT1_RGB , compressed, 4, 4, x64 , , , , xyz1, rgb
-PIPE_FORMAT_DXT1_RGBA , compressed, 4, 4, x64 , , , , xyzw, rgb
-PIPE_FORMAT_DXT3_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT5_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT1_SRGB , compressed, 4, 4, x64 , , , , xyz1, srgb
-PIPE_FORMAT_DXT1_SRGBA , compressed, 4, 4, x64 , , , , xyzw, srgb
-PIPE_FORMAT_DXT3_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb
-PIPE_FORMAT_DXT5_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb
+# - http://en.wikipedia.org/wiki/S3_Texture_Compression
+# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt
+# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt
+# - http://msdn.microsoft.com/en-us/library/bb694531.aspx
+PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb
+PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb
+PIPE_FORMAT_DXT3_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb
+PIPE_FORMAT_DXT5_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb
+PIPE_FORMAT_DXT1_SRGB , s3tc, 4, 4, x64 , , , , xyz1, srgb
+PIPE_FORMAT_DXT1_SRGBA , s3tc, 4, 4, x64 , , , , xyzw, srgb
+PIPE_FORMAT_DXT3_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb
+PIPE_FORMAT_DXT5_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb
# Straightforward D3D10-like formats (also used for
# vertex buffer element description)
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index c08fdcafcc8..98d4b98ebb5 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -56,15 +56,23 @@ enum util_format_layout {
*
* This is for formats like YV12 where there is less than one sample per
* pixel.
- *
- * XXX: This could actually b
*/
UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
/**
- * An unspecified compression algorithm.
+ * S3 Texture Compression formats.
+ */
+ UTIL_FORMAT_LAYOUT_S3TC = 4,
+
+ /**
+ * Red-Green Texture Compression formats.
+ */
+ UTIL_FORMAT_LAYOUT_RGTC = 5,
+
+ /**
+ * Everything else that doesn't fit in any of the above layouts.
*/
- UTIL_FORMAT_LAYOUT_COMPRESSED = 4
+ UTIL_FORMAT_LAYOUT_OTHER = 6
};
@@ -210,7 +218,7 @@ util_format_name(enum pipe_format format)
}
static INLINE boolean
-util_format_is_compressed(enum pipe_format format)
+util_format_is_s3tc(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
@@ -219,7 +227,7 @@ util_format_is_compressed(enum pipe_format format)
return FALSE;
}
- return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE;
+ return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
}
static INLINE boolean
diff --git a/src/gallium/auxiliary/util/u_format_tests.c b/src/gallium/auxiliary/util/u_format_tests.c
index 182a4740448..9d6debcd8c7 100644
--- a/src/gallium/auxiliary/util/u_format_tests.c
+++ b/src/gallium/auxiliary/util/u_format_tests.c
@@ -120,6 +120,13 @@ util_format_test_cases[] =
* 16-bit rendertarget formats
*/
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x7c00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x8000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}},
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}},
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 5c51b53d7bd..509d38754f5 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -938,6 +938,7 @@ format_to_type_comps(enum pipe_format pformat,
*datatype = DTYPE_UBYTE;
*comps = 4;
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
case PIPE_FORMAT_B5G5R5A1_UNORM:
*datatype = DTYPE_USHORT_1_5_5_5_REV;
*comps = 4;
@@ -1460,7 +1461,7 @@ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
* Generate mipmap images. It's assumed all needed texture memory is
* already allocated.
*
- * \param pt the texture to generate mipmap levels for
+ * \param psv the sampler view to the texture to generate mipmap levels for
* \param face which cube face to generate mipmaps for (0 for non-cube maps)
* \param baseLevel the first mipmap level to use as a src
* \param lastLevel the last mipmap level to generate
@@ -1469,12 +1470,13 @@ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
*/
void
util_gen_mipmap(struct gen_mipmap_state *ctx,
- struct pipe_texture *pt,
+ struct pipe_sampler_view *psv,
uint face, uint baseLevel, uint lastLevel, uint filter)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
+ struct pipe_texture *pt = psv->texture;
void *fs = (pt->target == PIPE_TEXTURE_CUBE) ? ctx->fsCube : ctx->fs2d;
uint dstLevel;
uint zslice = 0;
@@ -1492,7 +1494,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
filter == PIPE_TEX_FILTER_NEAREST);
/* check if we can render in the texture's format */
- if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
+ if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
@@ -1503,7 +1505,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(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);
@@ -1572,7 +1574,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_single_sampler(ctx->cso, 0, &ctx->sampler);
cso_single_sampler_done(ctx->cso);
- cso_set_sampler_textures(ctx->cso, 1, &pt);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &psv);
/* quad coords in clip coords */
offset = set_vertex_data(ctx,
@@ -1597,7 +1599,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(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);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h
index 54608f9466d..35ac9daeaa2 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.h
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.h
@@ -59,7 +59,7 @@ util_gen_mipmap_flush( struct gen_mipmap_state *ctx );
extern void
util_gen_mipmap(struct gen_mipmap_state *ctx,
- struct pipe_texture *pt,
+ struct pipe_sampler_view *psv,
uint face, uint baseLevel, uint lastLevel, uint filter);
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index e7255e3baa8..e22ab188e11 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -120,6 +120,16 @@ pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex)
*ptr = tex;
}
+static INLINE void
+pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
+{
+ struct pipe_sampler_view *old_view = *ptr;
+
+ if (pipe_reference(&(*ptr)->reference, &view->reference))
+ old_view->context->sampler_view_destroy(old_view->context, old_view);
+ *ptr = view;
+}
+
/*
* Convenience wrappers for screen buffer functions.
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index 50f1b1670b6..c5fd7a6783e 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -92,6 +92,11 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ {
+ uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
+ }
+ return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
@@ -216,6 +221,15 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc,
*a = (ubyte) 0xff;
}
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ {
+ ushort p = uc->us;
+ *r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7));
+ *g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7));
+ *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7));
+ *a = (ubyte) 0xff;
+ }
+ return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
ushort p = uc->us;
@@ -361,6 +375,11 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ {
+ uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
+ }
+ return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
diff --git a/src/gallium/auxiliary/util/u_sampler.c b/src/gallium/auxiliary/util/u_sampler.c
new file mode 100644
index 00000000000..4d8f861ce49
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_sampler.c
@@ -0,0 +1,100 @@
+/**************************************************************************
+ *
+ * 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 "u_format.h"
+#include "u_sampler.h"
+
+
+static void
+default_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format,
+ unsigned expand_green_blue)
+{
+ /* XXX: Check if format is compatible with texture->format.
+ */
+
+ view->format = format;
+ view->first_level = 0;
+ view->last_level = texture->last_level;
+ view->swizzle_r = PIPE_SWIZZLE_RED;
+ view->swizzle_g = PIPE_SWIZZLE_GREEN;
+ view->swizzle_b = PIPE_SWIZZLE_BLUE;
+ view->swizzle_a = PIPE_SWIZZLE_ALPHA;
+
+ /* Override default green and blue component expansion to the requested
+ * one.
+ *
+ * Gallium expands nonexistent components to (0,0,0,1), DX9 expands
+ * to (1,1,1,1). Since alpha is always expanded to 1, and red is
+ * always present, we only really care about green and blue
+ * components.
+ *
+ * To make it look less hackish, one would have to add
+ * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion
+ * and then override without exceptions or favoring one component
+ * over another.
+ */
+ if (format != PIPE_FORMAT_A8_UNORM) {
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(desc);
+ if (desc) {
+ if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) {
+ view->swizzle_g = expand_green_blue;
+ }
+ if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) {
+ view->swizzle_b = expand_green_blue;
+ }
+ }
+ }
+}
+
+void
+u_sampler_view_default_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format)
+{
+ /* Expand to (0, 0, 0, 1) */
+ default_template(view,
+ texture,
+ format,
+ PIPE_SWIZZLE_ZERO);
+}
+
+void
+u_sampler_view_default_dx9_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format)
+{
+ /* Expand to (1, 1, 1, 1) */
+ default_template(view,
+ texture,
+ format,
+ PIPE_SWIZZLE_ONE);
+}
diff --git a/src/gallium/auxiliary/util/u_sampler.h b/src/gallium/auxiliary/util/u_sampler.h
new file mode 100644
index 00000000000..bdd061c851c
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_sampler.h
@@ -0,0 +1,57 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+
+#ifndef U_SAMPLER_H
+#define U_SAMPLER_H
+
+
+#include "pipe/p_defines.h"
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void
+u_sampler_view_default_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format);
+
+void
+u_sampler_view_default_dx9_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format);
+
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+#endif /* U_SAMPLER_H */
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index e445895efc5..09b2382733d 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -295,6 +295,55 @@ r8g8b8a8_put_tile_rgba(unsigned *dst,
}
+/*** PIPE_FORMAT_B5G5R5X1_UNORM ***/
+
+static void
+x1r5g5b5_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ const ushort pixel = *src++;
+ pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
+ pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
+ pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
+ pRow[3] = 1.0f;
+ }
+ p += dst_stride;
+ }
+}
+
+
+static void
+x1r5g5b5_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const float *p,
+ unsigned src_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ unsigned r, g, b;
+ r = float_to_ubyte(pRow[0]);
+ g = float_to_ubyte(pRow[1]);
+ b = float_to_ubyte(pRow[2]);
+ r = r >> 3; /* 5 bits */
+ g = g >> 3; /* 5 bits */
+ b = b >> 3; /* 5 bits */
+ *dst++ = (1 << 15) | (r << 10) | (g << 5) | b;
+ }
+ p += src_stride;
+ }
+}
+
+
/*** PIPE_FORMAT_B5G5R5A1_UNORM ***/
static void
@@ -1174,6 +1223,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_A8B8G8R8_UNORM:
r8g8b8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ x1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
+ break;
case PIPE_FORMAT_B5G5R5A1_UNORM:
a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
@@ -1275,6 +1327,69 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
void
+pipe_get_tile_swizzle(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x,
+ uint y,
+ uint w,
+ uint h,
+ uint swizzle_r,
+ uint swizzle_g,
+ uint swizzle_b,
+ uint swizzle_a,
+ enum pipe_format format,
+ float *p)
+{
+ unsigned dst_stride = w * 4;
+ void *packed;
+ uint i;
+ float rgba01[6];
+
+ if (pipe_clip_tile(x, y, &w, &h, pt)) {
+ return;
+ }
+
+ packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
+ if (!packed) {
+ return;
+ }
+
+ if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
+ assert((x & 1) == 0);
+ }
+
+ pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
+
+ pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
+
+ FREE(packed);
+
+ if (swizzle_r == PIPE_SWIZZLE_RED &&
+ swizzle_g == PIPE_SWIZZLE_GREEN &&
+ swizzle_b == PIPE_SWIZZLE_BLUE &&
+ swizzle_a == PIPE_SWIZZLE_ALPHA) {
+ /* no-op, skip */
+ return;
+ }
+
+ rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
+ rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
+
+ for (i = 0; i < w * h; i++) {
+ rgba01[PIPE_SWIZZLE_RED] = p[0];
+ rgba01[PIPE_SWIZZLE_GREEN] = p[1];
+ rgba01[PIPE_SWIZZLE_BLUE] = p[2];
+ rgba01[PIPE_SWIZZLE_ALPHA] = p[3];
+
+ *p++ = rgba01[swizzle_r];
+ *p++ = rgba01[swizzle_g];
+ *p++ = rgba01[swizzle_b];
+ *p++ = rgba01[swizzle_a];
+ }
+}
+
+
+void
pipe_put_tile_rgba(struct pipe_context *pipe,
struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
@@ -1305,6 +1420,9 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
case PIPE_FORMAT_A8B8G8R8_UNORM:
r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
break;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ x1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
+ break;
case PIPE_FORMAT_B5G5R5A1_UNORM:
a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h
index 8329087cfa6..1d8ce7d8cbc 100644
--- a/src/gallium/auxiliary/util/u_tile.h
+++ b/src/gallium/auxiliary/util/u_tile.h
@@ -75,6 +75,20 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
float *p);
void
+pipe_get_tile_swizzle(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x,
+ uint y,
+ uint w,
+ uint h,
+ uint swizzle_r,
+ uint swizzle_g,
+ uint swizzle_b,
+ uint swizzle_a,
+ enum pipe_format format,
+ float *p);
+
+void
pipe_put_tile_rgba(struct pipe_context *pipe,
struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt
new file mode 100644
index 00000000000..0baf2682871
--- /dev/null
+++ b/src/gallium/docs/d3d11ddi.txt
@@ -0,0 +1,492 @@
+This document compares the D3D10/D3D11 device driver interface with Gallium.
+It is written from the perspective of a developer implementing a D3D10/D3D11 driver as a Gallium state tracker.
+
+Note that naming and other cosmetic differences are not noted, since they don't really matter and would severely clutter the document.
+Gallium/OpenGL terminology is used in preference to D3D terminology.
+
+NOTE: this document tries to be complete but most likely isn't fully complete and also not fully correct: please submit patches if you spot anything incorrect
+
+Also note that this is specifically for the DirectX 10/11 Windows Vista/7 DDI interfaces.
+DirectX 9 has both user-mode (for Vista) and kernel mode (pre-Vista) interfaces, but they are significantly different from Gallium due to the presence of a lot of fixed function functionality.
+
+The user-visible DirectX 10/11 interfaces are distinct from the kernel DDI, but they match very closely.
+
+* Accessing Microsoft documentation
+
+See http://msdn.microsoft.com/en-us/library/dd445501.aspx ("D3D11DDI_DEVICEFUNCS") for D3D documentation.
+
+Also see http://download.microsoft.com/download/f/2/d/f2d5ee2c-b7ba-4cd0-9686-b6508b5479a1/direct3d10_web.pdf ("The Direct3D 10 System" by David Blythe) for an introduction to Direct3D 10 and the rationale for its design.
+
+The Windows Driver Kit contains the actual headers, as well as shader bytecode documentation.
+
+To get the headers from Linux, run the following, in a dedicated directory:
+wget http://download.microsoft.com/download/4/A/2/4A25C7D5-EFBE-4182-B6A9-AE6850409A78/GRMWDK_EN_7600_1.ISO
+sudo mount -o loop GRMWDK_EN_7600_1.ISO /mnt/tmp
+cabextract -x /mnt/tmp/wdk/headers_cab001.cab
+rename 's/^_(.*)_[0-9]*$/$1/' *
+sudo umount /mnt/tmp
+
+d3d10umddi.h contains the DDI interface analyzed in this document: note that it is much easier to read this online on MSDN.
+d3d{10,11}TokenizedProgramFormat.hpp contains the shader bytecode definitions: this is not available on MSDN.
+d3d9types.h contains DX9 shader bytecode, and DX9 types
+d3dumddi.h contains the DirectX 9 DDI interface
+
+* Glossary
+
+BC1: DXT1
+BC2: DXT3
+BC3: DXT5
+BC5: RGTC
+BC6H: BPTC float
+BC7: BPTC
+CS = compute shader: OpenCL-like shader
+DS = domain shader: tessellation evaluation shader
+HS = hull shader: tessellation control shader
+IA = input assembler: primitive assembly
+Input layout: vertex elements
+OM = output merger: blender
+PS = pixel shader: fragment shader
+Primitive topology: primitive type
+Resource: buffer or texture
+Shader resource (view): sampler view
+SO = stream out: transform feedback
+Unordered access view: view supporting random read/write access (usually from compute shaders)
+
+* Legend
+
+-: features D3D11 has and Gallium lacks
++: features Gallium has and D3D11 lacks
+!: differences between D3D11 and Gallium
+*: possible improvements to Gallium
+>: references to comparisons of special enumerations
+#: comment
+
+* Gallium functions with no direct D3D10/D3D11 equivalent
+
+clear
+ + Gallium supports clearing both render targets and depth/stencil with a single call
+
+draw_range_elements
+ + Gallium supports indexed draw with explicit range
+
+fence_signalled
+fence_finish
+ + D3D10/D3D11 don't appear to support explicit fencing; queries can often substitute though, and flushing is supported
+
+set_clip_state
+ + Gallium supports fixed function user clip planes, D3D10/D3D11 only support using the vertex shader for them
+
+set_polygon_stipple
+ + Gallium supports polygon stipple
+
+surface_fill
+ + Gallium supports subrectangle fills of surfaces, D3D10 only supports full clears of views
+
+* DirectX 10/11 DDI functions and Gallium equivalents
+
+AbandonCommandList (D3D11 only)
+ - Gallium does not support deferred contexts
+
+CalcPrivateBlendStateSize
+CalcPrivateDepthStencilStateSize
+CalcPrivateDepthStencilViewSize
+CalcPrivateElementLayoutSize
+CalcPrivateGeometryShaderWithStreamOutput
+CalcPrivateOpenedResourceSize
+CalcPrivateQuerySize
+CalcPrivateRasterizerStateSize
+CalcPrivateRenderTargetViewSize
+CalcPrivateResourceSize
+CalcPrivateSamplerSize
+CalcPrivateShaderResourceViewSize
+CalcPrivateShaderSize
+CalcDeferredContextHandleSize (D3D11 only)
+CalcPrivateCommandListSize (D3D11 only)
+CalcPrivateDeferredContextSize (D3D11 only)
+CalcPrivateTessellationShaderSize (D3D11 only)
+CalcPrivateUnorderedAccessViewSize (D3D11 only)
+ ! D3D11 allocates private objects itself, using the size computed here
+ * Gallium could do something similar to be able to put the private data inline into state tracker objects: this would allow them to fit in the same cacheline and improve performance
+
+CheckDeferredContextHandleSizes (D3D11 only)
+ - Gallium does not support deferred contexts
+
+CheckFormatSupport -> screen->is_format_supported
+ ! Gallium passes usages to this function, D3D11 returns them
+ - Gallium does not differentiate between blendable and non-blendable render targets
+ - Gallium lacks multisampled-texture and multisampled-render-target usages
+
+CheckMultisampleQualityLevels
+ * could merge this with is_format_supported
+ - Gallium lacks multisampling support
+
+CommandListExecute (D3D11 only)
+ - Gallium does not support command lists
+
+CopyStructureCount (D3D11 only)
+ - Gallium does not support unordered access views (views that can be written to arbitrarily from compute shaders)
+
+ClearDepthStencilView -> clear
+ClearRenderTargetView -> clear
+ # D3D11 is not totally clear about whether this applies to any view or only a "currently-bound view"
+ + Gallium allows to clear both depth/stencil and render target(s) in a single operation
+ + Gallium supports double-precision depth values (but not rgba values!)
+ * May want to also support double-precision rgba or use "float" for "depth"
+
+ClearUnorderedAccessViewFloat (D3D11 only)
+ClearUnorderedAccessViewUint (D3D11 only)
+ - Gallium does not support unordered access views (views that can be written to arbitrarily from compute shaders)
+
+CreateBlendState (extended in D3D10.1) -> create_blend_state
+ # D3D10 does not support per-RT blending, only D3D10.1 does
+ - Gallium lacks alpha-to-coverage
+ + Gallium supports logic ops
+ + Gallium supports dithering
+ + Gallium supports using the broadcast alpha component of the blend constant color
+
+CreateCommandList (D3D11 only)
+ - Gallium does not support command lists
+
+CreateComputeShader (D3D11 only)
+ - Gallium does not support compute shaders
+
+CreateDeferredContext (D3D11 only)
+ - Gallium does not support deferred contexts
+
+CreateDomainShader (D3D11 only)
+ - Gallium does not support domain shaders
+
+CreateHullShader (D3D11 only)
+ - Gallium does not support hull shaders
+
+CreateUnorderedAccessView (D3D11 only)
+ - Gallium does not support unordered access views
+
+CreateDepthStencilState -> create_depth_stencil_alpha_state
+ ! D3D11 has both a global stencil enable, and front/back enables; Gallium has only front/back enables
+ + 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
+ ! 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
+ + Gallium supports using 3D texture zslices as a depth/stencil buffer (in theory)
+
+CreateElementLayout -> create_vertex_elements_state
+ ! D3D11 allows sparse vertex elements (via InputRegister); in Gallium they must be specified sequentially
+ ! D3D11 has an extra flag (InputSlotClass) that is the same as instance_divisor == 0
+
+CreateGeometryShader -> create_gs_state
+CreateGeometryShaderWithStreamOutput -> create_gs_state
+CreatePixelShader -> create_fs_state
+CreateVertexShader -> create_vs_state
+ > bytecode is different (see D3d10tokenizedprogramformat.hpp)
+ ! D3D11 describes input/outputs separately from bytecode; Gallium has the tgsi_scan.c module to extract it from TGSI
+ @ TODO: look into DirectX 10/11 semantics specification and bytecode
+
+CheckCounter
+CheckCounterInfo
+CreateQuery -> create_query
+ - Gallium only supports occlusion, primitives generated and primitives emitted queries
+ ! D3D11 implements fences with "event" queries
+ * TIMESTAMP could be implemented as an additional fields for other queries: some cards have hardware support for exactly this
+ * OCCLUSIONPREDICATE is required for the OpenGL v2 occlusion query functionality
+ * others are performance counters, we may want them but they are not critical
+
+CreateRasterizerState
+ - Gallium lacks clamping of polygon offset depth biases
+ - Gallium lacks support to disable depth clipping
+ - Gallium lacks multisampling
+ + Gallium, like OpenGL, supports PIPE_POLYGON_MODE_POINT
+ + Gallium, like OpenGL, supports per-face polygon fill modes
+ + Gallium, like OpenGL, supports culling everything
+ + Gallium, like OpenGL, supports two-side lighting; D3D11 only has the facing attribute
+ + Gallium, like OpenGL, supports per-fill-mode polygon offset enables
+ + Gallium, like OpenGL, supports polygon smoothing
+ + Gallium, like OpenGL, supports polygon stipple
+ + Gallium, like OpenGL, supports point smoothing
+ + Gallium, like OpenGL, supports point sprites
+ + Gallium supports specifying point quad rasterization
+ + Gallium, like OpenGL, supports per-point point size
+ + Gallium, like OpenGL, supports line smoothing
+ + Gallium, like OpenGL, supports line stipple
+ + Gallium supports line last pixel rule specification
+ + Gallium, like OpenGL, supports provoking vertex convention
+ + Gallium supports D3D9 rasterization rules
+ + Gallium supports fixed line width
+ + Gallium supports fixed point size
+
+CreateResource -> texture_create or buffer_create
+ ! D3D11 passes the dimensions of all mipmap levels to the create call, while Gallium has an implicit floor(x/2) rule
+ # Note that hardware often has the implicit rule, so the D3D11 interface seems to make little sense
+ # Also, the D3D11 API does not allow the user to specify mipmap sizes, so this really seems a dubious decision on Microsoft's part
+ - D3D11 supports specifying initial data to write in the resource
+ - Gallium lacks support for stream output buffer usage
+ - Gallium does not support unordered access buffers
+ ! 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 multisampling
+ - 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
+
+CreateSampler
+ - D3D11 supports a monochrome convolution filter for "text filtering"
+ + Gallium supports non-normalized coordinates
+ + Gallium supports CLAMP, MIRROR_CLAMP and MIRROR_CLAMP_TO_BORDER
+ + Gallium supports setting min/max/mip filters and anisotropy independently
+
+CreateShaderResourceView (extended in D3D10.1) -> create_sampler_view
+ - Gallium lacks sampler views over buffers
+ - Gallium lacks texture arrays, and cube map views over texture arrays
+ + Gallium supports specifying a swizzle
+ ! D3D11 implements "cube views" as views into a 2D array texture
+
+CsSetConstantBuffers (D3D11 only)
+CsSetSamplers (D3D11 only)
+CsSetShader (D3D11 only)
+CsSetShaderResources (D3D11 only)
+CsSetShaderWithIfaces (D3D11 only)
+CsSetUnorderedAccessViews (D3D11 only)
+ - Gallium does not support compute shaders
+
+DestroyBlendState
+DestroyCommandList (D3D11 only)
+DestroyDepthStencilState
+DestroyDepthStencilView
+DestroyDevice
+DestroyElementLayout
+DestroyQuery
+DestroyRasterizerState
+DestroyRenderTargetView
+DestroyResource
+DestroySampler
+DestroyShader
+DestroyShaderResourceView
+DestroyUnorderedAccessView (D3D11 only)
+ # these are trivial
+
+Dispatch (D3D11 only)
+ - Gallium does not support compute shaders
+
+DispatchIndirect (D3D11 only)
+ - Gallium does not support compute shaders
+
+Draw -> draw_arrays
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+
+DrawAuto
+ - Gallium lacks stream out and DrawAuto
+
+DrawIndexed -> draw_elements
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+ * may want to add a separate set_index_buffer
+ - Gallium lacks base vertex for indexed draw calls
+ + D3D11 lacks draw_range_elements functionality, which is required for OpenGL
+
+DrawIndexedInstanced -> draw_elements_instanced
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+ * may want to add a separate set_index_buffer
+ - Gallium lacks base vertex for indexed draw calls
+
+DrawIndexedInstancedIndirect (D3D11 only) -> call draw_elements_instanced multiple times in software
+ # this allows to use an hardware buffer to specify the parameters for multiple draw_elements_instanced calls
+ - Gallium does not support draw call parameter buffers and indirect draw
+
+DrawInstanced -> draw_arrays_instanced
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+
+DrawInstancedIndirect (D3D11 only) -> call draw_arrays_instanced multiple times in software
+ # this allows to use an hardware buffer to specify the parameters for multiple draw_arrays_instanced calls
+ - Gallium does not support draw call parameter buffers and indirect draws
+
+DsSetConstantBuffers (D3D11 only)
+DsSetSamplers (D3D11 only)
+DsSetShader (D3D11 only)
+DsSetShaderResources (D3D11 only)
+DsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support domain shaders
+
+Flush -> flush
+ ! Gallium supports fencing and several kinds of flushing here, D3D11 just has a dumb glFlush-like function
+
+GenMips
+ - Gallium lacks a mipmap generation interface, and does this manually with the 3D engine
+ * it may be useful to add a mipmap generation interface, since the hardware (especially older cards) may have a better way than using the 3D engine
+
+GsSetConstantBuffers -> for(i = StartBuffer; i < NumBuffers; ++i) set_constant_buffer(PIPE_SHADER_GEOMETRY, i, phBuffers[i])
+
+GsSetSamplers
+ - Gallium does not support sampling in geometry shaders
+
+GsSetShader -> bind_gs_state
+
+GsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support shader interfaces
+
+GsSetShaderResources
+ - Gallium does not support sampling in geometry shaders
+
+HsSetConstantBuffers (D3D11 only)
+HsSetSamplers (D3D11 only)
+HsSetShader (D3D11 only)
+HsSetShaderResources (D3D11 only)
+HsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support hull shaders
+
+IaSetIndexBuffer
+ ! Gallium passes this to the draw_elements or draw_elements_instanced calls
+ + Gallium supports 8-bit indices
+ ! the D3D11 interface allows index-size-unaligned byte offsets into index buffers; it's not clear whether they actually work
+
+IaSetInputLayout -> bind_vertex_elements_state
+
+IaSetTopology
+ ! Gallium passes the topology = primitive type to the draw calls
+ * may want to add an interface for this
+ - Gallium lacks support for DirectX 11 tessellated primitives
+ + Gallium supports line loops, triangle fans, quads, quad strips and polygons
+
+IaSetVertexBuffers -> set_vertex_buffers
+ + Gallium allows to specify a max_index here
+ - Gallium only allows setting all vertex buffers at once, while D3D11 supports setting a subset
+
+OpenResource -> texture_from_handle
+
+PsSetConstantBuffers -> for(i = StartBuffer; i < NumBuffers; ++i) set_constant_buffer(PIPE_SHADER_FRAGMENT, i, phBuffers[i])
+ * may want to split into fragment/vertex-specific versions
+
+PsSetSamplers -> bind_fragment_sampler_states
+ * may want to allow binding subsets instead of all at once
+
+PsSetShader -> bind_fs_state
+
+PsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support shader interfaces
+
+PsSetShaderResources -> set_fragment_sampler_views
+ * may want to allow binding subsets instead of all at once
+
+QueryBegin -> begin_query
+
+QueryEnd -> end_query
+
+QueryGetData -> get_query_result
+ - D3D11 supports reading an arbitrary data chunk for query results, Gallium only supports reading a 64-bit integer
+ + D3D11 doesn't seem to support actually waiting for the query result (?!)
+ - D3D11 supports optionally not flushing command buffers here and instead returning DXGI_DDI_ERR_WASSTILLDRAWING
+
+RecycleCommandList (D3D11 only)
+RecycleCreateCommandList (D3D11 only)
+RecycleDestroyCommandList (D3D11 only)
+ - Gallium does not support command lists
+
+RecycleCreateDeferredContext (D3D11 only)
+ - Gallium does not support deferred contexts
+
+RelocateDeviceFuncs
+ - Gallium does not support moving pipe_context, while D3D11 seems to, using this
+
+ResetPrimitiveID (D3D10.1+ only, #ifdef D3D10PSGP)
+ # used to do vertex processing on the GPU on Intel G45 chipsets when it is faster this way (see www.intel.com/Assets/PDF/whitepaper/322931.pdf)
+ # presumably this resets the primitive id system value
+ - Gallium does not support vertex pipeline bypass anymore
+
+ResourceCopy
+ResourceCopyRegion
+ResourceConvert (D3D10.1+ only)
+ResourceConvertRegion (D3D10.1+ only)
+ -> surface_copy
+ - Gallium does not support hardware buffer copies
+ - Gallium does not support copying 3D texture subregions in a single call
+
+ResourceIsStagingBusy -> is_texture_referenced, is_buffer_referenced
+ - Gallium does not support checking reference for a whole texture, but only a specific surface
+
+ResourceReadAfterWriteHazard
+ ! Gallium specifies hides this, except for the render and texture caches
+
+ResourceResolveSubresource
+ - Gallium does not support multisample sample resolution
+
+ResourceMap
+ResourceUnmap
+DynamicConstantBufferMapDiscard
+DynamicConstantBufferUnmap
+DynamicIABufferMapDiscard
+DynamicIABufferMapNoOverwrite
+DynamicIABufferUnmap
+DynamicResourceMapDiscard
+DynamicResourceUnmap
+StagingResourceMap
+StagingResourceUnmap
+ -> buffer_map / buffer_unmap
+ -> transfer functions
+ ! Gallium and D3D have different semantics for transfers
+ * D3D separates vertex/index buffers from constant buffers
+ ! D3D separates some buffer flags into specialized calls
+
+ResourceUpdateSubresourceUP -> transfer functionality, transfer_inline_write in gallium-resources
+DefaultConstantBufferUpdateSubresourceUP -> transfer functionality, transfer_inline_write in gallium-resources
+
+SetBlendState -> bind_blend_state and set_blend_color
+ ! D3D11 fuses bind_blend_state and set_blend_color in a single function
+ - Gallium lacks the sample mask
+
+SetDepthStencilState -> bind_depth_stencil_alpha_state and set_stencil_ref
+ ! D3D11 fuses bind_depth_stencil_alpha_state and set_stencil_ref in a single function
+
+SetPredication -> render_condition
+ # here both D3D11 and Gallium seem very limited (hardware is too, probably though)
+ # ideally, we should support nested conditional rendering, as well as more complex tests (checking for an arbitrary range, after an AND with arbitrary mask )
+ # of couse, hardware support is probably as limited as OpenGL/D3D11
+ + Gallium, like NV_conditional_render, supports by-region and wait flags
+ - D3D11 supports predication conditional on being equal any value (along with occlusion predicates); Gallium only supports on non-zero
+
+SetRasterizerState -> bind_rasterizer_state
+
+SetRenderTargets (extended in D3D11) -> set_framebuffer_state
+ ! Gallium passed a width/height here, D3D11 does not
+ ! Gallium lacks ClearTargets (but this is redundant and the driver can trivially compute this if desired)
+ - Gallium does not support unordered access views
+ - Gallium does not support geometry shader selection of texture array image / 3D texture zslice
+
+SetResourceMinLOD (D3D11 only)
+ - Gallium does not support min lod directly on textures
+
+SetScissorRects
+ - Gallium lacks support for multiple geometry-shader-selectable scissor rectangles D3D11 has
+
+SetTextFilterSize
+ - Gallium lacks support for text filters
+
+SetVertexPipelineOutput (D3D10.1+ only)
+ # used to do vertex processing on the GPU on Intel G45 chipsets when it is faster this way (see www.intel.com/Assets/PDF/whitepaper/322931.pdf)
+ - Gallium does not support vertex pipeline bypass anymore
+
+SetViewports
+ - Gallium lacks support for multiple geometry-shader-selectable viewports D3D11 has
+
+ShaderResourceViewReadAfterWriteHazard -> flush(PIPE_FLUSH_RENDER_CACHE)
+ - Gallium does not support specifying this per-render-target/view
+
+SoSetTargets
+ - Gallium does not support stream out
+
+VsSetConstantBuffers -> for(i = StartBuffer; i < NumBuffers; ++i) set_constant_buffer(PIPE_SHADER_VERTEX, i, phBuffers[i])
+ * may want to split into fragment/vertex-specific versions
+
+VsSetSamplers -> bind_vertex_sampler_states
+ * may want to allow binding subsets instead of all at once
+
+VsSetShader -> bind_vs_state
+
+VsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support shader interfaces
+
+VsSetShaderResources -> set_fragment_sampler_views
+ * may want to allow binding subsets instead of all at once
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 4608e97adbb..2b0941010b0 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -40,8 +40,7 @@ buffers, surfaces) are bound to the driver.
are mostly restricted to the first one right now).
* ``set_framebuffer_state``
-* ``set_fragment_sampler_textures``
-* ``set_vertex_sampler_textures``
+
* ``set_vertex_buffers``
@@ -51,6 +50,7 @@ Non-CSO State
These pieces of state are too small, variable, and/or trivial to have CSO
objects. They all follow simple, one-method binding calls, e.g.
``set_blend_color``.
+
* ``set_stencil_ref`` sets the stencil front and back reference values
which are used as comparison values in stencil test.
* ``set_blend_color``
@@ -63,6 +63,41 @@ objects. They all follow simple, one-method binding calls, e.g.
* ``set_viewport_state``
+Sampler Views
+^^^^^^^^^^^^^
+
+These are the means to bind textures to shader stages. To create one, specify
+its format, swizzle and LOD range in sampler view template.
+
+If texture format is different than template format, it is said the texture
+is being cast to another format. Casting can be done only between compatible
+formats, that is formats that have matching component order and sizes.
+
+Swizzle fields specify they way in which fetched texel components are placed
+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.
+
+* ``set_fragment_sampler_views`` binds an array of sampler views to
+ fragment shader stage. Every binding point acquires a reference
+ to a respective sampler view and releases a reference to the previous
+ sampler view.
+
+* ``set_vertex_sampler_views`` binds an array of sampler views to vertex
+ shader stage. Every binding point acquires a reference to a respective
+ sampler view and releases a reference to the previous sampler view.
+
+* ``create_sampler_view`` creates a new sampler view. ``texture`` is associated
+ with the sampler view which results in sampler view holding a reference
+ to the texture. Format specified in template must be compatible
+ with texture format.
+
+* ``sampler_view_destroy`` destroys a sampler view and releases its reference
+ to associated texture.
+
+
Clearing
^^^^^^^^
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index ccd9136a2eb..e8dc82964fa 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -7,7 +7,7 @@ The rasterizer state controls the rendering of points, lines and triangles.
Attributes include polygon culling state, line width, line stipple,
multisample state, scissoring and flat/smooth shading.
-Members
+Shading
-------
flatshade
@@ -46,6 +46,49 @@ There are several important exceptions to the specification of this rule.
second vertex, not the first. This permits each segment of the fan to have
a different color.
+Points
+------
+
+sprite_coord_enable
+^^^^^^^^^^^^^^^^^^^
+
+Specifies if a texture unit has its texture coordinates replaced or not. This
+is a packed bitfield containing the enable for all texcoords -- if all bits
+are zero, point sprites are effectively disabled. If any bit is set, then
+point_smooth and point_quad_rasterization are ignored; point smoothing is
+disabled and points are always rasterized as quads. If enabled, the four
+vertices of the resulting quad will be assigned texture coordinates,
+according to sprite_coord_mode.
+
+sprite_coord_mode
+^^^^^^^^^^^^^^^^^
+
+Specifies how the value for each shader output should be computed when drawing
+point sprites. For PIPE_SPRITE_COORD_LOWER_LEFT, the lower-left vertex will
+have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left
+vertex will have coordinates (0,0,0,1).
+This state is used by :ref:`Draw` to generate texcoords.
+
+.. note::
+
+ When geometry shaders are available, a special geometry shader could be
+ used instead of this functionality, to convert incoming points into quads
+ with the proper texture coordinates.
+
+point_quad_rasterization
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Determines if points should be rasterized as quads or points. Certain APIs,
+like Direct3D, always use quad rasterization for points, regardless of
+whether point sprites are enabled or not. If this state is enabled, point
+smoothing and antialiasing are disabled, and sprite coordinates are not
+generated.
+
+.. note::
+
+ Some renderers always internally translate points into quads; this state
+ still affects those renderers by overriding other rasterization state.
+
Other Members
^^^^^^^^^^^^^
@@ -107,37 +150,6 @@ point_size_per_vertex
Whether vertices have a point size element.
point_size
The size of points, if not specified per-vertex.
-sprite_coord_enable
- Specifies if a coord has its texture coordinates replaced or not. This
- is a packed bitfield containing the enable for all coords - if all are 0
- point sprites are effectively disabled, though points may still be
- rendered slightly different according to point_quad_rasterization.
- If any coord is non-zero, point_smooth should be disabled, and
- point_quad_rasterization enabled.
- If enabled, the four vertices of the resulting quad will be assigned
- texture coordinates, according to sprite_coord_mode.
-sprite_coord_mode
- Specifies how the value for each shader output should be computed when
- drawing sprites, for each coord which has sprite_coord_enable set.
- For PIPE_SPRITE_COORD_LOWER_LEFT, the lower left vertex will have
- coordinate (0,0,0,1).
- For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have
- coordinate (0,0,0,1).
- This state is needed by :ref:`Draw` because that's where each
- point vertex is converted into four quad vertices. There's no other
- place to emit the new vertex texture coordinates which are required for
- sprite rendering.
- Note that when geometry shaders are available, this state could be
- removed. A special geometry shader defined by the state tracker could
- convert the incoming points into quads with the proper texture coords.
-point_quad_rasterization
- This determines if points should be rasterized as quads or points.
- d3d always uses quad rasterization for points, regardless if point sprites
- are enabled or not, but OGL has different rules. If point_quad_rasterization
- is set, point_smooth should be disabled, and points will be rendered as
- squares even if multisample is enabled.
- sprite_coord_enable should be zero if point_quad_rasterization is not
- enabled.
scissor
Whether the scissor test is enabled.
diff --git a/src/gallium/docs/source/cso/velems.rst b/src/gallium/docs/source/cso/velems.rst
index 8e758fae103..92cde014fb8 100644
--- a/src/gallium/docs/source/cso/velems.rst
+++ b/src/gallium/docs/source/cso/velems.rst
@@ -1,4 +1,4 @@
-.. _vertex,elements
+.. _vertexelements:
Vertex Elements
===============
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index 28f80b82cd5..f7e2284445d 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -97,7 +97,7 @@ struct cell_velems_state
{
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
-}
+};
/**
* Per-context state, subclass of pipe_context.
@@ -127,6 +127,7 @@ struct cell_context
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct cell_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
uint num_textures;
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index dce10ae7f86..059ce8597bc 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -257,8 +257,9 @@ cell_delete_sampler_state(struct pipe_context *pipe,
static void
-cell_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+cell_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct cell_context *cell = cell_context(pipe);
uint i, changed = 0x0;
@@ -266,10 +267,14 @@ cell_set_sampler_textures(struct pipe_context *pipe,
assert(num <= CELL_MAX_SAMPLERS);
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
- struct cell_texture *new_tex = cell_texture(i < num ? texture[i] : NULL);
- struct cell_texture *old_tex = cell->texture[i];
- if (old_tex != new_tex) {
+ struct pipe_sampler_view *new_view = i < num ? views[i] : NULL;
+ struct pipe_sampler_view *old_view = cell->fragment_sampler_views[i];
+ if (old_view != new_view) {
+ struct pipe_texture *new_tex = new_view ? new_view->texture : NULL;
+
+ pipe_sampler_view_reference(&cell->fragment_sampler_views[i],
+ views[i]);
pipe_texture_reference((struct pipe_texture **) &cell->texture[i],
(struct pipe_texture *) new_tex);
@@ -286,6 +291,34 @@ cell_set_sampler_textures(struct pipe_context *pipe,
}
+static struct pipe_sampler_view *
+cell_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+cell_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+
/**
* Map color and z/stencil framebuffer surfaces.
*/
@@ -409,7 +442,9 @@ cell_init_state_functions(struct cell_context *cell)
cell->pipe.bind_fragment_sampler_states = cell_bind_sampler_states;
cell->pipe.delete_sampler_state = cell_delete_sampler_state;
- cell->pipe.set_fragment_sampler_textures = cell_set_sampler_textures;
+ cell->pipe.set_fragment_sampler_views = cell_set_fragment_sampler_views;
+ cell->pipe.create_sampler_view = cell_create_sampler_view;
+ cell->pipe.sampler_view_destroy = cell_sampler_view_destroy;
cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state;
cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state;
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 31fd963d19a..42045744060 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -97,6 +97,8 @@ cell_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
+ case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ return 1;
default:
return 0;
}
@@ -136,20 +138,23 @@ cell_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
- struct sw_winsys *winsys = cell_screen(screen)->winsys;
-
- if (format == PIPE_FORMAT_DXT5_RGBA ||
- format == PIPE_FORMAT_A8B8G8R8_SRGB)
- return FALSE;
-
- if (tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if (!winsys->is_displaytarget_format_supported(winsys, format))
+ if (tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
- /* This is often a lie. Pull in logic from llvmpipe to fix.
- */
- return TRUE;
+ /* only a few formats are known to work at this time */
+ switch (format) {
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ return TRUE;
+ default:
+ return FALSE;
+ }
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index c65c3b4f885..5b169afaf88 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -105,6 +105,7 @@ cell_displaytarget_layout(struct pipe_screen *screen,
/* Round up the surface size to a multiple of the tile size?
*/
ct->dt = winsys->displaytarget_create(winsys,
+ ct->base->tex_usage,
ct->base.format,
ct->base.width0,
ct->base.height0,
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index 4a754465bbe..73031321d98 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -47,7 +47,7 @@
#define FO_NEW_ALPHA_TEST 0x100
#define FO_NEW_DEPTH_STENCIL 0x200
#define FO_NEW_SAMPLER 0x400
-#define FO_NEW_TEXTURE 0x800
+#define FO_NEW_SAMPLER_VIEW 0x800
#define FO_NEW_VERTEX 0x2000
#define FO_NEW_VERTEX_SHADER 0x4000
#define FO_NEW_BLEND_COLOR 0x8000
@@ -65,6 +65,13 @@ struct fo_state {
void *sw_state;
void *hw_state;
};
+
+struct fo_sampler_view {
+ struct pipe_sampler_view base;
+ struct pipe_sampler_view *sw;
+ struct pipe_sampler_view *hw;
+};
+
struct failover_context {
struct pipe_context pipe; /**< base class */
@@ -86,8 +93,6 @@ struct failover_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
@@ -98,12 +103,15 @@ struct failover_context {
void *sw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];
void *hw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];
+ struct fo_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct fo_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+ unsigned num_fragment_sampler_views;
+ unsigned num_vertex_sampler_views;
+
unsigned dirty;
unsigned num_samplers;
unsigned num_vertex_samplers;
- unsigned num_textures;
- unsigned num_vertex_textures;
unsigned mode;
struct pipe_context *hw;
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index 0247fb803b2..25c62735705 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -447,60 +447,96 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
}
+static struct pipe_sampler_view *
+failover_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct fo_sampler_view *view = malloc(sizeof(struct fo_sampler_view));
+ struct failover_context *failover = failover_context(pipe);
+
+ view->sw = failover->sw->create_sampler_view(failover->sw, texture, templ);
+ view->hw = failover->hw->create_sampler_view(failover->hw, texture, templ);
+
+ view->base = *templ;
+ view->base.reference.count = 1;
+ view->base.texture = NULL;
+ pipe_texture_reference(&view->base.texture, texture);
+ view->base.context = pipe;
+
+ return &view->base;
+}
+
+static void
+failover_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ struct fo_sampler_view *fo_view = (struct fo_sampler_view *)view;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->sampler_view_destroy(failover->sw, fo_view->sw);
+ failover->hw->sampler_view_destroy(failover->hw, fo_view->hw);
+
+ pipe_texture_reference(&fo_view->base.texture, NULL);
+ free(fo_view);
+}
+
static void
-failover_set_fragment_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+failover_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct failover_context *failover = failover_context(pipe);
+ struct pipe_sampler_view *hw_views[PIPE_MAX_SAMPLERS];
uint i;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == failover->num_textures &&
- !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == failover->num_fragment_sampler_views &&
+ !memcmp(failover->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
- for (i = 0; i < num; i++)
- pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
- texture[i]);
- for (i = num; i < failover->num_textures; i++)
- pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
- NULL);
- failover->dirty |= FO_NEW_TEXTURE;
- failover->num_textures = num;
- failover->sw->set_fragment_sampler_textures( failover->sw, num, texture );
- failover->hw->set_fragment_sampler_textures( failover->hw, num, texture );
+ for (i = 0; i < num; i++) {
+ struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i];
+
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], views[i]);
+ hw_views[i] = fo_view->hw;
+ }
+ for (i = num; i < failover->num_fragment_sampler_views; i++)
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], NULL);
+ failover->dirty |= FO_NEW_SAMPLER_VIEW;
+ failover->num_fragment_sampler_views = num;
+ failover->hw->set_fragment_sampler_views(failover->hw, num, hw_views);
}
static void
-failover_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+failover_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct failover_context *failover = failover_context(pipe);
+ struct pipe_sampler_view *hw_views[PIPE_MAX_VERTEX_SAMPLERS];
uint i;
- assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
- if (num_textures == failover->num_vertex_textures &&
- !memcmp(failover->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ if (num == failover->num_vertex_sampler_views &&
+ !memcmp(failover->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
return;
}
- for (i = 0; i < num_textures; i++) {
- pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i],
- textures[i]);
- }
- for (i = num_textures; i < failover->num_vertex_textures; i++) {
- pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i],
- NULL);
+ for (i = 0; i < num; i++) {
+ struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i];
+
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], views[i]);
+ hw_views[i] = fo_view->hw;
}
- failover->dirty |= FO_NEW_TEXTURE;
- failover->num_vertex_textures = num_textures;
- failover->sw->set_vertex_sampler_textures(failover->sw, num_textures, textures);
- failover->hw->set_vertex_sampler_textures(failover->hw, num_textures, textures);
+ for (i = num; i < failover->num_vertex_sampler_views; i++)
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], NULL);
+ failover->dirty |= FO_NEW_SAMPLER_VIEW;
+ failover->num_vertex_sampler_views = num;
+ failover->hw->set_vertex_sampler_views(failover->hw, num, hw_views);
}
@@ -580,9 +616,11 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
failover->pipe.set_scissor_state = failover_set_scissor_state;
- failover->pipe.set_fragment_sampler_textures = failover_set_fragment_sampler_textures;
- failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures;
+ failover->pipe.set_fragment_sampler_views = failover_set_fragment_sampler_views;
+ failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
+ failover->pipe.create_sampler_view = failover_create_sampler_view;
+ failover->pipe.sampler_view_destroy = failover_sampler_view_destroy;
}
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index 09ca1944971..42bd6929a7f 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -106,12 +106,24 @@ failover_state_emit( struct failover_context *failover )
failover->sw_vertex_sampler_state);
}
- if (failover->dirty & FO_NEW_TEXTURE) {
- failover->sw->set_fragment_sampler_textures( failover->sw, failover->num_textures,
- failover->texture );
- failover->sw->set_vertex_sampler_textures(failover->sw,
- failover->num_vertex_textures,
- failover->vertex_textures);
+ if (failover->dirty & FO_NEW_SAMPLER_VIEW) {
+ struct pipe_sampler_view *fragment_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_views[PIPE_MAX_VERTEX_SAMPLERS];
+ uint i;
+
+ for (i = 0; i < failover->num_fragment_sampler_views; i++) {
+ fragment_views[i] = failover->fragment_sampler_views[i]->sw;
+ }
+ failover->sw->set_fragment_sampler_views(failover->sw,
+ failover->num_fragment_sampler_views,
+ fragment_views);
+
+ for (i = 0; i < failover->num_vertex_sampler_views; i++) {
+ vertex_views[i] = failover->vertex_sampler_views[i]->sw;
+ }
+ failover->sw->set_vertex_sampler_views(failover->sw,
+ failover->num_vertex_sampler_views,
+ vertex_views);
}
if (failover->dirty & FO_NEW_VERTEX_BUFFER) {
diff --git a/src/gallium/drivers/i915/i915_batch.h b/src/gallium/drivers/i915/i915_batch.h
index b813784723f..f0086695d16 100644
--- a/src/gallium/drivers/i915/i915_batch.h
+++ b/src/gallium/drivers/i915/i915_batch.h
@@ -28,19 +28,19 @@
#ifndef I915_BATCH_H
#define I915_BATCH_H
-#include "intel_batchbuffer.h"
+#include "i915_batchbuffer.h"
#define BEGIN_BATCH(dwords, relocs) \
- (intel_batchbuffer_check(i915->batch, dwords, relocs))
+ (i915_winsys_batchbuffer_check(i915->batch, dwords, relocs))
#define OUT_BATCH(dword) \
- intel_batchbuffer_dword(i915->batch, dword)
+ i915_winsys_batchbuffer_dword(i915->batch, dword)
#define OUT_RELOC(buf, usage, offset) \
- intel_batchbuffer_reloc(i915->batch, buf, usage, offset)
+ i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset)
#define FLUSH_BATCH(fence) do { \
- intel_batchbuffer_flush(i915->batch, fence); \
+ i915_winsys_batchbuffer_flush(i915->batch, fence); \
i915->hardware_dirty = ~0; \
} while (0)
diff --git a/src/gallium/drivers/i915/intel_batchbuffer.h b/src/gallium/drivers/i915/i915_batchbuffer.h
index db12dfd2ac2..27ccaa6b1fa 100644
--- a/src/gallium/drivers/i915/intel_batchbuffer.h
+++ b/src/gallium/drivers/i915/i915_batchbuffer.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,11 +10,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,34 +22,34 @@
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
-#ifndef INTEL_BATCH_H
-#define INTEL_BATCH_H
+#ifndef I915_BATCHBUFFER_H
+#define I915_BATCHBUFFER_H
-#include "intel_winsys.h"
+#include "i915_winsys.h"
static INLINE boolean
-intel_batchbuffer_check(struct intel_batchbuffer *batch,
- size_t dwords,
- size_t relocs)
+i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch,
+ size_t dwords,
+ size_t relocs)
{
return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
relocs <= (batch->max_relocs - batch->relocs);
}
static INLINE size_t
-intel_batchbuffer_space(struct intel_batchbuffer *batch)
+i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
{
return batch->size - (batch->ptr - batch->map);
}
static INLINE void
-intel_batchbuffer_dword(struct intel_batchbuffer *batch,
- unsigned dword)
+i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch,
+ unsigned dword)
{
- if (intel_batchbuffer_space(batch) < 4)
+ if (i915_winsys_batchbuffer_space(batch) < 4)
return;
*(unsigned *)batch->ptr = dword;
@@ -57,11 +57,11 @@ intel_batchbuffer_dword(struct intel_batchbuffer *batch,
}
static INLINE void
-intel_batchbuffer_write(struct intel_batchbuffer *batch,
- void *data,
- size_t size)
+i915_winsys_batchbuffer_write(struct i915_winsys_batchbuffer *batch,
+ void *data,
+ size_t size)
{
- if (intel_batchbuffer_space(batch) < size)
+ if (i915_winsys_batchbuffer_space(batch) < size)
return;
memcpy(data, batch->ptr, size);
@@ -69,17 +69,17 @@ intel_batchbuffer_write(struct intel_batchbuffer *batch,
}
static INLINE int
-intel_batchbuffer_reloc(struct intel_batchbuffer *batch,
- struct intel_buffer *buffer,
- enum intel_buffer_usage usage,
- size_t offset)
+i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch,
+ struct i915_winsys_buffer *buffer,
+ enum i915_winsys_buffer_usage usage,
+ size_t offset)
{
return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
}
static INLINE void
-intel_batchbuffer_flush(struct intel_batchbuffer *batch,
- struct pipe_fence_handle **fence)
+i915_winsys_batchbuffer_flush(struct i915_winsys_batchbuffer *batch,
+ struct pipe_fence_handle **fence)
{
batch->iws->batchbuffer_flush(batch, fence);
}
diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c
index 83dfc335288..533fa81219b 100644
--- a/src/gallium/drivers/i915/i915_blit.c
+++ b/src/gallium/drivers/i915/i915_blit.c
@@ -37,7 +37,7 @@ void
i915_fill_blit(struct i915_context *i915,
unsigned cpp,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short x, short y,
short w, short h,
@@ -77,7 +77,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, INTEL_USAGE_2D_TARGET, dst_offset);
+ OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
OUT_BATCH(color);
FLUSH_BATCH(NULL);
}
@@ -87,10 +87,10 @@ i915_copy_blit(struct i915_context *i915,
unsigned do_flip,
unsigned cpp,
unsigned short src_pitch,
- struct intel_buffer *src_buffer,
+ struct i915_winsys_buffer *src_buffer,
unsigned src_offset,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short src_x, short src_y,
short dst_x, short dst_y,
@@ -143,9 +143,9 @@ i915_copy_blit(struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((dst_y << 16) | dst_x);
OUT_BATCH((dst_y2 << 16) | dst_x2);
- OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
+ OUT_RELOC(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, INTEL_USAGE_2D_SOURCE, src_offset);
+ OUT_RELOC(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
FLUSH_BATCH(NULL);
}
diff --git a/src/gallium/drivers/i915/i915_blit.h b/src/gallium/drivers/i915/i915_blit.h
index 8ce3220cfd9..db576ed4c90 100644
--- a/src/gallium/drivers/i915/i915_blit.h
+++ b/src/gallium/drivers/i915/i915_blit.h
@@ -34,10 +34,10 @@ extern void i915_copy_blit(struct i915_context *i915,
unsigned do_flip,
unsigned cpp,
unsigned short src_pitch,
- struct intel_buffer *src_buffer,
+ struct i915_winsys_buffer *src_buffer,
unsigned src_offset,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short srcx, short srcy,
short dstx, short dsty,
@@ -46,7 +46,7 @@ extern void i915_copy_blit(struct i915_context *i915,
extern void i915_fill_blit(struct i915_context *i915,
unsigned cpp,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short x, short y,
short w, short h, unsigned color);
diff --git a/src/gallium/drivers/i915/i915_buffer.c b/src/gallium/drivers/i915/i915_buffer.c
index 0f76a59e93a..1247de320d4 100644
--- a/src/gallium/drivers/i915/i915_buffer.c
+++ b/src/gallium/drivers/i915/i915_buffer.c
@@ -28,13 +28,13 @@
#include "i915_screen.h"
#include "i915_buffer.h"
-struct intel_buffer;
+struct i915_winsys_buffer;
struct i915_buffer
{
struct pipe_buffer base;
- struct intel_buffer *ibuf; /** hw buffer */
+ struct i915_winsys_buffer *ibuf; /** hw buffer */
void *data; /**< user and malloc data */
boolean own; /**< we own the data incase of malloc */
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 039165b63f5..8df4dce8653 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -38,9 +38,9 @@
#include "tgsi/tgsi_scan.h"
-struct intel_winsys;
-struct intel_buffer;
-struct intel_batchbuffer;
+struct i915_winsys;
+struct i915_winsys_buffer;
+struct i915_winsys_batchbuffer;
#define I915_TEX_UNITS 8
@@ -219,14 +219,14 @@ struct i915_texture {
/* The data is held here:
*/
- struct intel_buffer *buffer;
+ struct i915_winsys_buffer *buffer;
};
struct i915_context
{
struct pipe_context base;
- struct intel_winsys *iws;
+ struct i915_winsys *iws;
struct draw_context *draw;
@@ -247,20 +247,20 @@ struct i915_context
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct i915_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned dirty;
unsigned num_samplers;
- unsigned num_textures;
+ unsigned num_fragment_sampler_views;
unsigned num_vertex_buffers;
- struct intel_batchbuffer *batch;
+ struct i915_winsys_batchbuffer *batch;
/** Vertex buffer */
- struct intel_buffer *vbo;
+ struct i915_winsys_buffer *vbo;
size_t vbo_offset;
unsigned vbo_flushed;
@@ -283,7 +283,7 @@ struct i915_context
#define I915_NEW_ALPHA_TEST 0x100
#define I915_NEW_DEPTH_STENCIL 0x200
#define I915_NEW_SAMPLER 0x400
-#define I915_NEW_TEXTURE 0x800
+#define I915_NEW_SAMPLER_VIEW 0x800
#define I915_NEW_CONSTANTS 0x1000
#define I915_NEW_VBO 0x2000
#define I915_NEW_VS 0x4000
diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c
index 237654d26b2..663fac3055c 100644
--- a/src/gallium/drivers/i915/i915_debug.c
+++ b/src/gallium/drivers/i915/i915_debug.c
@@ -863,7 +863,7 @@ static boolean i915_debug_packet( struct debug_stream *stream )
void
-i915_dump_batchbuffer( struct intel_batchbuffer *batch )
+i915_dump_batchbuffer( struct i915_winsys_batchbuffer *batch )
{
struct debug_stream stream;
unsigned *start = (unsigned*)batch->map;
diff --git a/src/gallium/drivers/i915/i915_debug.h b/src/gallium/drivers/i915/i915_debug.h
index 8f7484797de..67b8d9c2f63 100644
--- a/src/gallium/drivers/i915/i915_debug.h
+++ b/src/gallium/drivers/i915/i915_debug.h
@@ -104,9 +104,9 @@ I915_DBG(
#endif
-struct intel_batchbuffer;
+struct i915_winsys_batchbuffer;
-void i915_dump_batchbuffer( struct intel_batchbuffer *i915 );
+void i915_dump_batchbuffer( struct i915_winsys_batchbuffer *i915 );
void i915_debug_init( struct i915_context *i915 );
diff --git a/src/gallium/drivers/i915/i915_prim_emit.c b/src/gallium/drivers/i915/i915_prim_emit.c
index d9a5c40ab97..dd997e2cf48 100644
--- a/src/gallium/drivers/i915/i915_prim_emit.c
+++ b/src/gallium/drivers/i915/i915_prim_emit.c
@@ -102,6 +102,13 @@ emit_hw_vertex( struct i915_context *i915,
count += 4;
break;
case EMIT_4UB:
+ OUT_BATCH( pack_ub4(float_to_ubyte( attrib[0] ),
+ float_to_ubyte( attrib[1] ),
+ float_to_ubyte( attrib[2] ),
+ float_to_ubyte( attrib[3] )) );
+ count += 1;
+ break;
+ case EMIT_4UB_BGRA:
OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ),
float_to_ubyte( attrib[1] ),
float_to_ubyte( attrib[0] ),
diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c
index cad4109ee6b..df9e68af4fc 100644
--- a/src/gallium/drivers/i915/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915/i915_prim_vbuf.c
@@ -76,7 +76,7 @@ struct i915_vbuf_render {
unsigned fallback;
/* Stuff for the vbo */
- struct intel_buffer *vbo;
+ struct i915_winsys_buffer *vbo;
size_t vbo_size; /**< current size of allocated buffer */
size_t vbo_alloc_size; /**< minimum buffer size to allocate */
size_t vbo_offset;
@@ -141,7 +141,7 @@ static void
i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
{
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
if (i915_render->vbo) {
#ifdef VBUF_USE_FIFO
@@ -172,7 +172,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
if (i915_render->vbo_size != i915_render->pool_buffer_size) {
i915_render->pool_not_used = TRUE;
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
- INTEL_NEW_VERTEX);
+ I915_NEW_VERTEX);
} else {
i915_render->pool_not_used = FALSE;
@@ -185,7 +185,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
}
#else
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size,
- 64, INTEL_NEW_VERTEX);
+ 64, I915_NEW_VERTEX);
#endif
}
@@ -225,7 +225,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
if (i915->vbo_flushed)
debug_printf("%s bad vbo flush occured stalling on hw\n", __FUNCTION__);
@@ -246,7 +246,7 @@ i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
#ifdef VBUF_MAP_BUFFER
@@ -621,7 +621,7 @@ static struct vbuf_render *
i915_vbuf_render_create(struct i915_context *i915)
{
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
int i;
i915_render->i915 = i915;
@@ -662,7 +662,7 @@ i915_vbuf_render_create(struct i915_context *i915)
for (i = 0; i < 6; i++)
u_fifo_add(i915_render->pool_fifo,
iws->buffer_create(iws, i915_render->pool_buffer_size, 64,
- INTEL_NEW_VERTEX));
+ I915_NEW_VERTEX));
#else
(void)i;
(void)iws;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index e5bf4a20bd0..53ef6e50f6c 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -35,7 +35,7 @@
#include "i915_screen.h"
#include "i915_buffer.h"
#include "i915_texture.h"
-#include "intel_winsys.h"
+#include "i915_winsys.h"
/*
@@ -165,8 +165,12 @@ i915_is_format_supported(struct pipe_screen *screen,
unsigned geom_flags)
{
static const enum pipe_format tex_supported[] = {
- PIPE_FORMAT_A8B8G8R8_UNORM,
PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+#if 0
+ PIPE_FORMAT_R8G8B8X8_UNORM,
+#endif
PIPE_FORMAT_B5G6R5_UNORM,
PIPE_FORMAT_L8_UNORM,
PIPE_FORMAT_A8_UNORM,
@@ -256,7 +260,7 @@ i915_destroy_screen(struct pipe_screen *screen)
* Create a new i915_screen object
*/
struct pipe_screen *
-i915_create_screen(struct intel_winsys *iws, uint pci_id)
+i915_create_screen(struct i915_winsys *iws, uint pci_id)
{
struct i915_screen *is = CALLOC_STRUCT(i915_screen);
diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h
index 5126485caa7..7f9e02fc0f6 100644
--- a/src/gallium/drivers/i915/i915_screen.h
+++ b/src/gallium/drivers/i915/i915_screen.h
@@ -32,7 +32,7 @@
#include "pipe/p_screen.h"
-struct intel_winsys;
+struct i915_winsys;
/**
@@ -42,7 +42,7 @@ struct i915_screen
{
struct pipe_screen base;
- struct intel_winsys *iws;
+ struct i915_winsys *iws;
boolean is_i945;
uint pci_id;
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 377d8425a5c..0f7395246cc 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -560,9 +560,9 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
}
-static void i915_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static void i915_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct i915_context *i915 = i915_context(pipe);
uint i;
@@ -570,27 +570,54 @@ static void i915_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == i915->num_textures &&
- !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == i915->num_fragment_sampler_views &&
+ !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
/* Fixes wrong texture in texobj with VBUF */
draw_flush(i915->draw);
for (i = 0; i < num; i++)
- pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
- texture[i]);
+ pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
+ views[i]);
- for (i = num; i < i915->num_textures; i++)
- pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
- NULL);
+ for (i = num; i < i915->num_fragment_sampler_views; i++)
+ pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
+ NULL);
- i915->num_textures = num;
+ i915->num_fragment_sampler_views = num;
- i915->dirty |= I915_NEW_TEXTURE;
+ i915->dirty |= I915_NEW_SAMPLER_VIEW;
}
+static struct pipe_sampler_view *
+i915_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+i915_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
static void i915_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
@@ -818,7 +845,9 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_polygon_stipple = i915_set_polygon_stipple;
i915->base.set_scissor_state = i915_set_scissor_state;
- i915->base.set_fragment_sampler_textures = i915_set_sampler_textures;
+ i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views;
+ i915->base.create_sampler_view = i915_create_sampler_view;
+ i915->base.sampler_view_destroy = i915_sampler_view_destroy;
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
}
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index f5b0e9f011e..4da46772b5d 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -101,14 +101,14 @@ static void calculate_vertex_layout( struct i915_context *i915 )
/* primary color */
if (colors[0]) {
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
- draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
}
/* secondary color */
if (colors[1]) {
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
- draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
@@ -157,10 +157,10 @@ void i915_update_derived( struct i915_context *i915 )
if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS))
calculate_vertex_layout( i915 );
- if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE))
+ if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW))
i915_update_samplers(i915);
- if (i915->dirty & I915_NEW_TEXTURE)
+ if (i915->dirty & I915_NEW_SAMPLER_VIEW)
i915_update_textures(i915);
if (i915->dirty)
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 51f0ef12baf..04a3924aaf7 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -182,7 +182,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
if(i915->vbo)
OUT_RELOC(i915->vbo,
- INTEL_USAGE_VERTEX,
+ I915_USAGE_VERTEX,
i915->current.immediate[I915_IMMEDIATE_S0]);
else
/* FIXME: we should not do this */
@@ -226,7 +226,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
ctile);
OUT_RELOC(tex->buffer,
- INTEL_USAGE_RENDER,
+ I915_USAGE_RENDER,
cbuf_surface->offset);
}
@@ -250,7 +250,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
ztile);
OUT_RELOC(tex->buffer,
- INTEL_USAGE_RENDER,
+ I915_USAGE_RENDER,
depth_surface->offset);
}
@@ -290,13 +290,14 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
- struct intel_buffer *buf = i915->texture[unit]->buffer;
+ struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture;
+ struct i915_winsys_buffer *buf = texture->buffer;
uint offset = 0;
assert(buf);
count++;
- OUT_RELOC(buf, INTEL_USAGE_SAMPLER, offset);
+ OUT_RELOC(buf, I915_USAGE_SAMPLER, offset);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
}
diff --git a/src/gallium/drivers/i915/i915_state_immediate.c b/src/gallium/drivers/i915/i915_state_immediate.c
index d2c6f151434..8cec699285c 100644
--- a/src/gallium/drivers/i915/i915_state_immediate.c
+++ b/src/gallium/drivers/i915/i915_state_immediate.c
@@ -52,11 +52,11 @@ static void upload_S0S1(struct i915_context *i915)
{
unsigned LIS0, LIS1;
- /* INTEL_NEW_VBO */
+ /* I915_NEW_VBO */
/* TODO: re-use vertex buffers here? */
LIS0 = i915->vbo_offset;
- /* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated!
+ /* I915_NEW_VERTEX_SIZE -- do this where the vertex size is calculated!
*/
{
unsigned vertex_size = i915->current.vertex_info.size;
@@ -65,7 +65,7 @@ static void upload_S0S1(struct i915_context *i915)
(vertex_size << 16));
}
- /* INTEL_NEW_VBO */
+ /* I915_NEW_VBO */
/* TODO: use a vertex generation number to track vbo changes */
if (1 ||
i915->current.immediate[I915_IMMEDIATE_S0] != LIS0 ||
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index 9813290b51b..4c326561cb9 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -144,20 +144,22 @@ void i915_update_samplers( struct i915_context *i915 )
i915->current.sampler_enable_nr = 0;
i915->current.sampler_enable_flags = 0x0;
- for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
+ for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
- if (i915->texture[unit]) {
+ if (i915->fragment_sampler_views[unit]) {
+ struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture;
+
update_sampler( i915,
unit,
i915->sampler[unit], /* sampler state */
- i915->texture[unit], /* texture */
+ texture, /* texture */
i915->current.sampler[unit] /* the result */
);
i915_update_texture( i915,
unit,
- i915->texture[unit], /* texture */
+ texture, /* texture */
i915->sampler[unit], /* sampler state */
i915->current.texbuffer[unit] );
@@ -190,6 +192,14 @@ translate_texture_format(enum pipe_format pipeFormat)
return MAPSURF_16BIT | MT_16BIT_ARGB4444;
case PIPE_FORMAT_B8G8R8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_XRGB8888;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_ABGR8888;
+#if 0
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_XBGR8888;
+#endif
case PIPE_FORMAT_YUYV:
return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case PIPE_FORMAT_UYVY:
@@ -281,14 +291,16 @@ i915_update_textures(struct i915_context *i915)
{
uint unit;
- for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
+ for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
- if (i915->texture[unit]) {
+ if (i915->fragment_sampler_views[unit]) {
+ struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture;
+
i915_update_texture( i915,
unit,
- i915->texture[unit], /* texture */
+ texture, /* texture */
i915->sampler[unit], /* sampler state */
i915->current.texbuffer[unit] );
}
diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c
index b252fb5330c..8c405c2443e 100644
--- a/src/gallium/drivers/i915/i915_texture.c
+++ b/src/gallium/drivers/i915/i915_texture.c
@@ -41,7 +41,7 @@
#include "i915_context.h"
#include "i915_texture.h"
#include "i915_screen.h"
-#include "intel_winsys.h"
+#include "i915_winsys.h"
/*
@@ -162,7 +162,7 @@ i915_scanout_layout(struct i915_texture *tex)
if (pt->width0 >= 240) {
tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
- tex->hw_tiled = INTEL_TILE_X;
+ tex->hw_tiled = I915_TILE_X;
} else if (pt->width0 == 64 && pt->height0 == 64) {
tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
@@ -200,7 +200,7 @@ i915_display_target_layout(struct i915_texture *tex)
tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
- tex->hw_tiled = INTEL_TILE_X;
+ tex->hw_tiled = I915_TILE_X;
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
pt->width0, pt->height0, util_format_get_blocksize(pt->format),
@@ -617,7 +617,7 @@ i915_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
struct i915_screen *is = i915_screen(screen);
- struct intel_winsys *iws = is->iws;
+ struct i915_winsys *iws = is->iws;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size;
unsigned buf_usage = 0;
@@ -643,9 +643,9 @@ i915_texture_create(struct pipe_screen *screen,
/* for scanouts and cursors, cursors arn't scanouts */
if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64)
- buf_usage = INTEL_NEW_SCANOUT;
+ buf_usage = I915_NEW_SCANOUT;
else
- buf_usage = INTEL_NEW_TEXTURE;
+ buf_usage = I915_NEW_TEXTURE;
tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
if (!tex->buffer)
@@ -653,7 +653,7 @@ i915_texture_create(struct pipe_screen *screen,
/* setup any hw fences */
if (tex->hw_tiled) {
- assert(tex->sw_tiled == INTEL_TILE_NONE);
+ assert(tex->sw_tiled == I915_TILE_NONE);
iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled);
}
@@ -679,8 +679,8 @@ i915_texture_from_handle(struct pipe_screen * screen,
{
struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex;
- struct intel_winsys *iws = is->iws;
- struct intel_buffer *buffer;
+ struct i915_winsys *iws = is->iws;
+ struct i915_winsys_buffer *buffer;
unsigned stride;
assert(screen);
@@ -719,7 +719,7 @@ i915_texture_get_handle(struct pipe_screen * screen,
{
struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex = (struct i915_texture *)texture;
- struct intel_winsys *iws = is->iws;
+ struct i915_winsys *iws = is->iws;
return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride);
}
@@ -729,7 +729,7 @@ static void
i915_texture_destroy(struct pipe_texture *pt)
{
struct i915_texture *tex = (struct i915_texture *)pt;
- struct intel_winsys *iws = i915_screen(pt->screen)->iws;
+ struct i915_winsys *iws = i915_screen(pt->screen)->iws;
uint i;
/*
@@ -841,7 +841,7 @@ i915_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
- struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
+ struct i915_winsys *iws = i915_screen(tex->base.screen)->iws;
char *map;
boolean write = FALSE;
enum pipe_format format = tex->base.format;
@@ -863,7 +863,7 @@ i915_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
- struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
+ struct i915_winsys *iws = i915_screen(tex->base.screen)->iws;
iws->buffer_unmap(iws, tex->buffer);
}
diff --git a/src/gallium/drivers/i915/intel_winsys.h b/src/gallium/drivers/i915/i915_winsys.h
index 00fd0c1efea..246e95b00d6 100644
--- a/src/gallium/drivers/i915/intel_winsys.h
+++ b/src/gallium/drivers/i915/i915_winsys.h
@@ -23,46 +23,46 @@
*
**************************************************************************/
-#ifndef INTEL_WINSYS_H
-#define INTEL_WINSYS_H
+#ifndef I915_WINSYS_H
+#define I915_WINSYS_H
#include "pipe/p_compiler.h"
-struct intel_winsys;
-struct intel_buffer;
-struct intel_batchbuffer;
+struct i915_winsys;
+struct i915_winsys_buffer;
+struct i915_winsys_batchbuffer;
struct pipe_texture;
struct pipe_fence_handle;
struct winsys_handle;
-enum intel_buffer_usage
+enum i915_winsys_buffer_usage
{
/* use on textures */
- INTEL_USAGE_RENDER = 0x01,
- INTEL_USAGE_SAMPLER = 0x02,
- INTEL_USAGE_2D_TARGET = 0x04,
- INTEL_USAGE_2D_SOURCE = 0x08,
+ I915_USAGE_RENDER = 0x01,
+ I915_USAGE_SAMPLER = 0x02,
+ I915_USAGE_2D_TARGET = 0x04,
+ I915_USAGE_2D_SOURCE = 0x08,
/* use on vertex */
- INTEL_USAGE_VERTEX = 0x10
+ I915_USAGE_VERTEX = 0x10
};
-enum intel_buffer_type
+enum i915_winsys_buffer_type
{
- INTEL_NEW_TEXTURE,
- INTEL_NEW_SCANOUT, /**< a texture used for scanning out from */
- INTEL_NEW_VERTEX
+ I915_NEW_TEXTURE,
+ I915_NEW_SCANOUT, /**< a texture used for scanning out from */
+ I915_NEW_VERTEX
};
-enum intel_buffer_tile
+enum i915_winsys_buffer_tile
{
- INTEL_TILE_NONE,
- INTEL_TILE_X,
- INTEL_TILE_Y
+ I915_TILE_NONE,
+ I915_TILE_X,
+ I915_TILE_Y
};
-struct intel_batchbuffer {
+struct i915_winsys_batchbuffer {
- struct intel_winsys *iws;
+ struct i915_winsys *iws;
/**
* Values exported to speed up the writing the batchbuffer,
@@ -79,7 +79,7 @@ struct intel_batchbuffer {
/*@}*/
};
-struct intel_winsys {
+struct i915_winsys {
/**
* Batchbuffer functions.
@@ -88,7 +88,8 @@ struct intel_winsys {
/**
* Create a new batchbuffer.
*/
- struct intel_batchbuffer *(*batchbuffer_create)(struct intel_winsys *iws);
+ struct i915_winsys_batchbuffer *
+ (*batchbuffer_create)(struct i915_winsys *iws);
/**
* Emit a relocation to a buffer.
@@ -100,21 +101,21 @@ struct intel_winsys {
* @offset add this to the reloc buffers address
* @target buffer where to write the address, null for batchbuffer.
*/
- int (*batchbuffer_reloc)(struct intel_batchbuffer *batch,
- struct intel_buffer *reloc,
- enum intel_buffer_usage usage,
+ int (*batchbuffer_reloc)(struct i915_winsys_batchbuffer *batch,
+ struct i915_winsys_buffer *reloc,
+ enum i915_winsys_buffer_usage usage,
unsigned offset);
/**
* Flush a bufferbatch.
*/
- void (*batchbuffer_flush)(struct intel_batchbuffer *batch,
+ void (*batchbuffer_flush)(struct i915_winsys_batchbuffer *batch,
struct pipe_fence_handle **fence);
/**
* Destroy a batchbuffer.
*/
- void (*batchbuffer_destroy)(struct intel_batchbuffer *batch);
+ void (*batchbuffer_destroy)(struct i915_winsys_batchbuffer *batch);
/*@}*/
@@ -125,9 +126,10 @@ struct intel_winsys {
/**
* Create a buffer.
*/
- struct intel_buffer *(*buffer_create)(struct intel_winsys *iws,
- unsigned size, unsigned alignment,
- enum intel_buffer_type type);
+ struct i915_winsys_buffer *
+ (*buffer_create)(struct i915_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum i915_winsys_buffer_type type);
/**
* Creates a buffer from a handle.
@@ -135,16 +137,17 @@ struct intel_winsys {
* Also provides the stride information needed for the
* texture via the stride argument.
*/
- struct intel_buffer *(*buffer_from_handle)(struct intel_winsys *iws,
- struct winsys_handle *whandle,
- unsigned *stride);
+ struct i915_winsys_buffer *
+ (*buffer_from_handle)(struct i915_winsys *iws,
+ struct winsys_handle *whandle,
+ unsigned *stride);
/**
* Used to implement pipe_screen::texture_get_handle.
* The winsys might need the stride information.
*/
- boolean (*buffer_get_handle)(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+ boolean (*buffer_get_handle)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
struct winsys_handle *whandle,
unsigned stride);
@@ -152,37 +155,37 @@ struct intel_winsys {
* Fence a buffer with a fence reg.
* Not to be confused with pipe_fence_handle.
*/
- int (*buffer_set_fence_reg)(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+ int (*buffer_set_fence_reg)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
unsigned stride,
- enum intel_buffer_tile tile);
+ enum i915_winsys_buffer_tile tile);
/**
* Map a buffer.
*/
- void *(*buffer_map)(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+ void *(*buffer_map)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
boolean write);
/**
* Unmap a buffer.
*/
- void (*buffer_unmap)(struct intel_winsys *iws,
- struct intel_buffer *buffer);
+ void (*buffer_unmap)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer);
/**
* Write to a buffer.
*
* Arguments follows pipe_buffer_write.
*/
- int (*buffer_write)(struct intel_winsys *iws,
- struct intel_buffer *dst,
+ int (*buffer_write)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *dst,
size_t offset,
size_t size,
const void *data);
- void (*buffer_destroy)(struct intel_winsys *iws,
- struct intel_buffer *buffer);
+ void (*buffer_destroy)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer);
/*@}*/
@@ -193,20 +196,20 @@ struct intel_winsys {
/**
* Reference fence and set ptr to fence.
*/
- void (*fence_reference)(struct intel_winsys *iws,
+ void (*fence_reference)(struct i915_winsys *iws,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence);
/**
* Check if a fence has finished.
*/
- int (*fence_signalled)(struct intel_winsys *iws,
+ int (*fence_signalled)(struct i915_winsys *iws,
struct pipe_fence_handle *fence);
/**
* Wait on a fence to finish.
*/
- int (*fence_finish)(struct intel_winsys *iws,
+ int (*fence_finish)(struct i915_winsys *iws,
struct pipe_fence_handle *fence);
/*@}*/
@@ -214,14 +217,14 @@ struct intel_winsys {
/**
* Destroy the winsys.
*/
- void (*destroy)(struct intel_winsys *iws);
+ void (*destroy)(struct i915_winsys *iws);
};
/**
* Create i915 pipe_screen.
*/
-struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
+struct pipe_screen *i915_create_screen(struct i915_winsys *iws, unsigned pci_id);
#endif
diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript
index 9c2faaf4b49..d900ea25968 100644
--- a/src/gallium/drivers/i965/SConscript
+++ b/src/gallium/drivers/i965/SConscript
@@ -58,6 +58,7 @@ i965 = env.ConvenienceLibrary(
'brw_vs_emit.c',
'brw_vs_state.c',
'brw_vs_surface_state.c',
+ 'brw_winsys_debug.c',
'brw_wm.c',
# 'brw_wm_constant_buffer.c',
'brw_wm_debug.c',
diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c
index 3dbe2b91308..4bcdcdd17eb 100644
--- a/src/gallium/drivers/i965/brw_context.c
+++ b/src/gallium/drivers/i965/brw_context.c
@@ -118,6 +118,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen,
brw->sws = brw_screen(screen)->sws;
brw->chipset = brw_screen(screen)->chipset;
+ brw_tex_init( brw );
brw_pipe_blend_init( brw );
brw_pipe_depth_stencil_init( brw );
brw_pipe_framebuffer_init( brw );
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
index f5b1a06576b..dab881fea24 100644
--- a/src/gallium/drivers/i965/brw_context.h
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -551,9 +551,9 @@ struct brw_context
const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
unsigned num_samplers;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- unsigned num_textures;
+ unsigned num_fragment_sampler_views;
unsigned num_vertex_buffers;
struct pipe_scissor_state scissor;
diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c
index c7c0e2ae95e..d2aa2bc9f35 100644
--- a/src/gallium/drivers/i965/brw_pipe_sampler.c
+++ b/src/gallium/drivers/i965/brw_pipe_sampler.c
@@ -183,26 +183,26 @@ static void brw_delete_sampler_state(struct pipe_context *pipe,
FREE(cso);
}
-static void brw_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static void brw_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct brw_context *brw = brw_context(pipe);
int i;
for (i = 0; i < num; i++)
- pipe_texture_reference(&brw->curr.texture[i], texture[i]);
+ pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], views[i]);
- for (i = num; i < brw->curr.num_textures; i++)
- pipe_texture_reference(&brw->curr.texture[i], NULL);
+ for (i = num; i < brw->curr.num_fragment_sampler_views; i++)
+ pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], NULL);
- brw->curr.num_textures = num;
+ brw->curr.num_fragment_sampler_views = num;
brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES;
}
-static void brw_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static void brw_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
}
@@ -212,17 +212,47 @@ static void brw_bind_vertex_sampler_state(struct pipe_context *pipe,
}
+static struct pipe_sampler_view *
+brw_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+brw_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+
void brw_pipe_sampler_init( struct brw_context *brw )
{
brw->base.create_sampler_state = brw_create_sampler_state;
brw->base.delete_sampler_state = brw_delete_sampler_state;
- brw->base.set_fragment_sampler_textures = brw_set_sampler_textures;
+ brw->base.set_fragment_sampler_views = brw_set_fragment_sampler_views;
brw->base.bind_fragment_sampler_states = brw_bind_sampler_state;
- brw->base.set_vertex_sampler_textures = brw_set_vertex_sampler_textures;
+ brw->base.set_vertex_sampler_views = brw_set_vertex_sampler_views;
brw->base.bind_vertex_sampler_states = brw_bind_vertex_sampler_state;
+ brw->base.create_sampler_view = brw_create_sampler_view;
+ brw->base.sampler_view_destroy = brw_sampler_view_destroy;
}
void brw_pipe_sampler_cleanup( struct brw_context *brw )
{
diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c
index cadcb7cee2a..f9f17bdabac 100644
--- a/src/gallium/drivers/i965/brw_screen_texture.c
+++ b/src/gallium/drivers/i965/brw_screen_texture.c
@@ -206,7 +206,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
/* XXX: compressed textures need special treatment here
*/
tex->cpp = util_format_get_blocksize(tex->base.format);
- tex->compressed = util_format_is_compressed(tex->base.format);
+ tex->compressed = util_format_is_s3tc(tex->base.format);
make_empty_list(&tex->views[0]);
make_empty_list(&tex->views[1]);
@@ -321,7 +321,7 @@ brw_texture_from_handle(struct pipe_screen *screen,
templ->depth0 != 1)
return NULL;
- if (util_format_is_compressed(templ->format))
+ if (util_format_is_s3tc(templ->format))
return NULL;
tex = CALLOC_STRUCT(brw_texture);
diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c
index dfb718e64fe..7ed2378ec04 100644
--- a/src/gallium/drivers/i965/brw_wm.c
+++ b/src/gallium/drivers/i965/brw_wm.c
@@ -251,8 +251,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* PIPE_NEW_BOUND_TEXTURES */
- for (i = 0; i < brw->curr.num_textures; i++) {
- const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+ for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {
+ const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);
if (tex->base.format == PIPE_FORMAT_UYVY)
key->yuvtex_mask |= 1 << i;
diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c
index 6a6086fc51b..3f18062c584 100644
--- a/src/gallium/drivers/i965/brw_wm_sampler_state.c
+++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c
@@ -78,11 +78,11 @@ brw_wm_sampler_populate_key(struct brw_context *brw,
memset(key, 0, sizeof(*key));
- key->sampler_count = MIN2(brw->curr.num_textures,
+ key->sampler_count = MIN2(brw->curr.num_fragment_sampler_views,
brw->curr.num_samplers);
for (i = 0; i < key->sampler_count; i++) {
- const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+ const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);
const struct brw_sampler *sampler = brw->curr.sampler[i];
struct brw_sampler_state *entry = &key->sampler[i];
@@ -122,12 +122,12 @@ static enum pipe_error
brw_wm_sampler_update_default_colors(struct brw_context *brw)
{
enum pipe_error ret;
- int nr = MIN2(brw->curr.num_textures,
+ int nr = MIN2(brw->curr.num_fragment_sampler_views,
brw->curr.num_samplers);
int i;
for (i = 0; i < nr; i++) {
- const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+ const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);
const struct brw_sampler *sampler = brw->curr.sampler[i];
const float *bc;
float bordercolor[4] = {
diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c
index b01a7f194b7..2368ae3f808 100644
--- a/src/gallium/drivers/i965/brw_wm_surface_state.c
+++ b/src/gallium/drivers/i965/brw_wm_surface_state.c
@@ -242,9 +242,9 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
/* PIPE_NEW_TEXTURE
*/
- for (i = 0; i < brw->curr.num_textures; i++) {
+ for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {
ret = brw_update_texture_surface(brw,
- brw_texture(brw->curr.texture[i]),
+ brw_texture(brw->curr.fragment_sampler_views[i]->texture),
&brw->wm.surf_bo[BTI_TEXTURE(i)]);
if (ret)
return ret;
@@ -261,7 +261,7 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);
/* XXX: no pipe_max_textures define?? */
- for (i = brw->curr.num_textures; i < PIPE_MAX_SAMPLERS; i++)
+ for (i = brw->curr.num_fragment_sampler_views; i < PIPE_MAX_SAMPLERS; i++)
bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);
if (brw->wm.nr_surfaces != nr_surfaces) {
diff --git a/src/gallium/drivers/identity/SConscript b/src/gallium/drivers/identity/SConscript
index 7f079dd0a8b..2a68891c284 100644
--- a/src/gallium/drivers/identity/SConscript
+++ b/src/gallium/drivers/identity/SConscript
@@ -5,9 +5,10 @@ env = env.Clone()
identity = env.ConvenienceLibrary(
target = 'identity',
source = [
- 'id_screen.c',
'id_context.c',
+ 'id_drm.c',
'id_objects.c',
+ 'id_screen.c',
])
Export('identity')
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 26770d6b1e9..00a542215ad 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -528,53 +528,49 @@ identity_set_viewport_state(struct pipe_context *_pipe,
}
static void
-identity_set_fragment_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **_textures)
+identity_set_fragment_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **_views)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS];
- struct pipe_texture **textures = NULL;
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view **views = NULL;
unsigned i;
- if (_textures) {
- for (i = 0; i < num_textures; i++)
- unwrapped_textures[i] = identity_texture_unwrap(_textures[i]);
+ if (_views) {
+ for (i = 0; i < num; i++)
+ unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]);
for (; i < PIPE_MAX_SAMPLERS; i++)
- unwrapped_textures[i] = NULL;
+ unwrapped_views[i] = NULL;
- textures = unwrapped_textures;
+ views = unwrapped_views;
}
- pipe->set_fragment_sampler_textures(pipe,
- num_textures,
- textures);
+ pipe->set_fragment_sampler_views(pipe, num, views);
}
static void
-identity_set_vertex_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **_textures)
+identity_set_vertex_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **_views)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
- struct pipe_texture **textures = NULL;
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view **views = NULL;
unsigned i;
- if (_textures) {
- for (i = 0; i < num_textures; i++)
- unwrapped_textures[i] = identity_texture_unwrap(_textures[i]);
+ if (_views) {
+ for (i = 0; i < num; i++)
+ unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]);
for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
- unwrapped_textures[i] = NULL;
+ unwrapped_views[i] = NULL;
- textures = unwrapped_textures;
+ views = unwrapped_views;
}
- pipe->set_vertex_sampler_textures(pipe,
- num_textures,
- textures);
+ pipe->set_vertex_sampler_views(pipe, num, views);
}
static void
@@ -711,6 +707,45 @@ identity_is_buffer_referenced(struct pipe_context *_pipe,
buffer);
}
+static struct pipe_sampler_view *
+identity_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct identity_context *id_pipe = identity_context(pipe);
+ struct identity_texture *id_texture = identity_texture(texture);
+ struct pipe_context *pipe_unwrapped = id_pipe->pipe;
+ struct pipe_texture *texture_unwrapped = id_texture->texture;
+ struct identity_sampler_view *view = malloc(sizeof(struct identity_sampler_view));
+
+ view->sampler_view = pipe_unwrapped->create_sampler_view(pipe_unwrapped,
+ texture_unwrapped,
+ templ);
+
+ view->base = *templ;
+ view->base.reference.count = 1;
+ view->base.texture = NULL;
+ pipe_texture_reference(&view->base.texture, texture);
+ view->base.context = pipe;
+
+ return &view->base;
+}
+
+static void
+identity_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ struct identity_context *id_pipe = identity_context(pipe);
+ struct identity_sampler_view *id_view = identity_sampler_view(view);
+ struct pipe_context *pipe_unwrapped = id_pipe->pipe;
+ struct pipe_sampler_view *view_unwrapped = id_view->sampler_view;
+
+ pipe_unwrapped->sampler_view_destroy(pipe_unwrapped,
+ view_unwrapped);
+
+ pipe_texture_reference(&view->texture, NULL);
+ free(view);
+}
static struct pipe_transfer *
@@ -836,8 +871,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple;
id_pipe->base.set_scissor_state = identity_set_scissor_state;
id_pipe->base.set_viewport_state = identity_set_viewport_state;
- id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures;
- id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures;
+ id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views;
+ id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
id_pipe->base.surface_copy = identity_surface_copy;
id_pipe->base.surface_fill = identity_surface_fill;
@@ -845,6 +880,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.flush = identity_flush;
id_pipe->base.is_texture_referenced = identity_is_texture_referenced;
id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced;
+ id_pipe->base.create_sampler_view = identity_create_sampler_view;
+ id_pipe->base.sampler_view_destroy = identity_sampler_view_destroy;
id_pipe->base.get_tex_transfer = identity_context_get_tex_transfer;
id_pipe->base.tex_transfer_destroy = identity_context_tex_transfer_destroy;
id_pipe->base.transfer_map = identity_context_transfer_map;
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index 936ccc444a8..26920fed08d 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -31,7 +31,6 @@
#include "id_drm.h"
#include "id_screen.h"
#include "id_public.h"
-#include "id_screen.h"
#include "id_objects.h"
struct identity_drm_api
diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h
index 7333ecfb7fb..9a07ebe8d72 100644
--- a/src/gallium/drivers/identity/id_objects.h
+++ b/src/gallium/drivers/identity/id_objects.h
@@ -53,6 +53,14 @@ struct identity_texture
};
+struct identity_sampler_view
+{
+ struct pipe_sampler_view base;
+
+ struct pipe_sampler_view *sampler_view;
+};
+
+
struct identity_surface
{
struct pipe_surface base;
@@ -96,6 +104,15 @@ identity_texture(struct pipe_texture *_texture)
return (struct identity_texture *)_texture;
}
+static INLINE struct identity_sampler_view *
+identity_sampler_view(struct pipe_sampler_view *_sampler_view)
+{
+ if (!_sampler_view) {
+ return NULL;
+ }
+ return (struct identity_sampler_view *)_sampler_view;
+}
+
static INLINE struct identity_surface *
identity_surface(struct pipe_surface *_surface)
{
@@ -140,6 +157,15 @@ identity_texture_unwrap(struct pipe_texture *_texture)
return identity_texture(_texture)->texture;
}
+static INLINE struct pipe_sampler_view *
+identity_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view)
+{
+ if (!_sampler_view) {
+ return NULL;
+ }
+ return identity_sampler_view(_sampler_view)->sampler_view;
+}
+
static INLINE struct pipe_surface *
identity_surface_unwrap(struct pipe_surface *_surface)
{
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 89c06ea3ad7..b37c6754c08 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -42,6 +42,11 @@ C_SOURCES = \
CPP_SOURCES = \
+PROGS := lp_test_format \
+ lp_test_blend \
+ lp_test_conv \
+ lp_test_printf
+
include ../../Makefile.template
@@ -49,13 +54,7 @@ lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxil
python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@
-testprogs := lp_test_format \
- lp_test_blend \
- lp_test_conv
-
-LIBS += $(GL_LIB_DEPS) -L. -lllvmpipe -L../../auxiliary/ -lgallium
+LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium
-#$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a
-# $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group
+$(PROGS): lp_test_main.o
-#default: $(testprogs)
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index e0676c80a25..383e4b0614d 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -69,11 +69,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&llvmpipe->texture[i], NULL);
+ pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL);
+ pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], NULL);
}
for (i = 0; i < Elements(llvmpipe->constants); i++) {
@@ -158,8 +158,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
- llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures;
- llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures;
+ llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
+ llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
+ llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
+ llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index f391871b0ee..71f991049e5 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -69,15 +69,15 @@ struct llvmpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
- unsigned num_textures;
+ unsigned num_fragment_sampler_views;
unsigned num_vertex_samplers;
- unsigned num_vertex_textures;
+ unsigned num_vertex_sampler_views;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of LP_NEW_x flags */
diff --git a/src/gallium/drivers/llvmpipe/lp_fence.c b/src/gallium/drivers/llvmpipe/lp_fence.c
index 525c117f316..00dc3eab6b1 100644
--- a/src/gallium/drivers/llvmpipe/lp_fence.c
+++ b/src/gallium/drivers/llvmpipe/lp_fence.c
@@ -29,6 +29,7 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "lp_debug.h"
#include "lp_fence.h"
@@ -99,6 +100,21 @@ llvmpipe_fence_finish(struct pipe_screen *screen,
}
+void
+lp_fence_signal(struct lp_fence *fence)
+{
+ pipe_mutex_lock(fence->mutex);
+
+ fence->count++;
+ assert(fence->count <= fence->rank);
+
+ LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__,
+ fence->count, fence->rank);
+
+ pipe_condvar_signal(fence->signalled);
+
+ pipe_mutex_unlock(fence->mutex);
+}
void
diff --git a/src/gallium/drivers/llvmpipe/lp_fence.h b/src/gallium/drivers/llvmpipe/lp_fence.h
index c90e6de423b..d9270f5784a 100644
--- a/src/gallium/drivers/llvmpipe/lp_fence.h
+++ b/src/gallium/drivers/llvmpipe/lp_fence.h
@@ -54,6 +54,10 @@ lp_fence_create(unsigned rank);
void
+lp_fence_signal(struct lp_fence *fence);
+
+
+void
llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen);
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 636d72a9bb8..782669a1e77 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -111,7 +111,6 @@ llvmpipe_flush_texture(struct pipe_context *pipe,
boolean cpu_access,
boolean do_not_flush)
{
- struct pipe_fence_handle *last_fence = NULL;
unsigned referenced;
referenced = pipe->is_texture_referenced(pipe, texture, face, level);
@@ -142,7 +141,7 @@ llvmpipe_flush_texture(struct pipe_context *pipe,
pipe->flush(pipe, flush_flags, &fence);
- if (last_fence) {
+ if (fence) {
pipe->screen->fence_finish(pipe->screen, fence, 0);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 5887613120d..927e472ff26 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -91,36 +91,53 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
/* struct lp_jit_context */
{
- LLVMTypeRef elem_types[8];
+ LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
LLVMTypeRef context_type;
- elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
- elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ elem_types[2] = LLVMFloatType(); /* scissor_xmin */
- elem_types[3] = LLVMFloatType(); /* scissor_ymin */
- elem_types[4] = LLVMFloatType(); /* scissor_xmax */
- elem_types[5] = LLVMFloatType(); /* scissor_ymax */
- elem_types[6] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
- elem_types[7] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
+ 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_SCISSOR_XMIN] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_SCISSOR_YMIN] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_SCISSOR_XMAX] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_SCISSOR_YMAX] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_BLEND_COLOR] = LLVMPointerType(LLVMInt8Type(), 0);
+ elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type,
+ PIPE_MAX_SAMPLERS);
context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants,
- screen->target, context_type, 0);
+ screen->target, context_type,
+ LP_JIT_CTX_CONSTANTS);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
- screen->target, context_type, 1);
+ screen->target, context_type,
+ LP_JIT_CTX_ALPHA_REF);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front,
+ screen->target, context_type,
+ LP_JIT_CTX_STENCIL_REF_FRONT);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back,
+ screen->target, context_type,
+ LP_JIT_CTX_STENCIL_REF_BACK);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin,
- screen->target, context_type, 2);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_XMIN);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin,
- screen->target, context_type, 3);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_YMIN);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax,
- screen->target, context_type, 4);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_XMAX);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax,
- screen->target, context_type, 5);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_YMAX);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
- screen->target, context_type, 6);
+ screen->target, context_type,
+ LP_JIT_CTX_BLEND_COLOR);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
screen->target, context_type,
- LP_JIT_CONTEXT_TEXTURES_INDEX);
+ LP_JIT_CTX_TEXTURES);
LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
screen->target, context_type);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 13167ae3bf4..4930ff02e6b 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -84,6 +84,8 @@ struct lp_jit_context
float alpha_ref_value;
+ uint32_t stencil_ref_front, stencil_ref_back;
+
/** floats, not ints */
float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax;
@@ -94,37 +96,66 @@ struct lp_jit_context
};
+/**
+ * These enum values must match the position of the fields in the
+ * lp_jit_context struct above.
+ */
+enum {
+ LP_JIT_CTX_CONSTANTS = 0,
+ LP_JIT_CTX_ALPHA_REF,
+ LP_JIT_CTX_STENCIL_REF_FRONT,
+ LP_JIT_CTX_STENCIL_REF_BACK,
+ LP_JIT_CTX_SCISSOR_XMIN,
+ LP_JIT_CTX_SCISSOR_YMIN,
+ LP_JIT_CTX_SCISSOR_XMAX,
+ LP_JIT_CTX_SCISSOR_YMAX,
+ LP_JIT_CTX_BLEND_COLOR,
+ LP_JIT_CTX_TEXTURES,
+ LP_JIT_CTX_COUNT
+};
+
+
#define lp_jit_context_constants(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 0, "constants")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_CONSTANTS, "constants")
#define lp_jit_context_alpha_ref_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value")
+ lp_build_struct_get(_builder, _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_back_value(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_BACK, "stencil_ref_back")
#define lp_jit_context_scissor_xmin_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 2, "scissor_xmin")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMIN, "scissor_xmin")
#define lp_jit_context_scissor_ymin_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 3, "scissor_ymin")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMIN, "scissor_ymin")
#define lp_jit_context_scissor_xmax_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 4, "scissor_xmax")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMAX, "scissor_xmax")
#define lp_jit_context_scissor_ymax_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 5, "scissor_ymax")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMAX, "scissor_ymax")
#define lp_jit_context_blend_color(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 6, "blend_color")
-
-#define LP_JIT_CONTEXT_TEXTURES_INDEX 7
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color")
#define lp_jit_context_textures(_builder, _ptr) \
- lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures")
+ lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES, "textures")
+
+
+/** Indexes into jit_function[] array */
+#define RAST_WHOLE 0
+#define RAST_EDGE_TEST 1
typedef void
(*lp_jit_frag_func)(const struct lp_jit_context *context,
uint32_t x,
uint32_t y,
+ float facing,
const void *a0,
const void *dadx,
const void *dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 81ea11a16b6..8352f175598 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -189,7 +189,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
- assert(rast->zsbuf.map);
+ /*assert(rast->zsbuf.map);*/
if (!rast->zsbuf.map)
return;
@@ -312,15 +312,16 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
depth = lp_rast_depth_pointer(rast, tile_x + x, tile_y + y);
/* run shader */
- state->jit_function[0]( &state->jit_context,
- tile_x + x, tile_y + y,
- inputs->a0,
- inputs->dadx,
- inputs->dady,
- color,
- depth,
- INT_MIN, INT_MIN, INT_MIN,
- NULL, NULL, NULL );
+ state->jit_function[RAST_WHOLE]( &state->jit_context,
+ tile_x + x, tile_y + y,
+ inputs->facing,
+ inputs->a0,
+ inputs->dadx,
+ inputs->dady,
+ color,
+ depth,
+ INT_MIN, INT_MIN, INT_MIN,
+ NULL, NULL, NULL );
}
}
}
@@ -375,15 +376,18 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
assert(lp_check_alignment(inputs->step[2], 16));
/* run shader */
- state->jit_function[1]( &state->jit_context,
- x, y,
- inputs->a0,
- inputs->dadx,
- inputs->dady,
- color,
- depth,
- c1, c2, c3,
- inputs->step[0], inputs->step[1], inputs->step[2]);
+ state->jit_function[RAST_EDGE_TEST]( &state->jit_context,
+ x, y,
+ inputs->facing,
+ inputs->a0,
+ inputs->dadx,
+ inputs->dady,
+ color,
+ depth,
+ c1, c2, c3,
+ inputs->step[0],
+ inputs->step[1],
+ inputs->step[2]);
}
@@ -487,18 +491,7 @@ lp_rast_fence(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
struct lp_fence *fence = arg.fence;
-
- pipe_mutex_lock( fence->mutex );
-
- fence->count++;
- assert(fence->count <= fence->rank);
-
- LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__,
- fence->count, fence->rank);
-
- pipe_condvar_signal( fence->signalled );
-
- pipe_mutex_unlock( fence->mutex );
+ lp_fence_signal(fence);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 303f6e3f7e4..ae838f3fbef 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -82,6 +82,8 @@ struct lp_rast_state {
* These pointers point into the bin data buffer.
*/
struct lp_rast_shader_inputs {
+ float facing; /** Positive for front-facing, negative for back-facing */
+
float (*a0)[4];
float (*dadx)[4];
float (*dady)[4];
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 39bf2c25879..6ee9bcaae3a 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -195,6 +195,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
/* run shader */
state->jit_function[0]( &state->jit_context,
x, y,
+ inputs->facing,
inputs->a0,
inputs->dadx,
inputs->dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 5093f58bb19..f1bbc2092c4 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -204,8 +204,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
return FALSE;
}
- if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if(!winsys->is_displaytarget_format_supported(winsys, format))
+ if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index d977f98cfaa..af25e043cc9 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -34,7 +34,7 @@
#ifndef LP_SCREEN_H
#define LP_SCREEN_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include <llvm-c/ExecutionEngine.h>
#include "pipe/p_screen.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 16128c34c80..76a8b87a309 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -402,6 +402,20 @@ lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
}
void
+lp_setup_set_stencil_ref_values( struct lp_setup_context *setup,
+ const ubyte refs[2] )
+{
+ LP_DBG(DEBUG_SETUP, "%s %d %d\n", __FUNCTION__, refs[0], refs[1]);
+
+ if (setup->fs.current.jit_context.stencil_ref_front != refs[0] ||
+ setup->fs.current.jit_context.stencil_ref_back != refs[1]) {
+ setup->fs.current.jit_context.stencil_ref_front = refs[0];
+ setup->fs.current.jit_context.stencil_ref_back = refs[1];
+ setup->dirty |= LP_SETUP_NEW_FS;
+ }
+}
+
+void
lp_setup_set_blend_color( struct lp_setup_context *setup,
const struct pipe_blend_color *blend_color )
{
@@ -450,11 +464,12 @@ lp_setup_set_vertex_info( struct lp_setup_context *setup,
/**
- * Called during state validation when LP_NEW_TEXTURE is set.
+ * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
*/
void
-lp_setup_set_sampler_textures( struct lp_setup_context *setup,
- unsigned num, struct pipe_texture **texture)
+lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
unsigned i;
@@ -463,9 +478,10 @@ lp_setup_set_sampler_textures( struct lp_setup_context *setup,
assert(num <= PIPE_MAX_SAMPLERS);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num ? texture[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- if(tex) {
+ if(view) {
+ struct pipe_texture *tex = view->texture;
struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
struct lp_jit_texture *jit_tex;
jit_tex = &setup->fs.current.jit_context.textures[i];
@@ -473,6 +489,12 @@ lp_setup_set_sampler_textures( struct lp_setup_context *setup,
jit_tex->height = tex->height0;
jit_tex->depth = tex->depth0;
jit_tex->last_level = tex->last_level;
+
+ /* We're referencing the texture's internal data, so save a
+ * reference to it.
+ */
+ pipe_texture_reference(&setup->fs.current_tex[i], tex);
+
if (!lp_tex->dt) {
/* regular texture - setup array of mipmap level pointers */
int j;
@@ -495,12 +517,6 @@ lp_setup_set_sampler_textures( struct lp_setup_context *setup,
jit_tex->row_stride[0] = lp_tex->stride[0];
assert(jit_tex->data[0]);
}
-
- /* the scene references this texture */
- {
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
- lp_scene_texture_reference(scene, tex);
- }
}
}
@@ -635,6 +651,7 @@ lp_setup_update_state( struct lp_setup_context *setup )
* the new, current state. So allocate a new lp_rast_state object
* and append it to the bin's setup data buffer.
*/
+ uint i;
struct lp_rast_state *stored =
(struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
if(stored) {
@@ -648,6 +665,14 @@ lp_setup_update_state( struct lp_setup_context *setup )
lp_rast_set_state,
lp_rast_arg_state(setup->fs.stored) );
}
+
+ /* The scene now references the textures in the rasterization
+ * state record. Note that now.
+ */
+ for (i = 0; i < Elements(setup->fs.current_tex); i++) {
+ if (setup->fs.current_tex[i])
+ lp_scene_texture_reference(scene, setup->fs.current_tex[i]);
+ }
}
}
@@ -663,8 +688,14 @@ lp_setup_update_state( struct lp_setup_context *setup )
void
lp_setup_destroy( struct lp_setup_context *setup )
{
+ uint i;
+
reset_context( setup );
+ for (i = 0; i < Elements(setup->fs.current_tex); i++) {
+ pipe_texture_reference(&setup->fs.current_tex[i], NULL);
+ }
+
pipe_buffer_reference(&setup->constants.current, NULL);
/* free the scenes in the 'empty' queue */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index be1bf96f12d..dbfc1bf8d4c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -113,6 +113,10 @@ lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
float alpha_ref_value );
void
+lp_setup_set_stencil_ref_values( struct lp_setup_context *setup,
+ const ubyte refs[2] );
+
+void
lp_setup_set_blend_color( struct lp_setup_context *setup,
const struct pipe_blend_color *blend_color );
@@ -121,8 +125,9 @@ lp_setup_set_scissor( struct lp_setup_context *setup,
const struct pipe_scissor_state *scissor );
void
-lp_setup_set_sampler_textures( struct lp_setup_context *setup,
- unsigned num, struct pipe_texture **texture);
+lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_sampler_view **views);
unsigned
lp_setup_is_texture_referenced( const struct lp_setup_context *setup,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 464fb369840..ca0dafab627 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -111,6 +111,7 @@ struct lp_setup_context
const struct lp_rast_state *stored; /**< what's in the scene */
struct lp_rast_state current; /**< currently set state */
+ struct pipe_texture *current_tex[PIPE_MAX_SAMPLERS];
} fs;
/** fragment shader constants */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index ac6264dc73e..ce689d3d568 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -361,6 +361,8 @@ do_triangle_ccw(struct lp_setup_context *setup,
*/
setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing );
+ tri->inputs.facing = frontfacing ? 1.0F : -1.0F;
+
/* half-edge constants, will be interated over the whole render target.
*/
tri->c1 = tri->dy12 * x1 - tri->dx12 * y1;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index a5a1a720742..74ebf90d580 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -31,7 +31,7 @@
#ifndef LP_STATE_H
#define LP_STATE_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
@@ -50,7 +50,7 @@
#define LP_NEW_DEPTH_STENCIL_ALPHA 0x100
#define LP_NEW_CONSTANTS 0x200
#define LP_NEW_SAMPLER 0x400
-#define LP_NEW_TEXTURE 0x800
+#define LP_NEW_SAMPLER_VIEW 0x800
#define LP_NEW_VERTEX 0x1000
#define LP_NEW_VS 0x2000
#define LP_NEW_QUERY 0x4000
@@ -67,6 +67,7 @@ struct lp_fragment_shader;
struct lp_fragment_shader_variant_key
{
struct pipe_depth_state depth;
+ struct pipe_stencil_state stencil[2];
struct pipe_alpha_state alpha;
struct pipe_blend_state blend;
enum pipe_format zsbuf_format;
@@ -192,14 +193,23 @@ void llvmpipe_set_polygon_stipple( struct pipe_context *,
void llvmpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
-void llvmpipe_set_sampler_textures( struct pipe_context *,
- unsigned num,
- struct pipe_texture ** );
+void llvmpipe_set_fragment_sampler_views(struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view **);
void
-llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+llvmpipe_set_vertex_sampler_views(struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view **);
+
+struct pipe_sampler_view *
+llvmpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ);
+
+void
+llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index bdd906e1a73..777871638f6 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -150,7 +150,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
*/
if (llvmpipe->tex_timestamp != lp_screen->timestamp) {
llvmpipe->tex_timestamp = lp_screen->timestamp;
- llvmpipe->dirty |= LP_NEW_TEXTURE;
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
}
if (llvmpipe->dirty & (LP_NEW_RASTERIZER |
@@ -164,7 +164,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
LP_NEW_DEPTH_STENCIL_ALPHA |
LP_NEW_RASTERIZER |
LP_NEW_SAMPLER |
- LP_NEW_TEXTURE))
+ LP_NEW_SAMPLER_VIEW))
llvmpipe_update_fs( llvmpipe );
if (llvmpipe->dirty & LP_NEW_BLEND_COLOR)
@@ -174,18 +174,21 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
if (llvmpipe->dirty & LP_NEW_SCISSOR)
lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor);
- if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA)
+ if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) {
lp_setup_set_alpha_ref_value(llvmpipe->setup,
llvmpipe->depth_stencil->alpha.ref_value);
+ lp_setup_set_stencil_ref_values(llvmpipe->setup,
+ llvmpipe->stencil_ref.ref_value);
+ }
if (llvmpipe->dirty & LP_NEW_CONSTANTS)
lp_setup_set_fs_constants(llvmpipe->setup,
llvmpipe->constants[PIPE_SHADER_FRAGMENT]);
- if (llvmpipe->dirty & LP_NEW_TEXTURE)
- lp_setup_set_sampler_textures(llvmpipe->setup,
- llvmpipe->num_textures,
- llvmpipe->texture);
+ if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
+ lp_setup_set_fragment_sampler_views(llvmpipe->setup,
+ llvmpipe->num_fragment_sampler_views,
+ llvmpipe->fragment_sampler_views);
llvmpipe->dirty = 0;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 9a8de0edfda..7bbf348e0b8 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -138,20 +138,22 @@ generate_pos0(LLVMBuilderRef builder,
/**
- * Generate the depth test.
+ * Generate the depth /stencil test code.
*/
static void
-generate_depth(LLVMBuilderRef builder,
- const struct lp_fragment_shader_variant_key *key,
- struct lp_type src_type,
- struct lp_build_mask_context *mask,
- LLVMValueRef src,
- LLVMValueRef dst_ptr)
+generate_depth_stencil(LLVMBuilderRef builder,
+ const struct lp_fragment_shader_variant_key *key,
+ struct lp_type src_type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef stencil_refs[2],
+ LLVMValueRef src,
+ LLVMValueRef dst_ptr,
+ LLVMValueRef facing)
{
const struct util_format_description *format_desc;
struct lp_type dst_type;
- if(!key->depth.enabled)
+ if (!key->depth.enabled && !key->stencil[0].enabled && !key->stencil[1].enabled)
return;
format_desc = util_format_description(key->zsbuf_format);
@@ -178,19 +180,22 @@ generate_depth(LLVMBuilderRef builder,
assert(dst_type.width == src_type.width);
assert(dst_type.length == src_type.length);
+ /* Convert fragment Z from float to integer */
lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
dst_ptr = LLVMBuildBitCast(builder,
dst_ptr,
LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
-
- lp_build_depth_test(builder,
- &key->depth,
- dst_type,
- format_desc,
- mask,
- src,
- dst_ptr);
+ lp_build_depth_stencil_test(builder,
+ &key->depth,
+ key->stencil,
+ dst_type,
+ format_desc,
+ mask,
+ stencil_refs,
+ src,
+ dst_ptr,
+ facing);
}
@@ -252,7 +257,7 @@ generate_tri_edge_mask(LLVMBuilderRef builder,
LLVMConstInt(LLVMInt32Type(), INT_MIN, 0),
"");
- in_out_mask = lp_build_int_const_scalar(i32_type, ~0);
+ in_out_mask = lp_build_const_int_vec(i32_type, ~0);
lp_build_flow_scope_declare(flow, &in_out_mask);
@@ -367,7 +372,7 @@ build_int32_vec_const(int value)
i32_type.norm = FALSE; /* values are not normalized */
i32_type.width = 32; /* 32-bit int values */
i32_type.length = 4; /* 4 elements per vector */
- return lp_build_int_const_scalar(i32_type, value);
+ return lp_build_const_int_vec(i32_type, value);
}
@@ -390,6 +395,7 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef *pmask,
LLVMValueRef (*color)[4],
LLVMValueRef depth_ptr,
+ LLVMValueRef facing,
unsigned do_tri_test,
LLVMValueRef c0,
LLVMValueRef c1,
@@ -405,15 +411,19 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef consts_ptr;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef z = interp->pos[2];
+ LLVMValueRef stencil_refs[2];
struct lp_build_flow_context *flow;
struct lp_build_mask_context mask;
- boolean early_depth_test;
+ boolean early_depth_stencil_test;
unsigned attrib;
unsigned chan;
unsigned cbuf;
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);
+
elem_type = lp_build_elem_type(type);
vec_type = lp_build_vec_type(type);
int_vec_type = lp_build_int_vec_type(type);
@@ -453,16 +463,16 @@ generate_fs(struct llvmpipe_context *lp,
lp_build_mask_update(&mask, smask);
}
- early_depth_test =
- key->depth.enabled &&
+ early_depth_stencil_test =
+ (key->depth.enabled || key->stencil[0].enabled) &&
!key->alpha.enabled &&
!shader->info.uses_kill &&
!shader->info.writes_z;
- if(early_depth_test)
- generate_depth(builder, key,
- type, &mask,
- z, depth_ptr);
+ if (early_depth_stencil_test)
+ generate_depth_stencil(builder, key,
+ type, &mask,
+ stencil_refs, z, depth_ptr, facing);
lp_build_tgsi_soa(builder, tokens, type, &mask,
consts_ptr, interp->pos, interp->inputs,
@@ -506,10 +516,10 @@ generate_fs(struct llvmpipe_context *lp,
}
}
- if(!early_depth_test)
- generate_depth(builder, key,
- type, &mask,
- z, depth_ptr);
+ if (!early_depth_stencil_test)
+ generate_depth_stencil(builder, key,
+ type, &mask,
+ stencil_refs, z, depth_ptr, facing);
lp_build_mask_end(&mask);
@@ -585,6 +595,20 @@ generate_blend(const struct pipe_blend_state *blend,
}
+/** casting function to avoid compiler warnings */
+static lp_jit_frag_func
+cast_voidptr_to_lp_jit_frag_func(void *p)
+{
+ union {
+ void *v;
+ lp_jit_frag_func f;
+ } tmp;
+ assert(sizeof(tmp.v) == sizeof(tmp.f));
+ tmp.v = p;
+ return tmp.f;
+}
+
+
/**
* Generate the runtime callable function for the whole fragment pipeline.
* Note that the function which we generate operates on a block of 16
@@ -606,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMTypeRef fs_int_vec_type;
LLVMTypeRef blend_vec_type;
LLVMTypeRef blend_int_vec_type;
- LLVMTypeRef arg_types[14];
+ LLVMTypeRef arg_types[15];
LLVMTypeRef func_type;
LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
LLVMValueRef context_ptr;
@@ -629,6 +653,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMValueRef blend_mask;
LLVMValueRef blend_in_color[NUM_CHANNELS];
LLVMValueRef function;
+ LLVMValueRef facing;
unsigned num_fs;
unsigned i;
unsigned chan;
@@ -668,20 +693,21 @@ generate_fragment(struct llvmpipe_context *lp,
arg_types[0] = screen->context_ptr_type; /* context */
arg_types[1] = LLVMInt32Type(); /* x */
arg_types[2] = LLVMInt32Type(); /* y */
- arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */
- arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */
- arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */
- arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */
- arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
- arg_types[8] = LLVMInt32Type(); /* c0 */
- arg_types[9] = LLVMInt32Type(); /* c1 */
- arg_types[10] = LLVMInt32Type(); /* c2 */
+ arg_types[3] = LLVMFloatType(); /* 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(fs_int_vec_type, 0); /* depth */
+ arg_types[9] = LLVMInt32Type(); /* c0 */
+ arg_types[10] = LLVMInt32Type(); /* c1 */
+ arg_types[11] = LLVMInt32Type(); /* c2 */
/* Note: the step arrays are built as int32[16] but we interpret
* them here as int32_vec4[4].
*/
- arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
- arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
- arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
+ arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
+ arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
+ arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
@@ -701,17 +727,18 @@ generate_fragment(struct llvmpipe_context *lp,
context_ptr = LLVMGetParam(function, 0);
x = LLVMGetParam(function, 1);
y = LLVMGetParam(function, 2);
- a0_ptr = LLVMGetParam(function, 3);
- dadx_ptr = LLVMGetParam(function, 4);
- dady_ptr = LLVMGetParam(function, 5);
- color_ptr_ptr = LLVMGetParam(function, 6);
- depth_ptr = LLVMGetParam(function, 7);
- c0 = LLVMGetParam(function, 8);
- c1 = LLVMGetParam(function, 9);
- c2 = LLVMGetParam(function, 10);
- step0_ptr = LLVMGetParam(function, 11);
- step1_ptr = LLVMGetParam(function, 12);
- step2_ptr = LLVMGetParam(function, 13);
+ facing = LLVMGetParam(function, 3);
+ a0_ptr = LLVMGetParam(function, 4);
+ dadx_ptr = LLVMGetParam(function, 5);
+ dady_ptr = LLVMGetParam(function, 6);
+ color_ptr_ptr = LLVMGetParam(function, 7);
+ depth_ptr = LLVMGetParam(function, 8);
+ c0 = LLVMGetParam(function, 9);
+ c1 = LLVMGetParam(function, 10);
+ c2 = LLVMGetParam(function, 11);
+ step0_ptr = LLVMGetParam(function, 12);
+ step1_ptr = LLVMGetParam(function, 13);
+ step2_ptr = LLVMGetParam(function, 14);
lp_build_name(context_ptr, "context");
lp_build_name(x, "x");
@@ -770,6 +797,7 @@ generate_fragment(struct llvmpipe_context *lp,
&fs_mask[i], /* output */
out_color,
depth_ptr_i,
+ facing,
do_tri_test,
c0, c1, c2,
step0_ptr, step1_ptr, step2_ptr);
@@ -845,10 +873,14 @@ generate_fragment(struct llvmpipe_context *lp,
/*
* Translate the LLVM IR into machine code.
*/
- variant->jit_function[do_tri_test] = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, function);
+ {
+ void *f = LLVMGetPointerToGlobal(screen->engine, function);
+
+ variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f);
- if (LP_DEBUG & DEBUG_ASM)
- lp_disassemble(variant->jit_function[do_tri_test]);
+ if (LP_DEBUG & DEBUG_ASM)
+ lp_disassemble(f);
+ }
}
@@ -1054,10 +1086,15 @@ make_variant_key(struct llvmpipe_context *lp,
memset(key, 0, sizeof *key);
- if(lp->framebuffer.zsbuf &&
- lp->depth_stencil->depth.enabled) {
- key->zsbuf_format = lp->framebuffer.zsbuf->format;
- memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
+ if (lp->framebuffer.zsbuf) {
+ if (lp->depth_stencil->depth.enabled) {
+ key->zsbuf_format = lp->framebuffer.zsbuf->format;
+ memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
+ }
+ if (lp->depth_stencil->stencil[0].enabled) {
+ key->zsbuf_format = lp->framebuffer.zsbuf->format;
+ memcpy(&key->stencil, &lp->depth_stencil->stencil, sizeof key->stencil);
+ }
}
key->alpha.enabled = lp->depth_stencil->alpha.enabled;
@@ -1094,7 +1131,7 @@ make_variant_key(struct llvmpipe_context *lp,
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
- lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]);
+ lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i]->texture, lp->sampler[i]);
}
@@ -1140,6 +1177,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
opaque = !key.blend.logicop_enable &&
!key.blend.rt[0].blend_enable &&
key.blend.rt[0].colormask == 0xf &&
+ !key.stencil[0].enabled &&
!key.alpha.enabled &&
!key.depth.enabled &&
!key.scissor &&
@@ -1147,7 +1185,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
? TRUE : FALSE;
lp_setup_set_fs_functions(lp->setup,
- shader->current->jit_function[0],
- shader->current->jit_function[1],
+ shader->current->jit_function[RAST_WHOLE],
+ shader->current->jit_function[RAST_EDGE_TEST],
opaque);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index b30a0757768..2645441b58c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -105,8 +105,9 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
void
-llvmpipe_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
uint i;
@@ -114,51 +115,79 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == llvmpipe->num_textures &&
- !memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == llvmpipe->num_fragment_sampler_views &&
+ !memcmp(llvmpipe->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
draw_flush(llvmpipe->draw);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num ? texture[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&llvmpipe->texture[i], tex);
+ pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], view);
}
- llvmpipe->num_textures = num;
+ llvmpipe->num_fragment_sampler_views = num;
- llvmpipe->dirty |= LP_NEW_TEXTURE;
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
}
void
-llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
uint i;
- assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
- if (num_textures == llvmpipe->num_vertex_textures &&
- !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ if (num == llvmpipe->num_vertex_sampler_views &&
+ !memcmp(llvmpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
return;
}
draw_flush(llvmpipe->draw);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&llvmpipe->vertex_textures[i], tex);
+ pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], view);
}
- llvmpipe->num_vertex_textures = num_textures;
+ llvmpipe->num_vertex_sampler_views = num;
- llvmpipe->dirty |= LP_NEW_TEXTURE;
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
+}
+
+
+struct pipe_sampler_view *
+llvmpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+void
+llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h
index 1df98978988..338a04a4878 100644
--- a/src/gallium/drivers/llvmpipe/lp_test.h
+++ b/src/gallium/drivers/llvmpipe/lp_test.h
@@ -41,7 +41,7 @@
#include <stdio.h>
#include <float.h>
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index 2c4d7fb6e14..fb595893bd0 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c
new file mode 100644
index 00000000000..e5e5925012a
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gallivm/lp_bld.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"
+
+
+struct printf_test_case {
+};
+
+void
+write_tsv_header(FILE *fp)
+{
+ fprintf(fp,
+ "result\t"
+ "format\n");
+
+ fflush(fp);
+}
+
+
+
+typedef void (*test_printf_t)(int i);
+
+static LLVMValueRef
+add_printf_test(LLVMModuleRef module)
+{
+ LLVMTypeRef args[1] = { LLVMIntType(32) };
+ LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidType(), args, 1, 0));
+ LLVMBuilderRef builder = LLVMCreateBuilder();
+ LLVMBasicBlockRef block = LLVMAppendBasicBlock(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));
+ LLVMBuildRetVoid(builder);
+ LLVMDisposeBuilder(builder);
+ return func;
+}
+
+
+PIPE_ALIGN_STACK
+static boolean
+test_printf(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;
+ char *error = NULL;
+ test_printf_t test_printf;
+ float unpacked[4];
+ unsigned packed;
+ boolean success = TRUE;
+
+ module = LLVMModuleCreateWithName("test");
+
+ test = add_printf_test(module);
+
+ if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
+ LLVMDumpModule(module);
+ abort();
+ }
+ LLVMDisposeMessage(error);
+
+ provider = LLVMCreateModuleProviderForExistingModule(module);
+ if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
+ fprintf(stderr, "%s\n", error);
+ LLVMDisposeMessage(error);
+ abort();
+ }
+
+#if 0
+ pass = LLVMCreatePassManager();
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ LLVMAddConstantPropagationPass(pass);
+ LLVMAddInstructionCombiningPass(pass);
+ LLVMAddPromoteMemoryToRegisterPass(pass);
+ LLVMAddGVNPass(pass);
+ LLVMAddCFGSimplificationPass(pass);
+ LLVMRunPassManager(pass, module);
+#else
+ (void)pass;
+#endif
+
+ test_printf = (test_printf_t)LLVMGetPointerToGlobal(engine, test);
+
+ memset(unpacked, 0, sizeof unpacked);
+ packed = 0;
+
+
+ // LLVMDumpModule(module);
+
+ test_printf(0);
+
+ LLVMFreeMachineCodeForFunction(engine, test);
+
+ LLVMDisposeExecutionEngine(engine);
+ if(pass)
+ LLVMDisposePassManager(pass);
+
+ return success;
+}
+
+
+boolean
+test_all(unsigned verbose, FILE *fp)
+{
+ bool success = TRUE;
+
+ test_printf(verbose, fp, NULL);
+
+ return success;
+}
+
+
+boolean
+test_some(unsigned verbose, FILE *fp, unsigned long n)
+{
+ return test_all(verbose, fp);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
index 799df182b6a..1228a831f3b 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
@@ -29,7 +29,7 @@
#define LP_TEX_SAMPLE_H
-#include "os/os_llvm.h"
+#include "gallivm/lp_bld.h"
struct lp_sampler_static_state;
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 662508af61a..4715cfe4f62 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -105,7 +105,7 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
/* context[0] */
indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
/* context[0].textures */
- indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CONTEXT_TEXTURES_INDEX, 0);
+ indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CTX_TEXTURES, 0);
/* context[0].textures[unit] */
indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
/* context[0].textures[unit].member */
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 9a85a42897d..8137f29af52 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -103,6 +103,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
unsigned height = align(lpt->base.height0, TILE_SIZE);
lpt->dt = winsys->displaytarget_create(winsys,
+ lpt->base.tex_usage,
lpt->base.format,
width, height,
16,
@@ -250,6 +251,51 @@ llvmpipe_texture_unmap(struct pipe_texture *texture,
}
+static struct pipe_texture *
+llvmpipe_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *template,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
+ struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
+ if (!lpt)
+ return NULL;
+
+ lpt->base = *template;
+ pipe_reference_init(&lpt->base.reference, 1);
+ lpt->base.screen = screen;
+
+ lpt->dt = winsys->displaytarget_from_handle(winsys,
+ template,
+ whandle,
+ &lpt->stride[0]);
+ if (!lpt->dt)
+ goto fail;
+
+ return &lpt->base;
+
+ fail:
+ FREE(lpt);
+ return NULL;
+}
+
+
+static boolean
+llvmpipe_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
+ struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
+
+ assert(lpt->dt);
+ if (!lpt->dt)
+ return FALSE;
+
+ return winsys->displaytarget_get_handle(winsys, lpt->dt, whandle);
+}
+
+
static struct pipe_surface *
llvmpipe_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt,
@@ -418,6 +464,8 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = llvmpipe_texture_create;
screen->texture_destroy = llvmpipe_texture_destroy;
+ screen->texture_from_handle = llvmpipe_texture_from_handle;
+ screen->texture_get_handle = llvmpipe_texture_get_handle;
screen->get_tex_surface = llvmpipe_get_tex_surface;
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index 8afc95c9fc6..5447904e9ca 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -35,7 +35,10 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned mode = 0, i;
+ const unsigned dirty = nv50->dirty;
+ /* don't need NEW_BLEND, NV50TCL_COLOR_MASK doesn't affect CLEAR_BUFFERS */
+ nv50->dirty &= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
if (!nv50_state_validate(nv50, 64))
return;
@@ -64,5 +67,6 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
OUT_RING (chan, (i << 6) | 0x3c);
}
+ nv50->dirty = dirty;
}
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 1743f6fb394..bc7831d9aca 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -72,12 +72,23 @@ struct nv50_sampler_stateobj {
unsigned tsc[8];
};
+struct nv50_sampler_view {
+ struct pipe_sampler_view pipe;
+ uint32_t tic[8];
+};
+
struct nv50_vtxelt_stateobj {
struct pipe_vertex_element pipe[16];
unsigned num_elements;
uint32_t hw[16];
};
+static INLINE struct nv50_sampler_view *
+nv50_sampler_view(struct pipe_sampler_view *view)
+{
+ return (struct nv50_sampler_view *)view;
+}
+
static INLINE unsigned
get_tile_height(uint32_t tile_mode)
{
@@ -126,7 +137,7 @@ struct nv50_state {
struct nouveau_stateobj *hw[64];
uint64_t hw_dirty;
- unsigned miptree_nr[PIPE_SHADER_TYPES];
+ unsigned sampler_view_nr[3];
struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr;
unsigned vtxelt_nr;
@@ -158,10 +169,10 @@ struct nv50_context {
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
struct nv50_vtxelt_stateobj *vtxelt;
- struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
- unsigned sampler_nr[PIPE_SHADER_TYPES];
- struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
- unsigned miptree_nr[PIPE_SHADER_TYPES];
+ struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS];
+ unsigned sampler_nr[3];
+ struct pipe_sampler_view *sampler_views[3][PIPE_MAX_SAMPLERS];
+ unsigned sampler_view_nr[3];
unsigned vbo_fifo;
};
@@ -243,6 +254,7 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50,
unsigned offset, unsigned size);
/* nv50_tex.c */
+extern boolean nv50_tex_construct(struct nv50_sampler_view *view);
extern void nv50_tex_relocs(struct nv50_context *);
extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index c857816b31a..d7e06c93272 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -3762,7 +3762,7 @@ nv50_program_tx_prep(struct nv50_pc *pc)
p->cfg.in[n].hw = rid = aid;
i = p->cfg.in[n].id;
- if (p->info.input_semantic_name[n] ==
+ if (p->info.input_semantic_name[i] ==
TGSI_SEMANTIC_FACE) {
load_frontfacing(pc, &pc->attr[i * 4]);
continue;
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index adf0d3b3741..1a4606d9e25 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -109,7 +109,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_TWO_SIDED_STENCIL:
return 1;
case PIPE_CAP_GLSL:
- return 0;
+ return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
@@ -190,8 +190,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->tic);
if (screen->tsc)
nouveau_bo_ref(NULL, &screen->tsc);
- if (screen->static_init)
- so_ref(NULL, &screen->static_init);
nouveau_notifier_free(&screen->sync);
nouveau_grobj_free(&screen->tesla);
@@ -204,16 +202,65 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
FREE(screen);
}
+#define BGN_RELOC(ch, bo, gr, m, n, fl) \
+ OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
+
+void
+nv50_screen_relocs(struct nv50_screen *screen)
+{
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *tesla = screen->tesla;
+ unsigned i;
+ const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
+
+ MARK_RING (chan, 28, 26);
+
+ /* cause grobj autobind */
+ BEGIN_RING(chan, tesla, 0x0100, 1);
+ OUT_RING (chan, 0);
+
+ BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl);
+ OUT_RELOCh(chan, screen->tic, 0, rl);
+ OUT_RELOCl(chan, screen->tic, 0, rl);
+
+ BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl);
+ OUT_RELOCh(chan, screen->tsc, 0, rl);
+ OUT_RELOCl(chan, screen->tsc, 0, rl);
+
+ BGN_RELOC (chan, screen->constbuf_misc[0],
+ tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RELOC (chan, screen->constbuf_misc[0],
+ (NV50_CB_PMISC << 16) | 0x0200, rl, 0, 0);
+
+ BGN_RELOC (chan, screen->constbuf_misc[0],
+ tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RELOC (chan, screen->constbuf_misc[0],
+ (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0);
+
+ for (i = 0; i < 3; ++i) {
+ BGN_RELOC (chan, screen->constbuf_parm[i],
+ tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+ OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RELOC (chan, screen->constbuf_parm[i],
+ ((NV50_CB_PVP + i) << 16) | 0x0800, rl, 0, 0);
+ }
+}
+
struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
struct nouveau_channel *chan;
struct pipe_screen *pscreen;
- struct nouveau_stateobj *so;
unsigned chipset = dev->chipset;
unsigned tesla_class = 0;
int ret, i;
+ const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
if (!screen)
return NULL;
@@ -296,64 +343,58 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
}
/* Static M2MF init */
- so = so_new(1, 3, 0);
- so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
- so_data (so, screen->sync->handle);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_emit(chan, so);
- so_ref (NULL, &so);
+ BEGIN_RING(chan, screen->m2mf,
+ NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
+ OUT_RING (chan, screen->sync->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
/* Static 2D init */
- so = so_new(4, 7, 0);
- so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
- so_data (so, screen->sync->handle);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_method(so, screen->eng2d, NV50_2D_OPERATION, 1);
- so_data (so, NV50_2D_OPERATION_SRCCOPY);
- so_method(so, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
- so_data (so, 0);
- so_method(so, screen->eng2d, 0x0888, 1);
- so_data (so, 1);
- so_emit(chan, so);
- so_ref(NULL, &so);
+ BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
+ OUT_RING (chan, screen->sync->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
+ BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1);
+ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
+ BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, screen->eng2d, 0x0888, 1);
+ OUT_RING (chan, 1);
/* Static tesla init */
- so = so_new(47, 95, 24);
-
- so_method(so, screen->tesla, NV50TCL_COND_MODE, 1);
- so_data (so, NV50TCL_COND_MODE_ALWAYS);
- so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
- so_data (so, screen->sync->handle);
- so_method(so, screen->tesla, NV50TCL_DMA_ZETA, 11);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1);
+ OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
+ OUT_RING (chan, screen->sync->handle);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11);
for (i = 0; i < 11; i++)
- so_data(so, chan->vram->handle);
- so_method(so, screen->tesla, NV50TCL_DMA_COLOR(0),
- NV50TCL_DMA_COLOR__SIZE);
+ OUT_RING (chan, chan->vram->handle);
+ BEGIN_RING(chan, screen->tesla,
+ NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE);
for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++)
- so_data(so, chan->vram->handle);
- so_method(so, screen->tesla, NV50TCL_RT_CONTROL, 1);
- so_data (so, 1);
+ OUT_RING (chan, chan->vram->handle);
+
+ BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1);
+ OUT_RING (chan, 1);
/* activate all 32 lanes (threads) in a warp */
- so_method(so, screen->tesla, NV50TCL_WARP_HALVES, 1);
- so_data (so, 0x2);
- so_method(so, screen->tesla, 0x1400, 1);
- so_data (so, 0xf);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_WARP_HALVES, 1);
+ OUT_RING (chan, 2);
+ BEGIN_RING(chan, screen->tesla, 0x1400, 1);
+ OUT_RING (chan, 0xf);
/* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
for (i = 0; i < 3; ++i) {
- so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
- so_data (so, 0x54);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
+ OUT_RING (chan, 0x54);
}
/* origin is top left (set to 1 for bottom left) */
- so_method(so, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
- so_data (so, 0);
- so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
- so_data (so, 8);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
+ OUT_RING (chan, 8);
/* constant buffers for immediates and VP/FP parameters */
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
@@ -362,6 +403,14 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
nv50_screen_destroy(pscreen);
return NULL;
}
+ BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RING (chan, (NV50_CB_PMISC << 16) | 0x0200);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200);
for (i = 0; i < 3; i++) {
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4,
@@ -370,6 +419,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
nv50_screen_destroy(pscreen);
return NULL;
}
+ BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0800);
}
if (nouveau_resource_init(&screen->immd_heap[0], 0, 128) ||
@@ -381,118 +434,67 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- /*
- // map constant buffers:
- // B = buffer ID (maybe more than 1 byte)
- // N = CB index used in shader instruction
- // P = program type (0 = VP, 2 = GP, 3 = FP)
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x000BBNP1);
- */
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PMISC << 16) | 0x00000200);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000001 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000021 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000031 | (NV50_CB_PMISC << 12));
-
- /* bind auxiliary constbuf to immediate data bo */
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_AUX << 16) | 0x00000200);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000201 | (NV50_CB_AUX << 12));
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000221 | (NV50_CB_AUX << 12));
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PVP << 16) | 0x00000800);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000101 | (NV50_CB_PVP << 12));
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PGP << 16) | 0x00000800);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000121 | (NV50_CB_PGP << 12));
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PFP << 16) | 0x00000800);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000131 | (NV50_CB_PFP << 12));
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
&screen->tic);
if (ret) {
nv50_screen_destroy(pscreen);
return NULL;
}
+ BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RING (chan, 3 * 32 - 1);
- so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
- so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, PIPE_SHADER_TYPES * 32 - 1);
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
&screen->tsc);
if (ret) {
nv50_screen_destroy(pscreen);
return NULL;
}
-
- so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
- so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, 0x00000000); /* ignored if TSC_LINKED (0x1234) = 1 */
-
+ BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RING (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */
+
+ /* map constant buffers:
+ * B = buffer ID (maybe more than 1 byte)
+ * N = CB index used in shader instruction
+ * P = program type (0 = VP, 2 = GP, 3 = FP)
+ * SET_PROGRAM_CB = 0x000BBNP1
+ */
+ BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8);
+ /* bind immediate buffer */
+ OUT_RING (chan, 0x001 | (NV50_CB_PMISC << 12));
+ OUT_RING (chan, 0x021 | (NV50_CB_PMISC << 12));
+ OUT_RING (chan, 0x031 | (NV50_CB_PMISC << 12));
+ /* bind auxiliary constbuf to immediate data bo */
+ OUT_RING (chan, 0x201 | (NV50_CB_AUX << 12));
+ OUT_RING (chan, 0x221 | (NV50_CB_AUX << 12));
+ /* bind parameter buffers */
+ OUT_RING (chan, 0x101 | (NV50_CB_PVP << 12));
+ OUT_RING (chan, 0x121 | (NV50_CB_PGP << 12));
+ OUT_RING (chan, 0x131 | (NV50_CB_PFP << 12));
/* Vertex array limits - max them out */
for (i = 0; i < 16; i++) {
- so_method(so, screen->tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
- so_data (so, 0x000000ff);
- so_data (so, 0xffffffff);
+ BEGIN_RING(chan, screen->tesla,
+ NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
+ OUT_RING (chan, 0x000000ff);
+ OUT_RING (chan, 0xffffffff);
}
- so_method(so, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
- so_data (so, fui(0.0));
- so_data (so, fui(1.0));
+ BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
+ OUT_RINGf (chan, 0.0f);
+ OUT_RINGf (chan, 1.0f);
/* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
- so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1);
- so_data (so, 1);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
+ OUT_RING (chan, 1);
- so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
- so_data (so, 1); /* default edgeflag to TRUE */
+ BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, 1); /* default edgeflag to TRUE */
- so_emit(chan, so);
- so_ref (so, &screen->static_init);
- so_ref (NULL, &so);
- nouveau_pushbuf_flush(chan, 0);
+ FIRE_RING (chan);
screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
return pscreen;
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index ec19ea655b1..15bd4eed399 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -27,8 +27,6 @@ struct nv50_screen {
struct nouveau_bo *tic;
struct nouveau_bo *tsc;
- struct nouveau_stateobj *static_init;
-
boolean force_push;
};
@@ -38,4 +36,6 @@ nv50_screen(struct pipe_screen *screen)
return (struct nv50_screen *)screen;
}
+extern void nv50_screen_relocs(struct nv50_screen *);
+
#endif
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index b0e5552eff4..c1628089285 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -238,6 +238,9 @@ nv50_sampler_state_create(struct pipe_context *pipe,
return (void *)sso;
}
+/* type == 0 for VPs, 1 for GPs, 2 for FPs, which is how the
+ * relevant tesla methods are indexed (NV50TCL_BIND_TSC etc.)
+ */
static INLINE void
nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,
unsigned nr, void **sampler)
@@ -253,13 +256,13 @@ nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,
static void
nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
{
- nv50_sampler_state_bind(pipe, PIPE_SHADER_VERTEX, nr, s);
+ nv50_sampler_state_bind(pipe, 0, nr, s);
}
static void
nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
{
- nv50_sampler_state_bind(pipe, PIPE_SHADER_FRAGMENT, nr, s);
+ nv50_sampler_state_bind(pipe, 2, nr, s);
}
static void
@@ -269,35 +272,69 @@ nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
}
static INLINE void
-nv50_set_sampler_texture(struct pipe_context *pipe, unsigned type,
- unsigned nr, struct pipe_texture **pt)
+nv50_set_sampler_views(struct pipe_context *pipe, unsigned p,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
struct nv50_context *nv50 = nv50_context(pipe);
unsigned i;
for (i = 0; i < nr; i++)
- pipe_texture_reference((void *)&nv50->miptree[type][i], pt[i]);
- for (i = nr; i < nv50->miptree_nr[type]; i++)
- pipe_texture_reference((void *)&nv50->miptree[type][i], NULL);
+ pipe_sampler_view_reference(&nv50->sampler_views[p][i],
+ views[i]);
+
+ for (i = nr; i < nv50->sampler_view_nr[p]; i++)
+ pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL);
- nv50->miptree_nr[type] = nr;
+ nv50->sampler_view_nr[p] = nr;
nv50->dirty |= NV50_NEW_TEXTURE;
}
static void
-nv50_set_vp_sampler_textures(struct pipe_context *pipe,
- unsigned nr, struct pipe_texture **pt)
+nv50_set_vp_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
- nv50_set_sampler_texture(pipe, PIPE_SHADER_VERTEX, nr, pt);
+ nv50_set_sampler_views(pipe, 0, nr, views);
}
static void
-nv50_set_fp_sampler_textures(struct pipe_context *pipe,
- unsigned nr, struct pipe_texture **pt)
+nv50_set_fp_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
- nv50_set_sampler_texture(pipe, PIPE_SHADER_FRAGMENT, nr, pt);
+ nv50_set_sampler_views(pipe, 2, nr, views);
}
+static void
+nv50_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(nv50_sampler_view(view));
+}
+
+static struct pipe_sampler_view *
+nv50_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view);
+
+ view->pipe = *templ;
+ view->pipe.reference.count = 1;
+ view->pipe.texture = NULL;
+ pipe_texture_reference(&view->pipe.texture, texture);
+ view->pipe.context = pipe;
+
+ if (!nv50_tex_construct(view)) {
+ nv50_sampler_view_destroy(pipe, &view->pipe);
+ return NULL;
+ }
+ return &view->pipe;
+}
+
+
static void *
nv50_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
@@ -765,8 +802,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind;
nv50->pipe.bind_vertex_sampler_states = nv50_vp_sampler_state_bind;
- nv50->pipe.set_fragment_sampler_textures = nv50_set_fp_sampler_textures;
- nv50->pipe.set_vertex_sampler_textures = nv50_set_vp_sampler_textures;
+ nv50->pipe.set_fragment_sampler_views = nv50_set_fp_sampler_views;
+ nv50->pipe.set_vertex_sampler_views = nv50_set_vp_sampler_views;
+ nv50->pipe.create_sampler_view = nv50_create_sampler_view;
+ nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy;
nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index 2c8e7ca7982..b7e355283c8 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -310,15 +310,13 @@ validate_sampler(struct nv50_context *nv50)
struct nouveau_stateobj *so;
unsigned nr = 0, i;
- for (i = 0; i < PIPE_SHADER_TYPES; ++i)
+ for (i = 0; i < 3; ++i)
nr += nv50->sampler_nr[i];
- so = so_new(1 + 5 * PIPE_SHADER_TYPES,
- 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
- PIPE_SHADER_TYPES * 2);
+ so = so_new(1 + 5 * 3, 1 + 19 * 3 + nr * 8, 3 * 2);
- nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
- nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
+ nv50_validate_samplers(nv50, so, 0); /* VP */
+ nv50_validate_samplers(nv50, so, 2); /* FP */
so_method(so, tesla, 0x1334, 1); /* flush TSC */
so_data (so, 0);
@@ -437,7 +435,7 @@ nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords)
so_emit_reloc_markers(chan, nv50->state.hw[3]); /* vp */
so_emit_reloc_markers(chan, nv50->state.hw[4]); /* fp */
so_emit_reloc_markers(chan, nv50->state.hw[17]); /* vb */
- so_emit_reloc_markers(chan, nv50->screen->static_init);
+ nv50_screen_relocs(nv50->screen);
/* No idea.. */
BEGIN_RING(chan, tesla, 0x142c, 1);
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index cabd148bc5b..6467c48a32a 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -28,6 +28,7 @@
#include "util/u_inlines.h"
#include "util/u_tile.h"
+#include "util/u_format.h"
static INLINE int
nv50_format(enum pipe_format format)
@@ -37,10 +38,35 @@ nv50_format(enum pipe_format format)
return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
case PIPE_FORMAT_B8G8R8X8_UNORM:
return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return NV50_2D_DST_FORMAT_A8R8G8B8_SRGB;
+ case PIPE_FORMAT_B8G8R8X8_SRGB:
+ return NV50_2D_DST_FORMAT_X8R8G8B8_SRGB;
case PIPE_FORMAT_B5G6R5_UNORM:
return NV50_2D_DST_FORMAT_R5G6B5_UNORM;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ return NV50_2D_DST_FORMAT_A1R5G5B5_UNORM;
case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
return NV50_2D_DST_FORMAT_R8_UNORM;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return NV50_2D_DST_FORMAT_R32G32B32X32_FLOAT;
+ case PIPE_FORMAT_Z32_FLOAT:
+ return NV50_2D_DST_FORMAT_R32_FLOAT;
+
+ /* only because we require src format == dst format: */
+ case PIPE_FORMAT_R16G16_SNORM:
+ case PIPE_FORMAT_R16G16_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ return NV50_2D_DST_FORMAT_R16_UNORM;
+
default:
return -1;
}
@@ -57,8 +83,11 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
format = nv50_format(ps->format);
- if (format < 0)
+ if (format < 0) {
+ NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+ util_format_name(ps->format));
return 1;
+ }
if (!bo->tile_flags) {
MARK_RING (chan, 9, 2); /* flush on lack of space or relocs */
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 4c48b12cd87..85ab947c006 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -29,26 +29,16 @@
#include "util/u_format.h"
#define _MIXED(pf, t0, t1, t2, t3, cr, cg, cb, ca, f) \
-{ \
- PIPE_FORMAT_##pf, \
+[PIPE_FORMAT_##pf] = ( \
NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 | \
NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 | \
NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 | \
NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 | \
- NV50TIC_0_0_FMT_##f \
-}
+ NV50TIC_0_0_FMT_##f)
#define _(pf, t, cr, cg, cb, ca, f) _MIXED(pf, t, t, t, t, cr, cg, cb, ca, f)
-struct nv50_texture_format {
- enum pipe_format pf;
- uint32_t hw;
-};
-
-#define NV50_TEX_FORMAT_LIST_SIZE \
- (sizeof(nv50_tex_format_list) / sizeof(struct nv50_texture_format))
-
-static const struct nv50_texture_format nv50_tex_format_list[] =
+static const uint32_t nv50_texture_formats[PIPE_FORMAT_COUNT] =
{
_(B8G8R8A8_UNORM, UNORM, C2, C1, C0, C3, 8_8_8_8),
_(B8G8R8A8_SRGB, UNORM, C2, C1, C0, C3, 8_8_8_8),
@@ -60,10 +50,12 @@ static const struct nv50_texture_format nv50_tex_format_list[] =
_(B5G6R5_UNORM, UNORM, C2, C1, C0, ONE, 5_6_5),
_(L8_UNORM, UNORM, C0, C0, C0, ONE, 8),
+ _(L8_SRGB, UNORM, C0, C0, C0, ONE, 8),
_(A8_UNORM, UNORM, ZERO, ZERO, ZERO, C0, 8),
_(I8_UNORM, UNORM, C0, C0, C0, C0, 8),
_(L8A8_UNORM, UNORM, C0, C0, C0, C1, 8_8),
+ _(L8A8_SRGB, UNORM, C0, C0, C0, C1, 8_8),
_(DXT1_RGB, UNORM, C0, C1, C2, ONE, DXT1),
_(DXT1_RGBA, UNORM, C0, C1, C2, C3, DXT1),
@@ -81,117 +73,143 @@ static const struct nv50_texture_format nv50_tex_format_list[] =
_(R16G16_UNORM, UNORM, C0, C1, ZERO, ONE, 16_16),
_MIXED(Z32_FLOAT, FLOAT, UINT, UINT, UINT, C0, C0, C0, ONE, 32_DEPTH)
-
};
#undef _
#undef _MIXED
-static int
-nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
- struct nv50_miptree *mt, int unit, unsigned p)
+static INLINE uint32_t
+nv50_tic_swizzle(uint32_t tc, unsigned swz)
+{
+ switch (swz) {
+ case PIPE_SWIZZLE_RED:
+ return (tc & NV50TIC_0_0_MAPR_MASK) >> NV50TIC_0_0_MAPR_SHIFT;
+ case PIPE_SWIZZLE_GREEN:
+ return (tc & NV50TIC_0_0_MAPG_MASK) >> NV50TIC_0_0_MAPG_SHIFT;
+ case PIPE_SWIZZLE_BLUE:
+ return (tc & NV50TIC_0_0_MAPB_MASK) >> NV50TIC_0_0_MAPB_SHIFT;
+ case PIPE_SWIZZLE_ALPHA:
+ return (tc & NV50TIC_0_0_MAPA_MASK) >> NV50TIC_0_0_MAPA_SHIFT;
+ case PIPE_SWIZZLE_ONE:
+ return 7;
+ case PIPE_SWIZZLE_ZERO:
+ default:
+ return 0;
+ }
+}
+
+boolean
+nv50_tex_construct(struct nv50_sampler_view *view)
{
- unsigned i;
- uint32_t mode;
const struct util_format_description *desc;
+ struct nv50_miptree *mt = nv50_miptree(view->pipe.texture);
+ uint32_t swz[4], *tic = view->tic;
- for (i = 0; i < NV50_TEX_FORMAT_LIST_SIZE; i++)
- if (nv50_tex_format_list[i].pf == mt->base.base.format)
- break;
- if (i == NV50_TEX_FORMAT_LIST_SIZE)
- return 1;
-
- if (nv50->sampler[p][unit]->normalized)
- mode = 0x50001000 | (1 << 31);
- else {
- mode = 0x50001000 | (7 << 14);
- assert(mt->base.base.target == PIPE_TEXTURE_2D);
- }
+ tic[0] = nv50_texture_formats[view->pipe.format];
- mode |= ((mt->base.bo->tile_mode & 0x0f) << 22) |
- ((mt->base.bo->tile_mode & 0xf0) << 21);
+ swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r);
+ swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g);
+ swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b);
+ swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a);
+ view->tic[0] = (tic[0] & ~NV50TIC_0_0_SWIZZLE_MASK) |
+ (swz[0] << NV50TIC_0_0_MAPR_SHIFT) |
+ (swz[1] << NV50TIC_0_0_MAPG_SHIFT) |
+ (swz[2] << NV50TIC_0_0_MAPB_SHIFT) |
+ (swz[3] << NV50TIC_0_0_MAPA_SHIFT);
- desc = util_format_description(mt->base.base.format);
- assert(desc);
+ tic[2] = 0x50001000;
+ tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) |
+ ((mt->base.bo->tile_mode & 0xf0) << 21);
+ desc = util_format_description(mt->base.base.format);
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
- mode |= 0x0400;
+ tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB;
switch (mt->base.base.target) {
case PIPE_TEXTURE_1D:
+ tic[2] |= NV50TIC_0_2_TARGET_1D;
break;
case PIPE_TEXTURE_2D:
- mode |= (1 << 14);
+ tic[2] |= NV50TIC_0_2_TARGET_2D;
break;
case PIPE_TEXTURE_3D:
- mode |= (2 << 14);
+ tic[2] |= NV50TIC_0_2_TARGET_3D;
break;
case PIPE_TEXTURE_CUBE:
- mode |= (3 << 14);
+ tic[2] |= NV50TIC_0_2_TARGET_CUBE;
break;
default:
- assert(!"unsupported texture target");
- break;
+ NOUVEAU_ERR("invalid texture target: %d\n",
+ mt->base.base.target);
+ return FALSE;
}
- so_data (so, nv50_tex_format_list[i].hw);
- so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
- NOUVEAU_BO_RD, 0, 0);
- so_data (so, mode);
- so_data (so, 0x00300000);
- so_data (so, mt->base.base.width0 | (1 << 31));
- so_data (so, (mt->base.base.last_level << 28) |
- (mt->base.base.depth0 << 16) | mt->base.base.height0);
- so_data (so, 0x03000000);
- so_data (so, mt->base.base.last_level << 4);
-
- return 0;
-}
+ tic[3] = 0x00300000;
+
+ tic[4] = (1 << 31) | mt->base.base.width0;
+ tic[5] = (mt->base.base.last_level << 28) |
+ (mt->base.base.depth0 << 16) | mt->base.base.height0;
+
+ tic[6] = 0x03000000;
-#ifndef NV50TCL_BIND_TIC
-#define NV50TCL_BIND_TIC(n) (0x1448 + 8 * n)
-#endif
+ tic[7] = (view->pipe.last_level << 4) | view->pipe.first_level;
+
+ return TRUE;
+}
-static boolean
+static int
nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
unsigned p)
{
- static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2, 1 };
-
struct nouveau_grobj *eng2d = nv50->screen->eng2d;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned unit, j, p_hw = p_remap[p];
+ unsigned unit, j;
+
+ const unsigned rll = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW;
+ const unsigned rlh = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH
+ | NOUVEAU_BO_OR;
nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM,
- p * (32 * 8 * 4), nv50->miptree_nr[p] * 8 * 4);
+ p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4);
- for (unit = 0; unit < nv50->miptree_nr[p]; ++unit) {
- struct nv50_miptree *mt = nv50->miptree[p][unit];
+ for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) {
+ struct nv50_sampler_view *view =
+ nv50_sampler_view(nv50->sampler_views[p][unit]);
so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
- if (mt) {
- if (nv50_tex_construct(nv50, so, mt, unit, p))
- return FALSE;
+ if (view) {
+ uint32_t tic2 = view->tic[2];
+ struct nv50_miptree *mt =
+ nv50_miptree(view->pipe.texture);
+
+ if (nv50->sampler[p][unit]->normalized)
+ tic2 |= NV50TIC_0_2_NORMALIZED_COORDS;
+
+ so_data (so, view->tic[0]);
+ so_reloc (so, mt->base.bo, 0, rll, 0, 0);
+ so_reloc (so, mt->base.bo, 0, rlh, tic2, tic2);
+ so_datap (so, &view->tic[3], 5);
+
/* Set TEX insn $t src binding $unit in program type p
* to TIC, TSC entry (32 * p + unit), mark valid (1).
*/
- so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+ so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
so_data (so, ((32 * p + unit) << 9) | (unit << 1) | 1);
} else {
for (j = 0; j < 8; ++j)
so_data(so, 0);
- so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+ so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
so_data (so, (unit << 1) | 0);
}
}
- for (; unit < nv50->state.miptree_nr[p]; unit++) {
+ for (; unit < nv50->state.sampler_view_nr[p]; unit++) {
/* Make other bindings invalid. */
- so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+ so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
so_data (so, (unit << 1) | 0);
}
- nv50->state.miptree_nr[p] = nv50->miptree_nr[p];
+ nv50->state.sampler_view_nr[p] = nv50->sampler_view_nr[p];
return TRUE;
}
@@ -202,23 +220,25 @@ nv50_tex_relocs(struct nv50_context *nv50)
int p, unit;
p = PIPE_SHADER_FRAGMENT;
- for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
- if (!nv50->miptree[p][unit])
+ for (unit = 0; unit < nv50->sampler_view_nr[p]; unit++) {
+ struct pipe_sampler_view *view = nv50->sampler_views[p][unit];
+ if (!view)
continue;
nouveau_reloc_emit(chan, nv50->screen->tic,
((p * 32) + unit) * 32, NULL,
- nv50->miptree[p][unit]->base.bo, 0, 0,
+ nv50_miptree(view->texture)->base.bo, 0, 0,
NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
}
p = PIPE_SHADER_VERTEX;
- for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
- if (!nv50->miptree[p][unit])
+ for (unit = 0; unit < nv50->sampler_view_nr[p]; unit++) {
+ struct pipe_sampler_view *view = nv50->sampler_views[p][unit];
+ if (!view)
continue;
nouveau_reloc_emit(chan, nv50->screen->tic,
((p * 32) + unit) * 32, NULL,
- nv50->miptree[p][unit]->base.bo, 0, 0,
+ nv50_miptree(view->texture)->base.bo, 0, 0,
NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
}
@@ -229,21 +249,23 @@ nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_stateobj *so;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned p, start, push, nrlc;
-
- for (nrlc = 0, start = 0, push = 0, p = 0; p < PIPE_SHADER_TYPES; ++p) {
- start += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]);
- push += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]);
- nrlc += nv50->miptree_nr[p];
+ unsigned p, m = 0, d = 0, r = 0;
+
+ for (p = 0; p < 3; ++p) {
+ unsigned nr = MAX2(nv50->sampler_view_nr[p],
+ nv50->state.sampler_view_nr[p]);
+ m += nr;
+ d += nr;
+ r += nv50->sampler_view_nr[p];
}
- start = start * 2 + 4 * PIPE_SHADER_TYPES + 2;
- push = push * 9 + 19 * PIPE_SHADER_TYPES + 2;
- nrlc = nrlc * 2 + 2 * PIPE_SHADER_TYPES;
+ m = m * 2 + 3 * 4 + 1;
+ d = d * 9 + 3 * 19 + 1;
+ r = r * 2 + 3 * 2;
- so = so_new(start, push, nrlc);
+ so = so_new(m, d, r);
- if (nv50_validate_textures(nv50, so, PIPE_SHADER_VERTEX) == FALSE ||
- nv50_validate_textures(nv50, so, PIPE_SHADER_FRAGMENT) == FALSE) {
+ if (nv50_validate_textures(nv50, so, 0) == FALSE ||
+ nv50_validate_textures(nv50, so, 2) == FALSE) {
so_ref(NULL, &so);
NOUVEAU_ERR("failed tex validate\n");
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
index b870302019a..3475d3e4326 100644
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ b/src/gallium/drivers/nv50/nv50_texture.h
@@ -7,7 +7,9 @@
*/
/* Texture image control block */
+#define NV50TIC_0_0_SWIZZLE_MASK 0x3ffc0000
#define NV50TIC_0_0_MAPA_MASK 0x38000000
+#define NV50TIC_0_0_MAPA_SHIFT 27
#define NV50TIC_0_0_MAPA_ZERO 0x00000000
#define NV50TIC_0_0_MAPA_C0 0x10000000
#define NV50TIC_0_0_MAPA_C1 0x18000000
@@ -15,6 +17,7 @@
#define NV50TIC_0_0_MAPA_C3 0x28000000
#define NV50TIC_0_0_MAPA_ONE 0x38000000
#define NV50TIC_0_0_MAPB_MASK 0x07000000
+#define NV50TIC_0_0_MAPB_SHIFT 24
#define NV50TIC_0_0_MAPB_ZERO 0x00000000
#define NV50TIC_0_0_MAPB_C0 0x02000000
#define NV50TIC_0_0_MAPB_C1 0x03000000
@@ -22,6 +25,7 @@
#define NV50TIC_0_0_MAPB_C3 0x05000000
#define NV50TIC_0_0_MAPB_ONE 0x07000000
#define NV50TIC_0_0_MAPG_MASK 0x00e00000
+#define NV50TIC_0_0_MAPG_SHIFT 21
#define NV50TIC_0_0_MAPG_ZERO 0x00000000
#define NV50TIC_0_0_MAPG_C0 0x00400000
#define NV50TIC_0_0_MAPG_C1 0x00600000
@@ -29,6 +33,7 @@
#define NV50TIC_0_0_MAPG_C3 0x00a00000
#define NV50TIC_0_0_MAPG_ONE 0x00e00000
#define NV50TIC_0_0_MAPR_MASK 0x001c0000
+#define NV50TIC_0_0_MAPR_SHIFT 18
#define NV50TIC_0_0_MAPR_ZERO 0x00000000
#define NV50TIC_0_0_MAPR_C0 0x00080000
#define NV50TIC_0_0_MAPR_C1 0x000c0000
@@ -89,22 +94,39 @@
#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff
#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0
-#define NV50TIC_0_2_UNKNOWN_MASK 0xffffffff
+#define NV50TIC_0_2_COLORSPACE_SRGB 0x00000400
+#define NV50TIC_0_2_TARGET_1D 0x00000000
+#define NV50TIC_0_2_TARGET_2D 0x00004000
+#define NV50TIC_0_2_TARGET_3D 0x00008000
+#define NV50TIC_0_2_TARGET_CUBE 0x0000c000
+#define NV50TIC_0_2_TARGET_1D_ARRAY 0x00010000
+#define NV50TIC_0_2_TARGET_2D_ARRAY 0x00014000
+#define NV50TIC_0_2_TARGET_BUFFER 0x00018000
+#define NV50TIC_0_2_TARGET_RECT 0x0001c000
+/* #define NV50TIC_0_0_TILE_MODE_LINEAR 0x00040000 */
+#define NV50TIC_0_2_TILE_MODE_Y_MASK 0x01c00000
+#define NV50TIC_0_2_TILE_MODE_Y_SHIFT 22
+#define NV50TIC_0_2_TILE_MODE_Z_MASK 0x0e000000
+#define NV50TIC_0_2_TILE_MODE_Z_SHIFT 25
+#define NV50TIC_0_2_NORMALIZED_COORDS 0x80000000
#define NV50TIC_0_3_UNKNOWN_MASK 0xffffffff
#define NV50TIC_0_4_WIDTH_MASK 0x0000ffff
#define NV50TIC_0_4_WIDTH_SHIFT 0
-#define NV50TIC_0_5_DEPTH_MASK 0xffff0000
+#define NV50TIC_0_5_LAST_LEVEL_MASK 0xf0000000
+#define NV50TIC_0_5_LAST_LEVEL_SHIFT 28
+#define NV50TIC_0_5_DEPTH_MASK 0x0fff0000
#define NV50TIC_0_5_DEPTH_SHIFT 16
#define NV50TIC_0_5_HEIGHT_MASK 0x0000ffff
#define NV50TIC_0_5_HEIGHT_SHIFT 0
-
#define NV50TIC_0_6_UNKNOWN_MASK 0xffffffff
-#define NV50TIC_0_7_OFFSET_HIGH_MASK 0xffffffff
-#define NV50TIC_0_7_OFFSET_HIGH_SHIFT 0
+#define NV50TIC_0_7_BASE_LEVEL_MASK 0x0000000f
+#define NV50TIC_0_7_BASE_LEVEL_SHIFT 0
+#define NV50TIC_0_7_MAX_LEVEL_MASK 0x000000f0
+#define NV50TIC_0_7_MAX_LEVEL_SHIFT 4
/* Texture sampler control block */
#define NV50TSC_1_0_WRAPS_MASK 0x00000007
diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c
index 2b56f454921..54e47574c4d 100644
--- a/src/gallium/drivers/nvfx/nv30_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv30_fragtex.c
@@ -91,7 +91,7 @@ struct nouveau_stateobj *
nv30_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
- struct nvfx_miptree *nv30mt = nvfx->tex_miptree[unit];
+ struct nvfx_miptree *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
struct pipe_texture *pt = &nv30mt->base;
struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
struct nv30_texture_format *tf;
diff --git a/src/gallium/drivers/nvfx/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c
index 5889b5e40d5..05506e28099 100644
--- a/src/gallium/drivers/nvfx/nv40_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv40_fragtex.c
@@ -109,7 +109,7 @@ struct nouveau_stateobj *
nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
- struct nvfx_miptree *nv40mt = nvfx->tex_miptree[unit];
+ struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
struct pipe_texture *pt = &nv40mt->base;
struct nv40_texture_format *tf;
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index 5eed8a560e5..ab7225cf6c3 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -158,7 +158,7 @@ struct nvfx_context {
struct pipe_buffer *idxbuf;
unsigned idxbuf_format;
struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
- struct nvfx_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
unsigned nr_textures;
unsigned dirty_samplers;
diff --git a/src/gallium/drivers/nvfx/nvfx_draw.c b/src/gallium/drivers/nvfx/nvfx_draw.c
index 5379b29efd1..68e50a36479 100644
--- a/src/gallium/drivers/nvfx/nvfx_draw.c
+++ b/src/gallium/drivers/nvfx/nvfx_draw.c
@@ -79,6 +79,12 @@ nvfx_render_vertex(struct nvfx_context *nvfx, const struct vertex_header *v)
float_to_ubyte(v->data[idx][1]),
float_to_ubyte(v->data[idx][2]),
float_to_ubyte(v->data[idx][3])));
+ case EMIT_4UB_BGRA:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_4UB(hw), 1);
+ OUT_RING (chan, pack_ub4(float_to_ubyte(v->data[idx][2]),
+ float_to_ubyte(v->data[idx][1]),
+ float_to_ubyte(v->data[idx][0]),
+ float_to_ubyte(v->data[idx][3])));
break;
default:
assert(0);
diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c
index 76351430f44..b9c91cec8ce 100644
--- a/src/gallium/drivers/nvfx/nvfx_fragprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c
@@ -803,7 +803,8 @@ nvfx_fragprog_translate(struct nvfx_context *nvfx,
fp->fp_control |= fpc->num_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT;
/* Terminate final instruction */
- fp->insn[fpc->inst_offset] |= 0x00000001;
+ if(fp->insn)
+ fp->insn[fpc->inst_offset] |= 0x00000001;
/* Append NOP + END instruction, may or may not be necessary. */
fpc->inst_offset = fp->insn_len;
diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 0f5ed61aab7..9de25175e78 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -67,6 +67,9 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
struct nvfx_miptree *mt;
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
NOUVEAU_BUFFER_USAGE_TEXTURE;
+ static int no_swizzle = -1;
+ if(no_swizzle < 0)
+ no_swizzle = debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE);
mt = MALLOC(sizeof(struct nvfx_miptree));
if (!mt)
@@ -106,7 +109,7 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R16_SNORM:
{
- if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
+ if (no_swizzle)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 8138715cc7d..f7f39218944 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -68,11 +68,9 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return !!screen->is_nv4x;
case NOUVEAU_CAP_HW_VTXBUF:
- /* TODO: this is almost surely wrong */
- return !!screen->is_nv4x;
+ return 0;
case NOUVEAU_CAP_HW_IDXBUF:
- /* TODO: this is also almost surely wrong */
- return screen->is_nv4x && screen->eng3d->grclass == NV40TCL;
+ return 0;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return 16;
case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -295,6 +293,36 @@ static void nv40_screen_init(struct nvfx_screen *screen, struct nouveau_stateobj
so_data (so, 0x00000001);
}
+static void
+nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+{
+ int vram_hack_default = 0;
+ int vram_hack;
+ // TODO: this is a bit of a guess; also add other cards that may need this hack.
+ // It may also depend on the specific card or the AGP/PCIe chipset.
+ if(screen->base.device->chipset == 0x47 /* G70 */
+ || screen->base.device->chipset == 0x49 /* G71 */
+ || screen->base.device->chipset == 0x46 /* G72 */
+ )
+ vram_hack_default = 1;
+ vram_hack = debug_get_bool_option("NOUVEAU_VTXIDX_IN_VRAM", vram_hack_default);
+
+#ifdef DEBUG
+ if(!vram_hack)
+ {
+ fprintf(stderr, "Some systems may experience graphics corruption due to randomly misplaced vertices.\n"
+ "If this is happening, export NOUVEAU_VTXIDX_IN_VRAM=1 may reduce or eliminate the problem\n");
+ }
+ else
+ {
+ fprintf(stderr, "A performance reducing hack is being used to help avoid graphics corruption.\n"
+ "You can try export NOUVEAU_VTXIDX_IN_VRAM=0 to disable it.\n");
+ }
+#endif
+
+ screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+}
+
struct pipe_screen *
nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
@@ -352,6 +380,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
+ nvfx_screen_init_buffer_functions(screen);
nvfx_screen_init_miptree_functions(pscreen);
ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index c0b4b9899dd..baa848c47aa 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -12,6 +12,7 @@ struct nvfx_screen {
struct nvfx_context *cur_ctx;
unsigned is_nv4x; /* either 0 or ~0 */
+ int vertex_buffer_flags;
/* HW graphics objects */
struct nv04_surface_2d *eng2d;
diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c
index 88a9d01c509..ecaa0dcb16a 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.c
+++ b/src/gallium/drivers/nvfx/nvfx_state.c
@@ -137,21 +137,22 @@ nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
}
static void
-nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
- struct pipe_texture **miptree)
+nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
unsigned unit;
for (unit = 0; unit < nr; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nvfx->tex_miptree[unit], miptree[unit]);
+ pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+ views[unit]);
nvfx->dirty_samplers |= (1 << unit);
}
for (unit = nr; unit < nvfx->nr_textures; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nvfx->tex_miptree[unit], NULL);
+ pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+ NULL);
nvfx->dirty_samplers |= (1 << unit);
}
@@ -159,6 +160,34 @@ nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
nvfx->dirty |= NVFX_NEW_SAMPLER;
}
+
+static struct pipe_sampler_view *
+nvfx_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+nvfx_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
static void *
nvfx_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
@@ -581,7 +610,9 @@ nvfx_init_state_functions(struct nvfx_context *nvfx)
nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
- nvfx->pipe.set_fragment_sampler_textures = nvfx_set_sampler_texture;
+ nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
+ nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
+ nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nvfx/nvfx_state_viewport.c b/src/gallium/drivers/nvfx/nvfx_state_viewport.c
index 82e0e9220b0..ec730e3a9e9 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_viewport.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_viewport.c
@@ -1,15 +1,16 @@
#include "nvfx_context.h"
+/* Having this depend on FB and RAST looks wrong, but it seems
+ necessary to make this work on nv3x
+ TODO: find the right fix
+*/
+
static boolean
nvfx_state_viewport_validate(struct nvfx_context *nvfx)
{
struct pipe_viewport_state *vpt = &nvfx->viewport;
struct nouveau_stateobj *so;
- if (nvfx->state.hw[NVFX_STATE_VIEWPORT] &&
- !(nvfx->dirty & NVFX_NEW_VIEWPORT))
- return FALSE;
-
so = so_new(2, 9, 0);
so_method(so, nvfx->screen->eng3d,
NV34TCL_VIEWPORT_TRANSLATE_X, 8);
@@ -45,7 +46,7 @@ nvfx_state_viewport_validate(struct nvfx_context *nvfx)
struct nvfx_state_entry nvfx_state_viewport = {
.validate = nvfx_state_viewport_validate,
.dirty = {
- .pipe = NVFX_NEW_VIEWPORT,
+ .pipe = NVFX_NEW_VIEWPORT | NVFX_NEW_FB | NVFX_NEW_RAST,
.hw = NVFX_STATE_VIEWPORT
}
};
diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c
index 409b354d582..1c250e9fe44 100644
--- a/src/gallium/drivers/nvfx/nvfx_transfer.c
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.c
@@ -33,15 +33,18 @@ nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
}
static struct pipe_transfer *
-nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
+nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nvfx_transfer *tx;
struct pipe_texture tx_tex_template, *tx_tex;
+ static int no_transfer = -1;
+ if(no_transfer < 0)
+ no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/);
tx = CALLOC_STRUCT(nvfx_transfer);
if (!tx)
@@ -59,8 +62,7 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
tx->base.zslice = zslice;
/* Direct access to texture */
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
- debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) &&
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
{
tx->direct = true;
@@ -118,13 +120,13 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
}
static void
-nvfx_transfer_del(struct pipe_context *pcontext,
+nvfx_transfer_del(struct pipe_context *pipe,
struct pipe_transfer *ptx)
{
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
struct pipe_surface *dst;
@@ -147,9 +149,9 @@ nvfx_transfer_del(struct pipe_context *pcontext,
}
static void *
-nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+nvfx_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
@@ -163,9 +165,9 @@ nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
}
static void
-nvfx_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+nvfx_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index 257087f8f63..c26536b0e77 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -495,7 +495,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
struct pipe_buffer *ib = nvfx->idxbuf;
unsigned ib_format = nvfx->idxbuf_format;
- unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+ unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD;
int hw;
vtxbuf = so_new(3, 17, 18);
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 27b2e309932..221878c1c0c 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -24,6 +24,7 @@ r300 = env.ConvenienceLibrary(
'r300_query.c',
'r300_render.c',
'r300_screen.c',
+ 'r300_screen_buffer.c',
'r300_state.c',
'r300_state_derived.c',
'r300_state_invariant.c',
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index b7ad6b20206..bcdf950df9c 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -113,9 +113,9 @@ static void r300_hw_copy(struct pipe_context* pipe,
util_blitter_save_fragment_sampler_states(
r300->blitter, state->sampler_count, (void**)state->sampler_states);
- util_blitter_save_fragment_sampler_textures(
+ util_blitter_save_fragment_sampler_views(
r300->blitter, state->texture_count,
- (struct pipe_texture**)state->textures);
+ state->fragment_sampler_views);
/* Do a copy */
util_blitter_copy(r300->blitter,
@@ -149,6 +149,9 @@ void r300_surface_copy(struct pipe_context* pipe,
case 4:
new_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
+ case 8:
+ new_format = PIPE_FORMAT_R16G16B16A16_UNORM;
+ break;
default:
debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
"r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 92de297ef1d..41719862635 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -24,6 +24,8 @@
#include "util/u_debug.h"
+#include <stdio.h>
+
/* r300_chipset: A file all to itself for deducing the various properties of
* Radeons. */
@@ -365,8 +367,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
break;
default:
- debug_printf("r300: Warning: Unknown chipset 0x%x\n",
- caps->pci_id);
- break;
+ fprintf(stderr, "r300: Warning: Unknown chipset 0x%x\n",
+ caps->pci_id);
}
}
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index d994a46ccfe..4b470b2c6af 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -33,11 +33,10 @@
#include "r300_query.h"
#include "r300_render.h"
#include "r300_screen.h"
+#include "r300_screen_buffer.h"
#include "r300_state_invariant.h"
-#include "r300_texture.h"
#include "r300_transfer.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
static void r300_destroy_context(struct pipe_context* context)
{
@@ -72,29 +71,23 @@ static void r300_destroy_context(struct pipe_context* context)
}
static unsigned int
-r300_is_texture_referenced(struct pipe_context *pipe,
+r300_is_texture_referenced(struct pipe_context *context,
struct pipe_texture *texture,
unsigned face, unsigned level)
{
- return 0;
+ struct r300_context* r300 = r300_context(context);
+ struct r300_texture* tex = (struct r300_texture*)texture;
+
+ return r300->rws->is_buffer_referenced(r300->rws, tex->buffer);
}
static unsigned int
-r300_is_buffer_referenced(struct pipe_context *pipe,
+r300_is_buffer_referenced(struct pipe_context *context,
struct pipe_buffer *buf)
{
- /* This only checks to see whether actual hardware buffers are
- * referenced. Since we use managed BOs and transfers, it's actually not
- * possible for pipe_buffers to ever reference the actual hardware, so
- * buffers are never referenced.
- */
-
- /* XXX: that doesn't make sense given that
- * r300_is_texture_referenced is implemented on top of this
- * function and hardware can certainly refer to textures
- * directly...
- */
- return 0;
+ struct r300_context* r300 = r300_context(context);
+
+ return r300_buffer_is_referenced(r300, buf);
}
static void r300_flush_cb(void *data)
@@ -204,7 +197,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
/* Open up the OQ BO. */
r300->oqbo = screen->buffer_create(screen, 4096,
- PIPE_BUFFER_USAGE_VERTEX, 4096);
+ PIPE_BUFFER_USAGE_PIXEL, 4096);
make_empty_list(&r300->query_list);
r300_init_flush_functions(r300);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index db2f74e0745..0a82484e89d 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -30,6 +30,7 @@
#include "pipe/p_context.h"
#include "util/u_inlines.h"
+#include "r300_defines.h"
#include "r300_screen.h"
struct u_upload_mgr;
@@ -125,8 +126,6 @@ struct r300_texture_format_state {
uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */
};
-#define R300_MAX_TEXTURE_LEVELS 13
-
struct r300_texture_fb_state {
/* Colorbuffer. */
uint32_t colorpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
@@ -139,7 +138,7 @@ struct r300_texture_fb_state {
struct r300_textures_state {
/* Textures. */
- struct r300_texture *textures[8];
+ struct pipe_sampler_view *fragment_sampler_views[8];
int texture_count;
/* Sampler states. */
struct r300_sampler_state *sampler_states[8];
@@ -185,12 +184,6 @@ struct r300_ztop_state {
uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */
};
-#define R300_NEW_FRAGMENT_SHADER 0x00000020
-#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
-#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
-#define R300_NEW_QUERY 0x40000000
-#define R300_NEW_KITCHEN_SINK 0x7fffffff
-
/* The next several objects are not pure Radeon state; they inherit from
* various Gallium classes. */
@@ -228,12 +221,6 @@ struct r300_query {
struct r300_query* next;
};
-enum r300_buffer_tiling {
- R300_BUFFER_LINEAR = 0,
- R300_BUFFER_TILED,
- R300_BUFFER_SQUARETILED
-};
-
struct r300_texture {
/* Parent class */
struct pipe_texture tex;
@@ -422,7 +409,7 @@ static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags,
if (CTX_DBG_ON(ctx, flags)) {
va_list va;
va_start(va, fmt);
- debug_vprintf(fmt, va);
+ vfprintf(stderr, fmt, va);
va_end(va);
}
}
@@ -431,4 +418,3 @@ static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags,
#define DBG CTX_DBG
#endif /* R300_CONTEXT_H */
-
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index ad07efbffdb..456b2ec7b92 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -26,8 +26,7 @@
#include "util/u_math.h"
#include "r300_reg.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
/* Yes, I know macros are ugly. However, they are much prettier than the code
* that they neatly hide away, and don't have the cost of function setup,so
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index d6177577c8d..016e8d66061 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -22,6 +22,7 @@
#include "r300_context.h"
+#include <stdio.h>
struct debug_option {
const char * name;
@@ -69,7 +70,7 @@ void r300_init_debug(struct r300_screen * screen)
}
if (!opt->name) {
- debug_printf("Unknown debug option: %s\n", options);
+ fprintf(stderr, "Unknown debug option: %s\n", options);
printhint = TRUE;
}
@@ -81,10 +82,13 @@ void r300_init_debug(struct r300_screen * screen)
}
if (printhint || screen->debug & DBG_HELP) {
- debug_printf("You can enable debug output by setting the RADEON_DEBUG environment variable\n"
- "to a comma-separated list of debug options. Available options are:\n");
+ fprintf(stderr, "You can enable debug output by setting "
+ "the RADEON_DEBUG environment variable\n"
+ "to a comma-separated list of debug options. "
+ "Available options are:\n");
+
for(opt = debug_options; opt->name; ++opt) {
- debug_printf(" %s: %s\n", opt->name, opt->description);
+ fprintf(stderr, " %s: %s\n", opt->name, opt->description);
}
}
}
diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h
new file mode 100644
index 00000000000..2e04876de92
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_defines.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Marek Olšák <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef R300_DEFINES_H
+#define R300_DEFINES_H
+
+#include "pipe/p_defines.h"
+
+#define R300_MAX_TEXTURE_LEVELS 13
+#define R300_MAX_DRAW_VBO_SIZE (1024 * 1024)
+
+#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM
+
+/* Non-atom dirty state flags. */
+#define R300_NEW_FRAGMENT_SHADER 0x00000020
+#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
+#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
+#define R300_NEW_QUERY 0x40000000
+#define R300_NEW_KITCHEN_SINK 0x7fffffff
+
+/* Tiling flags. */
+enum r300_buffer_tiling {
+ R300_BUFFER_LINEAR = 0,
+ R300_BUFFER_TILED,
+ R300_BUFFER_SQUARETILED
+};
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d8c64dd9001..15bcf8907f3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -33,7 +33,6 @@
#include "r300_fs.h"
#include "r300_screen.h"
#include "r300_screen_buffer.h"
-#include "r300_state_inlines.h"
#include "r300_vs.h"
void r300_emit_blend_state(struct r300_context* r300,
@@ -146,10 +145,8 @@ static const float * get_shader_constant(
struct rc_constant * constant,
struct r300_constant_buffer * externals)
{
- struct r300_viewport_state* viewport =
- (struct r300_viewport_state*)r300->viewport_state.state;
- struct r300_textures_state* texstate =
- (struct r300_textures_state*)r300->textures_state.state;
+ struct r300_viewport_state* viewport = r300->viewport_state.state;
+ struct r300_textures_state* texstate = r300->textures_state.state;
static float vec[4] = { 0.0, 0.0, 0.0, 1.0 };
struct pipe_texture *tex;
@@ -165,7 +162,7 @@ static const float * get_shader_constant(
/* Factor for converting rectangle coords to
* normalized coords. Should only show up on non-r500. */
case RC_STATE_R300_TEXRECT_FACTOR:
- tex = &texstate->textures[constant->u.State[1]]->tex;
+ tex = texstate->fragment_sampler_views[constant->u.State[1]]->texture;
vec[0] = 1.0 / tex->width0;
vec[1] = 1.0 / tex->height0;
break;
@@ -189,13 +186,13 @@ static const float * get_shader_constant(
break;
default:
- debug_printf("r300: Implementation error: "
+ fprintf(stderr, "r300: Implementation error: "
"Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
}
break;
default:
- debug_printf("r300: Implementation error: "
+ fprintf(stderr, "r300: Implementation error: "
"Unhandled constant type %d\n", constant->Type);
}
@@ -517,9 +514,9 @@ static void r300_emit_query_finish(struct r300_context *r300,
0, RADEON_GEM_DOMAIN_GTT, 0);
break;
default:
- debug_printf("r300: Implementation error: Chipset reports %d"
+ fprintf(stderr, "r300: Implementation error: Chipset reports %d"
" pixel pipes!\n", caps->num_frag_pipes);
- assert(0);
+ abort();
}
/* And, finally, reset it to normal... */
@@ -749,8 +746,9 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format[2]);
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_CS_TEX_RELOC(allstate->textures[i], texstate->tile_config,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ OUT_CS_TEX_RELOC((struct r300_texture *)allstate->fragment_sampler_views[i]->texture,
+ texstate->tile_config,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
}
}
END_CS;
@@ -893,12 +891,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
CS_LOCALS(r300);
- if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vs_state called,"
- " but has_tcl is FALSE!\n");
- return;
- }
-
BEGIN_CS(size);
/* R300_VAP_PVS_CODE_CNTL_0
* R300_VAP_PVS_CONST_CNTL
@@ -928,28 +920,19 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
void r300_emit_vs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants)
{
- int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ unsigned i;
CS_LOCALS(r300);
- if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vs_constant_buffer called,"
- " but has_tcl is FALSE!\n");
- return;
- }
-
- if (constants->Count == 0)
- return;
-
BEGIN_CS(constants->Count * 4 + 3);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
(r300screen->caps->is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4);
for (i = 0; i < constants->Count; i++) {
- const float * data = get_shader_constant(r300,
- &constants->Constants[i],
- &r300->shader_constants[PIPE_SHADER_VERTEX]);
+ const float *data = get_shader_constant(r300,
+ &constants->Constants[i],
+ &r300->shader_constants[PIPE_SHADER_VERTEX]);
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
OUT_CS_32F(data[2]);
@@ -1043,9 +1026,11 @@ validate:
}
/* ...textures... */
for (i = 0; i < texstate->count; i++) {
- tex = texstate->textures[i];
- if (!tex || !texstate->sampler_states[i])
+ if (!(texstate->tx_enable & (1 << i))) {
continue;
+ }
+
+ tex = (struct r300_texture*)texstate->fragment_sampler_views[i]->texture;
if (!r300_add_texture(r300->rws, tex,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
r300->context.flush(&r300->context, 0, NULL);
@@ -1092,8 +1077,8 @@ validate:
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
/* Well, hell. */
- debug_printf("r300: Stuck in validation loop, gonna quit now.");
- exit(1);
+ fprintf(stderr, "r300: Stuck in validation loop, gonna quit now.\n");
+ abort();
}
invalid = TRUE;
goto validate;
@@ -1158,7 +1143,9 @@ void r300_emit_dirty_state(struct r300_context* r300)
if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
struct r300_vertex_shader* vs = r300->vs_state.state;
- r300_emit_vs_constant_buffer(r300, &vs->code.constants);
+ if (vs->code.constants.Count) {
+ r300_emit_vs_constant_buffer(r300, &vs->code.constants);
+ }
r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
}
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 9e71e61c303..e23fef8c9f7 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -204,9 +204,8 @@ static void r300_translate_fragment_shader(
r3xx_compile_fragment_program(&compiler);
if (compiler.Base.Error) {
/* XXX failover maybe? */
- DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
- compiler.Base.ErrorMsg);
- assert(0);
+ fprintf(stderr, "r300 FP: Compiler Error:\n%s",
+ compiler.Base.ErrorMsg);
abort();
}
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index ca00b043c51..f8b52d593d5 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -30,6 +30,8 @@
#include "r300_query.h"
#include "r300_reg.h"
+#include <stdio.h>
+
static struct pipe_query *r300_create_query(struct pipe_context *pipe,
unsigned query_type)
{
@@ -97,8 +99,10 @@ static void r300_end_query(struct pipe_context* pipe,
struct pipe_query* query)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_query* q = (struct r300_query*)query;
r300_emit_query_end(r300);
+ q->begin_emitted = false;
r300->query_current = NULL;
}
@@ -135,8 +139,8 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
if (*map == ~0U) {
/* Looks like our results aren't ready yet. */
if (wait) {
- debug_printf("r300: Despite waiting, OQ results haven't"
- " come in yet.\n");
+ fprintf(stderr, "r300: Despite waiting, OQ results haven't "
+ "come in yet.\n");
}
temp = ~0U;
break;
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 47100c83b0b..1fb7eac2b34 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -41,9 +41,6 @@
#include "r300_render.h"
#include "r300_state_derived.h"
-/* r300_render: Vertex and index buffer primitive emission. */
-#define R300_MAX_VBO_SIZE (1024 * 1024)
-
/* XXX The DRM rejects VAP_ALT_NUM_VERTICES.. */
//#define ENABLE_ALT_NUM_VERTS
@@ -141,7 +138,7 @@ static boolean immd_is_good_idea(struct r300_context *r300,
unsigned vertex_element_count = r300->velems->count;
unsigned i, vbi;
- if (count > 4) {
+ if (count > 10) {
return FALSE;
}
@@ -155,8 +152,7 @@ static boolean immd_is_good_idea(struct r300_context *r300,
if (!checked[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
- if (r300_buffer_is_referenced(r300,
- vbuf->buffer)) {
+ if (r300_buffer_is_referenced(r300, vbuf->buffer)) {
/* It's a very bad idea to map it... */
return FALSE;
}
@@ -304,10 +300,9 @@ static void r300_emit_draw_elements(struct r300_context *r300,
#endif
CS_LOCALS(r300);
- assert((start * indexSize) % 4 == 0);
assert(count < (1 << 24));
- maxIndex = MIN3(maxIndex, r300->vertex_buffer_max_index, count - minIndex);
+ maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
count, minIndex, maxIndex);
@@ -354,6 +349,7 @@ static void r300_emit_draw_elements(struct r300_context *r300,
static void r300_shorten_ubyte_elts(struct r300_context* r300,
struct pipe_buffer** elts,
+ unsigned start,
unsigned count)
{
struct pipe_screen* screen = r300->context.screen;
@@ -371,6 +367,8 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300,
in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ);
out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE);
+ in_map += start;
+
for (i = 0; i < count; i++) {
*out_map = (unsigned short)*in_map;
in_map++;
@@ -383,6 +381,32 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300,
*elts = new_elts;
}
+static void r300_align_ushort_elts(struct r300_context *r300,
+ struct pipe_buffer **elts,
+ unsigned start, unsigned count)
+{
+ struct pipe_screen* screen = r300->context.screen;
+ struct pipe_buffer* new_elts;
+ unsigned short *in_map;
+ unsigned short *out_map;
+
+ new_elts = screen->buffer_create(screen, 32,
+ PIPE_BUFFER_USAGE_INDEX |
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ,
+ 2 * count);
+
+ in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ);
+ out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(out_map, in_map+start, 2 * count);
+
+ pipe_buffer_unmap(screen, *elts);
+ pipe_buffer_unmap(screen, new_elts);
+
+ *elts = new_elts;
+}
+
/* This is the fast-path drawing & emission for HW TCL. */
void r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
@@ -408,8 +432,12 @@ void r300_draw_range_elements(struct pipe_context* pipe,
}
if (indexSize == 1) {
- r300_shorten_ubyte_elts(r300, &indexBuffer, count);
+ r300_shorten_ubyte_elts(r300, &indexBuffer, start, count);
indexSize = 2;
+ start = 0;
+ } else if (indexSize == 2 && start % 2 != 0) {
+ r300_align_ushort_elts(r300, &indexBuffer, start, count);
+ start = 0;
}
r300_update_derived_state(r300);
@@ -541,13 +569,6 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
draw_set_mapped_element_buffer(r300->draw, 0, NULL);
- draw_set_mapped_constant_buffer(r300->draw,
- PIPE_SHADER_VERTEX,
- 0,
- r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- r300->shader_constants[PIPE_SHADER_VERTEX].count *
- (sizeof(float) * 4));
-
draw_arrays(r300->draw, mode, start, count);
for (i = 0; i < r300->vertex_buffer_count; i++) {
@@ -586,13 +607,6 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
draw_set_mapped_element_buffer_range(r300->draw, indexSize,
minIndex, maxIndex, indices);
- draw_set_mapped_constant_buffer(r300->draw,
- PIPE_SHADER_VERTEX,
- 0,
- r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- r300->shader_constants[PIPE_SHADER_VERTEX].count *
- (sizeof(float) * 4));
-
draw_arrays(r300->draw, mode, start, count);
for (i = 0; i < r300->vertex_buffer_count; i++) {
@@ -658,9 +672,9 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
r300render->vbo = pipe_buffer_create(screen,
64,
PIPE_BUFFER_USAGE_VERTEX,
- R300_MAX_VBO_SIZE);
+ R300_MAX_DRAW_VBO_SIZE);
r300render->vbo_offset = 0;
- r300render->vbo_size = R300_MAX_VBO_SIZE;
+ r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE;
}
r300render->vertex_size = vertex_size;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 3e31688f8e8..e46f836dd2c 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -26,10 +26,8 @@
#include "r300_context.h"
#include "r300_texture.h"
-
-#include "radeon_winsys.h"
-
#include "r300_screen_buffer.h"
+#include "r300_winsys.h"
/* Return the identifier behind whom the brave coders responsible for this
* amalgamation of code, sweat, and duct tape, routinely obscure their names.
@@ -166,7 +164,7 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
- debug_printf("r300: Implementation error: Bad param %d\n",
+ fprintf(stderr, "r300: Implementation error: Bad param %d\n",
param);
return 0;
}
@@ -195,7 +193,7 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 16.0f;
default:
- debug_printf("r300: Implementation error: Bad paramf %d\n",
+ fprintf(stderr, "r300: Implementation error: Bad paramf %d\n",
param);
return 0.0f;
}
@@ -214,7 +212,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
- debug_printf("r300: Implementation error: Received bogus texture "
+ fprintf(stderr, "r300: Implementation error: Received bogus texture "
"target %d in %s\n", target, __FUNCTION__);
return FALSE;
}
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 1ccc0bfb7a5..1cf8b7452d7 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -28,9 +28,7 @@
#include "r300_chipset.h"
-#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM
-
-struct radeon_winsys;
+#include <stdio.h>
struct r300_screen {
/* Parent class */
@@ -84,7 +82,7 @@ static INLINE void SCREEN_DBG(struct r300_screen * screen, unsigned flags,
if (SCREEN_DBG_ON(screen, flags)) {
va_list va;
va_start(va, fmt);
- debug_vprintf(fmt, va);
+ vfprintf(stderr, fmt, va);
va_end(va);
}
}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index b97d0d76a4a..a1cd48ee730 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -237,7 +237,7 @@ r300_buffer_map_range(struct pipe_screen *screen,
}
}
just_map:
- map = rws->buffer_map(rws, rbuf->buf, usage | R300_USAGE_FLAG_DONT_SYNC);
+ map = rws->buffer_map(rws, rbuf->buf, usage);
return map;
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 712e9280e3c..39e05583dd4 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -38,8 +38,7 @@
#include "r300_state_inlines.h"
#include "r300_fs.h"
#include "r300_vs.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@@ -528,8 +527,8 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
if (tex) {
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[0],
- tex->microtile != 0,
- tex->macrotile != 0);
+ tex->microtile,
+ tex->macrotile);
}
}
if (old_state->zsbuf &&
@@ -540,8 +539,8 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
if (tex) {
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[0],
- tex->microtile != 0,
- tex->macrotile != 0);
+ tex->microtile,
+ tex->macrotile);
}
}
@@ -552,8 +551,8 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[level],
- tex->microtile != 0,
- tex->mip_macrotile[level] != 0);
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
if (new_state->zsbuf) {
tex = (struct r300_texture*)new_state->zsbuf->texture;
@@ -561,8 +560,8 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[level],
- tex->microtile != 0,
- tex->mip_macrotile[level] != 0);
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
}
@@ -576,9 +575,8 @@ static void
unsigned max_width, max_height;
uint32_t zbuffer_bpp = 0;
-
if (state->nr_cbufs > 4) {
- debug_printf("r300: Implementation error: Too many MRTs in %s, "
+ fprintf(stderr, "r300: Implementation error: Too many MRTs in %s, "
"refusing to bind framebuffer state!\n", __FUNCTION__);
return;
}
@@ -592,7 +590,7 @@ static void
}
if (state->width > max_width || state->height > max_height) {
- debug_printf("r300: Implementation error: Render targets are too "
+ fprintf(stderr, "r300: Implementation error: Render targets are too "
"big in %s, refusing to bind framebuffer state!\n", __FUNCTION__);
return;
}
@@ -933,13 +931,14 @@ static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
FREE(state);
}
-static void r300_set_sampler_textures(struct pipe_context* pipe,
- unsigned count,
- struct pipe_texture** texture)
+static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
+ unsigned count,
+ struct pipe_sampler_view** views)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
+ struct r300_texture *texture;
unsigned i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
boolean dirty_tex = FALSE;
@@ -950,13 +949,20 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
}
for (i = 0; i < count; i++) {
- if (state->textures[i] != (struct r300_texture*)texture[i]) {
- pipe_texture_reference((struct pipe_texture**)&state->textures[i],
- texture[i]);
+ if (state->fragment_sampler_views[i] != views[i]) {
+ pipe_sampler_view_reference(&state->fragment_sampler_views[i],
+ views[i]);
+
+ if (!views[i]) {
+ continue;
+ }
+
+ /* A new sampler view (= texture)... */
dirty_tex = TRUE;
/* R300-specific - set the texrect factor in the fragment shader */
- if (!is_r500 && state->textures[i]->is_npot) {
+ texture = (struct r300_texture *)views[i]->texture;
+ if (!is_r500 && texture->is_npot) {
/* XXX It would be nice to re-emit just 1 constant,
* XXX not all of them */
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
@@ -965,9 +971,9 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
}
for (i = count; i < 8; i++) {
- if (state->textures[i]) {
- pipe_texture_reference((struct pipe_texture**)&state->textures[i],
- NULL);
+ if (state->fragment_sampler_views[i]) {
+ pipe_sampler_view_reference(&state->fragment_sampler_views[i],
+ NULL);
}
}
@@ -980,6 +986,32 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
}
}
+static struct pipe_sampler_view *
+r300_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+static void
+r300_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
static void r300_set_scissor_state(struct pipe_context* pipe,
const struct pipe_scissor_state* state)
{
@@ -1041,117 +1073,71 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
- int i;
- unsigned max_index = (1 << 24) - 1;
- boolean any_user_buffer = false;
+ struct pipe_vertex_buffer *vbo;
+ unsigned i, max_index = (1 << 24) - 1;
+ boolean any_user_buffer = FALSE;
if (count == r300->vertex_buffer_count &&
- memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0)
+ memcmp(r300->vertex_buffer, buffers,
+ sizeof(struct pipe_vertex_buffer) * count) == 0) {
return;
+ }
+ /* Check if the stride is aligned to the size of DWORD. */
for (i = 0; i < count; i++) {
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer);
- if (r300_buffer_is_user_buffer(buffers[i].buffer))
- any_user_buffer = true;
- max_index = MIN2(buffers[i].max_index, max_index);
+ if (buffers[i].buffer) {
+ if (buffers[i].stride % 4 != 0) {
+ // XXX Shouldn't we align the buffer?
+ fprintf(stderr, "r300_set_vertex_buffers: "
+ "Unaligned buffer stride %i isn't supported.\n",
+ buffers[i].stride);
+ assert(0);
+ abort();
+ }
+ }
}
- for ( ; i < r300->vertex_buffer_count; i++)
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
-
- memcpy(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count);
+ for (i = 0; i < count; i++) {
+ /* Why, yes, I AM casting away constness. How did you know? */
+ vbo = (struct pipe_vertex_buffer*)&buffers[i];
- r300->vertex_buffer_count = count;
- r300->vertex_buffer_max_index = max_index;
- r300->any_user_vbs = any_user_buffer;
+ /* Reference our buffer. */
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
- if (r300->draw) {
- draw_flush(r300->draw);
- draw_set_vertex_buffers(r300->draw, count, buffers);
- }
-}
-
-static boolean r300_validate_aos(struct r300_context *r300)
-{
- struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->velems->velem;
- int i;
-
- /* Check if formats and strides are aligned to the size of DWORD. */
- for (i = 0; i < r300->velems->count; i++) {
- if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
- util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
- return FALSE;
+ /* Skip NULL buffers */
+ if (!buffers[i].buffer) {
+ continue;
}
- }
- return TRUE;
-}
-static void r300_draw_emit_attrib(struct r300_context* r300,
- enum attrib_emit emit,
- enum interp_mode interp,
- int index)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct tgsi_shader_info* info = &vs->info;
- int output;
-
- output = draw_find_shader_output(r300->draw,
- info->output_semantic_name[index],
- info->output_semantic_index[index]);
- draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
-}
+ if (r300_buffer_is_user_buffer(vbo->buffer)) {
+ any_user_buffer = TRUE;
+ }
-static void r300_draw_emit_all_attribs(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_shader_semantics* vs_outputs = &vs->outputs;
- int i, gen_count;
-
- /* Position. */
- if (vs_outputs->pos != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
- vs_outputs->pos);
- } else {
- assert(0);
- }
+ if (vbo->max_index == ~0) {
+ /* Bogus value from broken state tracker; hax it. */
+ vbo->max_index =
+ (vbo->buffer->size - vbo->buffer_offset) / vbo->stride;
+ }
- /* Point size. */
- if (vs_outputs->psize != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
- vs_outputs->psize);
+ max_index = MIN2(vbo->max_index, max_index);
}
- /* Colors. */
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
- vs_outputs->color[i]);
- }
+ for (; i < r300->vertex_buffer_count; i++) {
+ /* Dereference any old buffers. */
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
}
- /* XXX Back-face colors. */
+ memcpy(r300->vertex_buffer, buffers,
+ sizeof(struct pipe_vertex_buffer) * count);
- /* Texture coordinates. */
- gen_count = 0;
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- if (vs_outputs->generic[i] != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
- vs_outputs->generic[i]);
- gen_count++;
- }
- }
+ r300->vertex_buffer_count = count;
+ r300->vertex_buffer_max_index = max_index;
+ r300->any_user_vbs = any_user_buffer;
- /* Fog coordinates. */
- if (vs_outputs->fog != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
- vs_outputs->fog);
- gen_count++;
+ if (r300->draw) {
+ draw_flush(r300->draw);
+ draw_set_vertex_buffers(r300->draw, count, buffers);
}
-
- /* XXX magic */
- assert(gen_count <= 8);
}
/* Update the PSC tables. */
@@ -1193,70 +1179,13 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
vstream->count = (i >> 1) + 1;
}
-/* Update the PSC tables for SW TCL, using Draw. */
-static void r300_swtcl_vertex_psc(struct r300_context *r300,
- struct r300_vertex_element_state *velems)
-{
- struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct vertex_info* vinfo = &r300->vertex_info;
- uint16_t type, swizzle;
- enum pipe_format format;
- unsigned i, attrib_count;
- int* vs_output_tab = vs->stream_loc_notcl;
-
- /* For each Draw attribute, route it to the fragment shader according
- * to the vs_output_tab. */
- attrib_count = vinfo->num_attribs;
- DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
- for (i = 0; i < attrib_count; i++) {
- DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
- " vs_output_tab %d\n", vinfo->attrib[i].src_index,
- vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
- vs_output_tab[i]);
- }
-
- for (i = 0; i < attrib_count; i++) {
- /* Make sure we have a proper destination for our attribute. */
- assert(vs_output_tab[i] != -1);
-
- format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
-
- /* Obtain the type of data in this attribute. */
- type = r300_translate_vertex_data_type(format) |
- vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
-
- /* Obtain the swizzle for this attribute. Note that the default
- * swizzle in the hardware is not XYZW! */
- swizzle = r300_translate_vertex_data_swizzle(format);
-
- /* Add the attribute to the PSC table. */
- if (i & 1) {
- vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
- } else {
- vstream->vap_prog_stream_cntl[i >> 1] |= type;
- vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
- }
- }
-
- /* Set the last vector in the PSC. */
- if (i) {
- i -= 1;
- }
- vstream->vap_prog_stream_cntl[i >> 1] |=
- (R300_LAST_VEC << (i & 1 ? 16 : 0));
-
- vstream->count = (i >> 1) + 1;
-}
-
static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
unsigned count,
const struct pipe_vertex_element* attribs)
{
- struct r300_context *r300 = r300_context(pipe);
struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_vertex_element_state *velems;
+ unsigned i, size;
assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
@@ -1265,12 +1194,21 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
if (r300screen->caps->has_tcl) {
+ /* Check if the format is aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ size = util_format_get_blocksize(attribs[i].src_format);
+
+ if (size % 4 != 0) {
+ /* XXX Shouldn't we align the format? */
+ fprintf(stderr, "r300_create_vertex_elements_state: "
+ "Unaligned format %s:%i isn't supported\n",
+ util_format_name(attribs[i].src_format), size);
+ assert(0);
+ abort();
+ }
+ }
+
r300_vertex_psc(velems);
- } else {
- memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
- r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(&r300->vertex_info);
- r300_swtcl_vertex_psc(r300, velems);
}
}
return velems;
@@ -1293,12 +1231,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
}
- if (!r300_validate_aos(r300)) {
- /* XXX We should fallback using draw. */
- assert(0);
- abort();
- }
-
UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
}
@@ -1419,7 +1351,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
/* XXX Subtract immediates and RC_STATE_* variables. */
if (buf->size > (sizeof(float) * 4 * max_size)) {
- debug_printf("r300: Max size of the constant buffer is "
+ fprintf(stderr, "r300: Max size of the constant buffer is "
"%i*4 floats.\n", max_size);
abort();
}
@@ -1432,10 +1364,14 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
if (r300screen->caps->has_tcl) {
r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
r300->pvs_flush.dirty = TRUE;
+ } else if (r300->draw) {
+ draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
+ 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+ buf->size);
}
- }
- else if (shader == PIPE_SHADER_FRAGMENT)
+ } else if (shader == PIPE_SHADER_FRAGMENT) {
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ }
}
void r300_init_state_functions(struct r300_context* r300)
@@ -1473,7 +1409,9 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures;
r300->context.delete_sampler_state = r300_delete_sampler_state;
- r300->context.set_fragment_sampler_textures = r300_set_sampler_textures;
+ r300->context.set_fragment_sampler_views = r300_set_fragment_sampler_views;
+ r300->context.create_sampler_view = r300_create_sampler_view;
+ r300->context.sampler_view_destroy = r300_sampler_view_destroy;
r300->context.set_scissor_state = r300_set_scissor_state;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 6b9f61acd7b..bc5431c802d 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -37,6 +37,131 @@
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
+static void r300_draw_emit_attrib(struct r300_context* r300,
+ enum attrib_emit emit,
+ enum interp_mode interp,
+ int index)
+{
+ struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct tgsi_shader_info* info = &vs->info;
+ int output;
+
+ output = draw_find_shader_output(r300->draw,
+ info->output_semantic_name[index],
+ info->output_semantic_index[index]);
+ draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
+}
+
+static void r300_draw_emit_all_attribs(struct r300_context* r300)
+{
+ struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct r300_shader_semantics* vs_outputs = &vs->outputs;
+ int i, gen_count;
+
+ /* Position. */
+ if (vs_outputs->pos != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->pos);
+ } else {
+ assert(0);
+ }
+
+ /* Point size. */
+ if (vs_outputs->psize != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
+ vs_outputs->psize);
+ }
+
+ /* Colors. */
+ for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ if (vs_outputs->color[i] != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
+ vs_outputs->color[i]);
+ }
+ }
+
+ /* XXX Back-face colors. */
+
+ /* Texture coordinates. */
+ gen_count = 0;
+ for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+ if (vs_outputs->generic[i] != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->generic[i]);
+ gen_count++;
+ }
+ }
+
+ /* Fog coordinates. */
+ if (vs_outputs->fog != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->fog);
+ gen_count++;
+ }
+
+ /* XXX magic */
+ assert(gen_count <= 8);
+}
+
+/* Update the PSC tables for SW TCL, using Draw. */
+static void r300_swtcl_vertex_psc(struct r300_context *r300)
+{
+ struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state;
+ struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct vertex_info* vinfo = &r300->vertex_info;
+ uint16_t type, swizzle;
+ enum pipe_format format;
+ unsigned i, attrib_count;
+ int* vs_output_tab = vs->stream_loc_notcl;
+
+ /* XXX hax */
+ memset(vstream, 0, sizeof(struct r300_vertex_stream_state));
+
+ /* For each Draw attribute, route it to the fragment shader according
+ * to the vs_output_tab. */
+ attrib_count = vinfo->num_attribs;
+ DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
+ for (i = 0; i < attrib_count; i++) {
+ DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
+ " vs_output_tab %d\n", vinfo->attrib[i].src_index,
+ vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
+ vs_output_tab[i]);
+
+ /* Make sure we have a proper destination for our attribute. */
+ assert(vs_output_tab[i] != -1);
+
+ format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+
+ /* Obtain the type of data in this attribute. */
+ type = r300_translate_vertex_data_type(format) |
+ vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
+
+ /* Obtain the swizzle for this attribute. Note that the default
+ * swizzle in the hardware is not XYZW! */
+ swizzle = r300_translate_vertex_data_swizzle(format);
+
+ /* Add the attribute to the PSC table. */
+ if (i & 1) {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
+ } else {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
+ }
+ }
+
+ /* Set the last vector in the PSC. */
+ if (i) {
+ i -= 1;
+ }
+ vstream->vap_prog_stream_cntl[i >> 1] |=
+ (R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+ vstream->count = (i >> 1) + 1;
+ r300->vertex_stream_state.dirty = TRUE;
+ r300->vertex_stream_state.size = (1 + vstream->count) * 2;
+}
+
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
boolean swizzle_0001)
{
@@ -332,20 +457,25 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
(struct r300_textures_state*)r300->textures_state.state;
struct r300_texture_sampler_state *texstate;
struct r300_sampler_state *sampler;
+ struct pipe_sampler_view *view;
struct r300_texture *tex;
unsigned min_level, max_level, i, size;
unsigned count = MIN2(state->texture_count, state->sampler_count);
state->tx_enable = 0;
+ state->count = 0;
size = 2;
for (i = 0; i < count; i++) {
- if (state->textures[i] && state->sampler_states[i]) {
+ if (state->fragment_sampler_views[i] && state->sampler_states[i]) {
state->tx_enable |= 1 << i;
- tex = state->textures[i];
+ view = state->fragment_sampler_views[i];
+ tex = (struct r300_texture *)view->texture;
sampler = state->sampler_states[i];
+ assert(view->format == tex->tex.format);
+
texstate = &state->regs[i];
memcpy(texstate->format, &tex->state, sizeof(uint32_t)*3);
texstate->filter[0] = sampler->filter0;
@@ -367,8 +497,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
} else {
/* determine min/max levels */
/* the MAX_MIP level is the largest (finest) one */
- max_level = MIN2(sampler->max_lod, tex->tex.last_level);
- min_level = MIN2(sampler->min_lod, max_level);
+ max_level = MIN3(sampler->max_lod + view->first_level,
+ tex->tex.last_level, view->last_level);
+ min_level = MIN2(sampler->min_lod + view->first_level,
+ max_level);
texstate->format[0] |= R300_TX_NUM_LEVELS(max_level);
texstate->filter[0] |= R300_TX_MAX_MIP_LEVEL(min_level);
}
@@ -393,5 +525,12 @@ void r300_update_derived_state(struct r300_context* r300)
r300_merge_textures_and_samplers(r300);
}
+ if (r300->draw) {
+ memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+ r300_draw_emit_all_attribs(r300);
+ draw_compute_vertex_size(&r300->vertex_info);
+ r300_swtcl_vertex_psc(r300);
+ }
+
r300_update_ztop(r300);
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 8485d4f8f94..02d09c008c8 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -32,6 +32,8 @@
#include "r300_reg.h"
+#include <stdio.h>
+
/* Some maths. These should probably find their way to u_math, if needed. */
static INLINE int pack_float_16_6x(float f) {
@@ -54,7 +56,7 @@ static INLINE uint32_t r300_translate_blend_function(int blend_func)
case PIPE_BLEND_MAX:
return R300_COMB_FCN_MAX;
default:
- debug_printf("r300: Unknown blend function %d\n", blend_func);
+ fprintf(stderr, "r300: Unknown blend function %d\n", blend_func);
assert(0);
break;
}
@@ -100,13 +102,13 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact)
case PIPE_BLENDFACTOR_SRC1_ALPHA:
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- debug_printf("r300: Implementation error: "
+ fprintf(stderr, "r300: Implementation error: "
"Bad blend factor %d not supported!\n", blend_fact);
assert(0);
break;
default:
- debug_printf("r300: Unknown blend factor %d\n", blend_fact);
+ fprintf(stderr, "r300: Unknown blend factor %d\n", blend_fact);
assert(0);
break;
}
@@ -135,7 +137,7 @@ static INLINE uint32_t r300_translate_depth_stencil_function(int zs_func)
case PIPE_FUNC_ALWAYS:
return R300_ZS_ALWAYS;
default:
- debug_printf("r300: Unknown depth/stencil function %d\n",
+ fprintf(stderr, "r300: Unknown depth/stencil function %d\n",
zs_func);
assert(0);
break;
@@ -163,7 +165,7 @@ static INLINE uint32_t r300_translate_stencil_op(int s_op)
case PIPE_STENCIL_OP_INVERT:
return R300_ZS_INVERT;
default:
- debug_printf("r300: Unknown stencil op %d", s_op);
+ fprintf(stderr, "r300: Unknown stencil op %d", s_op);
assert(0);
break;
}
@@ -190,7 +192,7 @@ static INLINE uint32_t r300_translate_alpha_function(int alpha_func)
case PIPE_FUNC_ALWAYS:
return R300_FG_ALPHA_FUNC_ALWAYS;
default:
- debug_printf("r300: Unknown alpha function %d", alpha_func);
+ fprintf(stderr, "r300: Unknown alpha function %d", alpha_func);
assert(0);
break;
}
@@ -209,7 +211,7 @@ r300_translate_polygon_mode_front(unsigned mode) {
return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
default:
- debug_printf("r300: Bad polygon mode %i in %s\n", mode,
+ fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
__FUNCTION__);
return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
}
@@ -227,7 +229,7 @@ r300_translate_polygon_mode_back(unsigned mode) {
return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
default:
- debug_printf("r300: Bad polygon mode %i in %s\n", mode,
+ fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
__FUNCTION__);
return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
}
@@ -255,7 +257,7 @@ static INLINE uint32_t r300_translate_wrap(int wrap)
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
default:
- debug_printf("r300: Unknown texture wrap %d", wrap);
+ fprintf(stderr, "r300: Unknown texture wrap %d", wrap);
assert(0);
return 0;
}
@@ -276,7 +278,7 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
retval |= R300_TX_MIN_FILTER_LINEAR;
break;
default:
- debug_printf("r300: Unknown texture filter %d\n", min);
+ fprintf(stderr, "r300: Unknown texture filter %d\n", min);
assert(0);
break;
}
@@ -288,7 +290,7 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
retval |= R300_TX_MAG_FILTER_LINEAR;
break;
default:
- debug_printf("r300: Unknown texture filter %d\n", mag);
+ fprintf(stderr, "r300: Unknown texture filter %d\n", mag);
assert(0);
break;
}
@@ -304,7 +306,7 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
break;
default:
- debug_printf("r300: Unknown texture filter %d\n", mip);
+ fprintf(stderr, "r300: Unknown texture filter %d\n", mip);
assert(0);
break;
}
@@ -370,7 +372,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
desc = util_format_description(format);
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
- debug_printf("r300: Bad format %s in %s:%d\n", util_format_name(format),
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_name(format),
__FUNCTION__, __LINE__);
assert(0);
}
@@ -391,7 +393,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
break;
default:
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
assert(0);
}
@@ -412,15 +414,15 @@ r300_translate_vertex_data_type(enum pipe_format format) {
}
break;
default:
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
- debug_printf("r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n",
+ fprintf(stderr, "r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n",
util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0));
assert(0);
}
break;
default:
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
assert(0);
}
@@ -442,7 +444,7 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
assert(format);
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
return 0;
}
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 4a2c68269b1..88ae75bb816 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -127,7 +127,7 @@ void r300_emit_invariant_state(struct r300_context* r300,
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
/* XXX */
- OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
+ OUT_CS_REG(R300_SC_CLIP_RULE, 0xFFFF);
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 7c7656068bb..22ccadfe3dd 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -31,8 +31,7 @@
#include "r300_texture.h"
#include "r300_screen.h"
#include "r300_state_inlines.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
#define TILE_WIDTH 0
#define TILE_HEIGHT 1
@@ -46,6 +45,18 @@ static const unsigned microblock_table[5][3][2] = {
{{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
};
+/* Return true for non-compressed and non-YUV formats. */
+static boolean r300_format_is_plain(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ if (!format) {
+ return FALSE;
+ }
+
+ return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN;
+}
+
/* Translate a pipe_format into a useful texture format for sampling.
*
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
@@ -148,7 +159,7 @@ static uint32_t r300_translate_texformat(enum pipe_format format)
}
/* Compressed formats. */
- if (desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED) {
+ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
switch (format) {
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
@@ -302,7 +313,6 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return R300_COLOR_FORMAT_I8;
@@ -311,24 +321,19 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_B5G6R5_UNORM:
return R300_COLOR_FORMAT_RGB565;
case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
return R300_COLOR_FORMAT_ARGB1555;
case PIPE_FORMAT_B4G4R4A4_UNORM:
return R300_COLOR_FORMAT_ARGB4444;
/* 32-bit buffers. */
case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_SRGB:
case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_SRGB:
case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_X8B8G8R8_UNORM:
- case PIPE_FORMAT_X8B8G8R8_SRGB:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
return R300_COLOR_FORMAT_ARGB8888;
case PIPE_FORMAT_R10G10B10A2_UNORM:
@@ -393,12 +398,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
desc = util_format_description(format);
/* Specifies how the shader output is written to the fog unit. */
- if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
- /* The gamma correction causes precision loss so we need
- * higher precision to maintain reasonable quality.
- * It has nothing to do with the colorbuffer format. */
- modifier |= R300_US_OUT_FMT_C4_10_GAMMA;
- } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
if (desc->channel[0].size == 32) {
modifier |= R300_US_OUT_FMT_C4_32_FP;
} else {
@@ -428,46 +428,39 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
return modifier | R300_C2_SEL_A;
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return modifier | R300_C2_SEL_R;
- /* ARGB 32-bit outputs. */
+ /* BGRA outputs. */
case PIPE_FORMAT_B5G6R5_UNORM:
case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_SRGB:
return modifier |
R300_C0_SEL_B | R300_C1_SEL_G |
R300_C2_SEL_R | R300_C3_SEL_A;
- /* BGRA 32-bit outputs. */
+ /* ARGB outputs. */
case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_SRGB:
case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_SRGB:
return modifier |
R300_C0_SEL_A | R300_C1_SEL_R |
R300_C2_SEL_G | R300_C3_SEL_B;
- /* RGBA 32-bit outputs. */
+ /* ABGR outputs. */
case PIPE_FORMAT_A8B8G8R8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_X8B8G8R8_UNORM:
- case PIPE_FORMAT_X8B8G8R8_SRGB:
return modifier |
R300_C0_SEL_A | R300_C1_SEL_B |
R300_C2_SEL_G | R300_C3_SEL_R;
- /* ABGR 32-bit outputs. */
+ /* RGBA outputs. */
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_R10G10B10A2_UNORM:
- /* RGBA high precision outputs (same swizzles as ABGR low precision) */
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
//case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
@@ -658,7 +651,7 @@ unsigned r300_texture_get_stride(struct r300_screen* screen,
width = u_minify(tex->tex.width0, level);
- if (!util_format_is_compressed(tex->tex.format)) {
+ if (r300_format_is_plain(tex->tex.format)) {
tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
tex->mip_macrotile[level]);
width = align(width, tile_width);
@@ -676,7 +669,7 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
height = u_minify(tex->tex.height0, level);
- if (!util_format_is_compressed(tex->tex.format)) {
+ if (r300_format_is_plain(tex->tex.format)) {
tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
tex->mip_macrotile[level]);
height = align(height, tile_height);
@@ -699,7 +692,8 @@ static void r300_setup_miptree(struct r300_screen* screen,
/* Let's see if this miplevel can be macrotiled. */
tex->mip_macrotile[i] =
(tex->macrotile == R300_BUFFER_TILED &&
- r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH)) ?
+ r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH) &&
+ r300_texture_macro_switch(tex, i, rv350_mode, TILE_HEIGHT)) ?
R300_BUFFER_TILED : R300_BUFFER_LINEAR;
stride = r300_texture_get_stride(screen, tex, i);
@@ -733,10 +727,11 @@ static void r300_setup_flags(struct r300_texture* tex)
static void r300_setup_tiling(struct pipe_screen *screen,
struct r300_texture *tex)
{
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
enum pipe_format format = tex->tex.format;
boolean rv350_mode = r300_screen(screen)->caps->family >= CHIP_FAMILY_RV350;
- if (util_format_is_compressed(format)) {
+ if (!r300_format_is_plain(format)) {
return;
}
@@ -752,12 +747,12 @@ static void r300_setup_tiling(struct pipe_screen *screen,
tex->microtile = R300_BUFFER_TILED;
break;
- /* XXX Square-tiling doesn't work with kernel older than 2.6.34,
- * XXX need to check the DRM version */
- /*case 2:
+ case 2:
case 8:
- tex->microtile = R300_BUFFER_SQUARETILED;
- break;*/
+ if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
+ tex->microtile = R300_BUFFER_SQUARETILED;
+ }
+ break;
}
/* Set macrotiling. */
@@ -795,8 +790,8 @@ static struct pipe_texture* r300_texture_create(struct pipe_screen* screen,
tex->size);
rws->buffer_set_tiling(rws, tex->buffer,
tex->pitch[0],
- tex->microtile != R300_BUFFER_LINEAR,
- tex->macrotile != R300_BUFFER_LINEAR);
+ tex->microtile,
+ tex->macrotile);
if (!tex->buffer) {
FREE(tex);
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index aff4ddd4e23..3b3802ee2b2 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -25,12 +25,11 @@
#include "radeon_compiler.h"
#include "radeon_program.h"
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_util.h"
-#include "util/u_debug.h"
-
static unsigned translate_opcode(unsigned opcode)
{
switch(opcode) {
@@ -145,7 +144,7 @@ static unsigned translate_opcode(unsigned opcode)
case TGSI_OPCODE_KIL: return RC_OPCODE_KIL;
}
- debug_printf("r300: Unknown TGSI/RC opcode: %i\n", opcode);
+ fprintf(stderr, "r300: Unknown TGSI/RC opcode: %s\n", tgsi_get_opcode_name(opcode));
return RC_OPCODE_ILLEGAL_OPCODE;
}
@@ -272,9 +271,6 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst
struct rc_instruction * dst;
int i;
- if (src->Instruction.Opcode == TGSI_OPCODE_END)
- return;
-
dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev);
dst->U.I.Opcode = translate_opcode(src->Instruction.Opcode);
dst->U.I.SaturateMode = translate_saturate(src->Instruction.Saturate);
@@ -333,6 +329,7 @@ static void handle_immediate(struct tgsi_to_rc * ttr,
void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
const struct tgsi_token * tokens)
{
+ struct tgsi_full_instruction *inst;
struct tgsi_parse_context parser;
unsigned imm_index = 0;
int i;
@@ -367,7 +364,15 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
imm_index++;
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
- transform_instruction(ttr, &parser.FullToken.FullInstruction);
+ inst = &parser.FullToken.FullInstruction;
+ /* This hack with the RET opcode woudn't work with
+ * conditionals. */
+ if (inst->Instruction.Opcode == TGSI_OPCODE_END ||
+ inst->Instruction.Opcode == TGSI_OPCODE_RET) {
+ break;
+ }
+
+ transform_instruction(ttr, inst);
break;
}
}
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index bd6b95dccba..d5690caa68e 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -299,7 +299,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
r3xx_compile_vertex_program(&compiler);
if (compiler.Base.Error) {
/* XXX We should fallback using Draw. */
- fprintf(stderr, "r300 VP: Compiler error\n");
+ fprintf(stderr, "r300 VP: Compiler error:\n%s", compiler.Base.ErrorMsg);
abort();
}
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index e5183a8239c..acfa5dbeb9c 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -30,6 +30,8 @@
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "r300_defines.h"
+
struct r300_winsys_screen;
/* Creates a new r300 screen. */
@@ -47,10 +49,9 @@ enum r300_value_id {
R300_VID_PCI_ID,
R300_VID_GB_PIPES,
R300_VID_Z_PIPES,
+ R300_VID_SQUARE_TILING_SUPPORT
};
-#define R300_USAGE_FLAG_DONT_SYNC (1 << 17)
-
struct r300_winsys_screen {
void (*destroy)(struct r300_winsys_screen *ws);
@@ -148,8 +149,8 @@ struct r300_winsys_screen {
void (*buffer_set_tiling)(struct r300_winsys_screen *winsys,
struct r300_winsys_buffer *buffer,
uint32_t pitch,
- boolean microtiled,
- boolean macrotiled);
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled);
uint32_t (*get_value)(struct r300_winsys_screen *winsys,
enum r300_value_id vid);
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index de92a0cd2c7..937a573092f 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -104,12 +104,12 @@ softpipe_destroy( struct pipe_context *pipe )
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
sp_destroy_tex_tile_cache(softpipe->tex_cache[i]);
- pipe_texture_reference(&softpipe->texture[i], NULL);
+ pipe_sampler_view_reference(&softpipe->sampler_views[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]);
- pipe_texture_reference(&softpipe->vertex_textures[i], NULL);
+ pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL);
}
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
@@ -257,8 +257,10 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
- softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures;
- softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures;
+ softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views;
+ softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views;
+ softpipe->pipe.create_sampler_view = softpipe_create_sampler_view;
+ softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 9a8158e6a22..75e03c8ae6b 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -70,15 +70,15 @@ struct softpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
- unsigned num_textures;
+ unsigned num_sampler_views;
unsigned num_vertex_samplers;
- unsigned num_vertex_textures;
+ unsigned num_vertex_sampler_views;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of SP_NEW_x flags */
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 3d76af4d8cb..508fe8f764d 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -50,10 +50,10 @@ softpipe_flush( struct pipe_context *pipe,
draw_flush(softpipe->draw);
if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- for (i = 0; i < softpipe->num_textures; i++) {
+ for (i = 0; i < softpipe->num_sampler_views; i++) {
sp_flush_tex_tile_cache(softpipe->tex_cache[i]);
}
- for (i = 0; i < softpipe->num_vertex_textures; i++) {
+ for (i = 0; i < softpipe->num_vertex_sampler_views; i++) {
sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]);
}
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 4815a0d49f1..17cd5b82072 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +19,7 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL 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.
@@ -26,7 +27,7 @@
**************************************************************************/
/**
- * \brief Quad depth testing
+ * \brief Quad depth / stencil testing
*/
#include "pipe/p_defines.h"
@@ -96,7 +97,9 @@ get_depth_stencil_values( struct depth_data *data,
}
}
-/* If the shader has not been run, interpolate the depth values
+
+/**
+ * If the shader has not been run, interpolate the depth values
* ourselves.
*/
static void
@@ -115,6 +118,9 @@ interpolate_quad_depth( struct quad_header *quad )
}
+/**
+ * Compute the depth_data::qzzzz[] values from the float fragment Z values.
+ */
static void
convert_quad_depth( struct depth_data *data,
const struct quad_header *quad )
@@ -173,6 +179,9 @@ convert_quad_depth( struct depth_data *data,
+/**
+ * Write data->bzzzz[] values and data->stencilVals into the Z/stencil buffer.
+ */
static void
write_depth_stencil_values( struct depth_data *data,
struct quad_header *quad )
@@ -225,7 +234,6 @@ write_depth_stencil_values( struct depth_data *data,
-
/** Only 8-bit stencil supported */
#define STENCIL_MAX 0xff
@@ -408,12 +416,11 @@ apply_stencil_op(struct depth_data *data,
-/*
+/**
* To increase efficiency, we should probably have multiple versions
* of this function that are specifically for Z16, Z32 and FP Z buffers.
* Try to effectively do that with codegen...
*/
-
static boolean
depth_test_quad(struct quad_stage *qs,
struct depth_data *data,
@@ -523,7 +530,6 @@ depth_stencil_test_quad(struct quad_stage *qs,
wrtMask = softpipe->depth_stencil->stencil[face].writemask;
valMask = softpipe->depth_stencil->stencil[face].valuemask;
-
/* do the stencil test first */
{
unsigned passMask, failMask;
@@ -563,7 +569,7 @@ depth_stencil_test_quad(struct quad_stage *qs,
#define ALPHATEST( FUNC, COMP ) \
- static int \
+ static int \
alpha_test_quads_##FUNC( struct quad_stage *qs, \
struct quad_header *quads[], \
unsigned nr ) \
@@ -629,6 +635,7 @@ alpha_test_quads(struct quad_stage *qs,
}
}
+
static unsigned mask_count[16] =
{
0, /* 0x0 */
@@ -665,6 +672,9 @@ get_depth_bits(struct quad_stage *qs)
+/**
+ * General depth/stencil test function. Used when there's no fast-path.
+ */
static void
depth_test_quads_fallback(struct quad_stage *qs,
struct quad_header *quads[],
@@ -712,7 +722,6 @@ depth_test_quads_fallback(struct quad_stage *qs,
write_depth_stencil_values(&data, quads[i]);
}
-
quads[pass++] = quads[i];
}
@@ -730,169 +739,36 @@ depth_test_quads_fallback(struct quad_stage *qs,
/**
- * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LESS and
- * Z buffer writes enabled.
- *
- * NOTE: there's no guarantee that the quads are sequentially side by
- * side. The fragment shader may have culled some quads, etc. Sliver
- * triangles may generate non-sequential quads.
- */
-static void
-depth_interp_z16_less_write(struct quad_stage *qs,
- struct quad_header *quads[],
- unsigned nr)
-{
- unsigned i, pass = 0;
- const unsigned ix = quads[0]->input.x0;
- const unsigned iy = quads[0]->input.y0;
- const float fx = (float) ix;
- const float fy = (float) iy;
- const float dzdx = quads[0]->posCoef->dadx[2];
- const float dzdy = quads[0]->posCoef->dady[2];
- const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
- struct softpipe_cached_tile *tile;
- ushort (*depth16)[TILE_SIZE];
- ushort init_idepth[4], idepth[4], depth_step;
- const float scale = 65535.0;
-
- /* compute scaled depth of the four pixels in first quad */
- init_idepth[0] = (ushort)((z0) * scale);
- init_idepth[1] = (ushort)((z0 + dzdx) * scale);
- init_idepth[2] = (ushort)((z0 + dzdy) * scale);
- init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
-
- depth_step = (ushort)(dzdx * scale);
-
- tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
-
- for (i = 0; i < nr; i++) {
- const unsigned outmask = quads[i]->inout.mask;
- const int dx = quads[i]->input.x0 - ix;
- unsigned mask = 0;
-
- /* compute depth for this quad */
- idepth[0] = init_idepth[0] + dx * depth_step;
- idepth[1] = init_idepth[1] + dx * depth_step;
- idepth[2] = init_idepth[2] + dx * depth_step;
- idepth[3] = init_idepth[3] + dx * depth_step;
-
- depth16 = (ushort (*)[TILE_SIZE])
- &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
-
- if ((outmask & 1) && idepth[0] < depth16[0][0]) {
- depth16[0][0] = idepth[0];
- mask |= (1 << 0);
- }
-
- if ((outmask & 2) && idepth[1] < depth16[0][1]) {
- depth16[0][1] = idepth[1];
- mask |= (1 << 1);
- }
-
- if ((outmask & 4) && idepth[2] < depth16[1][0]) {
- depth16[1][0] = idepth[2];
- mask |= (1 << 2);
- }
-
- if ((outmask & 8) && idepth[3] < depth16[1][1]) {
- depth16[1][1] = idepth[3];
- mask |= (1 << 3);
- }
-
- quads[i]->inout.mask = mask;
- if (quads[i]->inout.mask)
- quads[pass++] = quads[i];
- }
-
- if (pass)
- qs->next->run(qs->next, quads, pass);
-
-}
-
-
-/**
- * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LEQUAL and
- * Z buffer writes enabled.
- *
- * NOTE: there's no guarantee that the quads are sequentially side by
- * side. The fragment shader may have culled some quads, etc. Sliver
- * triangles may generate non-sequential quads.
+ * Special-case Z testing for 16-bit Zbuffer and Z buffer writes enabled.
*/
-static void
-depth_interp_z16_lequal_write(struct quad_stage *qs,
- struct quad_header *quads[],
- unsigned nr)
-{
- unsigned i, pass = 0;
- const unsigned ix = quads[0]->input.x0;
- const unsigned iy = quads[0]->input.y0;
- const float fx = (float) ix;
- const float fy = (float) iy;
- const float dzdx = quads[0]->posCoef->dadx[2];
- const float dzdy = quads[0]->posCoef->dady[2];
- const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
- struct softpipe_cached_tile *tile;
- ushort (*depth16)[TILE_SIZE];
- ushort init_idepth[4], idepth[4], depth_step;
- const float scale = 65535.0;
-
- /* compute scaled depth of the four pixels in first quad */
- init_idepth[0] = (ushort)((z0) * scale);
- init_idepth[1] = (ushort)((z0 + dzdx) * scale);
- init_idepth[2] = (ushort)((z0 + dzdy) * scale);
- init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
-
- depth_step = (ushort)(dzdx * scale);
- tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
-
- for (i = 0; i < nr; i++) {
- const unsigned outmask = quads[i]->inout.mask;
- const int dx = quads[i]->input.x0 - ix;
- unsigned mask = 0;
-
- /* compute depth for this quad */
- idepth[0] = init_idepth[0] + dx * depth_step;
- idepth[1] = init_idepth[1] + dx * depth_step;
- idepth[2] = init_idepth[2] + dx * depth_step;
- idepth[3] = init_idepth[3] + dx * depth_step;
-
- depth16 = (ushort (*)[TILE_SIZE])
- &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
-
- if ((outmask & 1) && idepth[0] <= depth16[0][0]) {
- depth16[0][0] = idepth[0];
- mask |= (1 << 0);
- }
-
- if ((outmask & 2) && idepth[1] <= depth16[0][1]) {
- depth16[0][1] = idepth[1];
- mask |= (1 << 1);
- }
-
- if ((outmask & 4) && idepth[2] <= depth16[1][0]) {
- depth16[1][0] = idepth[2];
- mask |= (1 << 2);
- }
-
- if ((outmask & 8) && idepth[3] <= depth16[1][1]) {
- depth16[1][1] = idepth[3];
- mask |= (1 << 3);
- }
+#define NAME depth_interp_z16_less_write
+#define OPERATOR <
+#include "sp_quad_depth_test_tmp.h"
- depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
+#define NAME depth_interp_z16_equal_write
+#define OPERATOR ==
+#include "sp_quad_depth_test_tmp.h"
- quads[i]->inout.mask = mask;
- if (quads[i]->inout.mask)
- quads[pass++] = quads[i];
- }
+#define NAME depth_interp_z16_lequal_write
+#define OPERATOR <=
+#include "sp_quad_depth_test_tmp.h"
- if (pass)
- qs->next->run(qs->next, quads, pass);
+#define NAME depth_interp_z16_greater_write
+#define OPERATOR >
+#include "sp_quad_depth_test_tmp.h"
-}
+#define NAME depth_interp_z16_notequal_write
+#define OPERATOR !=
+#include "sp_quad_depth_test_tmp.h"
+#define NAME depth_interp_z16_gequal_write
+#define OPERATOR >=
+#include "sp_quad_depth_test_tmp.h"
+#define NAME depth_interp_z16_always_write
+#define ALWAYS 1
+#include "sp_quad_depth_test_tmp.h"
@@ -926,6 +802,10 @@ choose_depth_test(struct quad_stage *qs,
boolean occlusion = qs->softpipe->active_query_count;
+ /* default */
+ qs->run = depth_test_quads_fallback;
+
+ /* look for special cases */
if (!alpha &&
!depth &&
!stencil) {
@@ -938,57 +818,62 @@ choose_depth_test(struct quad_stage *qs,
!occlusion &&
!stencil)
{
- switch (depthfunc) {
- case PIPE_FUNC_LESS:
- switch (qs->softpipe->framebuffer.zsbuf->format) {
- case PIPE_FORMAT_Z16_UNORM:
+ if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
+ switch (depthfunc) {
+ case PIPE_FUNC_NEVER:
+ qs->run = depth_test_quads_fallback;
+ break;
+ case PIPE_FUNC_LESS:
qs->run = depth_interp_z16_less_write;
break;
- default:
- qs->run = depth_test_quads_fallback;
+ case PIPE_FUNC_EQUAL:
+ qs->run = depth_interp_z16_equal_write;
break;
- }
- break;
- case PIPE_FUNC_LEQUAL:
- switch (qs->softpipe->framebuffer.zsbuf->format) {
- case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FUNC_LEQUAL:
qs->run = depth_interp_z16_lequal_write;
break;
+ case PIPE_FUNC_GREATER:
+ qs->run = depth_interp_z16_greater_write;
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ qs->run = depth_interp_z16_notequal_write;
+ break;
+ case PIPE_FUNC_GEQUAL:
+ qs->run = depth_interp_z16_gequal_write;
+ break;
+ case PIPE_FUNC_ALWAYS:
+ qs->run = depth_interp_z16_always_write;
+ break;
default:
qs->run = depth_test_quads_fallback;
break;
}
- break;
- default:
- qs->run = depth_test_quads_fallback;
}
}
- else {
- qs->run = depth_test_quads_fallback;
- }
-
+ /* next quad/fragment stage */
qs->run( qs, quads, nr );
}
-
-
-static void depth_test_begin(struct quad_stage *qs)
+static void
+depth_test_begin(struct quad_stage *qs)
{
qs->run = choose_depth_test;
qs->next->begin(qs->next);
}
-static void depth_test_destroy(struct quad_stage *qs)
+static void
+depth_test_destroy(struct quad_stage *qs)
{
FREE( qs );
}
-struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe )
+struct quad_stage *
+sp_quad_depth_test_stage(struct softpipe_context *softpipe)
{
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h b/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h
new file mode 100644
index 00000000000..25af415c256
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h
@@ -0,0 +1,147 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+
+/*
+ * Template for generating Z test functions
+ * Only PIPE_FORMAT_Z16_UNORM supported at this time.
+ */
+
+
+#ifndef NAME
+#error "NAME is not defined!"
+#endif
+
+#if !defined(OPERATOR) && !defined(ALWAYS)
+#error "neither OPERATOR nor ALWAYS is defined!"
+#endif
+
+
+/*
+ * NOTE: there's no guarantee that the quads are sequentially side by
+ * side. The fragment shader may have culled some quads, etc. Sliver
+ * triangles may generate non-sequential quads.
+ */
+static void
+NAME(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ unsigned i, pass = 0;
+ const unsigned ix = quads[0]->input.x0;
+ const unsigned iy = quads[0]->input.y0;
+ const float fx = (float) ix;
+ const float fy = (float) iy;
+ const float dzdx = quads[0]->posCoef->dadx[2];
+ const float dzdy = quads[0]->posCoef->dady[2];
+ const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
+ struct softpipe_cached_tile *tile;
+ ushort (*depth16)[TILE_SIZE];
+ ushort init_idepth[4], idepth[4], depth_step;
+ const float scale = 65535.0;
+
+ /* compute scaled depth of the four pixels in first quad */
+ init_idepth[0] = (ushort)((z0) * scale);
+ init_idepth[1] = (ushort)((z0 + dzdx) * scale);
+ init_idepth[2] = (ushort)((z0 + dzdy) * scale);
+ init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
+
+ depth_step = (ushort)(dzdx * scale);
+
+ tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
+
+ for (i = 0; i < nr; i++) {
+ const unsigned outmask = quads[i]->inout.mask;
+ const int dx = quads[i]->input.x0 - ix;
+ unsigned mask = 0;
+
+ /* compute depth for this quad */
+ idepth[0] = init_idepth[0] + dx * depth_step;
+ idepth[1] = init_idepth[1] + dx * depth_step;
+ idepth[2] = init_idepth[2] + dx * depth_step;
+ idepth[3] = init_idepth[3] + dx * depth_step;
+
+ depth16 = (ushort (*)[TILE_SIZE])
+ &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
+
+#ifdef ALWAYS
+ if (outmask & 1) {
+ depth16[0][0] = idepth[0];
+ mask |= (1 << 0);
+ }
+
+ if (outmask & 2) {
+ depth16[0][1] = idepth[1];
+ mask |= (1 << 1);
+ }
+
+ if (outmask & 4) {
+ depth16[1][0] = idepth[2];
+ mask |= (1 << 2);
+ }
+
+ if (outmask & 8) {
+ depth16[1][1] = idepth[3];
+ mask |= (1 << 3);
+ }
+#else
+ /* Note: OPERATOR appears here: */
+ if ((outmask & 1) && (idepth[0] OPERATOR depth16[0][0])) {
+ depth16[0][0] = idepth[0];
+ mask |= (1 << 0);
+ }
+
+ if ((outmask & 2) && (idepth[1] OPERATOR depth16[0][1])) {
+ depth16[0][1] = idepth[1];
+ mask |= (1 << 1);
+ }
+
+ if ((outmask & 4) && (idepth[2] OPERATOR depth16[1][0])) {
+ depth16[1][0] = idepth[2];
+ mask |= (1 << 2);
+ }
+
+ if ((outmask & 8) && (idepth[3] OPERATOR depth16[1][1])) {
+ depth16[1][1] = idepth[3];
+ mask |= (1 << 3);
+ }
+#endif
+
+ depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
+
+ quads[i]->inout.mask = mask;
+ if (quads[i]->inout.mask)
+ quads[pass++] = quads[i];
+ }
+
+ if (pass)
+ qs->next->run(qs->next, quads, pass);
+}
+
+
+#undef NAME
+#undef OPERATOR
+#undef ALWAYS
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index d62bfa3d633..757dc861284 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -173,8 +173,10 @@ softpipe_is_format_supported( struct pipe_screen *screen,
break;
}
- if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if(!winsys->is_displaytarget_format_supported(winsys, format))
+ if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 6b01c0f4d72..ade96b0fd4c 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -177,14 +177,23 @@ void softpipe_set_polygon_stipple( struct pipe_context *,
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
-void softpipe_set_sampler_textures( struct pipe_context *,
- unsigned num,
- struct pipe_texture ** );
+void softpipe_set_sampler_views( struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view ** );
void
-softpipe_set_vertex_sampler_textures(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+softpipe_set_vertex_sampler_views(struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view **);
+
+struct pipe_sampler_view *
+softpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ);
+
+void
+softpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index 2b089c28316..d6f3229bed7 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -181,9 +181,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
/* note: reference counting */
pipe_buffer_reference(&softpipe->constants[shader][index], constants);
- if(shader == PIPE_SHADER_VERTEX) {
- draw_set_mapped_constant_buffer(softpipe->draw, PIPE_SHADER_VERTEX, index,
- data, size);
+ if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
+ draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
}
softpipe->mapped_constants[shader][index] = data;
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index ceb4e338f1a..d501952bba9 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -121,9 +121,38 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
}
+struct pipe_sampler_view *
+softpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
void
-softpipe_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+softpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+
+void
+softpipe_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
@@ -131,51 +160,51 @@ softpipe_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == softpipe->num_textures &&
- !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == softpipe->num_sampler_views &&
+ !memcmp(softpipe->sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
draw_flush(softpipe->draw);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num ? texture[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&softpipe->texture[i], tex);
- sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex);
+ pipe_sampler_view_reference(&softpipe->sampler_views[i], view);
+ sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[i], view);
}
- softpipe->num_textures = num;
+ softpipe->num_sampler_views = num;
softpipe->dirty |= SP_NEW_TEXTURE;
}
void
-softpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+softpipe_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
- assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
- if (num_textures == softpipe->num_vertex_textures &&
- !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ if (num == softpipe->num_vertex_sampler_views &&
+ !memcmp(softpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
return;
}
draw_flush(softpipe->draw);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&softpipe->vertex_textures[i], tex);
- sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex);
+ pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], view);
+ sp_tex_tile_cache_set_sampler_view(softpipe->vertex_tex_cache[i], view);
}
- softpipe->num_vertex_textures = num_textures;
+ softpipe->num_vertex_sampler_views = num;
softpipe->dirty |= SP_NEW_TEXTURE;
}
@@ -245,29 +274,41 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
*/
for (i = 0; i <= softpipe->vs->max_sampler; i++) {
if (softpipe->vertex_samplers[i]) {
+ struct pipe_texture *texture = NULL;
+
+ if (softpipe->vertex_sampler_views[i]) {
+ texture = softpipe->vertex_sampler_views[i]->texture;
+ }
+
softpipe->tgsi.vert_samplers_list[i] =
get_sampler_varient( i,
- sp_sampler(softpipe->vertex_samplers[i]),
- softpipe->vertex_textures[i],
+ sp_sampler(softpipe->vertex_samplers[i]),
+ texture,
TGSI_PROCESSOR_VERTEX );
sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i],
- softpipe->vertex_tex_cache[i],
- softpipe->vertex_textures[i] );
+ softpipe->vertex_tex_cache[i],
+ texture );
}
}
for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) {
if (softpipe->sampler[i]) {
+ struct pipe_texture *texture = NULL;
+
+ if (softpipe->sampler_views[i]) {
+ texture = softpipe->sampler_views[i]->texture;
+ }
+
softpipe->tgsi.frag_samplers_list[i] =
get_sampler_varient( i,
sp_sampler(softpipe->sampler[i]),
- softpipe->texture[i],
+ texture,
TGSI_PROCESSOR_FRAGMENT );
sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i],
softpipe->tex_cache[i],
- softpipe->texture[i] );
+ texture );
}
}
}
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index e3a5e37ce44..6594514c38f 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -116,12 +116,13 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc)
}
/**
- * Specify the texture to cache.
+ * Specify the sampler view to cache.
*/
void
-sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
- struct pipe_texture *texture)
+sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
+ struct pipe_sampler_view *view)
{
+ struct pipe_texture *texture = view ? view->texture : NULL;
uint i;
assert(!tc->transfer);
@@ -139,6 +140,14 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
tc->tex_trans = NULL;
}
+ if (view) {
+ tc->swizzle_r = view->swizzle_r;
+ tc->swizzle_g = view->swizzle_g;
+ tc->swizzle_b = view->swizzle_b;
+ tc->swizzle_a = view->swizzle_a;
+ tc->format = view->format;
+ }
+
/* mark as entries as invalid/empty */
/* XXX we should try to avoid this when the teximage hasn't changed */
for (i = 0; i < NUM_ENTRIES; i++) {
@@ -251,12 +260,18 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
/* get tile from the transfer (view into texture) */
- pipe_get_tile_rgba(tc->pipe,
- tc->tex_trans,
- addr.bits.x * TILE_SIZE,
- addr.bits.y * TILE_SIZE,
- TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ pipe_get_tile_swizzle(tc->pipe,
+ tc->tex_trans,
+ addr.bits.x * TILE_SIZE,
+ addr.bits.y * TILE_SIZE,
+ TILE_SIZE,
+ TILE_SIZE,
+ tc->swizzle_r,
+ tc->swizzle_g,
+ tc->swizzle_b,
+ tc->swizzle_a,
+ tc->format,
+ (float *) tile->data.color);
tile->addr = addr;
}
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
index b1163972587..12ae7ba12d6 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -83,6 +83,12 @@ struct softpipe_tex_tile_cache
void *tex_trans_map;
int tex_face, tex_level, tex_z;
+ unsigned swizzle_r;
+ unsigned swizzle_g;
+ unsigned swizzle_b;
+ unsigned swizzle_a;
+ unsigned format;
+
struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */
};
@@ -101,8 +107,8 @@ extern void
sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc);
extern void
-sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
- struct pipe_texture *texture);
+sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
+ struct pipe_sampler_view *view);
void
sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc);
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 2aff6118f41..f4983b7c8e8 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -91,6 +91,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
/* Round up the surface size to a multiple of the tile size?
*/
spt->dt = winsys->displaytarget_create(winsys,
+ spt->base.tex_usage,
spt->base.format,
spt->base.width0,
spt->base.height0,
@@ -139,8 +140,6 @@ softpipe_texture_create(struct pipe_screen *screen,
}
-
-
static void
softpipe_texture_destroy(struct pipe_texture *pt)
{
@@ -161,6 +160,55 @@ softpipe_texture_destroy(struct pipe_texture *pt)
}
+static struct pipe_texture *
+softpipe_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *template,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+ struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
+ if (!spt)
+ return NULL;
+
+ spt->base = *template;
+ pipe_reference_init(&spt->base.reference, 1);
+ spt->base.screen = screen;
+
+ spt->pot = (util_is_power_of_two(template->width0) &&
+ util_is_power_of_two(template->height0) &&
+ util_is_power_of_two(template->depth0));
+
+ spt->dt = winsys->displaytarget_from_handle(winsys,
+ template,
+ whandle,
+ &spt->stride[0]);
+ if (!spt->dt)
+ goto fail;
+
+ return &spt->base;
+
+ fail:
+ FREE(spt);
+ return NULL;
+}
+
+
+static boolean
+softpipe_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+ struct softpipe_texture *spt = softpipe_texture(pt);
+
+ assert(spt->dt);
+ if (!spt->dt)
+ return FALSE;
+
+ return winsys->displaytarget_get_handle(winsys, spt->dt, whandle);
+}
+
+
/**
* Get a pipe_surface "view" into a texture.
*/
@@ -461,6 +509,8 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
screen->texture_destroy = softpipe_texture_destroy;
+ screen->texture_from_handle = softpipe_texture_from_handle;
+ screen->texture_get_handle = softpipe_texture_get_handle;
screen->get_tex_surface = softpipe_get_tex_surface;
screen->tex_surface_destroy = softpipe_tex_surface_destroy;
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 791d30edc0e..1f66437dfe1 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -185,7 +185,7 @@ struct svga_state
const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct svga_velems_state *velems;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
struct svga_fragment_shader *fs;
struct svga_vertex_shader *vs;
@@ -208,7 +208,7 @@ struct svga_state
struct pipe_viewport_state viewport;
unsigned num_samplers;
- unsigned num_textures;
+ unsigned num_sampler_views;
unsigned num_vertex_buffers;
unsigned reduced_prim;
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index 1a8ef296cac..82d525ca33f 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -176,9 +176,36 @@ static void svga_delete_sampler_state(struct pipe_context *pipe,
}
-static void svga_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static struct pipe_sampler_view *
+svga_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+svga_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+static void svga_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct svga_context *svga = svga_context(pipe);
unsigned flag_1d = 0;
@@ -188,31 +215,31 @@ static void svga_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == svga->curr.num_textures &&
- !memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) {
+ if (num == svga->curr.num_sampler_views &&
+ !memcmp(svga->curr.sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
if (0) debug_printf("texture noop\n");
return;
}
for (i = 0; i < num; i++) {
- pipe_texture_reference(&svga->curr.texture[i],
- texture[i]);
+ pipe_sampler_view_reference(&svga->curr.sampler_views[i],
+ views[i]);
- if (!texture[i])
+ if (!views[i])
continue;
- if (texture[i]->format == PIPE_FORMAT_B8G8R8A8_SRGB)
+ if (views[i]->texture->format == PIPE_FORMAT_B8G8R8A8_SRGB)
flag_srgb |= 1 << i;
- if (texture[i]->target == PIPE_TEXTURE_1D)
+ if (views[i]->texture->target == PIPE_TEXTURE_1D)
flag_1d |= 1 << i;
}
- for (i = num; i < svga->curr.num_textures; i++)
- pipe_texture_reference(&svga->curr.texture[i],
- NULL);
+ for (i = num; i < svga->curr.num_sampler_views; i++)
+ pipe_sampler_view_reference(&svga->curr.sampler_views[i],
+ NULL);
- svga->curr.num_textures = num;
+ svga->curr.num_sampler_views = num;
svga->dirty |= SVGA_NEW_TEXTURE_BINDING;
if (flag_srgb != svga->curr.tex_flags.flag_srgb ||
@@ -231,7 +258,9 @@ void svga_init_sampler_functions( struct svga_context *svga )
svga->pipe.create_sampler_state = svga_create_sampler_state;
svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states;
svga->pipe.delete_sampler_state = svga_delete_sampler_state;
- svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures;
+ svga->pipe.set_fragment_sampler_views = svga_set_sampler_views;
+ svga->pipe.create_sampler_view = svga_create_sampler_view;
+ svga->pipe.sampler_view_destroy = svga_sampler_view_destroy;
}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index 4a058eda885..70d3a8a46ae 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -330,7 +330,7 @@ svga_texture_create(struct pipe_screen *screen,
*/
#if 0
if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
- !util_format_is_compressed(templat->format))
+ !util_format_is_s3tc(templat->format))
tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
#endif
@@ -969,7 +969,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
if (min_lod == 0 && max_lod >= pt->last_level)
view = FALSE;
- if (util_format_is_compressed(pt->format) && view) {
+ if (util_format_is_s3tc(pt->format) && view) {
format = svga_translate_format_render(pt->format);
}
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
index bb92f818eae..493f78a9908 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -137,7 +137,7 @@ static int emit_fs_consts( struct svga_context *svga,
for (i = 0; i < key->num_textures; i++) {
if (key->tex[i].unnormalized) {
- struct pipe_texture *tex = svga->curr.texture[i];
+ struct pipe_texture *tex = svga->curr.sampler_views[i]->texture;
float data[4];
data[0] = 1.0 / (float)tex->width0;
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index 2973444d0ab..1310fd9825f 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -158,10 +158,11 @@ static int make_fs_key( const struct svga_context *svga,
*
* SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
*/
- for (i = 0; i < svga->curr.num_textures; i++) {
- if (svga->curr.texture[i]) {
+ for (i = 0; i < svga->curr.num_sampler_views; i++) {
+ if (svga->curr.sampler_views[i]) {
assert(svga->curr.sampler[i]);
- key->tex[i].texture_target = svga->curr.texture[i]->target;
+ assert(svga->curr.sampler_views[i]->texture);
+ key->tex[i].texture_target = svga->curr.sampler_views[i]->texture->target;
if (!svga->curr.sampler[i]->normalized_coords) {
key->tex[i].width_height_idx = idx++;
key->tex[i].unnormalized = TRUE;
@@ -169,7 +170,7 @@ static int make_fs_key( const struct svga_context *svga,
}
}
}
- key->num_textures = svga->curr.num_textures;
+ key->num_textures = svga->curr.num_sampler_views;
idx = 0;
for (i = 0; i < svga->curr.num_samplers; ++i) {
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index 17b47859781..c08ec7c2e8c 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -37,14 +37,14 @@
void svga_cleanup_tss_binding(struct svga_context *svga)
{
int i;
- unsigned count = MAX2( svga->curr.num_textures,
+ unsigned count = MAX2( svga->curr.num_sampler_views,
svga->state.hw_draw.num_views );
for (i = 0; i < count; i++) {
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
svga_sampler_view_reference(&view->v, NULL);
- pipe_texture_reference( &svga->curr.texture[i], NULL );
+ pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL );
pipe_texture_reference( &view->texture, NULL );
view->dirty = 1;
@@ -57,7 +57,7 @@ update_tss_binding(struct svga_context *svga,
unsigned dirty )
{
unsigned i;
- unsigned count = MAX2( svga->curr.num_textures,
+ unsigned count = MAX2( svga->curr.num_sampler_views,
svga->state.hw_draw.num_views );
unsigned min_lod;
unsigned max_lod;
@@ -77,30 +77,32 @@ update_tss_binding(struct svga_context *svga,
for (i = 0; i < count; i++) {
const struct svga_sampler_state *s = svga->curr.sampler[i];
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
+ struct pipe_texture *texture = NULL;
/* get min max lod */
- if (svga->curr.texture[i]) {
+ if (svga->curr.sampler_views[i]) {
min_lod = MAX2(s->view_min_lod, 0);
- max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
+ max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level);
+ texture = svga->curr.sampler_views[i]->texture;
} else {
min_lod = 0;
max_lod = 0;
}
- if (view->texture != svga->curr.texture[i] ||
+ if (view->texture != texture ||
view->min_lod != min_lod ||
view->max_lod != max_lod) {
svga_sampler_view_reference(&view->v, NULL);
- pipe_texture_reference( &view->texture, svga->curr.texture[i] );
+ pipe_texture_reference( &view->texture, texture );
view->dirty = TRUE;
view->min_lod = min_lod;
view->max_lod = max_lod;
- if (svga->curr.texture[i])
+ if (texture)
view->v = svga_get_tex_sampler_view(&svga->pipe,
- svga->curr.texture[i],
+ texture,
min_lod,
max_lod);
}
@@ -115,7 +117,7 @@ update_tss_binding(struct svga_context *svga,
}
}
- svga->state.hw_draw.num_views = svga->curr.num_textures;
+ svga->state.hw_draw.num_views = svga->curr.num_sampler_views;
if (queue.bind_count) {
SVGA3dTextureState *ts;
diff --git a/src/gallium/drivers/sw/Makefile b/src/gallium/drivers/sw/Makefile
new file mode 100644
index 00000000000..2713a62ee9f
--- /dev/null
+++ b/src/gallium/drivers/sw/Makefile
@@ -0,0 +1,10 @@
+# Meta-driver which combines whichever software rasterizers have been
+# built into a single convenience library.
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+C_SOURCES = \
+ sw.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/sw/SConscript b/src/gallium/drivers/sw/SConscript
new file mode 100644
index 00000000000..6fbbdf3cc46
--- /dev/null
+++ b/src/gallium/drivers/sw/SConscript
@@ -0,0 +1,42 @@
+#######################################################################
+# SConscript for swrast convenience library
+#
+# This is a meta-driver which consists of any and all of the software
+# rasterizers into a single driver. A software rasterizer is defined
+# as any driver which takes an sw_winsys pointer as the only argument
+# to create_screen.
+#
+# XXX: unfortunately users of this driver still need to link in any
+# extra libraries needed for the particular driver (eg llvm for
+# llvmpipe). Not sure how to get around this.
+
+Import('*')
+
+if not set(('softpipe', 'llvmpipe', 'cell')).intersection(env['drivers']):
+ print 'warning: no supported pipe driver: skipping build of sw meta-driver'
+ Return()
+
+env = env.Clone()
+
+if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+ env.Prepend(LIBS = [softpipe])
+
+if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ env.Prepend(LIBS = [llvmpipe])
+
+if 'cell' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_CELL')
+ env.Prepend(LIBS = [cell])
+
+sw = env.ConvenienceLibrary(
+ target = 'sw',
+ source = [
+ 'sw.c',
+ ]
+ )
+ Export('sw')
diff --git a/src/gallium/drivers/sw/sw.c b/src/gallium/drivers/sw/sw.c
new file mode 100644
index 00000000000..9f156df45f5
--- /dev/null
+++ b/src/gallium/drivers/sw/sw.c
@@ -0,0 +1,59 @@
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "target-helpers/wrap_screen.h"
+#include "sw_public.h"
+#include "state_tracker/sw_winsys.h"
+
+
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * cell, llvmpipe, softpipe.
+ */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys)
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+ default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+ if (screen == NULL && strcmp(driver, "cell") == 0)
+ screen = cell_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+#endif
+
+ return screen;
+}
diff --git a/src/gallium/drivers/sw/sw_public.h b/src/gallium/drivers/sw/sw_public.h
new file mode 100644
index 00000000000..7085c5c85a0
--- /dev/null
+++ b/src/gallium/drivers/sw/sw_public.h
@@ -0,0 +1,13 @@
+#ifndef SW_PUBLIC_H
+#define SW_PUBLIC_H
+
+/* A convenience library, primarily to isolate the logic required to
+ * figure out which if any software rasterizers have been built and
+ * select between them.
+ */
+struct sw_winsys;
+
+struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index b7e6bbac68e..5c24bd1f7df 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -25,6 +25,7 @@
*
**************************************************************************/
+#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_simple_list.h"
#include "util/u_format.h"
@@ -114,7 +115,7 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)
(void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs,
(void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs,
(void *) tr_ctx->draw_rule.surf, 0,
- (void *) tr_ctx->draw_rule.tex, 0);
+ (void *) tr_ctx->draw_rule.sampler_view, 0);
if (tr_ctx->draw_rule.fs &&
tr_ctx->draw_rule.fs == tr_ctx->curr.fs)
block = TRUE;
@@ -128,12 +129,12 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)
for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)
if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])
block = TRUE;
- if (tr_ctx->draw_rule.tex) {
- for (k = 0; k < tr_ctx->curr.num_texs; k++)
- if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k])
+ if (tr_ctx->draw_rule.sampler_view) {
+ for (k = 0; k < tr_ctx->curr.num_sampler_views; k++)
+ if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.sampler_views[k])
block = TRUE;
- for (k = 0; k < tr_ctx->curr.num_vert_texs; k++) {
- if (tr_ctx->draw_rule.tex == tr_ctx->curr.vert_tex[k]) {
+ for (k = 0; k < tr_ctx->curr.num_vert_sampler_views; k++) {
+ if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.vert_sampler_views[k]) {
block = TRUE;
}
}
@@ -1015,63 +1016,119 @@ trace_context_set_viewport_state(struct pipe_context *_pipe,
}
+static struct pipe_sampler_view *
+trace_create_sampler_view(struct pipe_context *_pipe,
+ struct pipe_texture *_texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_texture *tr_tex = trace_texture(_texture);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_texture *texture = tr_tex->texture;
+ struct trace_sampler_view *result = CALLOC_STRUCT(trace_sampler_view);
+
+ trace_dump_call_begin("pipe_context", "create_sampler_view");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, texture);
+ trace_dump_arg(ptr, templ);
+
+ result->sampler_view = pipe->create_sampler_view(pipe, texture, templ);
+
+ result->base = *templ;
+ result->base.reference.count = 1;
+ result->base.texture = NULL;
+ pipe_texture_reference(&result->base.texture, _texture);
+ result->base.context = _pipe;
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ return &result->base;
+}
+
+
+static void
+trace_sampler_view_destroy(struct pipe_context *_pipe,
+ struct pipe_sampler_view *_view)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_sampler_view *tr_view = trace_sampler_view(_view);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_sampler_view *view = tr_view->sampler_view;
+
+ trace_dump_call_begin("pipe_context", "sampler_view_destroy");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, view);
+
+ pipe->sampler_view_destroy(pipe, view);
+
+ trace_dump_call_end();
+
+ pipe_texture_reference(&_view->texture, NULL);
+ FREE(_view);
+}
+
+
static INLINE void
-trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+trace_context_set_fragment_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_texture *tr_tex;
+ struct trace_sampler_view *tr_view;
struct pipe_context *pipe = tr_ctx->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
unsigned i;
- tr_ctx->curr.num_texs = num_textures;
- for(i = 0; i < num_textures; ++i) {
- tr_tex = trace_texture(textures[i]);
- tr_ctx->curr.tex[i] = tr_tex;
- unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
+ tr_ctx->curr.num_sampler_views = num;
+ for(i = 0; i < num; ++i) {
+ tr_view = trace_sampler_view(views[i]);
+ tr_ctx->curr.sampler_views[i] = tr_view;
+ unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;
}
- textures = unwrapped_textures;
+ views = unwrapped_views;
- trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures");
+ trace_dump_call_begin("pipe_context", "set_fragment_sampler_views");
trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_textures);
- trace_dump_arg_array(ptr, textures, num_textures);
+ trace_dump_arg(uint, num);
+ trace_dump_arg_array(ptr, views, num);
- pipe->set_fragment_sampler_textures(pipe, num_textures, textures);
+ pipe->set_fragment_sampler_views(pipe, num, views);
trace_dump_call_end();
}
static INLINE void
-trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+trace_context_set_vertex_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_texture *tr_tex;
+ struct trace_sampler_view *tr_view;
struct pipe_context *pipe = tr_ctx->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
unsigned i;
- tr_ctx->curr.num_vert_texs = num_textures;
- for(i = 0; i < num_textures; ++i) {
- tr_tex = trace_texture(textures[i]);
- tr_ctx->curr.vert_tex[i] = tr_tex;
- unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
+ tr_ctx->curr.num_vert_sampler_views = num;
+ for(i = 0; i < num; ++i) {
+ tr_view = trace_sampler_view(views[i]);
+ tr_ctx->curr.vert_sampler_views[i] = tr_view;
+ unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;
}
- textures = unwrapped_textures;
+ views = unwrapped_views;
- trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures");
+ trace_dump_call_begin("pipe_context", "set_vertex_sampler_views");
trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_textures);
- trace_dump_arg_array(ptr, textures, num_textures);
+ trace_dump_arg(uint, num);
+ trace_dump_arg_array(ptr, views, num);
- pipe->set_vertex_sampler_textures(pipe, num_textures, textures);
+ pipe->set_vertex_sampler_views(pipe, num, views);
trace_dump_call_end();
}
@@ -1487,8 +1544,10 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple;
tr_ctx->base.set_scissor_state = trace_context_set_scissor_state;
tr_ctx->base.set_viewport_state = trace_context_set_viewport_state;
- tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures;
- tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures;
+ tr_ctx->base.set_fragment_sampler_views = trace_context_set_fragment_sampler_views;
+ 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.set_vertex_buffers = trace_context_set_vertex_buffers;
if (pipe->surface_copy)
tr_ctx->base.surface_copy = trace_context_surface_copy;
diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h
index 14284232485..feec9b6bbf3 100644
--- a/src/gallium/drivers/trace/tr_context.h
+++ b/src/gallium/drivers/trace/tr_context.h
@@ -53,11 +53,11 @@ struct trace_context
struct trace_shader *fs;
struct trace_shader *vs;
- struct trace_texture *tex[PIPE_MAX_SAMPLERS];
- unsigned num_texs;
+ struct trace_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+ unsigned num_sampler_views;
- struct trace_texture *vert_tex[PIPE_MAX_VERTEX_SAMPLERS];
- unsigned num_vert_texs;
+ struct trace_sampler_view *vert_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+ unsigned num_vert_sampler_views;
unsigned nr_cbufs;
struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS];
@@ -68,7 +68,7 @@ struct trace_context
struct trace_shader *fs;
struct trace_shader *vs;
- struct trace_texture *tex;
+ struct trace_sampler_view *sampler_view;
struct trace_texture *surf;
int blocker;
diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c
index f4f17566fd3..53ab8c686d8 100644
--- a/src/gallium/drivers/trace/tr_rbug.c
+++ b/src/gallium/drivers/trace/tr_rbug.c
@@ -313,12 +313,12 @@ trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header,
for (i = 0; i < tr_ctx->curr.nr_cbufs; i++)
cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]);
- for (i = 0; i < tr_ctx->curr.num_texs; i++)
- texs[i] = VOID2U64(tr_ctx->curr.tex[i]);
+ for (i = 0; i < tr_ctx->curr.num_sampler_views; i++)
+ texs[i] = VOID2U64(tr_ctx->curr.sampler_views[i]);
rbug_send_context_info_reply(tr_rbug->con, serial,
VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs),
- texs, tr_ctx->curr.num_texs,
+ texs, tr_ctx->curr.num_sampler_views,
cbufs, tr_ctx->curr.nr_cbufs,
VOID2U64(tr_ctx->curr.zsbuf),
tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL);
@@ -444,7 +444,7 @@ trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *hea
pipe_mutex_lock(tr_ctx->draw_mutex);
tr_ctx->draw_rule.vs = U642VOID(rule->vertex);
tr_ctx->draw_rule.fs = U642VOID(rule->fragment);
- tr_ctx->draw_rule.tex = U642VOID(rule->texture);
+ tr_ctx->draw_rule.sampler_view = U642VOID(rule->texture);
tr_ctx->draw_rule.surf = U642VOID(rule->surface);
tr_ctx->draw_rule.blocker = rule->block;
tr_ctx->draw_blocker |= RBUG_BLOCK_RULE;
diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h
index 4dc95308a79..66250465e44 100644
--- a/src/gallium/drivers/trace/tr_texture.h
+++ b/src/gallium/drivers/trace/tr_texture.h
@@ -56,6 +56,14 @@ struct trace_surface
};
+struct trace_sampler_view
+{
+ struct pipe_sampler_view base;
+
+ struct pipe_sampler_view *sampler_view;
+};
+
+
struct trace_transfer
{
struct pipe_transfer base;
@@ -89,6 +97,15 @@ trace_surface(struct pipe_surface *surface)
}
+static INLINE struct trace_sampler_view *
+trace_sampler_view(struct pipe_sampler_view *sampler_view)
+{
+ if (!sampler_view)
+ return NULL;
+ return (struct trace_sampler_view *)sampler_view;
+}
+
+
static INLINE struct trace_transfer *
trace_transfer(struct pipe_transfer *transfer)
{
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index a7f12fb81e1..d1b734a9f9a 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -214,13 +214,13 @@ struct pipe_context {
void (*set_viewport_state)( struct pipe_context *,
const struct pipe_viewport_state * );
- void (*set_fragment_sampler_textures)(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+ void (*set_fragment_sampler_views)(struct pipe_context *,
+ unsigned num_views,
+ struct pipe_sampler_view **);
- void (*set_vertex_sampler_textures)(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+ void (*set_vertex_sampler_views)(struct pipe_context *,
+ unsigned num_views,
+ struct pipe_sampler_view **);
void (*set_vertex_buffers)( struct pipe_context *,
unsigned num_buffers,
@@ -307,6 +307,15 @@ struct pipe_context {
unsigned int (*is_buffer_referenced)(struct pipe_context *pipe,
struct pipe_buffer *buf);
+ /**
+ * Create a view on a texture to be used by a shader stage.
+ */
+ struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context *ctx,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templat);
+
+ void (*sampler_view_destroy)(struct pipe_context *ctx,
+ struct pipe_sampler_view *view);
/**
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 5c97dc87e82..c1e291b9da4 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -370,6 +370,17 @@ enum pipe_transfer_usage {
/**
+ * Texture swizzles
+ */
+#define PIPE_SWIZZLE_RED 0
+#define PIPE_SWIZZLE_GREEN 1
+#define PIPE_SWIZZLE_BLUE 2
+#define PIPE_SWIZZLE_ALPHA 3
+#define PIPE_SWIZZLE_ZERO 4
+#define PIPE_SWIZZLE_ONE 5
+
+
+/**
* Implementation capabilities/limits which are queried through
* pipe_screen::get_param() and pipe_screen::get_paramf().
*/
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index cbf3273ec8d..ba2985f4491 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -157,6 +157,7 @@ enum pipe_format {
PIPE_FORMAT_DXT5_SRGBA = 109,
PIPE_FORMAT_A8B8G8R8_UNORM = 110,
+ PIPE_FORMAT_B5G5R5X1_UNORM = 111,
PIPE_FORMAT_COUNT
};
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 3a97d888ce6..11072407d93 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -300,6 +300,24 @@ struct pipe_surface
/**
+ * A view into a texture that can be bound to a shader stage.
+ */
+struct pipe_sampler_view
+{
+ struct pipe_reference reference;
+ enum pipe_format format; /**< typed PIPE_FORMAT_x */
+ struct pipe_texture *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 */
+ 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 */
+ unsigned swizzle_a:3; /**< PIPE_SWIZZLE_x for alpha component */
+};
+
+
+/**
* Transfer object. For data transfer to/from a texture.
*/
struct pipe_transfer
diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h
index b173ba3683d..bb1cd6d1d82 100644
--- a/src/gallium/include/state_tracker/dri1_api.h
+++ b/src/gallium/include/state_tracker/dri1_api.h
@@ -7,14 +7,14 @@
#include "state_tracker/drm_api.h"
-#include <drm.h>
-
struct pipe_screen;
struct pipe_winsys;
struct pipe_buffer;
struct pipe_context;
struct pipe_texture;
+struct drm_clip_rect;
+
struct dri1_api_version
{
int major;
@@ -31,8 +31,8 @@ struct dri1_api_lock_funcs
{
void (*lock) (struct pipe_context * pipe);
void (*unlock) (struct pipe_context * locked_pipe);
- boolean(*is_locked) (struct pipe_context * locked_pipe);
- boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
+ boolean(*is_locked) (struct pipe_context * locked_pipe);
+ boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
void (*clear_lost_lock) (struct pipe_context * locked_pipe);
};
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
new file mode 100644
index 00000000000..c6adebb4ec5
--- /dev/null
+++ b/src/gallium/include/state_tracker/drisw_api.h
@@ -0,0 +1,35 @@
+#ifndef _DRISW_API_H_
+#define _DRISW_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_format.h"
+
+#include "state_tracker/drm_api.h"
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_buffer;
+struct pipe_context;
+struct pipe_texture;
+
+struct dri_drawable;
+
+/**
+ * This callback struct is intended for the winsys to call the loader.
+ */
+
+struct drisw_loader_funcs
+{
+ void (*put_image) (struct dri_drawable *dri_drawable,
+ void *data, unsigned width, unsigned height);
+};
+
+struct drisw_create_screen_arg
+{
+ struct drm_create_screen_arg base;
+
+ struct drisw_loader_funcs *lf;
+};
+
+#endif
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index fe7ef253ef0..9780cf250b8 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -13,6 +13,7 @@ struct pipe_texture;
enum drm_create_screen_mode {
DRM_CREATE_NORMAL = 0,
DRM_CREATE_DRI1,
+ DRM_CREATE_DRISW,
DRM_CREATE_DRIVER = 1024,
DRM_CREATE_MAX
};
diff --git a/src/gallium/include/state_tracker/graw.h b/src/gallium/include/state_tracker/graw.h
new file mode 100644
index 00000000000..a58e18e4739
--- /dev/null
+++ b/src/gallium/include/state_tracker/graw.h
@@ -0,0 +1,36 @@
+#ifndef GALLIUM_RAW_H
+#define GALLIUM_RAW_H
+
+/* This is an API for exercising gallium functionality in a
+ * platform-neutral fashion. Whatever platform integration is
+ * necessary to implement this interface is orchestrated by the
+ * individual target building this entity.
+ *
+ * For instance, the graw-xlib target includes code to implent these
+ * interfaces on top of the X window system.
+ *
+ * Programs using this interface may additionally benefit from some of
+ * the utilities currently in the libgallium.a library, especially
+ * those for parsing text representations of TGSI shaders.
+ */
+
+#include "pipe/p_format.h"
+
+struct pipe_screen;
+
+struct pipe_screen *graw_init( void );
+
+/* Returns a handle to be used with flush_frontbuffer()/present().
+ *
+ * Query format support with screen::is_format_supported and usage
+ * XXX.
+ */
+void *graw_create_window( int x,
+ int y,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format );
+
+void graw_destroy_window( void *handle );
+
+#endif
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
new file mode 100644
index 00000000000..70ad215bfce
--- /dev/null
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -0,0 +1,407 @@
+/**********************************************************
+ * 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef _ST_API_H_
+#define _ST_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+
+/**
+ * \file API for communication between state trackers and state tracker
+ * managers.
+ *
+ * While both are state tackers, we use the term state tracker for rendering
+ * APIs such as OpenGL or OpenVG, and state tracker manager for window system
+ * APIs such as EGL or GLX in this file.
+ *
+ * This file defines an API to be implemented by both state trackers and state
+ * tracker managers.
+ */
+
+/**
+ * The entry points of the state trackers.
+ */
+#define ST_MODULE_OPENGL_SYMBOL "st_module_OpenGL"
+#define ST_MODULE_OPENGL_ES1_SYMBOL "st_module_OpenGL_ES1"
+#define ST_MODULE_OPENGL_ES2_SYMBOL "st_module_OpenGL_ES2"
+#define ST_MODULE_OPENVG_SYMBOL "st_module_OpenVG"
+
+/**
+ * The supported rendering API of a state tracker.
+ */
+enum st_api_type {
+ ST_API_OPENGL,
+ ST_API_OPENGL_ES1,
+ ST_API_OPENGL_ES2,
+ ST_API_OPENVG,
+
+ ST_API_COUNT
+};
+
+/**
+ * Used in st_context_iface->teximage.
+ */
+enum st_texture_type {
+ ST_TEXTURE_1D,
+ ST_TEXTURE_2D,
+ ST_TEXTURE_3D,
+ ST_TEXTURE_RECT,
+};
+
+/**
+ * Available attachments of framebuffer.
+ */
+enum st_attachment_type {
+ ST_ATTACHMENT_FRONT_LEFT,
+ ST_ATTACHMENT_BACK_LEFT,
+ ST_ATTACHMENT_FRONT_RIGHT,
+ ST_ATTACHMENT_BACK_RIGHT,
+ ST_ATTACHMENT_DEPTH_STENCIL,
+ ST_ATTACHMENT_ACCUM,
+ ST_ATTACHMENT_SAMPLE,
+
+ ST_ATTACHMENT_COUNT,
+ ST_ATTACHMENT_INVALID = -1
+};
+
+/* for buffer_mask in st_visual */
+#define ST_ATTACHMENT_FRONT_LEFT_MASK (1 << ST_ATTACHMENT_FRONT_LEFT)
+#define ST_ATTACHMENT_BACK_LEFT_MASK (1 << ST_ATTACHMENT_BACK_LEFT)
+#define ST_ATTACHMENT_FRONT_RIGHT_MASK (1 << ST_ATTACHMENT_FRONT_RIGHT)
+#define ST_ATTACHMENT_BACK_RIGHT_MASK (1 << ST_ATTACHMENT_BACK_RIGHT)
+#define ST_ATTACHMENT_DEPTH_STENCIL_MASK (1 << ST_ATTACHMENT_DEPTH_STENCIL)
+#define ST_ATTACHMENT_ACCUM_MASK (1 << ST_ATTACHMENT_ACCUM)
+#define ST_ATTACHMENT_SAMPLE_MASK (1 << ST_ATTACHMENT_SAMPLE)
+
+/**
+ * Enumerations of state tracker context resources.
+ */
+enum st_context_resource_type {
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_2D,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_3D,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+ ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER,
+ ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE,
+};
+
+/**
+ * The return type of st_api->get_proc_address.
+ */
+typedef void (*st_proc_t)(void);
+
+struct pipe_context;
+struct pipe_texture;
+struct pipe_fence_handle;
+
+/**
+ * Used in st_context_iface->get_resource_for_egl_image.
+ */
+struct st_context_resource
+{
+ /* these fields are filled by the caller */
+ enum st_context_resource_type type;
+ void *resource;
+
+ /* this is owned by the caller */
+ struct pipe_texture *texture;
+};
+
+/**
+ * Used in st_manager_iface->get_egl_image.
+ */
+struct st_egl_image
+{
+ /* these fields are filled by the caller */
+ struct st_context_iface *stctxi;
+ void *egl_image;
+
+ /* this is owned by the caller */
+ struct pipe_texture *texture;
+
+ unsigned face;
+ unsigned level;
+ unsigned zslice;
+};
+
+/**
+ * Represent the visual of a framebuffer.
+ */
+struct st_visual
+{
+ /**
+ * Available buffers. Tested with ST_FRAMEBUFFER_*_MASK.
+ */
+ unsigned buffer_mask;
+
+ /**
+ * Buffer formats. The formats are always set even when the buffer is
+ * not available.
+ */
+ enum pipe_format color_format;
+ enum pipe_format depth_stencil_format;
+ enum pipe_format accum_format;
+ int samples;
+
+ /**
+ * Desired render buffer.
+ */
+ enum st_attachment_type render_buffer;
+};
+
+/**
+ * Represent a windowing system drawable.
+ *
+ * The framebuffer is implemented by the state tracker manager and
+ * used by the state trackers.
+ *
+ * Instead of the winsys pokeing into the API context to figure
+ * out what buffers that might be needed in the future by the API
+ * context, it calls into the framebuffer to get the textures.
+ *
+ * This structure along with the notify_invalid_framebuffer
+ * allows framebuffers to be shared between different threads
+ * but at the same make the API context free from thread
+ * syncronisation primitves, with the exception of a small
+ * atomic flag used for notification of framebuffer dirty status.
+ *
+ * The thread syncronisation is put inside the framebuffer
+ * and only called once the framebuffer has become dirty.
+ */
+struct st_framebuffer_iface
+{
+ /**
+ * Available for the state tracker manager to use.
+ */
+ void *st_manager_private;
+
+ /**
+ * The visual of a framebuffer.
+ */
+ const struct st_visual *visual;
+
+ /**
+ * Flush the front buffer.
+ *
+ * On some window systems, changes to the front buffers are not immediately
+ * visible. They need to be flushed.
+ *
+ * @att is one of the front buffer attachments.
+ */
+ boolean (*flush_front)(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt);
+
+ /**
+ * The state tracker asks for the textures it needs.
+ *
+ * It should try to only ask for attachments that it currently renders
+ * to, thus allowing the winsys to delay the allocation of textures not
+ * needed. For example front buffer attachments are not needed if you
+ * only do back buffer rendering.
+ *
+ * The implementor of this function needs to also ensure
+ * thread safty as this call might be done from multiple threads.
+ *
+ * The returned textures are owned by the caller. They should be
+ * unreferenced when no longer used. If this function is called multiple
+ * times with different sets of attachments, those buffers not included in
+ * the last call might be destroyed. This behavior might change in the
+ * future.
+ */
+ boolean (*validate)(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out);
+};
+
+/**
+ * Represent a rendering context.
+ *
+ * This entity is created from st_api and used by the state tracker manager.
+ */
+struct st_context_iface
+{
+ /**
+ * Available for the state tracker and the manager to use.
+ */
+ void *st_context_private;
+ void *st_manager_private;
+
+ /**
+ * Destroy the context.
+ */
+ void (*destroy)(struct st_context_iface *stctxi);
+
+ /**
+ * Invalidate the current textures that was taken from a framebuffer.
+ *
+ * The state tracker manager calls this function to let the rendering
+ * context know that it should update the textures it got from
+ * st_framebuffer_iface::validate. It should do so at the latest time possible.
+ * Possible right before sending triangles to the pipe context.
+ *
+ * For certain platforms this function might be called from a thread other
+ * than the thread that the context is currently bound in, and must
+ * therefore be thread safe. But it is the state tracker manager's
+ * responsibility to make sure that the framebuffer is bound to the context
+ * and the API context is current for the duration of this call.
+ *
+ * Thus reducing the sync primitive needed to a single atomic flag.
+ */
+ void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stfbi);
+
+ /**
+ * Flush all drawing from context to the pipe also flushes the pipe.
+ */
+ void (*flush)(struct st_context_iface *stctxi, unsigned flags,
+ struct pipe_fence_handle **fence);
+
+ /**
+ * Replace the texture image of a texture object at the specified level.
+ *
+ * This function is optional.
+ */
+ boolean (*teximage)(struct st_context_iface *stctxi, enum st_texture_type target,
+ int level, enum pipe_format internal_format,
+ struct pipe_texture *tex, boolean mipmap);
+
+ /**
+ * Used to implement glXCopyContext.
+ */
+ void (*copy)(struct st_context_iface *stctxi,
+ struct st_context_iface *stsrci, unsigned mask);
+
+ /**
+ * Look up and return the info of a resource for EGLImage.
+ *
+ * This function is optional.
+ */
+ boolean (*get_resource_for_egl_image)(struct st_context_iface *stctxi,
+ struct st_context_resource *stres);
+};
+
+
+/**
+ * Represent a state tracker manager.
+ *
+ * This interface is implemented by the state tracker manager. It corresponds
+ * to a "display" in the window system.
+ */
+struct st_manager
+{
+ struct pipe_screen *screen;
+
+ /**
+ * Look up and return the info of an EGLImage.
+ *
+ * This function is optional.
+ */
+ boolean (*get_egl_image)(struct st_manager *smapi,
+ struct st_egl_image *stimg);
+};
+
+/**
+ * Represent a rendering API such as OpenGL or OpenVG.
+ *
+ * Implemented by the state tracker and used by the state tracker manager.
+ */
+struct st_api
+{
+ /**
+ * Destroy the API.
+ */
+ void (*destroy)(struct st_api *stapi);
+
+ /**
+ * Return an API entry point.
+ *
+ * For GL this is the same as _glapi_get_proc_address.
+ */
+ st_proc_t (*get_proc_address)(struct st_api *stapi, const char *procname);
+
+ /**
+ * Return true if the visual is supported by the state tracker.
+ */
+ boolean (*is_visual_supported)(struct st_api *stapi,
+ const struct st_visual *visual);
+
+ /**
+ * Create a rendering context.
+ */
+ struct st_context_iface *(*create_context)(struct st_api *stapi,
+ struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *stsharei);
+
+ /**
+ * Bind the context to the calling thread with draw and read as drawables.
+ *
+ * The framebuffers might have different visuals than the context does.
+ */
+ boolean (*make_current)(struct st_api *stapi,
+ struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi);
+
+ /**
+ * Get the currently bound context in the calling thread.
+ */
+ struct st_context_iface *(*get_current)(struct st_api *stapi);
+};
+
+/**
+ * Represent a state tracker.
+ *
+ * This is the entry point of a state tracker.
+ */
+struct st_module
+{
+ enum st_api_type api;
+ struct st_api *(*create_api)(void);
+};
+
+/**
+ * Return true if the visual has the specified buffers.
+ */
+static INLINE boolean
+st_visual_have_buffers(const struct st_visual *visual, unsigned mask)
+{
+ return ((visual->buffer_mask & mask) == mask);
+}
+
+/* these symbols may need to be dynamically lookup up */
+extern PUBLIC const struct st_module st_module_OpenGL;
+extern PUBLIC const struct st_module st_module_OpenGL_ES1;
+extern PUBLIC const struct st_module st_module_OpenGL_ES2;
+extern PUBLIC const struct st_module st_module_OpenVG;
+
+#endif /* _ST_API_H_ */
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
index 0de98bbc1c9..a87650dc77d 100644
--- a/src/gallium/include/state_tracker/sw_winsys.h
+++ b/src/gallium/include/state_tracker/sw_winsys.h
@@ -44,8 +44,10 @@ extern "C" {
#endif
+struct winsys_handle;
struct pipe_screen;
struct pipe_context;
+struct pipe_texture;
/**
@@ -68,6 +70,7 @@ struct sw_winsys
boolean
(*is_displaytarget_format_supported)( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format );
/**
@@ -83,12 +86,30 @@ struct sw_winsys
*/
struct sw_displaytarget *
(*displaytarget_create)( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride );
/**
+ * Used to implement texture_from_handle.
+ */
+ struct sw_displaytarget *
+ (*displaytarget_from_handle)( struct sw_winsys *ws,
+ const struct pipe_texture *templat,
+ struct winsys_handle *whandle,
+ unsigned *stride );
+
+ /**
+ * Used to implement texture_get_handle.
+ */
+ boolean
+ (*displaytarget_get_handle)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle );
+
+ /**
* \param flags bitmask of PIPE_BUFFER_USAGE_x flags
*/
void *
diff --git a/src/gallium/state_trackers/dri/Makefile b/src/gallium/state_trackers/dri/Makefile
index ef8f19709ab..72e70577b3d 100644
--- a/src/gallium/state_trackers/dri/Makefile
+++ b/src/gallium/state_trackers/dri/Makefile
@@ -1,28 +1,12 @@
+# src/gallium/state_trackers/dri/Makefile
TOP = ../../../..
include $(TOP)/configs/current
-LIBNAME = dridrm
+SUBDIRS = drm sw
-LIBRARY_INCLUDES = \
- -I$(TOP)/include \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/drivers/dri/common \
- -I$(TOP)/src/mesa/main \
- $(shell pkg-config --cflags-only-I libdrm)
-
-
-C_SOURCES = \
- dri_context.c \
- dri_screen.c \
- dri_drawable.c \
- dri_extensions.c
-
-# $(TOP)/src/mesa/drivers/dri/common/utils.c \
- $(TOP)/src/mesa/drivers/dri/common/vblank.c \
- $(TOP)/src/mesa/drivers/dri/common/dri_util.c \
- $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \
- $(TOP)/src/mesa/drivers/common/driverfuncs.c \
- $(TOP)/src/mesa/drivers/dri/common/texmem.c \
- $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c
-
-include ../../Makefile.template
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript
index ce2c2735974..aba60fb8c5b 100644
--- a/src/gallium/state_trackers/dri/SConscript
+++ b/src/gallium/state_trackers/dri/SConscript
@@ -1,23 +1,6 @@
-#######################################################################
-# SConscript for dri state_tracker
-
Import('*')
-if env['dri']:
-
- env = env.Clone()
-
- env.Append(CPPPATH = [
- '#/src/mesa',
- '#/src/mesa/drivers/dri/common',
- ])
-
- st_dri = env.ConvenienceLibrary(
- target = 'st_dri',
- source = [ 'dri_context.c',
- 'dri_drawable.c',
- 'dri_extensions.c',
- 'dri_screen.c',
- ]
- )
- Export('st_dri')
+SConscript([
+ 'sw/SConscript',
+ 'drm/SConscript',
+])
diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.c b/src/gallium/state_trackers/dri/common/dri1_helper.c
new file mode 100644
index 00000000000..7eeb868d422
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri1_helper.c
@@ -0,0 +1,129 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Management of pipe objects (surface / pipe / fences) used by DRI1 and DRISW.
+ *
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri1_helper.h"
+
+struct pipe_fence_handle *
+dri1_swap_fences_pop_front(struct dri_drawable *draw)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ if (draw->cur_fences >= draw->desired_fences) {
+ screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
+ screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
+ --draw->cur_fences;
+ draw->tail &= DRI_SWAP_FENCES_MASK;
+ }
+ return fence;
+}
+
+void
+dri1_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+
+ if (!fence)
+ return;
+
+ if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
+ draw->cur_fences++;
+ screen->fence_reference(screen, &draw->swap_fences[draw->head++],
+ fence);
+ draw->head &= DRI_SWAP_FENCES_MASK;
+ }
+}
+
+void
+dri1_swap_fences_clear(struct dri_drawable *drawable)
+{
+ struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence;
+
+ while (drawable->cur_fences) {
+ fence = dri1_swap_fences_pop_front(drawable);
+ screen->fence_reference(screen, &fence, NULL);
+ }
+}
+
+struct pipe_surface *
+dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex)
+{
+ struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct pipe_surface *psurf = drawable->dri1_surface;
+
+ if (!psurf || psurf->texture != ptex) {
+ pipe_surface_reference(&drawable->dri1_surface, NULL);
+
+ drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen,
+ ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+
+ psurf = drawable->dri1_surface;
+ }
+
+ return psurf;
+}
+
+void
+dri1_destroy_pipe_surface(struct dri_drawable *drawable)
+{
+ pipe_surface_reference(&drawable->dri1_surface, NULL);
+}
+
+struct pipe_context *
+dri1_get_pipe_context(struct dri_screen *screen)
+{
+ struct pipe_context *pipe = screen->dri1_pipe;
+
+ if (!pipe) {
+ screen->dri1_pipe =
+ screen->pipe_screen->context_create(screen->pipe_screen, NULL);
+ pipe = screen->dri1_pipe;
+ }
+
+ return pipe;
+}
+
+void
+dri1_destroy_pipe_context(struct dri_screen *screen)
+{
+ if (screen->dri1_pipe)
+ screen->dri1_pipe->destroy(screen->dri1_pipe);
+}
diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.h b/src/gallium/state_trackers/dri/common/dri1_helper.h
new file mode 100644
index 00000000000..3254b7ff872
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri1_helper.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#ifndef DRI1_HELPER_H
+#define DRI1_HELPER_H
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+struct pipe_fence_handle *
+dri1_swap_fences_pop_front(struct dri_drawable *draw);
+
+void
+dri1_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence);
+
+void
+dri1_swap_fences_clear(struct dri_drawable *drawable);
+
+struct pipe_surface *
+dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex);
+
+void
+dri1_destroy_pipe_surface(struct dri_drawable *drawable);
+
+struct pipe_context *
+dri1_get_pipe_context(struct dri_screen *screen);
+
+void
+dri1_destroy_pipe_context(struct dri_screen *screen);
+
+#endif /* DRI1_HELPER_H */
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index 2f991c39e33..f14f4130bf4 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -29,27 +29,36 @@
* Author: Jakob Bornecrantz <[email protected]>
*/
-#include "dri_screen.h"
+#include "utils.h"
+#include "dri_screen.h"
#include "dri_drawable.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
+#include "dri_context.h"
+#include "dri_st_api.h"
+
#include "pipe/p_context.h"
+#include "state_tracker/st_context.h"
-#include "dri_context.h"
+static void
+dri_init_extensions(struct dri_context *ctx)
+{
+ struct st_context *st = (struct st_context *) ctx->st;
-#include "util/u_memory.h"
+ /* New extensions should be added in mesa/state_tracker/st_extensions.c
+ * and not in this file. */
+ driInitExtensions(st->ctx, NULL, GL_FALSE);
+}
GLboolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * cPriv, void *sharedContextPrivate)
{
+ struct st_api *stapi = dri_get_st_api();
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct dri_context *ctx = NULL;
- struct st_context *st_share = NULL;
+ struct st_context_iface *st_share = NULL;
+ struct st_visual stvis;
if (sharedContextPrivate) {
st_share = ((struct dri_context *)sharedContextPrivate)->st;
@@ -63,21 +72,15 @@ dri_create_context(const __GLcontextModes * visual,
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
ctx->lock = screen->drmLock;
- ctx->d_stamp = -1;
- ctx->r_stamp = -1;
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen,
- ctx );
-
- if (ctx->pipe == NULL)
- goto fail;
-
- ctx->st = st_create_context(ctx->pipe, visual, st_share);
+ dri_fill_st_visual(&stvis, screen, visual);
+ ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share);
if (ctx->st == NULL)
goto fail;
+ ctx->st->st_manager_private = (void *) ctx;
dri_init_extensions(ctx);
@@ -85,10 +88,7 @@ dri_create_context(const __GLcontextModes * visual,
fail:
if (ctx && ctx->st)
- st_destroy_context(ctx->st);
-
- if (ctx && ctx->pipe)
- ctx->pipe->destroy(ctx->pipe);
+ ctx->st->destroy(ctx->st);
FREE(ctx);
return FALSE;
@@ -110,11 +110,8 @@ dri_destroy_context(__DRIcontext * cPriv)
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
- st_flush(ctx->st, 0, NULL);
-
- /* Also frees ctx->pipe?
- */
- st_destroy_context(ctx->st);
+ ctx->st->flush(ctx->st, 0, NULL);
+ ctx->st->destroy(ctx->st);
FREE(ctx);
}
@@ -122,14 +119,16 @@ dri_destroy_context(__DRIcontext * cPriv)
GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
+ struct st_api *stapi = dri_get_st_api();
+
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
if (--ctx->bind_count == 0) {
- if (ctx->st && ctx->st == st_get_current()) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- st_make_current(NULL, NULL, NULL, NULL);
- }
+ if (ctx->st == stapi->get_current(stapi)) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ stapi->make_current(stapi, NULL, NULL, NULL);
+ }
}
}
@@ -141,83 +140,47 @@ dri_make_current(__DRIcontext * cPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv)
{
+ struct st_api *stapi = dri_get_st_api();
+
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
- struct st_context *old_st = st_get_current();
+ struct st_context_iface *old_st;
+ old_st = stapi->get_current(stapi);
if (old_st && old_st != ctx->st)
- st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
++ctx->bind_count;
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
- ctx->d_stamp = driDrawPriv->lastStamp - 1;
+ draw->texture_stamp = driDrawPriv->lastStamp - 1;
}
if (ctx->rPriv != driReadPriv) {
ctx->rPriv = driReadPriv;
- ctx->r_stamp = driReadPriv->lastStamp - 1;
+ read->texture_stamp = driReadPriv->lastStamp - 1;
}
- /* DRI co-state tracker currently overrides flush_frontbuffer.
- * When this is fixed, will need to pass the drawable in the
- * fourth parameter here so that when Mesa calls
- * flush_frontbuffer directly (in front-buffer rendering), it
- * will have access to the drawable argument:
- */
- st_make_current(ctx->st, draw->stfb, read->stfb, NULL);
-
- if (__dri1_api_hooks) {
- dri1_update_drawables(ctx, draw, read);
- } else {
- dri_update_buffer(ctx->pipe->screen,
- ctx->pipe->priv);
- }
- } else {
- st_make_current(NULL, NULL, NULL, NULL);
+ stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb);
+ }
+ else {
+ stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
}
-static void
-st_dri_lock(struct pipe_context *pipe)
+struct dri_context *
+dri_get_current(void)
{
- dri_lock((struct dri_context *)pipe->priv);
-}
+ struct st_api *stapi = dri_get_st_api();
+ struct st_context_iface *st;
-static void
-st_dri_unlock(struct pipe_context *pipe)
-{
- dri_unlock((struct dri_context *)pipe->priv);
-}
+ st = stapi->get_current(stapi);
-static boolean
-st_dri_is_locked(struct pipe_context *pipe)
-{
- return ((struct dri_context *)pipe->priv)->isLocked;
+ return (struct dri_context *) (st) ? st->st_manager_private : NULL;
}
-static boolean
-st_dri_lost_lock(struct pipe_context *pipe)
-{
- return ((struct dri_context *)pipe->priv)->wsLostLock;
-}
-
-static void
-st_dri_clear_lost_lock(struct pipe_context *pipe)
-{
- ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
-}
-
-struct dri1_api_lock_funcs dri1_lf = {
- .lock = st_dri_lock,
- .unlock = st_dri_unlock,
- .is_locked = st_dri_is_locked,
- .is_lock_lost = st_dri_lost_lock,
- .clear_lost_lock = st_dri_clear_lost_lock
-};
-
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h
index 13f497462f7..594618874a4 100644
--- a/src/gallium/state_trackers/dri/dri_context.h
+++ b/src/gallium/state_trackers/dri/common/dri_context.h
@@ -33,8 +33,7 @@
#define DRI_CONTEXT_H
#include "pipe/p_compiler.h"
-#include "drm.h"
-#include "dri_util.h"
+#include "dri_wrapper.h"
struct pipe_context;
struct pipe_fence;
@@ -51,9 +50,6 @@ struct dri_context
driOptionCache optionCache;
- unsigned int d_stamp;
- unsigned int r_stamp;
-
drmLock *lock;
boolean isLocked;
boolean stLostLock;
@@ -62,8 +58,7 @@ struct dri_context
unsigned int bind_count;
/* gallium */
- struct st_context *st;
- struct pipe_context *pipe;
+ struct st_context_iface *st;
};
static INLINE struct dri_context *
@@ -72,33 +67,9 @@ dri_context(__DRIcontext * driContextPriv)
return (struct dri_context *)driContextPriv->driverPrivate;
}
-static INLINE void
-dri_lock(struct dri_context *ctx)
-{
- drm_context_t hw_context = ctx->cPriv->hHWContext;
- char ret = 0;
-
- DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
- if (ret) {
- drmGetLock(ctx->sPriv->fd, hw_context, 0);
- ctx->stLostLock = TRUE;
- ctx->wsLostLock = TRUE;
- }
- ctx->isLocked = TRUE;
-}
-
-static INLINE void
-dri_unlock(struct dri_context *ctx)
-{
- ctx->isLocked = FALSE;
- DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
-}
-
/***********************************************************************
* dri_context.c
*/
-extern struct dri1_api_lock_funcs dri1_lf;
-
void dri_destroy_context(__DRIcontext * driContextPriv);
boolean dri_unbind_context(__DRIcontext * driContextPriv);
@@ -108,16 +79,14 @@ dri_make_current(__DRIcontext * driContextPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv);
+struct dri_context *
+dri_get_current(void);
+
boolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * driContextPriv,
void *sharedContextPrivate);
-/***********************************************************************
- * dri_extensions.c
- */
-void dri_init_extensions(struct dri_context *ctx);
-
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
new file mode 100644
index 00000000000..75b4cc56289
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -0,0 +1,94 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+
+#include "pipe/p_screen.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+/**
+ * This is called when we need to set up GL rendering to a new X window.
+ */
+boolean
+dri_create_buffer(__DRIscreen * sPriv,
+ __DRIdrawable * dPriv,
+ const __GLcontextModes * visual, boolean isPixmap)
+{
+ struct dri_screen *screen = sPriv->private;
+ struct dri_drawable *drawable = NULL;
+
+ if (isPixmap)
+ goto fail; /* not implemented */
+
+ drawable = CALLOC_STRUCT(dri_drawable);
+ if (drawable == NULL)
+ goto fail;
+
+ dri_fill_st_visual(&drawable->stvis, screen, visual);
+ drawable->stfb = dri_create_st_framebuffer(drawable);
+ if (drawable->stfb == NULL)
+ goto fail;
+
+ drawable->sPriv = sPriv;
+ drawable->dPriv = dPriv;
+ dPriv->driverPrivate = (void *)drawable;
+
+ drawable->desired_fences = 2;
+
+ return GL_TRUE;
+fail:
+ FREE(drawable);
+ return GL_FALSE;
+}
+
+void
+dri_destroy_buffer(__DRIdrawable * dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+
+ dri1_swap_fences_clear(drawable);
+
+ dri1_destroy_pipe_surface(drawable);
+
+ dri_destroy_st_framebuffer(drawable->stfb);
+
+ drawable->desired_fences = 0;
+
+ FREE(drawable);
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 8bc59cb4c3d..98abeb9ec05 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -29,6 +29,8 @@
#define DRI_DRAWABLE_H
#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "state_tracker/st_api.h"
struct pipe_surface;
struct pipe_fence_handle;
@@ -44,26 +46,26 @@ struct dri_drawable
__DRIdrawable *dPriv;
__DRIscreen *sPriv;
- unsigned attachments[8];
- unsigned num_attachments;
-
- boolean is_pixmap;
+ /* gallium */
+ struct st_framebuffer_iface *stfb;
+ struct st_visual stvis;
__DRIbuffer old[8];
unsigned old_num;
unsigned old_w;
unsigned old_h;
- /* gallium */
- struct st_framebuffer *stfb;
+ struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+ unsigned int texture_mask, texture_stamp;
+
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
unsigned int head;
unsigned int tail;
unsigned int desired_fences;
unsigned int cur_fences;
- enum pipe_format color_format;
- enum pipe_format depth_stencil_format;
+ /* used only by DRI1 */
+ struct pipe_surface *dri1_surface;
};
static INLINE struct dri_drawable *
@@ -80,35 +82,8 @@ dri_create_buffer(__DRIscreen * sPriv,
__DRIdrawable * dPriv,
const __GLcontextModes * visual, boolean isPixmap);
-void
-dri_update_buffer(struct pipe_screen *screen, void *context_private);
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private);
-
-void dri_swap_buffers(__DRIdrawable * dPriv);
-
-void
-dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
-
-void dri_get_buffers(__DRIdrawable * dPriv);
-
void dri_destroy_buffer(__DRIdrawable * dPriv);
-void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint glx_texture_format, __DRIdrawable *dPriv);
-
-void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv);
-
-void
-dri1_update_drawables(struct dri_context *ctx,
- struct dri_drawable *draw, struct dri_drawable *read);
-
-void
-dri1_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index 7ccad8f5dd6..821c1dea626 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -30,17 +30,26 @@
*/
#include "utils.h"
+#ifndef __NOT_HAVE_DRM_H
#include "vblank.h"
+#endif
#include "xmlpool.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
-
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#ifndef __NOT_HAVE_DRM_H
+#include "dri1.h"
+#include "dri2.h"
+#else
+#include "drisw.h"
+#endif
+
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_format.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
#include "util/u_debug.h"
@@ -49,41 +58,11 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
- /*DRI_CONF_FORCE_S3TC_ENABLE(false) */
+/* DRI_CONF_FORCE_S3TC_ENABLE(false) */
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
- const uint __driNConfigOptions = 3;
-
-static const __DRItexBufferExtension dri2TexBufferExtension = {
- { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
- dri2_set_tex_buffer,
- dri2_set_tex_buffer2,
-};
-
-static void
-dri2_flush_drawable(__DRIdrawable *draw)
-{
-}
-
-static const __DRI2flushExtension dri2FlushExtension = {
- { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
- dri2_flush_drawable,
- dri2InvalidateDrawable,
-};
-
- static const __DRIextension *dri_screen_extensions[] = {
- &driReadDrawableExtension,
- &driCopySubBufferExtension.base,
- &driSwapControlExtension.base,
- &driFrameTrackingExtension.base,
- &driMediaStreamCounterExtension.base,
- &dri2TexBufferExtension.base,
- &dri2FlushExtension.base,
- NULL
- };
-
-struct dri1_api *__dri1_api_hooks = NULL;
+static const uint __driNConfigOptions = 3;
static const __DRIconfig **
dri_fill_in_modes(struct dri_screen *screen,
@@ -135,9 +114,7 @@ dri_fill_in_modes(struct dri_screen *screen,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
- if (screen->sPriv->dri2.loader &&
- (screen->sPriv->dri2.loader->base.version > 2) &&
- (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
+ if (dri_with_format(screen->sPriv)) {
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
@@ -229,6 +206,70 @@ dri_fill_in_modes(struct dri_screen *screen,
}
/**
+ * Roughly the converse of dri_fill_in_modes.
+ */
+void
+dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
+ const __GLcontextModes *mode)
+{
+ memset(stvis, 0, sizeof(*stvis));
+
+ stvis->samples = mode->samples;
+ stvis->render_buffer = ST_ATTACHMENT_INVALID;
+
+ if (mode->redBits == 8) {
+ if (mode->alphaBits == 8)
+ stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ else
+ stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ } else {
+ stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
+ }
+
+ switch (mode->depthBits) {
+ default:
+ case 0:
+ stvis->depth_stencil_format = PIPE_FORMAT_NONE;
+ break;
+ case 16:
+ stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
+ break;
+ case 24:
+ if (mode->stencilBits == 0) {
+ stvis->depth_stencil_format = (screen->d_depth_bits_last) ?
+ PIPE_FORMAT_Z24X8_UNORM:
+ PIPE_FORMAT_X8Z24_UNORM;
+ } else {
+ stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
+ PIPE_FORMAT_Z24S8_UNORM:
+ PIPE_FORMAT_S8Z24_UNORM;
+ }
+ break;
+ case 32:
+ stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
+ break;
+ }
+
+ stvis->accum_format = (mode->haveAccumBuffer) ?
+ PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
+
+ stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (mode->doubleBufferMode)
+ stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (mode->stereoMode) {
+ stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (mode->doubleBufferMode)
+ stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ if (mode->haveDepthBuffer || mode->haveStencilBuffer)
+ stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
+ /* let the state tracker allocate the accum buffer */
+}
+
+#ifndef __NOT_HAVE_DRM_H
+
+/**
* Get information about previous buffer swaps.
*/
static int
@@ -240,164 +281,101 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
return 0;
}
-static INLINE void
-dri_copy_version(struct dri1_api_version *dst,
- const struct __DRIversionRec *src)
-{
- dst->major = src->major;
- dst->minor = src->minor;
- dst->patch_level = src->patch;
-}
+#endif
-static const __DRIconfig **
-dri_init_screen(__DRIscreen * sPriv)
+static void
+dri_destroy_option_cache(struct dri_screen * screen)
{
- struct dri_screen *screen;
- const __DRIconfig **configs;
- struct dri1_create_screen_arg arg;
-
- screen = CALLOC_STRUCT(dri_screen);
- if (!screen)
- return NULL;
+ int i;
- screen->api = drm_api_create();
- screen->sPriv = sPriv;
- screen->fd = sPriv->fd;
- screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
-
- sPriv->private = (void *)screen;
- sPriv->extensions = dri_screen_extensions;
-
- arg.base.mode = DRM_CREATE_DRI1;
- arg.lf = &dri1_lf;
- arg.ddx_info = sPriv->pDevPriv;
- arg.ddx_info_size = sPriv->devPrivSize;
- arg.sarea = sPriv->pSAREA;
- dri_copy_version(&arg.ddx_version, &sPriv->ddx_version);
- dri_copy_version(&arg.dri_version, &sPriv->dri_version);
- dri_copy_version(&arg.drm_version, &sPriv->drm_version);
- arg.api = NULL;
-
- screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg.base);
-
- if (!screen->pipe_screen || !arg.api) {
- debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
- goto out_no_screen;
+ for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
+ FREE(screen->optionCache.info[i].name);
+ FREE(screen->optionCache.info[i].ranges);
}
- __dri1_api_hooks = arg.api;
-
- screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer;
- driParseOptionInfo(&screen->optionCache,
- __driConfigOptions, __driNConfigOptions);
-
- /**
- * FIXME: If the driver supports format conversion swapbuffer blits, we might
- * want to support other color bit depths than the server is currently
- * using.
- */
-
- configs = dri_fill_in_modes(screen, sPriv->fbBPP);
- if (!configs)
- goto out_no_configs;
-
- return configs;
- out_no_configs:
- screen->pipe_screen->destroy(screen->pipe_screen);
- out_no_screen:
- FREE(screen);
- return NULL;
+ FREE(screen->optionCache.info);
+ FREE(screen->optionCache.values);
}
-/**
- * This is the driver specific part of the createNewScreen entry point.
- *
- * Returns the __GLcontextModes supported by this driver.
- */
-static const __DRIconfig **
-dri_init_screen2(__DRIscreen * sPriv)
+void
+dri_destroy_screen_helper(struct dri_screen * screen)
{
- struct dri_screen *screen;
- struct drm_create_screen_arg arg;
- const __DRIdri2LoaderExtension *dri2_ext =
- sPriv->dri2.loader;
-
- screen = CALLOC_STRUCT(dri_screen);
- if (!screen)
- goto fail;
-
- screen->api = drm_api_create();
- screen->sPriv = sPriv;
- screen->fd = sPriv->fd;
- sPriv->private = (void *)screen;
- sPriv->extensions = dri_screen_extensions;
- arg.mode = DRM_CREATE_NORMAL;
-
- screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg);
- if (!screen->pipe_screen) {
- debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
- goto fail;
- }
+ dri1_destroy_pipe_context(screen);
- /* We need to hook in here */
- screen->pipe_screen->update_buffer = dri_update_buffer;
- screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
-
- driParseOptionInfo(&screen->optionCache,
- __driConfigOptions, __driNConfigOptions);
+ if (screen->smapi)
+ dri_destroy_st_manager(screen->smapi);
- screen->auto_fake_front = dri2_ext->base.version >= 3 &&
- dri2_ext->getBuffersWithFormat != NULL;
+ if (screen->pipe_screen)
+ screen->pipe_screen->destroy(screen->pipe_screen);
- return dri_fill_in_modes(screen, 32);
- fail:
- return NULL;
+ dri_destroy_option_cache(screen);
}
static void
dri_destroy_screen(__DRIscreen * sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
- int i;
-
- screen->pipe_screen->destroy(screen->pipe_screen);
-
- for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
- FREE(screen->optionCache.info[i].name);
- FREE(screen->optionCache.info[i].ranges);
- }
- FREE(screen->optionCache.info);
- FREE(screen->optionCache.values);
+ dri_destroy_screen_helper(screen);
FREE(screen);
sPriv->private = NULL;
+ sPriv->extensions = NULL;
}
-PUBLIC const struct __DriverAPIRec driDriverAPI = {
- .InitScreen = dri_init_screen,
+const __DRIconfig **
+dri_init_screen_helper(struct dri_screen *screen,
+ struct drm_create_screen_arg *arg,
+ unsigned pixel_bits)
+{
+ screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, arg);
+ if (!screen->pipe_screen) {
+ debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
+ return NULL;
+ }
+
+ screen->smapi = dri_create_st_manager(screen);
+ if (!screen->smapi)
+ return NULL;
+
+ driParseOptionInfo(&screen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ return dri_fill_in_modes(screen, pixel_bits);
+}
+
+/**
+ * DRI driver virtual function table.
+ *
+ * DRI versions differ in their implementation of init_screen and swap_buffers.
+ */
+const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
- .SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
+
+#ifndef __NOT_HAVE_DRM_H
+
.GetSwapInfo = dri_get_swap_info,
.GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
- .CopySubBuffer = dri_copy_sub_buffer,
- .InitScreen = dri_init_screen,
- .InitScreen2 = dri_init_screen2,
-};
+ .InitScreen2 = dri2_init_screen,
+
+ .InitScreen = dri1_init_screen,
+ .SwapBuffers = dri1_swap_buffers,
+ .CopySubBuffer = dri1_copy_sub_buffer,
+
+#else
+
+ .InitScreen = drisw_init_screen,
+ .SwapBuffers = drisw_swap_buffers,
+
+#endif
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
- &driCoreExtension.base,
- &driLegacyExtension.base,
- &driDRI2Extension.base,
- NULL
};
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index 75a0ee4250e..e77bce17ae9 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -32,12 +32,14 @@
#ifndef DRI_SCREEN_H
#define DRI_SCREEN_H
-#include "dri_util.h"
+#include "dri_wrapper.h"
#include "xmlconfig.h"
#include "pipe/p_compiler.h"
-
-#include "state_tracker/dri1_api.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/st_api.h"
+#include "state_tracker/drm_api.h"
struct dri_screen
{
@@ -60,6 +62,11 @@ struct dri_screen
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
boolean auto_fake_front;
+
+ struct st_manager *smapi;
+
+ /* used only by DRI1 */
+ struct pipe_context *dri1_pipe;
};
/** cast wrapper */
@@ -69,11 +76,39 @@ dri_screen(__DRIscreen * sPriv)
return (struct dri_screen *)sPriv->private;
}
-/***********************************************************************
- * dri_screen.c
- */
+#ifndef __NOT_HAVE_DRM_H
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ const __DRIdri2LoaderExtension *loader = sPriv->dri2.loader;
+
+ return loader
+ && (loader->base.version >= 3)
+ && (loader->getBuffersWithFormat != NULL);
+}
+
+#else
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ return TRUE;
+}
+
+#endif
+
+void
+dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
+ const __GLcontextModes *mode);
+
+const __DRIconfig **
+dri_init_screen_helper(struct dri_screen *screen,
+ struct drm_create_screen_arg *arg,
+ unsigned pixel_bits);
-extern struct dri1_api *__dri1_api_hooks;
+void
+dri_destroy_screen_helper(struct dri_screen * screen);
#endif
diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.c b/src/gallium/state_trackers/dri/common/dri_st_api.c
new file mode 100644
index 00000000000..7ba7ec383d8
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_st_api.c
@@ -0,0 +1,263 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "state_tracker/st_manager.h" /* for st_manager_create_api */
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#ifndef __NOT_HAVE_DRM_H
+#include "dri1.h"
+#include "dri2.h"
+#else
+#include "drisw.h"
+#endif
+
+static boolean
+dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ unsigned statt_mask, new_mask;
+ boolean new_stamp;
+ int i;
+
+ statt_mask = 0x0;
+ for (i = 0; i < count; i++)
+ statt_mask |= (1 << statts[i]);
+
+ /* record newly allocated textures */
+ new_mask = (statt_mask & ~drawable->texture_mask);
+
+ /*
+ * dPriv->pStamp is the server stamp. It should be accessed with a lock, at
+ * least for DRI1. dPriv->lastStamp is the client stamp. It has the value
+ * of the server stamp when last checked.
+ */
+ new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp);
+
+ if (new_stamp || new_mask) {
+
+#ifndef __NOT_HAVE_DRM_H
+ if (__dri1_api_hooks) {
+ dri1_allocate_textures(drawable, statt_mask);
+ }
+ else {
+ dri2_allocate_textures(drawable, statts, count);
+ }
+#else
+ if (new_stamp)
+ drisw_update_drawable_info(drawable);
+
+ drisw_allocate_textures(drawable, statt_mask);
+#endif
+
+ /* add existing textures */
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ if (drawable->textures[i])
+ statt_mask |= (1 << i);
+ }
+
+ drawable->texture_stamp = drawable->dPriv->lastStamp;
+ drawable->texture_mask = statt_mask;
+ }
+
+ if (!out)
+ return TRUE;
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_texture_reference(&out[i], drawable->textures[statts[i]]);
+ }
+
+ return TRUE;
+}
+
+static boolean
+dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+
+#ifndef __NOT_HAVE_DRM_H
+ if (__dri1_api_hooks) {
+ dri1_flush_frontbuffer(drawable, statt);
+ }
+ else {
+ dri2_flush_frontbuffer(drawable, statt);
+ }
+#else
+ drisw_flush_frontbuffer(drawable, statt);
+#endif
+
+ return TRUE;
+}
+
+/**
+ * Create a framebuffer from the given drawable.
+ */
+struct st_framebuffer_iface *
+dri_create_st_framebuffer(struct dri_drawable *drawable)
+{
+ struct st_framebuffer_iface *stfbi;
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ if (stfbi) {
+ stfbi->visual = &drawable->stvis;
+ stfbi->flush_front = dri_st_framebuffer_flush_front;
+ stfbi->validate = dri_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) drawable;
+ }
+
+ return stfbi;
+}
+
+/**
+ * Destroy a framebuffer.
+ */
+void
+dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ int i;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+
+ FREE(stfbi);
+}
+
+/**
+ * Validate the texture at an attachment. Allocate the texture if it does not
+ * exist.
+ */
+void
+dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
+ unsigned i, count = 0;
+
+ /* check if buffer already exists */
+ if (drawable->texture_mask & (1 << statt))
+ return;
+
+ /* make sure DRI2 does not destroy existing buffers */
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ if (drawable->texture_mask & (1 << i)) {
+ statts[count++] = i;
+ }
+ }
+ statts[count++] = statt;
+
+ drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
+
+ stfbi->validate(stfbi, statts, count, NULL);
+}
+
+/**
+ * Reference counted st_api.
+ */
+static struct {
+ int32_t refcnt;
+ struct st_api *stapi;
+} dri_st_api;
+
+/**
+ * Add a reference to the st_api of the state tracker.
+ */
+static void
+_dri_get_st_api(void)
+{
+ p_atomic_inc(&dri_st_api.refcnt);
+ if (p_atomic_read(&dri_st_api.refcnt) == 1)
+ dri_st_api.stapi = st_manager_create_api();
+}
+
+/**
+ * Remove a reference to the st_api of the state tracker.
+ */
+static void
+_dri_put_st_api(void)
+{
+ struct st_api *stapi = dri_st_api.stapi;
+
+ if (p_atomic_dec_zero(&dri_st_api.refcnt)) {
+ stapi->destroy(dri_st_api.stapi);
+ dri_st_api.stapi = NULL;
+ }
+}
+
+/**
+ * Create a state tracker manager from the given screen.
+ */
+struct st_manager *
+dri_create_st_manager(struct dri_screen *screen)
+{
+ struct st_manager *smapi;
+
+ smapi = CALLOC_STRUCT(st_manager);
+ if (smapi) {
+ smapi->screen = screen->pipe_screen;
+ _dri_get_st_api();
+ }
+
+ return smapi;
+}
+
+/**
+ * Destroy a state tracker manager.
+ */
+void
+dri_destroy_st_manager(struct st_manager *smapi)
+{
+ _dri_put_st_api();
+ FREE(smapi);
+}
+
+/**
+ * Return the st_api of OpenGL state tracker.
+ */
+struct st_api *
+dri_get_st_api(void)
+{
+ assert(dri_st_api.stapi);
+ return dri_st_api.stapi;
+}
diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.h b/src/gallium/state_trackers/dri/common/dri_st_api.h
new file mode 100644
index 00000000000..99a217bfa79
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_st_api.h
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef _DRI_ST_API_H_
+#define _DRI_ST_API_H_
+
+#include "state_tracker/st_api.h"
+
+struct dri_screen;
+struct dri_drawable;
+
+struct st_api *
+dri_get_st_api(void);
+
+struct st_manager *
+dri_create_st_manager(struct dri_screen *screen);
+
+void
+dri_destroy_st_manager(struct st_manager *smapi);
+
+struct st_framebuffer_iface *
+dri_create_st_framebuffer(struct dri_drawable *drawable);
+
+void
+dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt);
+
+#endif /* _DRI_ST_API_H_ */
diff --git a/src/gallium/state_trackers/dri/common/dri_wrapper.h b/src/gallium/state_trackers/dri/common/dri_wrapper.h
new file mode 100644
index 00000000000..141ba02706a
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_wrapper.h
@@ -0,0 +1,10 @@
+#ifndef DRI_WRAPPER_H
+#define DRI_WRAPPER_H
+
+#ifndef __NOT_HAVE_DRM_H
+#include "dri_util.h"
+#else
+#include "drisw_util.h"
+#endif
+
+#endif
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
deleted file mode 100644
index 458473853cf..00000000000
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ /dev/null
@@ -1,765 +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.
- *
- **************************************************************************/
-/*
- * Author: Keith Whitwell <[email protected]>
- * Author: Jakob Bornecrantz <[email protected]>
- */
-
-#include "dri_screen.h"
-#include "dri_context.h"
-#include "dri_drawable.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "main/mtypes.h"
-#include "main/renderbuffer.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-
-#include "util/u_format.h"
-#include "util/u_memory.h"
-#include "util/u_rect.h"
-#include "util/u_inlines.h"
-
-static struct pipe_surface *
-dri_surface_from_handle(struct drm_api *api,
- struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width, unsigned height, unsigned pitch)
-{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
- struct winsys_handle whandle;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth0 = 1;
- templat.format = format;
- templat.width0 = width;
- templat.height0 = height;
-
- memset(&whandle, 0, sizeof(whandle));
- whandle.handle = handle;
- whandle.stride = pitch;
-
- texture = screen->texture_from_handle(screen, &templat, &whandle);
-
- if (!texture) {
- debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
- return NULL;
- }
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
-}
-
-/**
- * Pixmaps have will have the same name of fake front and front.
- */
-static boolean
-dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
-{
- boolean found = FALSE;
- boolean is_pixmap = FALSE;
- unsigned name;
- int i;
-
- for (i = 0; i < count; i++) {
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- if (found) {
- is_pixmap = buffers[i].name == name;
- } else {
- name = buffers[i].name;
- found = TRUE;
- }
- default:
- continue;
- }
- }
-
- return is_pixmap;
-}
-
-/**
- * This will be called a drawable is known to have been resized.
- */
-void
-dri_get_buffers(__DRIdrawable * dPriv)
-{
-
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *surface = NULL;
- struct dri_screen *st_screen = dri_screen(drawable->sPriv);
- struct pipe_screen *screen = st_screen->pipe_screen;
- __DRIbuffer *buffers = NULL;
- __DRIscreen *dri_screen = drawable->sPriv;
- __DRIdrawable *dri_drawable = drawable->dPriv;
- struct drm_api *api = st_screen->api;
- boolean have_depth = FALSE;
- int i, count;
-
- if ((dri_screen->dri2.loader
- && (dri_screen->dri2.loader->base.version > 2)
- && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) {
- buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
- (dri_drawable, &dri_drawable->w, &dri_drawable->h,
- drawable->attachments, drawable->num_attachments,
- &count, dri_drawable->loaderPrivate);
- } else {
- assert(dri_screen->dri2.loader);
- buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
- &dri_drawable->w,
- &dri_drawable->h,
- drawable->attachments,
- drawable->
- num_attachments, &count,
- dri_drawable->
- loaderPrivate);
- }
-
- if (buffers == NULL) {
- return;
- }
-
- /* set one cliprect to cover the whole dri_drawable */
- dri_drawable->x = 0;
- dri_drawable->y = 0;
- dri_drawable->backX = 0;
- dri_drawable->backY = 0;
- dri_drawable->numClipRects = 1;
- dri_drawable->pClipRects[0].x1 = 0;
- dri_drawable->pClipRects[0].y1 = 0;
- dri_drawable->pClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pClipRects[0].y2 = dri_drawable->h;
- dri_drawable->numBackClipRects = 1;
- dri_drawable->pBackClipRects[0].x1 = 0;
- dri_drawable->pBackClipRects[0].y1 = 0;
- dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
-
- if (drawable->old_num == count &&
- drawable->old_w == dri_drawable->w &&
- drawable->old_h == dri_drawable->h &&
- memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) {
- return;
- } else {
- drawable->old_num = count;
- drawable->old_w = dri_drawable->w;
- drawable->old_h = dri_drawable->h;
- memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
- }
-
- drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
-
- for (i = 0; i < count; i++) {
- enum pipe_format format = 0;
- int index = 0;
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- if (!st_screen->auto_fake_front)
- continue;
- /* fallthrough */
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- index = ST_SURFACE_FRONT_LEFT;
- format = drawable->color_format;
- break;
- case __DRI_BUFFER_BACK_LEFT:
- index = ST_SURFACE_BACK_LEFT;
- format = drawable->color_format;
- break;
- case __DRI_BUFFER_DEPTH:
- case __DRI_BUFFER_DEPTH_STENCIL:
- case __DRI_BUFFER_STENCIL:
- index = ST_SURFACE_DEPTH;
- format = drawable->depth_stencil_format;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
-
- if (index == ST_SURFACE_DEPTH) {
- if (have_depth)
- continue;
- else
- have_depth = TRUE;
- }
-
- surface = dri_surface_from_handle(api,
- screen,
- buffers[i].name,
- format,
- dri_drawable->w,
- dri_drawable->h, buffers[i].pitch);
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- case __DRI_BUFFER_BACK_LEFT:
- drawable->color_format = surface->format;
- break;
- case __DRI_BUFFER_DEPTH:
- case __DRI_BUFFER_DEPTH_STENCIL:
- case __DRI_BUFFER_STENCIL:
- drawable->depth_stencil_format = surface->format;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
-
- st_set_framebuffer_surface(drawable->stfb, index, surface);
- pipe_surface_reference(&surface, NULL);
- }
- /* this needed, or else the state tracker fails to pick the new buffers */
- st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
-}
-
-/**
- * These are used for GLX_EXT_texture_from_pixmap
- */
-void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint format, __DRIdrawable *dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *ps;
-
- if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
- struct gl_renderbuffer *rb =
- st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE);
- _mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb);
- }
-
- dri_get_buffers(drawable->dPriv);
- st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
-
- if (!ps)
- return;
-
- st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
- ST_TEXTURE_RECT, 0, drawable->color_format);
-}
-
-void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv)
-{
- dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
-}
-
-void
-dri_update_buffer(struct pipe_screen *screen, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
-
- if (ctx->d_stamp == *ctx->dPriv->pStamp &&
- ctx->r_stamp == *ctx->rPriv->pStamp)
- return;
-
- ctx->d_stamp = *ctx->dPriv->pStamp;
- ctx->r_stamp = *ctx->rPriv->pStamp;
-
- /* Ask the X server for new renderbuffers. */
- dri_get_buffers(ctx->dPriv);
- if (ctx->dPriv != ctx->rPriv)
- dri_get_buffers(ctx->rPriv);
-
-}
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
- __DRIdrawable *dri_drawable = ctx->dPriv;
- __DRIscreen *dri_screen = ctx->sPriv;
-
- /* XXX Does this function get called with DRI1? */
-
- if (ctx->dPriv == NULL) {
- debug_printf("%s: no drawable bound to context\n", __func__);
- return;
- }
-
-#if 0
- /* TODO if rendering to pixmaps is slow enable this code. */
- if (drawable->is_pixmap)
- return;
-#else
- (void)drawable;
-#endif
-
- (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
- dri_drawable->loaderPrivate);
-}
-
-/**
- * This is called when we need to set up GL rendering to a new X window.
- */
-boolean
-dri_create_buffer(__DRIscreen * sPriv,
- __DRIdrawable * dPriv,
- const __GLcontextModes * visual, boolean isPixmap)
-{
- struct dri_screen *screen = sPriv->private;
- struct dri_drawable *drawable = NULL;
- int i;
-
- if (isPixmap)
- goto fail; /* not implemented */
-
- drawable = CALLOC_STRUCT(dri_drawable);
- if (drawable == NULL)
- goto fail;
-
- if (visual->redBits == 8) {
- if (visual->alphaBits == 8)
- drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
- else
- drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
- } else {
- drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM;
- }
-
- switch(visual->depthBits) {
- default:
- case 0:
- drawable->depth_stencil_format = PIPE_FORMAT_NONE;
- break;
- case 16:
- drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
- break;
- case 24:
- if (visual->stencilBits == 0) {
- drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
- PIPE_FORMAT_Z24X8_UNORM:
- PIPE_FORMAT_X8Z24_UNORM;
- } else {
- drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
- PIPE_FORMAT_Z24S8_UNORM:
- PIPE_FORMAT_S8Z24_UNORM;
- }
- break;
- case 32:
- drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
- break;
- }
-
- drawable->stfb = st_create_framebuffer(visual,
- drawable->color_format,
- drawable->depth_stencil_format,
- drawable->depth_stencil_format,
- dPriv->w,
- dPriv->h, (void *)drawable);
- if (drawable->stfb == NULL)
- goto fail;
-
- drawable->sPriv = sPriv;
- drawable->dPriv = dPriv;
- dPriv->driverPrivate = (void *)drawable;
-
- /* setup dri2 buffers information */
- /* TODO incase of double buffer visual, delay fake creation */
- i = 0;
- if (sPriv->dri2.loader
- && (sPriv->dri2.loader->base.version > 2)
- && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- if (!screen->auto_fake_front) {
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- }
- if (visual->doubleBufferMode) {
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- }
- if (visual->depthBits && visual->stencilBits) {
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
- } else if (visual->depthBits) {
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- drawable->attachments[i++] = visual->depthBits;
- } else if (visual->stencilBits) {
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->attachments[i++] = visual->stencilBits;
- }
- drawable->num_attachments = i / 2;
- } else {
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- if (!screen->auto_fake_front)
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
- if (visual->doubleBufferMode)
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (visual->depthBits && visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- else if (visual->depthBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- else if (visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->num_attachments = i;
- }
-
- drawable->desired_fences = 2;
-
- return GL_TRUE;
-fail:
- FREE(drawable);
- return GL_FALSE;
-}
-
-static struct pipe_fence_handle *
-dri_swap_fences_pop_front(struct dri_drawable *draw)
-{
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
- struct pipe_fence_handle *fence = NULL;
-
- if (draw->cur_fences >= draw->desired_fences) {
- screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
- screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
- --draw->cur_fences;
- draw->tail &= DRI_SWAP_FENCES_MASK;
- }
- return fence;
-}
-
-static void
-dri_swap_fences_push_back(struct dri_drawable *draw,
- struct pipe_fence_handle *fence)
-{
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
-
- if (!fence)
- return;
-
- if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
- draw->cur_fences++;
- screen->fence_reference(screen, &draw->swap_fences[draw->head++],
- fence);
- draw->head &= DRI_SWAP_FENCES_MASK;
- }
-}
-
-void
-dri_destroy_buffer(__DRIdrawable * dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_fence_handle *fence;
- struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
-
- st_unreference_framebuffer(drawable->stfb);
- drawable->desired_fences = 0;
- while (drawable->cur_fences) {
- fence = dri_swap_fences_pop_front(drawable);
- screen->fence_reference(screen, &fence, NULL);
- }
-
- FREE(drawable);
-}
-
-static void
-dri1_update_drawables_locked(struct dri_context *ctx,
- __DRIdrawable * driDrawPriv,
- __DRIdrawable * driReadPriv)
-{
- if (ctx->stLostLock) {
- ctx->stLostLock = FALSE;
- if (driDrawPriv == driReadPriv)
- DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
- else
- DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
- driReadPriv);
- }
-}
-
-/**
- * This ensures all contexts which bind to a drawable pick up the
- * drawable change and signal new buffer state.
- * Calling st_resize_framebuffer for each context may seem like overkill,
- * but no new buffers will actually be allocated if the dimensions don't
- * change.
- */
-
-static void
-dri1_propagate_drawable_change(struct dri_context *ctx)
-{
- __DRIdrawable *dPriv = ctx->dPriv;
- __DRIdrawable *rPriv = ctx->rPriv;
- boolean flushed = FALSE;
-
- if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
-
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- flushed = TRUE;
- ctx->d_stamp = dPriv->lastStamp;
- st_resize_framebuffer(dri_drawable(dPriv)->stfb, dPriv->w, dPriv->h);
-
- }
-
- if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) {
-
- if (!flushed)
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- ctx->r_stamp = rPriv->lastStamp;
- st_resize_framebuffer(dri_drawable(rPriv)->stfb, rPriv->w, rPriv->h);
-
- } else if (rPriv && dPriv == rPriv) {
-
- ctx->r_stamp = ctx->d_stamp;
-
- }
-}
-
-void
-dri1_update_drawables(struct dri_context *ctx,
- struct dri_drawable *draw, struct dri_drawable *read)
-{
- dri_lock(ctx);
- dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv);
- dri_unlock(ctx);
-
- dri1_propagate_drawable_change(ctx);
-}
-
-static INLINE boolean
-dri1_intersect_src_bbox(struct drm_clip_rect *dst,
- int dst_x,
- int dst_y,
- const struct drm_clip_rect *src,
- const struct drm_clip_rect *bbox)
-{
- int xy1;
- int xy2;
-
- xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
- (int)bbox->x1 + dst_x;
- xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
- (int)bbox->x2 + dst_x;
- if (xy1 >= xy2 || xy1 < 0)
- return FALSE;
-
- dst->x1 = xy1;
- dst->x2 = xy2;
-
- xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
- (int)bbox->y1 + dst_y;
- xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
- (int)bbox->y2 + dst_y;
- if (xy1 >= xy2 || xy1 < 0)
- return FALSE;
-
- dst->y1 = xy1;
- dst->y2 = xy2;
- return TRUE;
-}
-
-static void
-dri1_swap_copy(struct dri_context *ctx,
- struct pipe_surface *dst,
- struct pipe_surface *src,
- __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct drm_clip_rect clip;
- struct drm_clip_rect *cur;
- int i;
-
- cur = dPriv->pClipRects;
-
- for (i = 0; i < dPriv->numClipRects; ++i) {
- if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
- if (pipe->surface_copy) {
- pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
- src,
- (int)clip.x1 - dPriv->x,
- (int)clip.y1 - dPriv->y,
- clip.x2 - clip.x1, clip.y2 - clip.y1);
- } else {
- util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
- src,
- (int)clip.x1 - dPriv->x,
- (int)clip.y1 - dPriv->y,
- clip.x2 - clip.x1, clip.y2 - clip.y1);
- }
- }
- }
-}
-
-static void
-dri1_copy_to_front(struct dri_context *ctx,
- struct pipe_surface *surf,
- __DRIdrawable * dPriv,
- const struct drm_clip_rect *sub_box,
- struct pipe_fence_handle **fence)
-{
- struct pipe_context *pipe = ctx->pipe;
- boolean save_lost_lock;
- uint cur_w;
- uint cur_h;
- struct drm_clip_rect bbox;
- boolean visible = TRUE;
-
- *fence = NULL;
-
- dri_lock(ctx);
- save_lost_lock = ctx->stLostLock;
- dri1_update_drawables_locked(ctx, dPriv, dPriv);
- st_get_framebuffer_dimensions(dri_drawable(dPriv)->stfb, &cur_w, &cur_h);
-
- bbox.x1 = 0;
- bbox.x2 = cur_w;
- bbox.y1 = 0;
- bbox.y2 = cur_h;
-
- if (sub_box)
- visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
-
- if (visible && __dri1_api_hooks->present_locked) {
-
- __dri1_api_hooks->present_locked(pipe,
- surf,
- dPriv->pClipRects,
- dPriv->numClipRects,
- dPriv->x, dPriv->y, &bbox, fence);
-
- } else if (visible && __dri1_api_hooks->front_srf_locked) {
-
- struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
-
- if (front)
- dri1_swap_copy(ctx, front, surf, dPriv, &bbox);
-
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
- }
-
- ctx->stLostLock = save_lost_lock;
-
- /**
- * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
- */
-
- if (!sub_box)
- dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
-
- dri_unlock(ctx);
- dri1_propagate_drawable_change(ctx);
-}
-
-void
-dri1_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- struct pipe_fence_handle *dummy_fence;
-
- dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence);
- screen->fence_reference(screen, &dummy_fence, NULL);
-
- /**
- * FIXME: Do we need swap throttling here?
- */
-}
-
-void
-dri_swap_buffers(__DRIdrawable * dPriv)
-{
- struct dri_context *ctx;
- struct pipe_surface *back_surf;
- struct dri_drawable *draw = dri_drawable(dPriv);
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
- struct pipe_fence_handle *fence;
- struct st_context *st = st_get_current();
-
- assert(__dri1_api_hooks != NULL);
-
- if (!st)
- return; /* For now */
-
- ctx = (struct dri_context *)st->pipe->priv;
-
- st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
- if (back_surf) {
- st_notify_swapbuffers(draw->stfb);
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- fence = dri_swap_fences_pop_front(draw);
- if (fence) {
- (void)screen->fence_finish(screen, fence, 0);
- screen->fence_reference(screen, &fence, NULL);
- }
- dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence);
- dri_swap_fences_push_back(draw, fence);
- screen->fence_reference(screen, &fence, NULL);
- }
-}
-
-void
-dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
-{
- struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
- struct drm_clip_rect sub_bbox;
- struct dri_context *ctx;
- struct pipe_surface *back_surf;
- struct dri_drawable *draw = dri_drawable(dPriv);
- struct pipe_fence_handle *dummy_fence;
- struct st_context *st = st_get_current();
-
- assert(__dri1_api_hooks != NULL);
-
- if (!st)
- return;
-
- ctx = (struct dri_context *)st->pipe->priv;
-
- sub_bbox.x1 = x;
- sub_bbox.x2 = x + w;
- sub_bbox.y1 = y;
- sub_bbox.y2 = y + h;
-
- st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
- if (back_surf) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- dri1_copy_to_front(ctx, back_surf, dPriv, &sub_bbox, &dummy_fence);
- screen->fence_reference(screen, &dummy_fence, NULL);
- }
-}
-
-/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/drm/Makefile b/src/gallium/state_trackers/dri/drm/Makefile
new file mode 100644
index 00000000000..7a236da0c0f
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/Makefile
@@ -0,0 +1,32 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = dridrm
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/gallium/state_trackers/dri/common \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/mesa/main \
+ $(shell pkg-config --cflags-only-I libdrm)
+
+
+C_SOURCES = \
+ dri_context.c \
+ dri_screen.c \
+ dri_drawable.c \
+ dri_st_api.c \
+ dri1_helper.c \
+ dri1.c \
+ dri2.c
+
+# $(TOP)/src/mesa/drivers/dri/common/utils.c \
+ $(TOP)/src/mesa/drivers/dri/common/vblank.c \
+ $(TOP)/src/mesa/drivers/dri/common/dri_util.c \
+ $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \
+ $(TOP)/src/mesa/drivers/common/driverfuncs.c \
+ $(TOP)/src/mesa/drivers/dri/common/texmem.c \
+ $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript
new file mode 100644
index 00000000000..b9726ee3113
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/SConscript
@@ -0,0 +1,27 @@
+#######################################################################
+# SConscript for dri state_tracker
+
+Import('*')
+
+if env['dri']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/gallium/state_trackers/dri/common',
+ '#/src/mesa/drivers/dri/common',
+ ])
+
+ st_dri = env.ConvenienceLibrary(
+ target = 'st_dri',
+ source = [ 'dri_context.c',
+ 'dri_drawable.c',
+ 'dri_screen.c',
+ 'dri_st_api.c',
+ 'dri1_helper.c',
+ 'dri1.c',
+ 'dri2.c',
+ ]
+ )
+ Export('st_dri')
diff --git a/src/gallium/state_trackers/dri/drm/dri1.c b/src/gallium/state_trackers/dri/drm/dri1.c
new file mode 100644
index 00000000000..cca7cd8f0c3
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri1.c
@@ -0,0 +1,522 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+/* XXX DRI1 is untested after the switch to st_api.h */
+
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+#include "state_tracker/dri1_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#include "dri1.h"
+
+static INLINE void
+dri1_lock(struct dri_context *ctx)
+{
+ drm_context_t hw_context = ctx->cPriv->hHWContext;
+ char ret = 0;
+
+ DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
+ if (ret) {
+ drmGetLock(ctx->sPriv->fd, hw_context, 0);
+ ctx->stLostLock = TRUE;
+ ctx->wsLostLock = TRUE;
+ }
+ ctx->isLocked = TRUE;
+}
+
+static INLINE void
+dri1_unlock(struct dri_context *ctx)
+{
+ ctx->isLocked = FALSE;
+ DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
+}
+
+static void
+dri1_update_drawables_locked(struct dri_context *ctx,
+ __DRIdrawable * driDrawPriv,
+ __DRIdrawable * driReadPriv)
+{
+ if (ctx->stLostLock) {
+ ctx->stLostLock = FALSE;
+ if (driDrawPriv == driReadPriv)
+ DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
+ else
+ DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
+ driReadPriv);
+ }
+}
+
+/**
+ * This ensures all contexts which bind to a drawable pick up the
+ * drawable change and signal new buffer state.
+ */
+static void
+dri1_propagate_drawable_change(struct dri_context *ctx)
+{
+ __DRIdrawable *dPriv = ctx->dPriv;
+ __DRIdrawable *rPriv = ctx->rPriv;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct dri_drawable *read = dri_drawable(rPriv);
+ boolean flushed = FALSE;
+
+ if (dPriv && draw->texture_stamp != dPriv->lastStamp) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ flushed = TRUE;
+ ctx->st->notify_invalid_framebuffer(ctx->st, draw->stfb);
+ }
+
+ if (rPriv && dPriv != rPriv && read->texture_stamp != rPriv->lastStamp) {
+ if (!flushed)
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->notify_invalid_framebuffer(ctx->st, read->stfb);
+ }
+}
+
+static INLINE boolean
+dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+ int dst_x,
+ int dst_y,
+ const struct drm_clip_rect *src,
+ const struct drm_clip_rect *bbox)
+{
+ int xy1;
+ int xy2;
+
+ xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+ (int)bbox->x1 + dst_x;
+ xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+ (int)bbox->x2 + dst_x;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->x1 = xy1;
+ dst->x2 = xy2;
+
+ xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+ (int)bbox->y1 + dst_y;
+ xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+ (int)bbox->y2 + dst_y;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->y1 = xy1;
+ dst->y2 = xy2;
+ return TRUE;
+}
+
+static void
+dri1_swap_copy(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ struct pipe_surface *src,
+ __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
+{
+ struct drm_clip_rect clip;
+ struct drm_clip_rect *cur;
+ int i;
+
+ cur = dPriv->pClipRects;
+
+ for (i = 0; i < dPriv->numClipRects; ++i) {
+ if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
+ if (pipe->surface_copy) {
+ pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ } else {
+ util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ }
+ }
+ }
+}
+
+static void
+dri1_present_texture_locked(__DRIdrawable * dPriv,
+ struct pipe_texture *ptex,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_context *pipe;
+ struct pipe_surface *psurf;
+ struct drm_clip_rect bbox;
+ boolean visible = TRUE;
+
+ *fence = NULL;
+
+ bbox.x1 = 0;
+ bbox.x2 = ptex->width0;
+ bbox.y1 = 0;
+ bbox.y2 = ptex->height0;
+
+ if (sub_box)
+ visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
+ if (!visible)
+ return;
+
+ pipe = dri1_get_pipe_context(screen);
+ psurf = dri1_get_pipe_surface(drawable, ptex);
+ if (!pipe || !psurf)
+ return;
+
+ if (__dri1_api_hooks->present_locked) {
+ __dri1_api_hooks->present_locked(pipe, psurf,
+ dPriv->pClipRects, dPriv->numClipRects,
+ dPriv->x, dPriv->y, &bbox, fence);
+ } else if (__dri1_api_hooks->front_srf_locked) {
+ struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
+
+ if (front)
+ dri1_swap_copy(pipe, front, psurf, dPriv, &bbox);
+
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, fence);
+ }
+}
+
+static void
+dri1_copy_to_front(struct dri_context *ctx,
+ struct pipe_texture *ptex,
+ __DRIdrawable * dPriv,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ boolean save_lost_lock;
+
+ dri1_lock(ctx);
+ save_lost_lock = ctx->stLostLock;
+ dri1_update_drawables_locked(ctx, dPriv, dPriv);
+
+ dri1_present_texture_locked(dPriv, ptex, sub_box, fence);
+
+ ctx->stLostLock = save_lost_lock;
+
+ /**
+ * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
+ */
+
+ if (!sub_box)
+ dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
+
+ dri1_unlock(ctx);
+ dri1_propagate_drawable_change(ctx);
+}
+
+/*
+ * Backend functions for st_framebuffer interface and swap_buffers.
+ */
+
+void
+dri1_flush_frontbuffer(struct dri_drawable *draw,
+ enum st_attachment_type statt)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_screen *screen = dri_screen(draw->sPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct pipe_fence_handle *dummy_fence;
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return; /* For now */
+
+ ptex = draw->textures[statt];
+ if (ptex) {
+ dri1_copy_to_front(ctx, ptex, ctx->dPriv, NULL, &dummy_fence);
+ pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
+ }
+
+ /**
+ * FIXME: Do we need swap throttling here?
+ */
+}
+
+void
+dri1_swap_buffers(__DRIdrawable * dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(draw->sPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct pipe_fence_handle *fence;
+ struct pipe_texture *ptex;
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!ctx)
+ return; /* For now */
+
+ ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ fence = dri1_swap_fences_pop_front(draw);
+ if (fence) {
+ (void)pipe_screen->fence_finish(pipe_screen, fence, 0);
+ pipe_screen->fence_reference(pipe_screen, &fence, NULL);
+ }
+ dri1_copy_to_front(ctx, ptex, dPriv, NULL, &fence);
+ dri1_swap_fences_push_back(draw, fence);
+ pipe_screen->fence_reference(pipe_screen, &fence, NULL);
+ }
+}
+
+void
+dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_screen *screen = dri_screen(dPriv->driScreenPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct drm_clip_rect sub_bbox;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct pipe_fence_handle *dummy_fence;
+ struct pipe_texture *ptex;
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!ctx)
+ return;
+
+ sub_bbox.x1 = x;
+ sub_bbox.x2 = x + w;
+ sub_bbox.y1 = y;
+ sub_bbox.y2 = y + h;
+
+ ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ dri1_copy_to_front(ctx, ptex, dPriv, &sub_bbox, &dummy_fence);
+ pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
+ }
+}
+
+/**
+ * Allocate framebuffer attachments.
+ *
+ * During fixed-size operation, the function keeps allocating new attachments
+ * as they are requested. Unused attachments are not removed, not until the
+ * framebuffer is resized or destroyed.
+ */
+void
+dri1_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_texture templ;
+ unsigned width, height;
+ boolean resized;
+ int i;
+
+ width = drawable->dPriv->w;
+ height = drawable->dPriv->h;
+
+ resized = (drawable->old_w != width ||
+ drawable->old_h != height);
+
+ /* remove outdated textures */
+ if (resized) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (drawable->textures[i] || !(mask & (1 << i))) {
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ drawable->textures[i] =
+ screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
+ }
+ }
+
+ drawable->old_w = width;
+ drawable->old_h = height;
+}
+
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *dri1_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+};
+
+static void
+st_dri_lock(struct pipe_context *pipe)
+{
+ dri1_lock((struct dri_context *)pipe->priv);
+}
+
+static void
+st_dri_unlock(struct pipe_context *pipe)
+{
+ dri1_unlock((struct dri_context *)pipe->priv);
+}
+
+static boolean
+st_dri_is_locked(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->isLocked;
+}
+
+static boolean
+st_dri_lost_lock(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->wsLostLock;
+}
+
+static void
+st_dri_clear_lost_lock(struct pipe_context *pipe)
+{
+ ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
+}
+
+static struct dri1_api_lock_funcs dri1_lf = {
+ .lock = st_dri_lock,
+ .unlock = st_dri_unlock,
+ .is_locked = st_dri_is_locked,
+ .is_lock_lost = st_dri_lost_lock,
+ .clear_lost_lock = st_dri_clear_lost_lock
+};
+
+static INLINE void
+dri1_copy_version(struct dri1_api_version *dst,
+ const struct __DRIversionRec *src)
+{
+ dst->major = src->major;
+ dst->minor = src->minor;
+ dst->patch_level = src->patch;
+}
+
+struct dri1_api *__dri1_api_hooks = NULL;
+
+const __DRIconfig **
+dri1_init_screen(__DRIscreen * sPriv)
+{
+ const __DRIconfig **configs;
+ struct dri_screen *screen;
+ struct dri1_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+ screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri1_screen_extensions;
+
+ arg.base.mode = DRM_CREATE_DRI1;
+ arg.lf = &dri1_lf;
+ arg.ddx_info = sPriv->pDevPriv;
+ arg.ddx_info_size = sPriv->devPrivSize;
+ arg.sarea = sPriv->pSAREA;
+ dri1_copy_version(&arg.ddx_version, &sPriv->ddx_version);
+ dri1_copy_version(&arg.dri_version, &sPriv->dri_version);
+ dri1_copy_version(&arg.drm_version, &sPriv->drm_version);
+ arg.api = NULL;
+
+ /**
+ * FIXME: If the driver supports format conversion swapbuffer blits, we might
+ * want to support other color bit depths than the server is currently
+ * using.
+ */
+
+ configs = dri_init_screen_helper(screen, &arg.base, sPriv->fbBPP);
+ if (!configs)
+ goto fail;
+
+ if (!arg.api) {
+ debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
+ goto fail;
+ }
+
+ __dri1_api_hooks = arg.api;
+
+ return configs;
+fail:
+ if (configs)
+ FREE(configs);
+ dri_destroy_screen_helper(screen);
+ FREE(screen);
+ return NULL;
+}
diff --git a/src/gallium/state_trackers/dri/drm/dri1.h b/src/gallium/state_trackers/dri/drm/dri1.h
new file mode 100644
index 00000000000..f7441f98abc
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri1.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#ifndef DRI1_H
+#define DRI1_H
+
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "state_tracker/st_api.h"
+#include "dri_wrapper.h"
+
+extern struct dri1_api *__dri1_api_hooks;
+
+const __DRIconfig **
+dri1_init_screen(__DRIscreen * sPriv);
+
+void
+dri1_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+dri1_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask);
+
+void dri1_swap_buffers(__DRIdrawable * dPriv);
+
+void
+dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
+
+#endif /* DRI1_H */
diff --git a/src/gallium/state_trackers/dri/drm/dri1_helper.c b/src/gallium/state_trackers/dri/drm/dri1_helper.c
new file mode 120000
index 00000000000..c45ebf5c102
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri1_helper.c
@@ -0,0 +1 @@
+../common/dri1_helper.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
new file mode 100644
index 00000000000..c632f0fe4f3
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -0,0 +1,416 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ * Jakob Bornecrantz <[email protected]>
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "state_tracker/drm_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri2.h"
+
+/**
+ * DRI2 flush extension.
+ */
+static void
+dri2_flush_drawable(__DRIdrawable *draw)
+{
+}
+
+static void
+dri2_invalidate_drawable(__DRIdrawable *dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_context *ctx = dri_context(dPriv->driContextPriv);
+
+ dri2InvalidateDrawable(dPriv);
+ drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
+
+ if (ctx)
+ ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
+}
+
+static const __DRI2flushExtension dri2FlushExtension = {
+ { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+ dri2_flush_drawable,
+ dri2_invalidate_drawable,
+};
+
+/**
+ * These are used for GLX_EXT_texture_from_pixmap
+ */
+static void
+dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint format, __DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_context(pDRICtx);
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_texture *pt;
+
+ dri_st_framebuffer_validate_att(drawable->stfb, ST_ATTACHMENT_FRONT_LEFT);
+
+ pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
+
+ if (pt) {
+ ctx->st->teximage(ctx->st,
+ (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
+ 0, drawable->stvis.color_format, pt, FALSE);
+ }
+}
+
+static void
+dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension dri2TexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ dri2_set_tex_buffer,
+ dri2_set_tex_buffer2,
+};
+
+/**
+ * Get the format of an attachment.
+ */
+static INLINE enum pipe_format
+dri2_drawable_get_format(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ enum pipe_format format;
+
+ switch (statt) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return format;
+}
+
+/**
+ * Retrieve __DRIbuffer from the DRI loader.
+ */
+static __DRIbuffer *
+dri2_drawable_get_buffers(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned *count)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+ boolean with_format;
+ __DRIbuffer *buffers;
+ int num_buffers;
+ unsigned attachments[10];
+ unsigned num_attachments, i;
+
+ assert(loader);
+ with_format = dri_with_format(drawable->sPriv);
+
+ num_attachments = 0;
+
+ /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */
+ if (!with_format)
+ attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT;
+
+ for (i = 0; i < *count; i++) {
+ enum pipe_format format;
+ int att, bpp;
+
+ format = dri2_drawable_get_format(drawable, statts[i]);
+ if (format == PIPE_FORMAT_NONE)
+ continue;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ /* already added */
+ if (!with_format)
+ continue;
+ att = __DRI_BUFFER_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ att = __DRI_BUFFER_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ att = __DRI_BUFFER_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ att = __DRI_BUFFER_BACK_RIGHT;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ att = __DRI_BUFFER_DEPTH_STENCIL;
+ break;
+ default:
+ att = -1;
+ break;
+ }
+
+ bpp = util_format_get_blocksizebits(format);
+
+ if (att >= 0) {
+ attachments[num_attachments++] = att;
+ if (with_format) {
+ attachments[num_attachments++] = bpp;
+ }
+ }
+ }
+
+ if (with_format) {
+ num_attachments /= 2;
+ buffers = loader->getBuffersWithFormat(dri_drawable,
+ &dri_drawable->w, &dri_drawable->h,
+ attachments, num_attachments,
+ &num_buffers, dri_drawable->loaderPrivate);
+ }
+ else {
+ buffers = loader->getBuffers(dri_drawable,
+ &dri_drawable->w, &dri_drawable->h,
+ attachments, num_attachments,
+ &num_buffers, dri_drawable->loaderPrivate);
+ }
+
+ if (buffers) {
+ /* set one cliprect to cover the whole dri_drawable */
+ dri_drawable->x = 0;
+ dri_drawable->y = 0;
+ dri_drawable->backX = 0;
+ dri_drawable->backY = 0;
+ dri_drawable->numClipRects = 1;
+ dri_drawable->pClipRects[0].x1 = 0;
+ dri_drawable->pClipRects[0].y1 = 0;
+ dri_drawable->pClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pClipRects[0].y2 = dri_drawable->h;
+ dri_drawable->numBackClipRects = 1;
+ dri_drawable->pBackClipRects[0].x1 = 0;
+ dri_drawable->pBackClipRects[0].y1 = 0;
+ dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
+
+ *count = num_buffers;
+ }
+
+ return buffers;
+}
+
+/**
+ * Process __DRIbuffer and convert them into pipe_textures.
+ */
+static void
+dri2_drawable_process_buffers(struct dri_drawable *drawable,
+ __DRIbuffer *buffers, unsigned count)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct pipe_texture templ;
+ struct winsys_handle whandle;
+ boolean have_depth = FALSE;
+ unsigned i;
+
+ if (drawable->old_num == count &&
+ drawable->old_w == dri_drawable->w &&
+ drawable->old_h == dri_drawable->h &&
+ memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0)
+ return;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+
+ memset(&templ, 0, sizeof(templ));
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = dri_drawable->w;
+ templ.height0 = dri_drawable->h;
+ templ.depth0 = 1;
+
+ memset(&whandle, 0, sizeof(whandle));
+
+ for (i = 0; i < count; i++) {
+ __DRIbuffer *buf = &buffers[i];
+ enum st_attachment_type statt;
+ enum pipe_format format;
+
+ switch (buf->attachment) {
+ case __DRI_BUFFER_FRONT_LEFT:
+ if (!screen->auto_fake_front) {
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+ /* fallthrough */
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ break;
+ case __DRI_BUFFER_BACK_LEFT:
+ statt = ST_ATTACHMENT_BACK_LEFT;
+ break;
+ case __DRI_BUFFER_DEPTH:
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ case __DRI_BUFFER_STENCIL:
+ /* use only the first depth/stencil buffer */
+ if (!have_depth) {
+ have_depth = TRUE;
+ statt = ST_ATTACHMENT_DEPTH_STENCIL;
+ }
+ else {
+ statt = ST_ATTACHMENT_INVALID;
+ }
+ break;
+ default:
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+
+ format = dri2_drawable_get_format(drawable, statt);
+ if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE)
+ continue;
+
+ templ.format = format;
+ whandle.handle = buf->name;
+ whandle.stride = buf->pitch;
+
+ drawable->textures[statt] =
+ screen->pipe_screen->texture_from_handle(screen->pipe_screen,
+ &templ, &whandle);
+ }
+
+ drawable->old_num = count;
+ drawable->old_w = dri_drawable->w;
+ drawable->old_h = dri_drawable->h;
+ memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
+}
+
+/*
+ * Backend functions for st_framebuffer interface.
+ */
+
+void
+dri2_allocate_textures(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned count)
+{
+ __DRIbuffer *buffers;
+ unsigned num_buffers = count;
+
+ buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers);
+ dri2_drawable_process_buffers(drawable, buffers, num_buffers);
+}
+
+void
+dri2_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+
+ if (loader->flushFrontBuffer == NULL)
+ return;
+
+ if (statt == ST_ATTACHMENT_FRONT_LEFT) {
+ loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
+ }
+}
+
+/*
+ * Backend function init_screen.
+ */
+
+static const __DRIextension *dri_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ &dri2TexBufferExtension.base,
+ &dri2FlushExtension.base,
+ NULL
+};
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * Returns the __GLcontextModes supported by this driver.
+ */
+const __DRIconfig **
+dri2_init_screen(__DRIscreen * sPriv)
+{
+ const __DRIconfig **configs;
+ struct dri_screen *screen;
+ struct drm_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri_screen_extensions;
+
+ arg.mode = DRM_CREATE_NORMAL;
+
+ configs = dri_init_screen_helper(screen, &arg, 32);
+ if (!configs)
+ goto fail;
+
+ screen->auto_fake_front = dri_with_format(sPriv);
+
+ return configs;
+fail:
+ dri_destroy_screen_helper(screen);
+ FREE(screen);
+ return NULL;
+}
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driLegacyExtension.base,
+ &driDRI2Extension.base,
+ NULL
+};
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/drm/dri2.h
index 800677a2d1e..379963431fb 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.h
@@ -24,23 +24,23 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
-/*
- * Author: Keith Whitwell <[email protected]>
- * Author: Jakob Bornecrantz <[email protected]>
- */
-#include "dri_screen.h"
-#include "dri_context.h"
-#include "state_tracker/st_context.h"
+#ifndef DRI2_H
+#define DRI2_H
-#include "utils.h"
+#include "dri_drawable.h"
+#include "dri_wrapper.h"
+
+const __DRIconfig **
+dri2_init_screen(__DRIscreen * sPriv);
+
+void
+dri2_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
void
-dri_init_extensions(struct dri_context *ctx)
-{
- /* New extensions should be added in mesa/state_tracker/st_extensions.c
- * and not in this file. */
- driInitExtensions(ctx->st->ctx, NULL, GL_FALSE);
-}
+dri2_allocate_textures(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned count);
-/* vim: set sw=3 ts=8 sts=3 expandtab: */
+#endif /* DRI2_H */
diff --git a/src/gallium/state_trackers/dri/drm/dri_context.c b/src/gallium/state_trackers/dri/drm/dri_context.c
new file mode 120000
index 00000000000..5cfbbaeb068
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_context.c
@@ -0,0 +1 @@
+../common/dri_context.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri_drawable.c b/src/gallium/state_trackers/dri/drm/dri_drawable.c
new file mode 120000
index 00000000000..0fc19be6ea6
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_drawable.c
@@ -0,0 +1 @@
+../common/dri_drawable.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri_screen.c b/src/gallium/state_trackers/dri/drm/dri_screen.c
new file mode 120000
index 00000000000..847f6515f25
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_screen.c
@@ -0,0 +1 @@
+../common/dri_screen.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri_st_api.c b/src/gallium/state_trackers/dri/drm/dri_st_api.c
new file mode 120000
index 00000000000..a8f6bd06b09
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_st_api.c
@@ -0,0 +1 @@
+../common/dri_st_api.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/Makefile b/src/gallium/state_trackers/dri/sw/Makefile
new file mode 100644
index 00000000000..18d7aabd9f0
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/Makefile
@@ -0,0 +1,26 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = drisw
+
+LIBRARY_DEFINES = -D__NOT_HAVE_DRM_H
+
+LIBRARY_INCLUDES = \
+ -I../dri \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/gallium/state_trackers/dri/common \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/mesa/main \
+ -D__NOT_HAVE_DRM_H
+
+
+C_SOURCES = \
+ dri_context.c \
+ dri_screen.c \
+ dri_drawable.c \
+ dri_st_api.c \
+ dri1_helper.c \
+ drisw.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/dri/sw/SConscript b/src/gallium/state_trackers/dri/sw/SConscript
new file mode 100644
index 00000000000..c97124c8310
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/SConscript
@@ -0,0 +1,28 @@
+#######################################################################
+# SConscript for dri state_tracker
+
+Import('*')
+
+if env['dri']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/gallium/state_trackers/dri/common',
+ '#/src/mesa/drivers/dri/common',
+ ])
+
+ env.Append(CPPDEFINES = [('__NOT_HAVE_DRM_H', '1')])
+
+ st_drisw = env.ConvenienceLibrary(
+ target = 'st_drisw',
+ source = [ 'dri_context.c',
+ 'dri_drawable.c',
+ 'dri_screen.c',
+ 'dri_st_api.c',
+ 'dri1_helper.c',
+ 'drisw.c',
+ ]
+ )
+ Export('st_drisw')
diff --git a/src/gallium/state_trackers/dri/sw/dri1_helper.c b/src/gallium/state_trackers/dri/sw/dri1_helper.c
new file mode 120000
index 00000000000..c45ebf5c102
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri1_helper.c
@@ -0,0 +1 @@
+../common/dri1_helper.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_context.c b/src/gallium/state_trackers/dri/sw/dri_context.c
new file mode 120000
index 00000000000..5cfbbaeb068
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_context.c
@@ -0,0 +1 @@
+../common/dri_context.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_drawable.c b/src/gallium/state_trackers/dri/sw/dri_drawable.c
new file mode 120000
index 00000000000..0fc19be6ea6
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_drawable.c
@@ -0,0 +1 @@
+../common/dri_drawable.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_screen.c b/src/gallium/state_trackers/dri/sw/dri_screen.c
new file mode 120000
index 00000000000..847f6515f25
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_screen.c
@@ -0,0 +1 @@
+../common/dri_screen.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_st_api.c b/src/gallium/state_trackers/dri/sw/dri_st_api.c
new file mode 120000
index 00000000000..a8f6bd06b09
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_st_api.c
@@ -0,0 +1 @@
+../common/dri_st_api.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
new file mode 100644
index 00000000000..42fa789aaf7
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -0,0 +1,298 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ *
+ **************************************************************************/
+
+/* TODO:
+ *
+ * xshm / texture_from_pixmap / EGLImage:
+ *
+ * Allow the loaders to use the XSHM extension. It probably requires callbacks
+ * for createImage/destroyImage similar to DRI2 getBuffers.
+ */
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+#include "state_tracker/drisw_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri1_helper.h"
+#include "drisw.h"
+
+
+static INLINE void
+get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+ int x, y;
+
+ loader->getDrawableInfo(dPriv,
+ &x, &y, w, h,
+ dPriv->loaderPrivate);
+}
+
+static INLINE void
+put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+
+ loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+ 0, 0, width, height,
+ data, dPriv->loaderPrivate);
+}
+
+void
+drisw_update_drawable_info(struct dri_drawable *drawable)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
+ get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
+}
+
+static void
+drisw_put_image(struct dri_drawable *drawable,
+ void *data, unsigned width, unsigned height)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
+ put_image(dPriv, data, width, height);
+}
+
+static INLINE void
+drisw_present_texture(__DRIdrawable *dPriv,
+ struct pipe_texture *ptex)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_surface *psurf;
+
+ psurf = dri1_get_pipe_surface(drawable, ptex);
+ if (!psurf)
+ return;
+
+ screen->pipe_screen->flush_frontbuffer(screen->pipe_screen, psurf, drawable);
+}
+
+static INLINE void
+drisw_invalidate_drawable(__DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+
+ drawable->texture_stamp = dPriv->lastStamp - 1;
+
+ /* check if swapping currently bound buffer */
+ if (ctx && ctx->dPriv == dPriv)
+ ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
+}
+
+static INLINE void
+drisw_copy_to_front(__DRIdrawable * dPriv,
+ struct pipe_texture *ptex)
+{
+ drisw_present_texture(dPriv, ptex);
+
+ drisw_invalidate_drawable(dPriv);
+}
+
+/*
+ * Backend functions for st_framebuffer interface and swap_buffers.
+ */
+
+void
+drisw_swap_buffers(__DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return;
+
+ ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
+
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ drisw_copy_to_front(dPriv, ptex);
+ }
+}
+
+void
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return;
+
+ ptex = drawable->textures[statt];
+
+ if (ptex) {
+ drisw_copy_to_front(ctx->dPriv, ptex);
+ }
+}
+
+/**
+ * Allocate framebuffer attachments.
+ *
+ * During fixed-size operation, the function keeps allocating new attachments
+ * as they are requested. Unused attachments are not removed, not until the
+ * framebuffer is resized or destroyed.
+ *
+ * It should be possible for DRI1 and DRISW to share this function, but it
+ * seems a better seperation and safer for each DRI version to provide its own
+ * function.
+ */
+void
+drisw_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_texture templ;
+ unsigned width, height;
+ boolean resized;
+ int i;
+
+ width = drawable->dPriv->w;
+ height = drawable->dPriv->h;
+
+ resized = (drawable->old_w != width ||
+ drawable->old_h != height);
+
+ /* remove outdated textures */
+ if (resized) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (drawable->textures[i] || !(mask & (1 << i))) {
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ drawable->textures[i] =
+ screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
+ }
+ }
+
+ drawable->old_w = width;
+ drawable->old_h = height;
+}
+
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *drisw_screen_extensions[] = {
+ NULL
+};
+
+static struct drisw_loader_funcs drisw_lf = {
+ .put_image = drisw_put_image
+};
+
+const __DRIconfig **
+drisw_init_screen(__DRIscreen * sPriv)
+{
+ const __DRIconfig **configs;
+ struct dri_screen *screen;
+ struct drisw_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = -1;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = drisw_screen_extensions;
+
+ arg.base.mode = DRM_CREATE_DRISW;
+ arg.lf = &drisw_lf;
+
+ configs = dri_init_screen_helper(screen, &arg.base, 32);
+ if (!configs)
+ goto fail;
+
+ return configs;
+fail:
+ dri_destroy_screen_helper(screen);
+ FREE(screen);
+ return NULL;
+}
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driSWRastExtension.base,
+ NULL
+};
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/sw/drisw.h b/src/gallium/state_trackers/dri/sw/drisw.h
new file mode 100644
index 00000000000..c0c874f7326
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/drisw.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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 DRISW_H
+#define DRISW_H
+
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "state_tracker/st_api.h"
+#include "dri_wrapper.h"
+
+const __DRIconfig **
+drisw_init_screen(__DRIscreen * sPriv);
+
+void
+drisw_update_drawable_info(struct dri_drawable *drawable);
+
+void
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+drisw_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask);
+
+void drisw_swap_buffers(__DRIdrawable * dPriv);
+
+#endif /* DRISW_H */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index e4972d493d6..5eabe10558a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -36,234 +36,27 @@
#include "native.h"
#include "egl_g3d.h"
+#include "egl_g3d_st.h"
#include "egl_g3d_image.h"
-#include "egl_st.h"
-
-/**
- * Validate the draw/read surfaces of the context.
- */
-static void
-egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct pipe_screen *screen = gdpy->native->screen;
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
- ST_SURFACE_FRONT_LEFT,
- ST_SURFACE_BACK_LEFT,
- ST_SURFACE_FRONT_RIGHT,
- ST_SURFACE_BACK_RIGHT,
- };
- EGLint num_surfaces, s;
-
- /* validate draw and/or read buffers */
- num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
- for (s = 0; s < num_surfaces; s++) {
- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
- struct egl_g3d_surface *gsurf;
- struct egl_g3d_buffer *gbuf;
- EGLint att;
-
- if (s == 0) {
- gsurf = egl_g3d_surface(gctx->base.DrawSurface);
- gbuf = &gctx->draw;
- }
- else {
- gsurf = egl_g3d_surface(gctx->base.ReadSurface);
- gbuf = &gctx->read;
- }
-
- if (!gctx->force_validate) {
- unsigned int seq_num;
-
- gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
- &seq_num, NULL, NULL, NULL);
- /* skip validation */
- if (gsurf->sequence_number == seq_num)
- continue;
- }
-
- pipe_surface_reference(&gsurf->render_surface, NULL);
- memset(textures, 0, sizeof(textures));
-
- gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
- &gsurf->sequence_number, textures,
- &gsurf->base.Width, &gsurf->base.Height);
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- struct pipe_texture *pt = textures[att];
- struct pipe_surface *ps;
-
- if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) {
- ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
- gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
- st_att_map[att], ps);
-
- if (gsurf->render_att == att)
- pipe_surface_reference(&gsurf->render_surface, ps);
-
- pipe_surface_reference(&ps, NULL);
- pipe_texture_reference(&pt, NULL);
- }
- }
-
- gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
- gsurf->base.Width, gsurf->base.Height);
- }
-
- gctx->force_validate = EGL_FALSE;
-
-}
-
-/**
- * Create a st_framebuffer.
- */
-static struct st_framebuffer *
-create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
-
- return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
- gconf->native->color_format, gconf->native->depth_format,
- gconf->native->stencil_format,
- gsurf->base.Width, gsurf->base.Height, &gsurf->base);
-}
-
-/**
- * Update the attachments of draw/read surfaces.
- */
-static void
-egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- EGLint s;
-
- /* route draw and read buffers' attachments */
- for (s = 0; s < 2; s++) {
- struct egl_g3d_surface *gsurf;
- struct egl_g3d_buffer *gbuf;
-
- if (s == 0) {
- gsurf = egl_g3d_surface(gctx->base.DrawSurface);
- gbuf = &gctx->draw;
- }
- else {
- gsurf = egl_g3d_surface(gctx->base.ReadSurface);
- gbuf = &gctx->read;
- }
-
- gbuf->attachment_mask = (1 << gsurf->render_att);
-
- /* FIXME OpenGL defaults to draw the front or back buffer when the
- * context is single-buffered or double-buffered respectively. In EGL,
- * however, the buffer to be drawn is determined by the surface, instead
- * of the context. As a result, rendering to a pixmap surface with a
- * double-buffered context does not work as expected.
- *
- * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
- * NATIVE_ATTACHMENT_FRONT_LEFT);
- */
-
- /*
- * FIXME If the back buffer is asked for here, and the front buffer is
- * later needed by the client API (e.g. glDrawBuffer is called to draw
- * the front buffer), it will create a new pipe texture and draw there.
- * One fix is to ask for both buffers here, but it would be a waste if
- * the front buffer is never used. A better fix is to add a callback to
- * the pipe screen with context private (just like flush_frontbuffer).
- */
- }
-}
-
-/**
- * Reallocate the context's framebuffers after draw/read surfaces change.
- */
-static EGLBoolean
-egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
- struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);
-
- /* unreference the old framebuffers */
- if (gctx->draw.st_fb) {
- EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
- void *priv;
-
- priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
- if (!gdraw || priv != (void *) &gdraw->base) {
- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
- gctx->draw.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
-
- if (is_equal) {
- gctx->read.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
- else {
- priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
- if (!gread || priv != (void *) &gread->base) {
- gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
- gctx->read.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
- }
- }
-
- if (!gdraw)
- return EGL_TRUE;
-
- /* create the draw fb */
- if (!gctx->draw.st_fb) {
- gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
- if (!gctx->draw.st_fb)
- return EGL_FALSE;
- }
-
- /* create the read fb */
- if (!gctx->read.st_fb) {
- if (gread != gdraw) {
- gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
- if (!gctx->read.st_fb) {
- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
- gctx->draw.st_fb = NULL;
- return EGL_FALSE;
- }
- }
- else {
- /* there is no st_reference_framebuffer... */
- gctx->read.st_fb = gctx->draw.st_fb;
- }
- }
-
- egl_g3d_route_context(dpy, &gctx->base);
- gctx->force_validate = EGL_TRUE;
-
- return EGL_TRUE;
-}
/**
* Return the state tracker for the given context.
*/
-static const struct egl_g3d_st *
+static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
- const struct egl_g3d_st *stapi;
+ struct st_api *stapi;
EGLint idx = -1;
switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
switch (ctx->ClientVersion) {
case 1:
- idx = EGL_G3D_ST_OPENGL_ES;
+ idx = ST_API_OPENGL_ES1;
break;
case 2:
- idx = EGL_G3D_ST_OPENGL_ES2;
+ idx = ST_API_OPENGL_ES2;
break;
default:
_eglLog(_EGL_WARNING, "unknown client version %d",
@@ -272,10 +65,10 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
}
break;
case EGL_OPENVG_API:
- idx = EGL_G3D_ST_OPENVG;
+ idx = ST_API_OPENVG;
break;
case EGL_OPENGL_API:
- idx = EGL_G3D_ST_OPENGL;
+ idx = ST_API_OPENGL;
break;
default:
_eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
@@ -299,10 +92,10 @@ egl_g3d_init_st(_EGLDriver *drv)
if (gdrv->api_mask)
return;
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- gdrv->stapis[i] = egl_g3d_get_st(i);
+ for (i = 0; i < ST_API_COUNT; i++) {
+ gdrv->stapis[i] = egl_g3d_create_st_api(i);
if (gdrv->stapis[i])
- gdrv->api_mask |= gdrv->stapis[i]->api_bit;
+ gdrv->api_mask |= egl_g3d_st_api_bit(i);
}
if (gdrv->api_mask)
@@ -351,35 +144,6 @@ egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
}
}
-/**
- * Return an API mask that consists of the state trackers that supports the
- * given mode.
- *
- * FIXME add st_is_mode_supported()?
- */
-static EGLint
-get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
-{
- EGLint check;
-
- /* OpenGL ES 1.x and 2.x are checked together */
- check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
- if (api_mask & check) {
- /* this is required by EGL, not by OpenGL ES */
- if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
- api_mask &= ~check;
- }
-
- check = EGL_OPENVG_BIT;
- if (api_mask & check) {
- /* vega st needs the depth/stencil rb */
- if (!mode->depthBits && !mode->stencilBits)
- api_mask &= ~check;
- }
-
- return api_mask;
-}
-
#ifdef EGL_MESA_screen_surface
static void
@@ -444,18 +208,88 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
#endif /* EGL_MESA_screen_surface */
/**
+ * Initialize an EGL config from the native config.
+ */
+static EGLBoolean
+egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const struct native_config *nconf)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ const __GLcontextModes *mode = &nconf->mode;
+ EGLint buffer_mask, api_mask;
+ EGLBoolean valid;
+ EGLint i;
+
+ buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (mode->doubleBufferMode)
+ buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (mode->stereoMode) {
+ buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (mode->doubleBufferMode)
+ buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ gconf->stvis.buffer_mask = buffer_mask;
+ gconf->stvis.color_format = nconf->color_format;
+ gconf->stvis.depth_stencil_format = nconf->depth_format;
+ gconf->stvis.accum_format = PIPE_FORMAT_NONE;
+ gconf->stvis.samples = 0;
+
+ gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT) ?
+ ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
+
+ api_mask = 0;
+ for (i = 0; i < ST_API_COUNT; i++) {
+ struct st_api *stapi = gdrv->stapis[i];
+ if (stapi) {
+ if (stapi->is_visual_supported(stapi, &gconf->stvis))
+ api_mask |= egl_g3d_st_api_bit(i);
+ }
+ }
+ /* this is required by EGL, not by OpenGL ES */
+ if ((mode->drawableType & GLX_WINDOW_BIT) && !mode->doubleBufferMode)
+ api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
+
+ if (!api_mask) {
+ _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
+ mode->visualID);
+ }
+
+ valid = _eglConfigFromContextModesRec(&gconf->base,
+ mode, api_mask, api_mask);
+ if (valid) {
+#ifdef EGL_MESA_screen_surface
+ /* check if scanout surface bit is set */
+ if (nconf->scanout_bit) {
+ EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
+ val |= EGL_SCREEN_BIT_MESA;
+ SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+ }
+#endif
+ valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
+ }
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", mode->visualID);
+ return EGL_FALSE;
+ }
+
+ gconf->native = nconf;
+
+ return EGL_TRUE;
+}
+
+/**
* Add configs to display and return the next config ID.
*/
static EGLint
egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
const struct native_config **native_configs;
int num_configs, i;
- native_configs = gdpy->native->get_configs(gdpy->native,
- &num_configs);
+ native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
if (!num_configs) {
if (native_configs)
free(native_configs);
@@ -463,61 +297,25 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}
for (i = 0; i < num_configs; i++) {
- EGLint api_mask;
struct egl_g3d_config *gconf;
- EGLBoolean valid;
gconf = CALLOC_STRUCT(egl_g3d_config);
- if (!gconf)
- continue;
-
- _eglInitConfig(&gconf->base, dpy, id);
-
- api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
- if (!api_mask) {
- _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
- native_configs[i]->mode.visualID);
- }
-
- valid = _eglConfigFromContextModesRec(&gconf->base,
- &native_configs[i]->mode, api_mask, api_mask);
- if (valid) {
-#ifdef EGL_MESA_screen_surface
- /* check if scanout surface bit is set */
- if (native_configs[i]->scanout_bit) {
- EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
- val |= EGL_SCREEN_BIT_MESA;
- SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+ if (gconf) {
+ _eglInitConfig(&gconf->base, dpy, id);
+ if (!egl_g3d_init_config(drv, dpy, &gconf->base, native_configs[i])) {
+ free(gconf);
+ continue;
}
-#endif
- valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
- }
- if (!valid) {
- _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
- native_configs[i]->mode.visualID);
- free(gconf);
- continue;
- }
- gconf->native = native_configs[i];
- _eglAddConfig(dpy, &gconf->base);
- id++;
+ _eglAddConfig(dpy, &gconf->base);
+ id++;
+ }
}
free(native_configs);
return id;
}
-/**
- * Re-validate the context.
- */
-static void
-egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
-}
-
static void
egl_g3d_invalid_surface(struct native_display *ndpy,
struct native_surface *nsurf,
@@ -525,11 +323,15 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
- struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
-
- /* set force_validate to skip an unnecessary check */
+ struct egl_g3d_context *gctx;
+
+ /*
+ * Some functions such as egl_g3d_copy_buffers create a temporary native
+ * surface. There is no gsurf associated with it.
+ */
+ gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
if (gctx)
- gctx->force_validate = TRUE;
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
}
static struct native_event_handler egl_g3d_native_event_handler = {
@@ -545,6 +347,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
_eglReleaseDisplayResources(drv, dpy);
_eglCleanupDisplay(dpy);
+ if (gdpy->pipe)
+ gdpy->pipe->destroy(gdpy->pipe);
+
if (dpy->Screens) {
for (i = 0; i < dpy->NumScreens; i++) {
struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
@@ -554,6 +359,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
free(dpy->Screens);
}
+ if (gdpy->smapi)
+ egl_g3d_destroy_st_manager(gdpy->smapi);
+
if (gdpy->native)
gdpy->native->destroy(gdpy->native);
@@ -588,11 +396,17 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
gdpy->native->user_data = (void *) dpy;
- gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
egl_g3d_init_st(&gdrv->base);
dpy->ClientAPIsMask = gdrv->api_mask;
+ gdpy->smapi = egl_g3d_create_st_manager(dpy);
+ if (!gdpy->smapi) {
+ _eglError(EGL_NOT_INITIALIZED,
+ "eglInitialize(failed to create st manager)");
+ goto fail;
+ }
+
#ifdef EGL_MESA_screen_surface
/* enable MESA_screen_surface before adding (and validating) configs */
if (gdpy->native->modeset) {
@@ -629,7 +443,6 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
struct egl_g3d_context *gshare = egl_g3d_context(share);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_context *gctx;
- const __GLcontextModes *mode;
gctx = CALLOC_STRUCT(egl_g3d_context);
if (!gctx) {
@@ -648,24 +461,14 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
- mode = &gconf->native->mode;
-
- gctx->pipe = gdpy->native->screen->context_create(
- gdpy->native->screen,
- (void *) &gctx->base);
-
- if (!gctx->pipe) {
+ gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
+ &gconf->stvis, (gshare) ? gshare->stctxi : NULL);
+ if (!gctx->stctxi) {
free(gctx);
return NULL;
}
- gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
- (gshare) ? gshare->st_ctx : NULL);
- if (!gctx->st_ctx) {
- gctx->pipe->destroy(gctx->pipe);
- free(gctx);
- return NULL;
- }
+ gctx->stctxi->st_manager_private = (void *) &gctx->base;
return &gctx->base;
}
@@ -682,9 +485,7 @@ destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
- egl_g3d_realloc_context(dpy, &gctx->base);
- /* it will destroy the associated pipe context */
- gctx->stapi->st_destroy_context(gctx->st_ctx);
+ gctx->stctxi->destroy(gctx->stctxi);
free(gctx);
}
@@ -786,14 +587,20 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
+ gsurf->stvis = gconf->stvis;
+ if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER)
+ gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;
+
+ gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
+ if (!gsurf->stfbi) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
nsurf->user_data = &gsurf->base;
gsurf->native = nsurf;
- gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
- if (!gconf->native->mode.doubleBufferMode)
- gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
-
return &gsurf->base;
}
@@ -849,7 +656,8 @@ destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
- pipe_surface_reference(&gsurf->render_surface, NULL);
+ pipe_texture_reference(&gsurf->render_texture, NULL);
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
gsurf->native->destroy(gsurf->native);
free(gsurf);
}
@@ -868,6 +676,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
+ struct egl_g3d_surface *gread = egl_g3d_surface(read);
struct egl_g3d_context *old_gctx;
EGLBoolean ok = EGL_TRUE;
@@ -878,39 +687,29 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
if (old_gctx) {
/* flush old context */
- old_gctx->stapi->st_flush(old_gctx->st_ctx,
+ old_gctx->stctxi->flush(old_gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
-
- /*
- * The old context is no longer current, and egl_g3d_realloc_context()
- * should be called to destroy the framebuffers. However, it is possible
- * that it will be made current again with the same draw/read surfaces.
- * It might be better to keep it around.
- */
}
if (gctx) {
- ok = egl_g3d_realloc_context(dpy, &gctx->base);
+ ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
+ (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
- /* XXX: need to pass the winsys argument for
- * flush_frontbuffer in the fourth parameter here:
- */
- ok = gctx->stapi->st_make_current(gctx->st_ctx,
- gctx->draw.st_fb,
- gctx->read.st_fb,
- NULL);
- if (ok) {
- egl_g3d_validate_context(dpy, &gctx->base);
- if (gdraw->base.Type == EGL_WINDOW_BIT) {
- gctx->base.WindowRenderBuffer =
- (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
- EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
- }
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gdraw->stfbi);
+ if (gread != gdraw) {
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
+ gread->stfbi);
+ }
+
+ if (gdraw->base.Type == EGL_WINDOW_BIT) {
+ gctx->base.WindowRenderBuffer =
+ (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
+ EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
}
}
else if (old_gctx) {
- ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL, NULL);
+ ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
@@ -937,15 +736,17 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return EGL_TRUE;
/* or when the surface is single-buffered */
- if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
+ if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT)
return EGL_TRUE;
if (ctx && ctx->DrawSurface == surf)
gctx = egl_g3d_context(ctx);
/* flush if the surface is current */
- if (gctx)
- gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
+ if (gctx) {
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
return gsurf->native->swap_buffers(gsurf->native);
}
@@ -985,7 +786,7 @@ get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
return NULL;
psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
+ 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
pipe_texture_reference(&textures[natt], NULL);
return psurf;
@@ -1003,7 +804,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_surface *psurf;
- if (!gsurf->render_surface)
+ if (!gsurf->render_texture)
return EGL_TRUE;
gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
@@ -1018,26 +819,33 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
/* flush if the surface is current */
if (ctx && ctx->DrawSurface == &gsurf->base) {
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stapi->st_flush(gctx->st_ctx,
+ gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
+ /* create a pipe context to copy surfaces */
+ if (!gdpy->pipe) {
+ gdpy->pipe =
+ gdpy->native->screen->context_create(gdpy->native->screen, NULL);
+ if (!gdpy->pipe)
+ return EGL_FALSE;
+ }
+
psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (psurf) {
- struct pipe_context pipe;
+ struct pipe_surface *psrc;
- /**
- * XXX This is hacky. If we might allow the EGLDisplay to create a pipe
- * context of its own and use the blitter context for this.
- */
- memset(&pipe, 0, sizeof(pipe));
- pipe.screen = screen;
+ psrc = screen->get_tex_surface(screen, gsurf->render_texture,
+ 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ if (psrc) {
+ gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0,
+ psrc, 0, 0, psurf->width, psurf->height);
+ pipe_surface_reference(&psrc, NULL);
- util_surface_copy(&pipe, FALSE, psurf, 0, 0,
- gsurf->render_surface, 0, 0, psurf->width, psurf->height);
+ nsurf->flush_frontbuffer(nsurf);
+ }
pipe_surface_reference(&psurf, NULL);
- nsurf->flush_frontbuffer(nsurf);
}
nsurf->destroy(nsurf);
@@ -1048,8 +856,16 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
static EGLBoolean
egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stapi->st_finish(gctx->st_ctx);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ screen->fence_finish(screen, fence, 0);
+ screen->fence_reference(screen, &fence, NULL);
+
return EGL_TRUE;
}
@@ -1079,10 +895,10 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
/* in case this is called before a display is initialized */
egl_g3d_init_st(&gdrv->base);
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- const struct egl_g3d_st *stapi = gdrv->stapis[i];
+ for (i = 0; i < ST_API_COUNT; i++) {
+ struct st_api *stapi = gdrv->stapis[i];
if (stapi) {
- proc = (_EGLProc) stapi->st_get_proc_address(procname);
+ proc = (_EGLProc) stapi->get_proc_address(stapi, procname);
if (proc)
return proc;
}
@@ -1098,8 +914,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx;
- enum pipe_format target_format;
- int target;
+ enum pipe_format internal_format;
+ enum st_texture_type target;
if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
@@ -1110,10 +926,10 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
switch (gsurf->base.TextureFormat) {
case EGL_TEXTURE_RGB:
- target_format = PIPE_FORMAT_R8G8B8_UNORM;
+ internal_format = PIPE_FORMAT_R8G8B8_UNORM;
break;
case EGL_TEXTURE_RGBA:
- target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
@@ -1129,21 +945,24 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (!es1)
return EGL_TRUE;
- if (!gsurf->render_surface)
+ if (!gsurf->render_texture)
return EGL_FALSE;
/* flush properly if the surface is bound */
if (gsurf->base.CurrentContext) {
gctx = egl_g3d_context(gsurf->base.CurrentContext);
- gctx->stapi->st_flush(gctx->st_ctx,
+ gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
gctx = egl_g3d_context(es1);
- gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
- target, gsurf->base.MipmapLevel, target_format);
-
- gsurf->base.BoundToTexture = EGL_TRUE;
+ if (gctx->stctxi->teximage) {
+ if (!gctx->stctxi->teximage(gctx->stctxi, target,
+ gsurf->base.MipmapLevel, internal_format,
+ gsurf->render_texture, gsurf->base.MipmapTexture))
+ return EGL_FALSE;
+ gsurf->base.BoundToTexture = EGL_TRUE;
+ }
return EGL_TRUE;
}
@@ -1160,14 +979,15 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
- if (gsurf->render_surface) {
+ if (gsurf->render_texture) {
_EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
/* what if the context the surface binds to is no longer current? */
- if (gctx)
- gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
- ST_TEXTURE_2D, gsurf->base.MipmapLevel);
+ if (gctx) {
+ gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
+ gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
+ }
}
gsurf->base.BoundToTexture = EGL_FALSE;
@@ -1279,6 +1099,12 @@ static void
egl_g3d_unload(_EGLDriver *drv)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ EGLint i;
+
+ for (i = 0; i < ST_API_COUNT; i++) {
+ if (gdrv->stapis[i])
+ gdrv->stapis[i]->destroy(gdrv->stapis[i]);
+ }
egl_g3d_destroy_probe(drv, NULL);
free(gdrv);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index e3e55e46d3b..2788f1bf4ac 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -39,11 +39,11 @@
#include "eglmode.h"
#include "native.h"
-#include "egl_st.h"
+#include "egl_g3d_st.h"
struct egl_g3d_driver {
_EGLDriver base;
- const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
+ struct st_api *stapis[ST_API_COUNT];
EGLint api_mask;
EGLint probe_key;
@@ -51,35 +51,34 @@ struct egl_g3d_driver {
struct egl_g3d_display {
struct native_display *native;
-};
-struct egl_g3d_buffer {
- struct st_framebuffer *st_fb;
- uint attachment_mask;
+ struct st_manager *smapi;
+ struct pipe_context *pipe;
};
struct egl_g3d_context {
_EGLContext base;
- const struct egl_g3d_st *stapi;
- struct pipe_context *pipe;
+ struct st_api *stapi;
- struct st_context *st_ctx;
- EGLBoolean force_validate;
- struct egl_g3d_buffer draw, read;
+ struct st_context_iface *stctxi;
};
struct egl_g3d_surface {
_EGLSurface base;
+
+ struct st_visual stvis;
+ struct st_framebuffer_iface *stfbi;
+
struct native_surface *native;
- enum native_attachment render_att;
- struct pipe_surface *render_surface;
+ struct pipe_texture *render_texture;
unsigned int sequence_number;
};
struct egl_g3d_config {
_EGLConfig base;
const struct native_config *native;
+ struct st_visual stvis;
};
struct egl_g3d_image {
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
new file mode 100644
index 00000000000..36094096d36
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -0,0 +1,227 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_dl.h"
+#include "eglimage.h"
+#include "eglmutex.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_st.h"
+
+struct egl_g3d_st_manager {
+ struct st_manager base;
+ _EGLDisplay *display;
+};
+
+static INLINE struct egl_g3d_st_manager *
+egl_g3d_st_manager(struct st_manager *smapi)
+{
+ return (struct egl_g3d_st_manager *) smapi;
+}
+
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api)
+{
+ const char *stmod_name;
+ struct util_dl_library *lib;
+ const struct st_module *mod;
+
+ switch (api) {
+ case ST_API_OPENGL:
+ stmod_name = ST_MODULE_OPENGL_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES1:
+ stmod_name = ST_MODULE_OPENGL_ES1_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES2:
+ stmod_name = ST_MODULE_OPENGL_ES2_SYMBOL;
+ break;
+ case ST_API_OPENVG:
+ stmod_name = ST_MODULE_OPENVG_SYMBOL;
+ break;
+ default:
+ stmod_name = NULL;
+ break;
+ }
+ if (!stmod_name)
+ return NULL;
+
+ mod = NULL;
+ lib = util_dl_open(NULL);
+ if (lib) {
+ mod = (const struct st_module *)
+ util_dl_get_proc_address(lib, stmod_name);
+ util_dl_close(lib);
+ }
+ if (!mod || mod->api != api)
+ return NULL;
+
+ return mod->create_api();
+}
+
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_st_manager *gsmapi;
+
+ gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
+ if (gsmapi) {
+ gsmapi->display = dpy;
+
+ gsmapi->base.screen = gdpy->native->screen;
+ }
+
+ return &gsmapi->base;;
+}
+
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi)
+{
+ struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
+ free(gsmapi);
+}
+
+static boolean
+egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ return gsurf->native->flush_frontbuffer(gsurf->native);
+}
+
+static boolean
+egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ uint attachment_mask = 0;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ int natt;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ natt = NATIVE_ATTACHMENT_BACK_RIGHT;
+ default:
+ natt = -1;
+ break;
+ }
+
+ if (natt >= 0)
+ attachment_mask |= 1 << natt;
+ }
+
+ if (!gsurf->native->validate(gsurf->native, attachment_mask,
+ &gsurf->sequence_number, textures, &gsurf->base.Width,
+ &gsurf->base.Height))
+ return FALSE;
+
+ for (i = 0; i < count; i++) {
+ struct pipe_texture *tex;
+ int natt;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ natt = NATIVE_ATTACHMENT_BACK_RIGHT;
+ break;
+ default:
+ natt = -1;
+ break;
+ }
+
+ if (natt >= 0) {
+ tex = textures[natt];
+
+ if (statts[i] == stfbi->visual->render_buffer)
+ pipe_texture_reference(&gsurf->render_texture, tex);
+
+ if (attachment_mask & (1 << natt)) {
+ /* transfer the ownership to the caller */
+ out[i] = tex;
+ attachment_mask &= ~(1 << natt);
+ }
+ else {
+ /* the attachment is listed more than once */
+ pipe_texture_reference(&out[i], tex);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct st_framebuffer_iface *stfbi;
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ if (!stfbi)
+ return NULL;
+
+ stfbi->visual = &gsurf->stvis;
+ stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
+ stfbi->validate = egl_g3d_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) &gsurf->base;
+
+ return stfbi;
+}
+
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ free(stfbi);
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
index 8fb464bd3d7..ea8b4068cd8 100644
--- a/src/gallium/state_trackers/egl/common/egl_st.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 7.8
+ * Version: 7.9
*
- * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ * Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,54 +20,60 @@
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
*/
-#ifndef _EGL_ST_H_
-#define _EGL_ST_H_
-
-#include "GL/gl.h" /* for GL types */
-#include "GL/internal/glcore.h" /* for __GLcontextModes */
+#ifndef _EGL_G3D_ST_H_
+#define _EGL_G3D_ST_H_
#include "pipe/p_compiler.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
+#include "state_tracker/st_api.h"
+#include "egltypedefs.h"
-/* avoid calling st functions directly */
-#if 1
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api);
-#define ST_SURFACE_FRONT_LEFT 0
-#define ST_SURFACE_BACK_LEFT 1
-#define ST_SURFACE_FRONT_RIGHT 2
-#define ST_SURFACE_BACK_RIGHT 3
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy);
-#define ST_TEXTURE_2D 0x2
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi);
-struct st_context;
-struct st_framebuffer;
-typedef void (*st_proc)();
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf);
-#else
-#include "state_tracker/st_public.h"
-#endif
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
-/* remember to update egl_g3d_get_st() when update the enums */
-enum egl_g3d_st_api {
- EGL_G3D_ST_OPENGL_ES = 0,
- EGL_G3D_ST_OPENVG,
- EGL_G3D_ST_OPENGL_ES2,
- EGL_G3D_ST_OPENGL,
-
- NUM_EGL_G3D_STS
-};
+/**
+ * Return the EGL_<api>_BIT of the st api.
+ */
+static INLINE int
+egl_g3d_st_api_bit(enum st_api_type api)
+{
+ int bit;
-struct egl_g3d_st {
-#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__);
-#include "st_public_tmp.h"
- /* fields must be added here */
- EGLint api_bit;
-};
+ switch (api) {
+ case ST_API_OPENGL:
+ bit = EGL_OPENGL_BIT;
+ break;
+ case ST_API_OPENGL_ES1:
+ bit = EGL_OPENGL_ES_BIT;
+ break;
+ case ST_API_OPENGL_ES2:
+ bit = EGL_OPENGL_ES2_BIT;
+ break;
+ case ST_API_OPENVG:
+ bit = EGL_OPENVG_BIT;
+ break;
+ default:
+ bit = 0;
+ break;
+ }
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api);
+ return bit;
+}
-#endif /* _EGL_ST_H_ */
+#endif /* _EGL_G3D_ST_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c
deleted file mode 100644
index a88ff911cd5..00000000000
--- a/src/gallium/state_trackers/egl/common/egl_st.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.8
- *
- * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <dlfcn.h>
-#include "pipe/p_compiler.h"
-#include "util/u_memory.h"
-#include "egllog.h"
-#include "EGL/egl.h" /* for EGL_api_BIT */
-
-#include "egl_st.h"
-
-#ifndef HAVE_DLADDR
-#define HAVE_DLADDR 1
-#endif
-
-#if HAVE_DLADDR
-
-static const char *
-egl_g3d_st_names[] = {
-#define ST_PUBLIC(name, ...) #name,
-#include "st_public_tmp.h"
- NULL
-};
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
- st_proc *procs = (st_proc *) stapi;
- void *handle;
- Dl_info info;
- const char **name;
-
- if (!dladdr(sym, &info))
- return FALSE;
- handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
- if (!handle)
- return FALSE;
-
- for (name = egl_g3d_st_names; *name; name++) {
- st_proc proc = (st_proc) dlsym(handle, *name);
- if (!proc) {
- _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
- memset(stapi, 0, sizeof(*stapi));
- dlclose(handle);
- return FALSE;
- }
- *procs++ = proc;
- }
-
- dlclose(handle);
- return TRUE;
-}
-
-#else /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
-#define ST_PUBLIC(name, ...) stapi->name = name;
-#include "st_public_tmp.h"
- return TRUE;
-}
-
-#endif /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
-{
- void *handle, *sym;
- boolean res = FALSE;
-
- /* already initialized */
- if (stapi->st_notify_swapbuffers != NULL)
- return TRUE;
-
- handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
- if (!handle)
- return FALSE;
-
- sym = dlsym(handle, api);
- if (sym && egl_g3d_fill_st(stapi, sym))
- res = TRUE;
-
- dlclose(handle);
- return res;
-}
-
-static struct {
- const char *symbol;
- EGLint api_bit;
-} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
- { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT },
- { "st_api_OpenVG", EGL_OPENVG_BIT },
- { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT },
- { "st_api_OpenGL", EGL_OPENGL_BIT },
-};
-
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api)
-{
- static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];
-
- if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
- all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
- return &all_trackers[api];
- }
- else {
- return NULL;
- }
-}
diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
deleted file mode 100644
index 562dd68c150..00000000000
--- a/src/gallium/state_trackers/egl/common/st_public_tmp.h
+++ /dev/null
@@ -1,20 +0,0 @@
-ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share)
-ST_PUBLIC(st_destroy_context, void, struct st_context *st)
-ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask)
-ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData)
-ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height)
-ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf)
-ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height)
-ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface)
-ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
-ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb)
-ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read, void *winsys_drawable_handle)
-ST_PUBLIC(st_get_current, struct st_context *, void)
-ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
-ST_PUBLIC(st_finish, void, struct st_context *st)
-ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format)
-ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level)
-ST_PUBLIC(st_get_proc_address, st_proc, const char *procname)
-#undef ST_PUBLIC
diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile
index b0365512719..089d4411675 100644
--- a/src/gallium/state_trackers/es/Makefile
+++ b/src/gallium/state_trackers/es/Makefile
@@ -38,6 +38,8 @@ SYS_LIBS = -lm -pthread
INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
-I$(TOP)/src/gallium/include
.c.o:
diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c
index 25bc53b21eb..4e89e06b34c 100644
--- a/src/gallium/state_trackers/es/st_es1.c
+++ b/src/gallium/state_trackers/es/st_es1.c
@@ -1,3 +1,8 @@
-#include "pipe/p_compiler.h"
+#include "state_tracker/st_manager.h"
PUBLIC const int st_api_OpenGL_ES1 = 1;
+
+PUBLIC const struct st_module st_module_OpenGL_ES1 = {
+ .api = ST_API_OPENGL_ES1,
+ .create_api = st_manager_create_api
+};
diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c
index 171ea62b97f..82e88b176ac 100644
--- a/src/gallium/state_trackers/es/st_es2.c
+++ b/src/gallium/state_trackers/es/st_es2.c
@@ -1,3 +1,8 @@
-#include "pipe/p_compiler.h"
+#include "state_tracker/st_manager.h"
PUBLIC const int st_api_OpenGL_ES2 = 1;
+
+PUBLIC const struct st_module st_module_OpenGL_ES2 = {
+ .api = ST_API_OPENGL_ES2,
+ .create_api = st_manager_create_api
+};
diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile
index 8c7cc524dfc..35509fd708b 100644
--- a/src/gallium/state_trackers/glx/xlib/Makefile
+++ b/src/gallium/state_trackers/glx/xlib/Makefile
@@ -6,12 +6,13 @@ LIBNAME = xlib
LIBRARY_INCLUDES = \
-I$(TOP)/include \
-I$(TOP)/src/mesa \
- $(X_CFLAGS)
+ $(X11_CFLAGS)
C_SOURCES = \
glx_api.c \
glx_getproc.c \
glx_usefont.c \
- xm_api.c
+ xm_api.c \
+ xm_st.c
include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index bb202351509..d6c16ad2f52 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -20,6 +20,7 @@ if env['platform'] == 'linux' \
'glx_getproc.c',
'glx_usefont.c',
'xm_api.c',
+ 'xm_st.c',
]
)
Export('st_xlib')
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 24545858500..eb8d6a19333 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -35,12 +35,9 @@
#include "xm_api.h"
#include "main/context.h"
-#include "main/config.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/version.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
/* This indicates the client-side GLX API and GLX encoder version. */
@@ -1304,7 +1301,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
if (MakeCurrent_PrevContext == src) {
_mesa_Flush();
}
- st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
+ XMesaCopyContext(xm_src, xm_dst, mask);
}
@@ -1761,6 +1758,10 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
}
for (i = 0; i < *nelements; i++) {
results[i] = create_glx_visual(dpy, visuals + i);
+ if (!results[i]) {
+ *nelements = i;
+ break;
+ }
}
return (GLXFBConfig *) results;
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index f4d7133d2ff..fd03d3c46a4 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -54,11 +54,9 @@
#endif
#include "xm_api.h"
-#include "main/context.h"
-#include "main/framebuffer.h"
+#include "xm_st.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
+#include "main/context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
@@ -72,19 +70,78 @@
* global.
*/
static struct xm_driver driver;
+static struct st_api *stapi;
void xmesa_set_driver( const struct xm_driver *templ )
{
driver = *templ;
+ stapi = driver.create_st_api();
}
-/**
- * Global X driver lock
+
+/*
+ * XXX replace this with a linked list, or better yet, try to attach the
+ * gallium/mesa extra bits to the X Display object with XAddExtension().
*/
-pipe_mutex _xmesa_lock;
+#define MAX_DISPLAYS 10
+static struct xmesa_display Displays[MAX_DISPLAYS];
+static int NumDisplays = 0;
+
+
+static XMesaDisplay
+xmesa_init_display( Display *display )
+{
+ pipe_static_mutex(init_mutex);
+ XMesaDisplay xmdpy;
+ int i;
+
+ pipe_mutex_lock(init_mutex);
+
+ /* Look for XMesaDisplay which corresponds to 'display' */
+ for (i = 0; i < NumDisplays; i++) {
+ if (Displays[i].display == display) {
+ /* Found it */
+ pipe_mutex_unlock(init_mutex);
+ return &Displays[i];
+ }
+ }
+
+ /* Create new XMesaDisplay */
+
+ assert(NumDisplays < MAX_DISPLAYS);
+ xmdpy = &Displays[NumDisplays];
+ NumDisplays++;
+
+ if (!xmdpy->display && display) {
+ xmdpy->display = display;
+ xmdpy->screen = driver.create_pipe_screen(display);
+ xmdpy->smapi = CALLOC_STRUCT(st_manager);
+ if (xmdpy->smapi)
+ xmdpy->smapi->screen = xmdpy->screen;
+
+ if (xmdpy->screen && xmdpy->smapi) {
+ pipe_mutex_init(xmdpy->mutex);
+ }
+ else {
+ if (xmdpy->screen) {
+ xmdpy->screen->destroy(xmdpy->screen);
+ xmdpy->screen = NULL;
+ }
+ if (xmdpy->smapi) {
+ FREE(xmdpy->smapi);
+ xmdpy->smapi = NULL;
+ }
-static struct pipe_screen *screen = NULL;
+ xmdpy->display = NULL;
+ }
+ }
+ if (!xmdpy->display || xmdpy->display != display)
+ xmdpy = NULL;
+
+ pipe_mutex_unlock(init_mutex);
+ return xmdpy;
+}
/**********************************************************************/
/***** X Utility Functions *****/
@@ -194,12 +251,13 @@ void
xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height)
{
+ XMesaDisplay xmdpy = xmesa_init_display(dpy);
Status stat;
- pipe_mutex_lock(_xmesa_lock);
+ pipe_mutex_lock(xmdpy->mutex);
XSync(b->xm_visual->display, 0); /* added for Chromium */
stat = get_drawable_size(dpy, b->ws.drawable, width, height);
- pipe_mutex_unlock(_xmesa_lock);
+ pipe_mutex_unlock(xmdpy->mutex);
if (!stat) {
/* probably querying a window that's recently been destroyed */
@@ -269,53 +327,51 @@ choose_pixel_format(XMesaVisual v)
return PIPE_FORMAT_B5G6R5_UNORM;
}
- assert(0);
- return 0;
+ return PIPE_FORMAT_NONE;
}
-
/**
- * Query the default gallium screen for a Z/Stencil format that
- * at least matches the given depthBits and stencilBits.
+ * Choose a depth/stencil format that satisfies the given depth and
+ * stencil sizes.
*/
-static void
-xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
- enum pipe_format *depthFormat,
- enum pipe_format *stencilFormat)
+static enum pipe_format
+choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
{
const enum pipe_texture_target target = PIPE_TEXTURE_2D;
const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
- static enum pipe_format formats[] = {
- PIPE_FORMAT_S8Z24_UNORM,
- PIPE_FORMAT_Z24S8_UNORM,
- PIPE_FORMAT_Z16_UNORM,
- PIPE_FORMAT_Z32_UNORM
- };
- int i;
+ enum pipe_format formats[8], fmt;
+ int count, i;
- assert(screen);
+ count = 0;
- *depthFormat = *stencilFormat = PIPE_FORMAT_NONE;
+ if (depth <= 16 && stencil == 0) {
+ formats[count++] = PIPE_FORMAT_Z16_UNORM;
+ }
+ if (depth <= 24 && stencil == 0) {
+ formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
+ formats[count++] = PIPE_FORMAT_Z24X8_UNORM;
+ }
+ if (depth <= 24 && stencil <= 8) {
+ formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
+ formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
+ }
+ if (depth <= 32 && stencil == 0) {
+ formats[count++] = PIPE_FORMAT_Z32_UNORM;
+ }
- /* search for supported format */
- for (i = 0; i < Elements(formats); i++) {
- if (screen->is_format_supported(screen, formats[i],
+ fmt = PIPE_FORMAT_NONE;
+ for (i = 0; i < count; i++) {
+ if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i],
target, tex_usage, geom_flags)) {
- *depthFormat = formats[i];
+ fmt = formats[i];
break;
}
}
- if (stencilBits) {
- *stencilFormat = *depthFormat;
- }
-
- /* XXX we should check that he chosen format has at least as many bits
- * as what was requested.
- */
+ return fmt;
}
@@ -324,7 +380,7 @@ xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
/***** Linked list of XMesaBuffers *****/
/**********************************************************************/
-XMesaBuffer XMesaBufferList = NULL;
+static XMesaBuffer XMesaBufferList = NULL;
/**
@@ -342,13 +398,15 @@ static XMesaBuffer
create_xmesa_buffer(Drawable d, BufferType type,
XMesaVisual vis, Colormap cmap)
{
+ XMesaDisplay xmdpy = xmesa_init_display(vis->display);
XMesaBuffer b;
- GLframebuffer *fb;
- enum pipe_format colorFormat, depthFormat, stencilFormat;
uint width, height;
ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
+ if (!xmdpy)
+ return NULL;
+
b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
if (!b)
return NULL;
@@ -361,24 +419,12 @@ create_xmesa_buffer(Drawable d, BufferType type,
b->type = type;
b->cmap = cmap;
- /* determine PIPE_FORMATs for buffers */
- colorFormat = choose_pixel_format(vis);
-
- xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
- vis->mesa_visual.stencilBits,
- &depthFormat, &stencilFormat);
-
-
get_drawable_size(vis->display, d, &width, &height);
/*
* Create framebuffer, but we'll plug in our own renderbuffers below.
*/
- b->stfb = st_create_framebuffer(&vis->mesa_visual,
- colorFormat, depthFormat, stencilFormat,
- width, height,
- (void *) b);
- fb = &b->stfb->Base;
+ b->stfb = xmesa_create_st_framebuffer(xmdpy, b);
/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
@@ -422,24 +468,21 @@ xmesa_free_buffer(XMesaBuffer buffer)
for (b = XMesaBufferList; b; b = b->Next) {
if (b == buffer) {
- struct gl_framebuffer *fb = &buffer->stfb->Base;
-
/* unlink buffer from list */
if (prev)
prev->Next = buffer->Next;
else
XMesaBufferList = buffer->Next;
- /* mark as delete pending */
- fb->DeletePending = GL_TRUE;
-
/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
b->ws.drawable = 0;
- /* Unreference. If count = zero we'll really delete the buffer */
- _mesa_reference_framebuffer(&fb, NULL);
+ /* XXX we should move the buffer to a delete-pending list and destroy
+ * the buffer until it is no longer current.
+ */
+ xmesa_destroy_st_framebuffer(buffer->stfb);
free(buffer);
@@ -596,10 +639,12 @@ XMesaVisual XMesaCreateVisual( Display *display,
GLint level,
GLint visualCaveat )
{
+ XMesaDisplay xmdpy = xmesa_init_display(display);
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;
- xmesa_init( display );
+ if (!xmdpy)
+ return NULL;
/* For debugging only */
if (_mesa_getenv("MESA_XSYNC")) {
@@ -681,6 +726,32 @@ XMesaVisual XMesaCreateVisual( Display *display,
accum_blue_size, accum_alpha_size,
0 );
+ v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (db_flag)
+ v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (stereo_flag) {
+ v->stvis.buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (db_flag)
+ v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ v->stvis.color_format = choose_pixel_format(v);
+ if (v->stvis.color_format == PIPE_FORMAT_NONE) {
+ FREE(v->visinfo);
+ FREE(v);
+ return NULL;
+ }
+
+ v->stvis.depth_stencil_format =
+ choose_depth_stencil_format(xmdpy, depth_size, stencil_size);
+
+ v->stvis.accum_format = (accum_red_size +
+ accum_green_size + accum_blue_size + accum_alpha_size) ?
+ PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
+
+ v->stvis.samples = num_samples;
+ v->stvis.render_buffer = ST_ATTACHMENT_INVALID;
+
/* XXX minor hack */
v->mesa_visual.level = level;
return v;
@@ -696,17 +767,12 @@ void XMesaDestroyVisual( XMesaVisual v )
/**
- * Do one-time initializations.
+ * Do per-display initializations.
*/
void
xmesa_init( Display *display )
{
- static GLboolean firstTime = GL_TRUE;
- if (firstTime) {
- pipe_mutex_init(_xmesa_lock);
- screen = driver.create_pipe_screen( display );
- firstTime = GL_FALSE;
- }
+ xmesa_init_display(display);
}
@@ -720,51 +786,33 @@ xmesa_init( Display *display )
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
- struct pipe_context *pipe = NULL;
+ XMesaDisplay xmdpy = xmesa_init_display(v->display);
XMesaContext c;
- GLcontext *mesaCtx;
- uint pf;
- xmesa_init( v->display );
+ if (!xmdpy)
+ return NULL;
/* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
if (!c)
return NULL;
- pf = choose_pixel_format(v);
- assert(pf);
-
c->xm_visual = v;
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
- if (screen == NULL)
- goto fail;
-
- /* Trace screen knows how to properly wrap context creation in the
- * wrapped screen, so nothing special to do here:
- */
- pipe = screen->context_create(screen, (void *) c);
- if (pipe == NULL)
- goto fail;
-
- c->st = st_create_context(pipe,
- &v->mesa_visual,
- share_list ? share_list->st : NULL);
+ c->st = stapi->create_context(stapi, xmdpy->smapi,
+ &v->stvis, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;
- mesaCtx = c->st->ctx;
- c->st->ctx->DriverCtx = c;
+ c->st->st_manager_private = (void *) c;
return c;
fail:
if (c->st)
- st_destroy_context(c->st);
- else if (pipe)
- pipe->destroy(pipe);
+ c->st->destroy(c->st);
free(c);
return NULL;
@@ -775,7 +823,7 @@ fail:
PUBLIC
void XMesaDestroyContext( XMesaContext c )
{
- st_destroy_context(c->st);
+ c->st->destroy(c->st);
/* FIXME: We should destroy the screen here, but if we do so, surfaces may
* outlive it, causing segfaults
@@ -881,7 +929,6 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
{
GET_CURRENT_CONTEXT(ctx);
XMesaBuffer b;
- GLuint width, height;
assert(v);
@@ -889,19 +936,18 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
if (!b)
return NULL;
- /* get pixmap size, update framebuffer/renderbuffer dims */
- xmesa_get_window_size(v->display, b, &width, &height);
- _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
+ /* get pixmap size */
+ xmesa_get_window_size(v->display, b, &b->width, &b->height);
if (target == 0) {
/* examine dims */
if (ctx->Extensions.ARB_texture_non_power_of_two) {
target = GLX_TEXTURE_2D_EXT;
}
- else if ( _mesa_bitcount(width) == 1
- && _mesa_bitcount(height) == 1) {
+ else if ( _mesa_bitcount(b->width) == 1
+ && _mesa_bitcount(b->height) == 1) {
/* power of two size */
- if (height == 1) {
+ if (b->height == 1) {
target = GLX_TEXTURE_1D_EXT;
}
else {
@@ -974,23 +1020,20 @@ XMesaDestroyBuffer(XMesaBuffer b)
/**
- * Query the current window size and update the corresponding GLframebuffer
- * and all attached renderbuffers.
- * Called when:
- * 1. the first time a buffer is bound to a context.
- * 2. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too...
- * Note: it's possible (and legal) for xmctx to be NULL. That can happen
- * when resizing a buffer when no rendering context is bound.
+ * Query the current drawable size and notify the binding context.
*/
void
-xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
+xmesa_check_buffer_size(XMesaBuffer b)
{
- GLuint width, height;
- xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
- st_resize_framebuffer(drawBuffer->stfb, width, height);
-}
+ XMesaContext xmctx = XMesaGetCurrentContext();
+ if (b->type == PBUFFER)
+ return;
+ xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height);
+ if (xmctx && xmctx->xm_buffer == b)
+ xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb);
+}
/*
@@ -1017,22 +1060,21 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_read_buffer == readBuffer)
return GL_TRUE;
+ xmesa_check_buffer_size(drawBuffer);
+ if (readBuffer != drawBuffer)
+ xmesa_check_buffer_size(readBuffer);
+
c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;
- st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb,
- &drawBuffer->ws);
-
- xmesa_check_and_update_buffer_size(c, drawBuffer);
- if (readBuffer != drawBuffer)
- xmesa_check_and_update_buffer_size(c, readBuffer);
+ stapi->make_current(stapi, c->st, drawBuffer->stfb, readBuffer->stfb);
/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
drawBuffer->wasCurrent = GL_TRUE;
}
else {
/* Detach */
- st_make_current( NULL, NULL, NULL, NULL );
+ stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
@@ -1051,14 +1093,8 @@ GLboolean XMesaUnbindContext( XMesaContext c )
XMesaContext XMesaGetCurrentContext( void )
{
- GET_CURRENT_CONTEXT(ctx);
- if (ctx) {
- XMesaContext xmesa = xmesa_context(ctx);
- return xmesa;
- }
- else {
- return 0;
- }
+ struct st_context_iface *st = stapi->get_current(stapi);
+ return (XMesaContext) (st) ? st->st_manager_private : NULL;
}
@@ -1070,17 +1106,17 @@ XMesaContext XMesaGetCurrentContext( void )
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
- struct pipe_surface *frontLeftSurf;
-
- st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
-
- if (frontLeftSurf) {
- screen->flush_frontbuffer( screen,
- frontLeftSurf,
- &b->ws );
+ XMesaContext xmctx = XMesaGetCurrentContext();
+
+ if (xmctx && xmctx->xm_buffer == b) {
+ xmctx->st->flush( xmctx->st,
+ PIPE_FLUSH_RENDER_CACHE |
+ PIPE_FLUSH_SWAPBUFFERS |
+ PIPE_FLUSH_FRAME,
+ NULL);
}
- xmesa_check_and_update_buffer_size(NULL, b);
+ xmesa_swap_st_framebuffer(b->stfb);
}
@@ -1090,21 +1126,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
*/
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
{
- struct pipe_surface *surf_front;
- struct pipe_surface *surf_back;
- struct pipe_context *pipe = NULL; /* XXX fix */
-
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf_back);
-
- if (!surf_front || !surf_back)
- return;
-
- assert(pipe);
- pipe->surface_copy(pipe,
- surf_front, x, y, /* dest */
- surf_back, x, y, /* src */
- width, height);
+ xmesa_copy_st_framebuffer(b->stfb,
+ ST_ATTACHMENT_BACK_LEFT, ST_ATTACHMENT_FRONT_LEFT,
+ x, y, width, height);
}
@@ -1112,7 +1136,14 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
void XMesaFlush( XMesaContext c )
{
if (c && c->xm_visual->display) {
- st_finish(c->st);
+ XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
+ struct pipe_fence_handle *fence = NULL;
+
+ c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ if (fence) {
+ xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
+ xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
+ }
XSync( c->xm_visual->display, False );
}
}
@@ -1186,3 +1217,10 @@ XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
{
}
+
+void
+XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask)
+{
+ if (dst->st->copy)
+ dst->st->copy(dst->st, src->st, mask);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index de47064b410..4f2c8a6e6a9 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -58,8 +58,7 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "main/mtypes.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
+#include "state_tracker/st_api.h"
#include "os/os_thread.h"
#include "state_tracker/xlib_sw_winsys.h"
@@ -68,11 +67,22 @@ and create a window, you must do the following to use the X/Mesa interface:
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
+typedef struct xmesa_display *XMesaDisplay;
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
typedef struct xmesa_visual *XMesaVisual;
+struct xmesa_display {
+ pipe_mutex mutex;
+
+ Display *display;
+ struct pipe_screen *screen;
+ struct st_manager *smapi;
+
+ struct pipe_context *pipe;
+};
+
/*
* Create a new X/Mesa visual.
@@ -258,16 +268,13 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
int format, int target, int mipmap);
+extern void
+XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);
/***********************************************************************
*/
-extern pipe_mutex _xmesa_lock;
-
-extern struct xmesa_buffer *XMesaBufferList;
-
-
/**
* Visual inforation, derived from GLvisual.
* Basically corresponds to an XVisualInfo.
@@ -280,6 +287,8 @@ struct xmesa_visual {
GLint BitsPerPixel; /* True bits per pixel for XImages */
GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
+
+ struct st_visual stvis;
};
@@ -288,7 +297,7 @@ struct xmesa_visual {
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
- struct st_context *st;
+ struct st_context_iface *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
@@ -311,7 +320,7 @@ typedef enum {
* Basically corresponds to a GLXDrawable.
*/
struct xmesa_buffer {
- struct st_framebuffer *stfb;
+ struct st_framebuffer_iface *stfb;
struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
@@ -335,33 +344,15 @@ struct xmesa_buffer {
GLint TextureMipmap; /** 0 or 1 */
struct xmesa_buffer *Next; /* Linked list pointer: */
-};
-
-
-
-/** cast wrapper */
-static INLINE XMesaContext
-xmesa_context(GLcontext *ctx)
-{
- return (XMesaContext) ctx->DriverCtx;
-}
+ unsigned width, height;
+};
-/** cast wrapper */
-static INLINE XMesaBuffer
-xmesa_buffer(GLframebuffer *fb)
-{
- struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
- return (XMesaBuffer) st_framebuffer_private(stfb);
-}
extern void
xmesa_init(Display *dpy);
-extern void
-xmesa_delete_framebuffer(struct gl_framebuffer *fb);
-
extern XMesaBuffer
xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis);
@@ -370,7 +361,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void
-xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
+xmesa_check_buffer_size(XMesaBuffer b);
extern void
xmesa_destroy_buffers_on_display(Display *dpy);
@@ -378,13 +369,13 @@ xmesa_destroy_buffers_on_display(Display *dpy);
static INLINE GLuint
xmesa_buffer_width(XMesaBuffer b)
{
- return b->stfb->Base.Width;
+ return b->width;
}
static INLINE GLuint
xmesa_buffer_height(XMesaBuffer b)
{
- return b->stfb->Base.Height;
+ return b->height;
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_public.h b/src/gallium/state_trackers/glx/xlib/xm_public.h
index ac6a8ffb27a..950eb21521f 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_public.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_public.h
@@ -26,19 +26,23 @@
*
**************************************************************************/
-#ifndef XM_WINSYS_H
-#define XM_WINSYS_H
+#ifndef XM_PUBLIC_H
+#define XM_PUBLIC_H
-struct xm_driver;
+#include <X11/Xlib.h>
+
+struct pipe_screen;
+struct st_api;
/* This is the driver interface required by the glx/xlib state tracker.
*/
struct xm_driver {
struct pipe_screen *(*create_pipe_screen)( Display *display );
+ struct st_api *(*create_st_api)( void );
};
extern void
xmesa_set_driver( const struct xm_driver *driver );
-#endif
+#endif /* XM_PUBLIC_H */
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
new file mode 100644
index 00000000000..b6ed7e8e1e8
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -0,0 +1,332 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "xm_api.h"
+#include "xm_st.h"
+
+struct xmesa_st_framebuffer {
+ XMesaDisplay display;
+ XMesaBuffer buffer;
+ struct pipe_screen *screen;
+
+ struct st_visual stvis;
+
+ unsigned texture_width, texture_height, texture_mask;
+ struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+
+ struct pipe_surface *display_surface;
+};
+
+static INLINE struct xmesa_st_framebuffer *
+xmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ return (struct xmesa_st_framebuffer *) stfbi->st_manager_private;
+}
+
+/**
+ * Display an attachment to the xlib_drawable of the framebuffer.
+ */
+static boolean
+xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture *ptex = xstfb->textures[statt];
+ struct pipe_surface *psurf;
+
+ if (!ptex)
+ return TRUE;
+
+ psurf = xstfb->display_surface;
+ /* (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_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
+ return FALSE;
+
+ xstfb->display_surface = psurf;
+ }
+
+ xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
+
+ return TRUE;
+}
+
+/**
+ * Copy the contents between the attachments.
+ */
+static void
+xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src_statt,
+ enum st_attachment_type dst_statt,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture *src_ptex = xstfb->textures[src_statt];
+ struct pipe_texture *dst_ptex = xstfb->textures[dst_statt];
+ struct pipe_surface *src, *dst;
+ struct pipe_context *pipe;
+
+ if (!src_ptex || !dst_ptex)
+ return;
+
+ pipe = xstfb->display->pipe;
+ if (!pipe) {
+ pipe = xstfb->screen->context_create(xstfb->screen, NULL);
+ if (!pipe)
+ return;
+ xstfb->display->pipe = pipe;
+ }
+
+ src = xstfb->screen->get_tex_surface(xstfb->screen,
+ src_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ dst = xstfb->screen->get_tex_surface(xstfb->screen,
+ dst_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ if (src && dst)
+ pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+/**
+ * Remove outdated textures and create the requested ones.
+ */
+static void
+xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
+ unsigned width, unsigned height,
+ unsigned mask)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture templ;
+ unsigned i;
+
+ /* remove outdated textures */
+ if (xstfb->texture_width != width || xstfb->texture_height != height) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&xstfb->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (xstfb->textures[i] || !(mask & (1 << i))) {
+ /* remember the texture */
+ if (xstfb->textures[i])
+ mask |= (1 << i);
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = xstfb->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = xstfb->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ xstfb->textures[i] =
+ xstfb->screen->texture_create(xstfb->screen, &templ);
+ }
+ }
+
+ xstfb->texture_width = width;
+ xstfb->texture_height = height;
+ xstfb->texture_mask = mask;
+}
+
+static boolean
+xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ unsigned statt_mask, new_mask, i;
+ boolean resized;
+
+ statt_mask = 0x0;
+ for (i = 0; i < count; i++)
+ statt_mask |= 1 << statts[i];
+ /* record newly allocated textures */
+ new_mask = statt_mask & ~xstfb->texture_mask;
+
+ resized = (xstfb->buffer->width != xstfb->texture_width ||
+ xstfb->buffer->height != xstfb->texture_height);
+
+ /* revalidate textures */
+ if (resized || new_mask) {
+ xmesa_st_framebuffer_validate_textures(stfbi,
+ xstfb->buffer->width, xstfb->buffer->height, statt_mask);
+
+ if (!resized) {
+ enum st_attachment_type back, front;
+
+ back = ST_ATTACHMENT_BACK_LEFT;
+ front = ST_ATTACHMENT_FRONT_LEFT;
+ /* copy the contents if front is newly allocated and back is not */
+ if ((statt_mask & (1 << back)) &&
+ (new_mask & (1 << front)) &&
+ !(new_mask & (1 << back))) {
+ xmesa_st_framebuffer_copy_textures(stfbi, back, front,
+ 0, 0, xstfb->texture_width, xstfb->texture_height);
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_texture_reference(&out[i], xstfb->textures[statts[i]]);
+ }
+
+ return TRUE;
+}
+
+static boolean
+xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ boolean ret;
+
+ ret = xmesa_st_framebuffer_display(stfbi, statt);
+ if (ret)
+ xmesa_check_buffer_size(xstfb->buffer);
+
+ return ret;
+}
+
+struct st_framebuffer_iface *
+xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
+{
+ struct st_framebuffer_iface *stfbi;
+ struct xmesa_st_framebuffer *xstfb;
+
+ assert(xmdpy->display == b->xm_visual->display);
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
+ if (!stfbi || !xstfb) {
+ if (stfbi)
+ FREE(stfbi);
+ if (xstfb)
+ FREE(xstfb);
+ return NULL;
+ }
+
+ xstfb->display = xmdpy;
+ xstfb->buffer = b;
+ xstfb->screen = xmdpy->screen;
+ xstfb->stvis = b->xm_visual->stvis;
+
+ stfbi->visual = &xstfb->stvis;
+ stfbi->flush_front = xmesa_st_framebuffer_flush_front;
+ stfbi->validate = xmesa_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) xstfb;
+
+ return stfbi;
+}
+
+void
+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);
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&xstfb->textures[i], NULL);
+
+ FREE(xstfb);
+ FREE(stfbi);
+}
+
+void
+xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ boolean ret;
+
+ ret = xmesa_st_framebuffer_display(stfbi, ST_ATTACHMENT_BACK_LEFT);
+ if (ret) {
+ struct pipe_texture **front, **back, *tmp;
+
+ front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
+ back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
+ /* swap textures only if the front texture has been allocated */
+ if (*front) {
+ tmp = *front;
+ *front = *back;
+ *back = tmp;
+ }
+
+ xmesa_check_buffer_size(xstfb->buffer);
+ }
+}
+
+void
+xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src,
+ enum st_attachment_type dst,
+ int x, int y, int w, int h)
+{
+ xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h);
+ if (dst == ST_ATTACHMENT_FRONT_LEFT)
+ xmesa_st_framebuffer_display(stfbi, dst);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.h b/src/gallium/state_trackers/glx/xlib/xm_st.h
new file mode 100644
index 00000000000..396495c1893
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.h
@@ -0,0 +1,51 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef _XM_ST_H_
+#define _XM_ST_H_
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/st_api.h"
+
+#include "xm_api.h"
+
+struct st_framebuffer_iface *
+xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b);
+
+void
+xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src,
+ enum st_attachment_type dst,
+ int x, int y, int w, int h);
+
+#endif /* _XM_ST_H_ */
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index d0d141fd249..781f54bf2b9 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -3,8 +3,7 @@ import os.path
Import('*')
-if 'python' in env['statetrackers'] and 0:
- # FIXME: Disable python state tracker until transfers are done by contexts
+if 'python' in env['statetrackers']:
env = env.Clone()
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index ffb084e358b..632d71ccbee 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -49,6 +49,7 @@
#include "util/u_format.h"
#include "util/u_dump.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
#include "tgsi/tgsi_text.h"
#include "tgsi/tgsi_dump.h"
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 5c44462e80f..bccaeead015 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -169,22 +169,39 @@ struct st_context {
void set_fragment_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ struct pipe_sampler_view templ;
+
if(!texture)
texture = $self->default_texture;
- pipe_texture_reference(&$self->fragment_sampler_textures[index], texture);
- $self->pipe->set_fragment_sampler_textures($self->pipe,
- PIPE_MAX_SAMPLERS,
- $self->fragment_sampler_textures);
+ pipe_sampler_view_reference(&$self->fragment_sampler_views[index], NULL);
+ u_sampler_view_default_template(&templ,
+ texture,
+ texture->format);
+ $self->fragment_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe,
+ texture,
+ &templ);
+ $self->pipe->set_fragment_sampler_views($self->pipe,
+ PIPE_MAX_SAMPLERS,
+ $self->fragment_sampler_views);
}
void set_vertex_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ struct pipe_sampler_view templ;
+
if(!texture)
texture = $self->default_texture;
- pipe_texture_reference(&$self->vertex_sampler_textures[index], texture);
- $self->pipe->set_vertex_sampler_textures($self->pipe,
- PIPE_MAX_VERTEX_SAMPLERS,
- $self->vertex_sampler_textures);
+ pipe_sampler_view_reference(&$self->vertex_sampler_views[index], NULL);
+ u_sampler_view_default_template(&templ,
+ texture,
+ texture->format);
+ $self->vertex_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe,
+ texture,
+ &templ);
+
+ $self->pipe->set_vertex_sampler_views($self->pipe,
+ PIPE_MAX_VERTEX_SAMPLERS,
+ $self->vertex_sampler_views);
}
void set_vertex_buffer(unsigned index,
@@ -263,8 +280,11 @@ struct st_context {
struct pipe_context *pipe = $self->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_buffer *vbuf;
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_buffer vbuffer;
float *map;
unsigned size;
+ unsigned i;
size = num_verts * num_attribs * 4 * sizeof(float);
@@ -280,9 +300,31 @@ struct st_context {
goto error2;
memcpy(map, vertices, size);
pipe_buffer_unmap(screen, vbuf);
-
- util_draw_vertex_buffer(pipe, vbuf, 0, prim, num_verts, num_attribs);
-
+
+ cso_save_vertex_elements($self->cso);
+
+ /* tell pipe about the vertex attributes */
+ for (i = 0; i < num_attribs; i++) {
+ velements[i].src_offset = i * 4 * sizeof(float);
+ velements[i].instance_divisor = 0;
+ velements[i].vertex_buffer_index = 0;
+ velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+ cso_set_vertex_elements($self->cso, num_attribs, velements);
+
+ /* tell pipe about the vertex buffer */
+ memset(&vbuffer, 0, sizeof(vbuffer));
+ vbuffer.buffer = vbuf;
+ vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */
+ vbuffer.buffer_offset = 0;
+ vbuffer.max_index = num_verts - 1;
+ pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+
+ /* draw */
+ pipe->draw_arrays(pipe, prim, 0, num_verts);
+
+ cso_restore_vertex_elements($self->cso);
+
error2:
pipe_buffer_reference(&vbuf, NULL);
error1:
@@ -290,6 +332,13 @@ error1:
}
void
+ clear(unsigned buffers, const float *rgba, double depth = 0.0f,
+ unsigned stencil = 0)
+ {
+ $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil);
+ }
+
+ void
flush(unsigned flags = 0) {
struct pipe_fence_handle *fence = NULL;
$self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence);
@@ -345,10 +394,253 @@ error1:
pipe_surface_reference(&_dst, NULL);
}
- void clear(unsigned buffers, const float *rgba, double depth = 0.0f,
- unsigned stencil = 0)
+ %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
+ void
+ surface_read_raw(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ char **STRING, int *LENGTH)
{
- $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil);
+ struct pipe_texture *texture = surface->texture;
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ unsigned stride;
+
+ stride = util_format_get_stride(texture->format, w);
+ *LENGTH = util_format_get_nblocksy(texture->format, h) * stride;
+ *STRING = (char *) malloc(*LENGTH);
+ if(!*STRING)
+ return;
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(transfer) {
+ pipe_get_tile_raw(pipe, transfer, 0, 0, w, h, *STRING, stride);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ %cstring_input_binary(const char *STRING, unsigned LENGTH);
+ void
+ surface_write_raw(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const char *STRING, unsigned LENGTH, unsigned stride = 0)
+ {
+ struct pipe_texture *texture = surface->texture;
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+
+ if(stride == 0)
+ stride = util_format_get_stride(texture->format, w);
+
+ if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride)
+ SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size");
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ if(!transfer)
+ SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer");
+
+ pipe_put_tile_raw(pipe, transfer, 0, 0, w, h, STRING, stride);
+ pipe->tex_transfer_destroy(pipe, transfer);
+
+ fail:
+ return;
+ }
+
+ void
+ surface_read_rgba(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ float *rgba)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(transfer) {
+ pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ void
+ surface_write_rgba(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const float *rgba)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ if(transfer) {
+ pipe_put_tile_rgba(pipe, transfer, 0, 0, w, h, rgba);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
+ void
+ surface_read_rgba8(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ char **STRING, int *LENGTH)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ float *rgba;
+ unsigned char *rgba8;
+ unsigned i, j, k;
+
+ *LENGTH = 0;
+ *STRING = NULL;
+
+ if (!surface)
+ return;
+
+ *LENGTH = h*w*4;
+ *STRING = (char *) malloc(*LENGTH);
+ if(!*STRING)
+ return;
+
+ rgba = malloc(h*w*4*sizeof(float));
+ if(!rgba)
+ return;
+
+ rgba8 = (unsigned char *) *STRING;
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y,
+ w, h);
+ if(transfer) {
+ pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba);
+ for(j = 0; j < h; ++j) {
+ for(i = 0; i < w; ++i)
+ for(k = 0; k <4; ++k)
+ rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]);
+ }
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+
+ free(rgba);
+ }
+
+ void
+ surface_read_z(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ unsigned *z)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(transfer) {
+ pipe_get_tile_z(pipe, transfer, 0, 0, w, h, z);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ void
+ surface_write_z(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const unsigned *z)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ if(transfer) {
+ pipe_put_tile_z(pipe, transfer, 0, 0, w, h, z);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ void
+ surface_sample_rgba(struct st_surface *surface,
+ float *rgba)
+ {
+ st_sample_surface($self->pipe, surface, rgba);
+ }
+
+ unsigned
+ surface_compare_rgba(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const float *rgba, float tol = 0.0)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ float *rgba2;
+ const float *p1;
+ const float *p2;
+ unsigned i, j, n;
+
+ rgba2 = MALLOC(h*w*4*sizeof(float));
+ if(!rgba2)
+ return ~0;
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(!transfer) {
+ FREE(rgba2);
+ return ~0;
+ }
+
+ pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba2);
+ pipe->tex_transfer_destroy(pipe, transfer);
+
+ p1 = rgba;
+ p2 = rgba2;
+ n = 0;
+ for(i = h*w; i; --i) {
+ unsigned differs = 0;
+ for(j = 4; j; --j) {
+ float delta = *p2++ - *p1++;
+ if (delta < -tol || delta > tol)
+ differs = 1;
+ }
+ n += differs;
+ }
+
+ FREE(rgba2);
+
+ return n;
}
};
diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i
index 761587dc533..923a6285289 100644
--- a/src/gallium/state_trackers/python/p_texture.i
+++ b/src/gallium/state_trackers/python/p_texture.i
@@ -124,234 +124,6 @@ struct st_surface
FREE($self);
}
- %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
- void get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH)
- {
- struct pipe_texture *texture = $self->texture;
- struct pipe_screen *screen = texture->screen;
- struct pipe_transfer *transfer;
- unsigned stride;
-
- stride = util_format_get_stride(texture->format, w);
- *LENGTH = util_format_get_nblocksy(texture->format, h) * stride;
- *STRING = (char *) malloc(*LENGTH);
- if(!*STRING)
- return;
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(transfer) {
- pipe_get_tile_raw(transfer, 0, 0, w, h, *STRING, stride);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- %cstring_input_binary(const char *STRING, unsigned LENGTH);
- void put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *STRING, unsigned LENGTH, unsigned stride = 0)
- {
- struct pipe_texture *texture = $self->texture;
- struct pipe_screen *screen = texture->screen;
- struct pipe_transfer *transfer;
-
- if(stride == 0)
- stride = util_format_get_stride(texture->format, w);
-
- if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride)
- SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size");
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_WRITE,
- x, y, w, h);
- if(!transfer)
- SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer");
-
- pipe_put_tile_raw(transfer, 0, 0, w, h, STRING, stride);
- screen->tex_transfer_destroy(transfer);
-
- fail:
- return;
- }
-
- void
- get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(transfer) {
- pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- void
- put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_WRITE,
- x, y, w, h);
- if(transfer) {
- pipe_put_tile_rgba(transfer, 0, 0, w, h, rgba);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
- void
- get_tile_rgba8(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- float *rgba;
- unsigned char *rgba8;
- unsigned i, j, k;
-
- *LENGTH = 0;
- *STRING = NULL;
-
- if (!$self)
- return;
-
- *LENGTH = h*w*4;
- *STRING = (char *) malloc(*LENGTH);
- if(!*STRING)
- return;
-
- rgba = malloc(h*w*4*sizeof(float));
- if(!rgba)
- return;
-
- rgba8 = (unsigned char *) *STRING;
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y,
- w, h);
- if(transfer) {
- pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba);
- for(j = 0; j < h; ++j) {
- for(i = 0; i < w; ++i)
- for(k = 0; k <4; ++k)
- rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]);
- }
- screen->tex_transfer_destroy(transfer);
- }
-
- free(rgba);
- }
-
- void
- get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(transfer) {
- pipe_get_tile_z(transfer, 0, 0, w, h, z);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- void
- put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_WRITE,
- x, y, w, h);
- if(transfer) {
- pipe_put_tile_z(transfer, 0, 0, w, h, z);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- void
- sample_rgba(float *rgba) {
- st_sample_surface($self, rgba);
- }
-
- unsigned
- compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- float *rgba2;
- const float *p1;
- const float *p2;
- unsigned i, j, n;
-
- rgba2 = MALLOC(h*w*4*sizeof(float));
- if(!rgba2)
- return ~0;
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(!transfer) {
- FREE(rgba2);
- return ~0;
- }
-
- pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba2);
- screen->tex_transfer_destroy(transfer);
-
- p1 = rgba;
- p2 = rgba2;
- n = 0;
- for(i = h*w; i; --i) {
- unsigned differs = 0;
- for(j = 4; j; --j) {
- float delta = *p2++ - *p1++;
- if (delta < -tol || delta > tol)
- differs = 1;
- }
- n += differs;
- }
-
- FREE(rgba2);
-
- return n;
- }
};
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 335e8e7f0d8..44d65e3fc1e 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -31,8 +31,10 @@
#include "pipe/p_shader_tokens.h"
#include "util/u_inlines.h"
#include "cso_cache/cso_context.h"
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
#include "trace/tr_public.h"
@@ -124,9 +126,9 @@ st_context_destroy(struct st_context *st_ctx)
st_ctx->pipe->destroy(st_ctx->pipe);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
- pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], NULL);
+ pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], NULL);
for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
- pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], NULL);
+ pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], NULL);
pipe_texture_reference(&st_ctx->default_texture, NULL);
FREE(st_ctx);
@@ -227,9 +229,12 @@ st_context_create(struct st_device *st_dev)
/* default textures */
{
+ struct pipe_context *pipe = st_ctx->pipe;
struct pipe_screen *screen = st_dev->screen;
struct pipe_texture templat;
struct pipe_transfer *transfer;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
unsigned i;
memset( &templat, 0, sizeof( templat ) );
@@ -242,31 +247,44 @@ st_context_create(struct st_device *st_dev)
st_ctx->default_texture = screen->texture_create( screen, &templat );
if(st_ctx->default_texture) {
- transfer = screen->get_tex_transfer(screen,
- st_ctx->default_texture,
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0,
- st_ctx->default_texture->width0,
- st_ctx->default_texture->height0);
+ transfer = pipe->get_tex_transfer(pipe,
+ st_ctx->default_texture,
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0,
+ st_ctx->default_texture->width0,
+ st_ctx->default_texture->height0);
if (transfer) {
uint32_t *map;
- map = (uint32_t *) screen->transfer_map(screen, transfer);
+ map = (uint32_t *) pipe->transfer_map(pipe, transfer);
if(map) {
*map = 0x00000000;
- screen->transfer_unmap(screen, transfer);
+ pipe->transfer_unmap(pipe, transfer);
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
-
+
+ u_sampler_view_default_template(&view_templ,
+ st_ctx->default_texture,
+ st_ctx->default_texture->format);
+ view = st_ctx->pipe->create_sampler_view(st_ctx->pipe,
+ st_ctx->default_texture,
+ &view_templ);
+
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], st_ctx->default_texture);
+ pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], view);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
- pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], st_ctx->default_texture);
-
- cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->fragment_sampler_textures);
- cso_set_vertex_sampler_textures(st_ctx->cso, PIPE_MAX_VERTEX_SAMPLERS, st_ctx->vertex_sampler_textures);
+ pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], view);
+
+ st_ctx->pipe->set_fragment_sampler_views(st_ctx->pipe,
+ PIPE_MAX_SAMPLERS,
+ st_ctx->fragment_sampler_views);
+ st_ctx->pipe->set_vertex_sampler_views(st_ctx->pipe,
+ PIPE_MAX_VERTEX_SAMPLERS,
+ st_ctx->vertex_sampler_views);
+
+ pipe_sampler_view_reference(&view, NULL);
}
/* vertex shader */
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index 6ec7409b11d..dcd0dc6e273 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -60,8 +60,8 @@ struct st_context
void *gs;
struct pipe_texture *default_texture;
- struct pipe_texture *fragment_sampler_textures[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_sampler_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
unsigned num_vertex_buffers;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
index e1808153461..e2c1e060174 100644
--- a/src/gallium/state_trackers/python/st_sample.c
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -523,29 +523,30 @@ st_sample_pixel_block(enum pipe_format format,
void
-st_sample_surface(struct st_surface *surface, float *rgba)
+st_sample_surface(struct pipe_context *pipe,
+ struct st_surface *surface,
+ float *rgba)
{
struct pipe_texture *texture = surface->texture;
- struct pipe_screen *screen = texture->screen;
unsigned width = u_minify(texture->width0, surface->level);
unsigned height = u_minify(texture->height0, surface->level);
uint rgba_stride = width * 4;
struct pipe_transfer *transfer;
void *raw;
- transfer = screen->get_tex_transfer(screen,
- surface->texture,
- surface->face,
- surface->level,
- surface->zslice,
- PIPE_TRANSFER_WRITE,
- 0, 0,
- width,
- height);
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ 0, 0,
+ width,
+ height);
if (!transfer)
return;
- raw = screen->transfer_map(screen, transfer);
+ raw = pipe->transfer_map(pipe, transfer);
if (raw) {
enum pipe_format format = texture->format;
uint x, y;
@@ -567,8 +568,8 @@ st_sample_surface(struct st_surface *surface, float *rgba)
}
}
- screen->transfer_unmap(screen, transfer);
+ pipe->transfer_unmap(pipe, transfer);
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h
index 888114d3021..6fb8417add8 100644
--- a/src/gallium/state_trackers/python/st_sample.h
+++ b/src/gallium/state_trackers/python/st_sample.h
@@ -32,6 +32,9 @@
#include "pipe/p_format.h"
+struct pipe_context;
+struct st_surface;
+
void
st_sample_pixel_block(enum pipe_format format,
@@ -40,7 +43,9 @@ st_sample_pixel_block(enum pipe_format format,
unsigned w, unsigned h);
void
-st_sample_surface(struct st_surface *surface, float *rgba);
+st_sample_surface(struct pipe_context *pipe,
+ struct st_surface *surface,
+ float *rgba);
#endif /* ST_SAMPLE_H_ */
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 985374190c3..0a332aaa9f1 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -30,7 +30,7 @@
#include "softpipe/sp_public.h"
#include "llvmpipe/lp_public.h"
#include "state_tracker/sw_winsys.h"
-#include "null/null_sw_winsys.h"
+#include "sw/null/null_sw_winsys.h"
#include "st_winsys.h"
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 7f04b2aa832..7c315de8271 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -25,6 +25,7 @@ VG_SOURCES = \
api_transform.c \
vgu.c \
vg_context.c \
+ vg_manager.c \
vg_state.c \
vg_tracker.c \
vg_translate.c \
diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c
index 47db102dd2d..eb2fbe26e7f 100644
--- a/src/gallium/state_trackers/vega/api_context.c
+++ b/src/gallium/state_trackers/vega/api_context.c
@@ -26,6 +26,7 @@
#include "VG/openvg.h"
+#include "vg_manager.h"
#include "vg_context.h"
#include "pipe/p_context.h"
@@ -55,6 +56,8 @@ void vgFlush(void)
pipe = ctx->pipe;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ vg_manager_flush_frontbuffer(ctx);
}
void vgFinish(void)
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 18e2cc1f250..a643f38624f 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -40,6 +40,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "asm_filters.h"
@@ -53,7 +54,7 @@ struct filter_info {
const void *const_buffer;
VGint const_buffer_len;
VGTilingMode tiling_mode;
- struct pipe_texture *extra_texture;
+ struct pipe_sampler_view *extra_texture_view;
};
static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
@@ -91,13 +92,35 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
return tex;
}
+static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context *ctx,
+ const VGuint *color_data,
+ const VGint color_data_len)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_texture_1d(ctx, color_data, color_data_len);
+
+ 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_texture_reference(&texture, NULL);
+
+ 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->texture, 0, 0, 0,
+ pipe->screen, dst->sampler_view->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* drawing dest */
@@ -168,7 +191,7 @@ static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[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;
@@ -177,10 +200,10 @@ static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
samplers[1] = NULL;
samplers[2] = NULL;
samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[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;
@@ -215,21 +238,21 @@ static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
}
samplers[0] = &sampler[0];
- textures[0] = info->src->texture;
+ sampler_views[0] = info->src->sampler_view;
++num_samplers;
++num_textures;
- if (info->extra_texture) {
+ if (info->extra_texture_view) {
memcpy(&sampler[1], &sampler[0], sizeof(struct pipe_sampler_state));
samplers[1] = &sampler[1];
- textures[1] = info->extra_texture;
+ 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_sampler_textures(ctx->cso_context, num_textures, textures);
+ 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)
@@ -308,7 +331,7 @@ static void execute_filter(struct vg_context *ctx,
cso_save_viewport(ctx->cso_context);
cso_save_blend(ctx->cso_context);
cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(ctx->cso_context);
+ cso_save_fragment_sampler_views(ctx->cso_context);
dst_surf = setup_framebuffer(info->dst);
setup_viewport(info->dst);
@@ -318,7 +341,7 @@ static void execute_filter(struct vg_context *ctx,
setup_samplers(ctx, info);
renderer_draw_texture(ctx->renderer,
- info->src->texture,
+ info->src->sampler_view->texture,
info->dst->x, info->dst->y,
info->dst->x + info->dst->width,
info->dst->y + info->dst->height,
@@ -331,7 +354,7 @@ static void execute_filter(struct vg_context *ctx,
cso_restore_viewport(ctx->cso_context);
cso_restore_blend(ctx->cso_context);
cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
+ cso_restore_fragment_sampler_views(ctx->cso_context);
vg_shader_destroy(ctx, shader);
@@ -369,7 +392,7 @@ void vgColorMatrix(VGImage dst, VGImage src,
info.const_buffer = matrix;
info.const_buffer_len = 20 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
}
@@ -479,7 +502,7 @@ void vgConvolve(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
@@ -669,7 +692,7 @@ void vgGaussianBlur(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
@@ -688,7 +711,7 @@ void vgLookup(VGImage dst, VGImage src,
struct vg_image *d, *s;
VGuint color_data[256];
VGint i;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
@@ -714,7 +737,7 @@ void vgLookup(VGImage dst, VGImage src,
color_data[i] = blueLUT[i] << 24 | greenLUT[i] << 16 |
redLUT[i] << 8 | alphaLUT[i];
}
- lut_texture = create_texture_1d(ctx, color_data, 255);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 255);
buffer[0] = 0.f;
buffer[1] = 0.f;
@@ -728,11 +751,11 @@ void vgLookup(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
void vgLookupSingle(VGImage dst, VGImage src,
@@ -743,7 +766,7 @@ void vgLookupSingle(VGImage dst, VGImage src,
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
VGuint color_data[256];
@@ -783,7 +806,7 @@ void vgLookupSingle(VGImage dst, VGImage src,
color_data[i] = blue << 24 | green << 16 |
red << 8 | alpha;
}
- lut_texture = create_texture_1d(ctx, color_data, 256);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 256);
buffer[0] = 0.f;
buffer[1] = 0.f;
@@ -797,9 +820,9 @@ void vgLookupSingle(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 7eb5ea1f078..2f2d925252d 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -117,10 +117,6 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
x1, y1);
*/
- if (st->pipe->screen && st->pipe->screen->update_buffer)
- st->pipe->screen->update_buffer( st->pipe->screen,
- st->pipe->priv );
-
cso_save_blend(st->cso_context);
cso_save_rasterizer(st->cso_context);
cso_save_fragment_shader(st->cso_context);
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index a71579cd264..c3268a84a60 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -43,6 +43,7 @@
#include "util/u_tile.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_sampler.h"
static enum pipe_format vg_format_to_pipe(VGImageFormat format)
{
@@ -81,7 +82,7 @@ static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
static void vg_copy_texture(struct vg_context *ctx,
struct pipe_texture *dst, VGint dx, VGint dy,
- struct pipe_texture *src, VGint sx, VGint sy,
+ struct pipe_sampler_view *src, VGint sx, VGint sy,
VGint width, VGint height)
{
VGfloat dst_loc[4], src_loc[4];
@@ -103,8 +104,8 @@ static void vg_copy_texture(struct vg_context *ctx,
src_loc[3] = height;
src_bounds[0] = 0.f;
src_bounds[1] = 0.f;
- src_bounds[2] = src->width0;
- src_bounds[3] = src->height0;
+ src_bounds[2] = src->texture->width0;
+ src_bounds[3] = src->texture->height0;
vg_bound_rect(src_loc, src_bounds, src_shift);
vg_bound_rect(dst_loc, dst_bounds, dst_shift);
@@ -218,7 +219,7 @@ void vg_copy_surface(struct vg_context *ctx,
static struct pipe_texture *image_texture(struct vg_image *img)
{
- struct pipe_texture *tex = img->texture;
+ struct pipe_texture *tex = img->sampler_view->texture;
return tex;
}
@@ -247,9 +248,12 @@ struct vg_image * image_create(VGImageFormat format,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_context *pipe = ctx->pipe;
struct vg_image *image = CALLOC_STRUCT(vg_image);
enum pipe_format pformat = vg_format_to_pipe(format);
struct pipe_texture pt, *newtex;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
struct pipe_screen *screen = ctx->pipe->screen;
vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
@@ -281,7 +285,12 @@ struct vg_image * image_create(VGImageFormat format,
debug_assert(newtex);
- image->texture = newtex;
+ u_sampler_view_default_template(&view_templ, newtex, newtex->format);
+ view = pipe->create_sampler_view(pipe, newtex, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&newtex, NULL);
+
+ image->sampler_view = view;
vg_context_add_object(ctx, VG_OBJECT_IMAGE, image);
@@ -345,7 +354,7 @@ void image_destroy(struct vg_image *img)
array_destroy(img->children_array);
}
- pipe_texture_reference(&img->texture, NULL);
+ pipe_sampler_view_reference(&img->sampler_view, NULL);
free(img);
}
@@ -444,7 +453,7 @@ void image_get_sub_data(struct vg_image * image,
{
struct pipe_transfer *transfer =
pipe->get_tex_transfer(pipe,
- image->texture, 0, 0, 0,
+ image->sampler_view->texture, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0,
image->x + image->width,
@@ -478,9 +487,9 @@ struct vg_image * image_child_image(struct vg_image *parent,
image->width = width;
image->height = height;
image->parent = parent;
- image->texture = 0;
- pipe_texture_reference(&image->texture,
- parent->texture);
+ image->sampler_view = NULL;
+ pipe_sampler_view_reference(&image->sampler_view,
+ parent->sampler_view);
image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -514,8 +523,8 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
}
/* make sure rendering has completed */
ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- vg_copy_texture(ctx, dst->texture, dst->x + dx, dst->y + dy,
- src->texture, src->x + sx, src->y + sy, width, height);
+ vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy,
+ src->sampler_view, src->x + sx, src->y + sy, width, height);
}
void image_draw(struct vg_image *img)
@@ -624,12 +633,12 @@ VGboolean vg_image_overlaps(struct vg_image *dst,
}
VGint image_bind_samplers(struct vg_image *img, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
img->sampler.min_img_filter = image_sampler_filter(img->base.ctx);
img->sampler.mag_img_filter = image_sampler_filter(img->base.ctx);
samplers[3] = &img->sampler;
- textures[3] = img->texture;
+ sampler_views[3] = img->sampler_view;
return 1;
}
diff --git a/src/gallium/state_trackers/vega/image.h b/src/gallium/state_trackers/vega/image.h
index 78e17cffa64..805b35fab9f 100644
--- a/src/gallium/state_trackers/vega/image.h
+++ b/src/gallium/state_trackers/vega/image.h
@@ -43,7 +43,7 @@ struct vg_image {
struct vg_image *parent;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
struct pipe_sampler_state sampler;
struct array *children_array;
@@ -89,7 +89,7 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
VGint width, VGint height);
VGint image_bind_samplers(struct vg_image *dst, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
VGboolean vg_image_overlaps(struct vg_image *dst,
struct vg_image *src);
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 839dc19a3b8..316ea7a9c95 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -45,7 +45,7 @@ struct vg_mask_layer {
VGint width;
VGint height;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
};
static INLINE struct pipe_surface *
@@ -54,7 +54,7 @@ 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,
+ stfb->alpha_mask_view->texture,
0, 0, 0,
usage);
}
@@ -284,35 +284,33 @@ static void setup_mask_operation(VGMaskOperation operation)
cso_set_fragment_shader_handle(ctx->cso_context, shader);
}
-static void setup_mask_samplers(struct pipe_texture *umask)
+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_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
- struct pipe_texture *uprev = NULL;
+ struct pipe_sampler_view *uprev = NULL;
struct pipe_sampler_state sampler;
- uprev = fb_buffers->blend_texture;
+ uprev = fb_buffers->blend_texture_view;
sampler = ctx->mask.sampler;
sampler.normalized_coords = 1;
samplers[0] = NULL;
samplers[1] = NULL;
- samplers[2] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
samplers[0] = &sampler;
samplers[1] = &ctx->mask.sampler;
- textures[0] = umask;
- textures[1] = uprev;
+ sampler_views[0] = umask;
+ sampler_views[1] = uprev;
cso_set_samplers(ctx->cso_context, 2,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, 2, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, 2, sampler_views);
}
@@ -411,12 +409,13 @@ static void surface_fill(struct pipe_surface *surf,
}
-static void mask_using_texture(struct pipe_texture *texture,
+static void mask_using_texture(struct pipe_sampler_view *sampler_view,
VGMaskOperation operation,
VGint x, VGint y,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_texture *texture = sampler_view->texture;
struct pipe_surface *surface =
alpha_mask_surface(ctx, PIPE_BUFFER_USAGE_GPU_WRITE);
VGint offsets[4], loc[4];
@@ -439,13 +438,13 @@ static void mask_using_texture(struct pipe_texture *texture,
vg_prepare_blend_surface_from_mask(ctx);
cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(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(texture);
+ setup_mask_samplers(sampler_view);
setup_mask_blend();
setup_mask_operation(operation);
setup_mask_framebuffer(surface, surface->width, surface->height);
@@ -463,7 +462,7 @@ static void mask_using_texture(struct pipe_texture *texture,
cso_restore_framebuffer(ctx->cso_context);
cso_restore_fragment_shader(ctx->cso_context);
cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
+ cso_restore_fragment_sampler_views(ctx->cso_context);
cso_restore_viewport(ctx->cso_context);
pipe_surface_reference(&surface, NULL);
@@ -484,7 +483,11 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
{
struct pipe_texture pt;
+ struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = ctx->pipe->screen;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view = NULL;
+ struct pipe_texture *texture;
memset(&pt, 0, sizeof(pt));
pt.target = PIPE_TEXTURE_2D;
@@ -496,7 +499,14 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
pt.compressed = 0;
- mask->texture = screen->texture_create(screen, &pt);
+ texture = screen->texture_create(screen, &pt);
+
+ if (texture) {
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ }
+ pipe_texture_reference(&texture, NULL);
+ mask->sampler_view = view;
}
vg_context_add_object(ctx, VG_OBJECT_MASK, mask);
@@ -525,7 +535,7 @@ void mask_layer_fill(struct vg_mask_layer *layer,
alpha_color[3] = value;
surface = ctx->pipe->screen->get_tex_surface(
- ctx->pipe->screen, layer->texture,
+ ctx->pipe->screen, layer->sampler_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -545,10 +555,10 @@ void mask_copy(struct vg_mask_layer *layer,
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
renderer_copy_texture(ctx->renderer,
- layer->texture,
+ layer->sampler_view,
sx, sy,
sx + width, sy + height,
- fb_buffers->alpha_mask,
+ fb_buffers->alpha_mask_view->texture,
dx, dy,
dx + width, dy + height);
}
@@ -562,7 +572,7 @@ static void mask_layer_render_to(struct vg_mask_layer *layer,
struct pipe_screen *screen = ctx->pipe->screen;
struct pipe_surface *surface;
- surface = screen->get_tex_surface(screen, layer->texture, 0, 0, 0,
+ surface = screen->get_tex_surface(screen, layer->sampler_view->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
cso_save_framebuffer(ctx->cso_context);
@@ -604,8 +614,8 @@ void mask_render_to(struct path *path,
struct vg_mask_layer *temp_layer;
VGint width, height;
- width = fb_buffers->alpha_mask->width0;
- height = fb_buffers->alpha_mask->width0;
+ width = fb_buffers->alpha_mask_view->texture->width0;
+ height = fb_buffers->alpha_mask_view->texture->width0;
temp_layer = mask_layer_create(width, height);
@@ -622,7 +632,7 @@ void mask_using_layer(struct vg_mask_layer *layer,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(layer->texture, operation,
+ mask_using_texture(layer->sampler_view, operation,
x, y, width, height);
}
@@ -644,7 +654,7 @@ void mask_using_image(struct vg_image *image,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(image->texture, operation,
+ mask_using_texture(image->sampler_view, operation,
x, y, width, height);
}
@@ -672,7 +682,7 @@ void mask_fill(VGint x, VGint y, VGint width, VGint height,
}
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
struct vg_context *ctx = vg_current_context();
@@ -680,7 +690,7 @@ VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
samplers[1] = &ctx->mask.sampler;
- textures[1] = fb_buffers->alpha_mask;
+ sampler_views[1] = fb_buffers->alpha_mask_view;
return 1;
} else
return 0;
diff --git a/src/gallium/state_trackers/vega/mask.h b/src/gallium/state_trackers/vega/mask.h
index 5eaaede0e3a..4feacbefda8 100644
--- a/src/gallium/state_trackers/vega/mask.h
+++ b/src/gallium/state_trackers/vega/mask.h
@@ -63,6 +63,6 @@ void mask_fill(VGint x, VGint y,
VGfloat value);
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
#endif
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index dc56b8c5f3b..508e1863a57 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -37,6 +37,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
@@ -61,7 +62,7 @@ struct vg_paint {
VGfloat vals[5];
VGint valsi[5];
} radial;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
struct pipe_sampler_state sampler;
VGfloat *ramp_stops;
@@ -72,7 +73,7 @@ struct vg_paint {
} gradient;
struct {
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
VGTilingMode tiling_mode;
struct pipe_sampler_state sampler;
} pattern;
@@ -173,6 +174,26 @@ static INLINE struct pipe_texture *create_gradient_texture(struct vg_paint *p)
return tex;
}
+static INLINE struct pipe_sampler_view *create_gradient_sampler_view(struct vg_paint *p)
+{
+ struct pipe_context *pipe = p->base.ctx->pipe;
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_gradient_texture(p);
+
+ 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_texture_reference(&texture, NULL);
+
+ return view;
+}
+
struct vg_paint * paint_create(struct vg_context *ctx)
{
struct vg_paint *paint = CALLOC_STRUCT(vg_paint);
@@ -207,8 +228,9 @@ struct vg_paint * paint_create(struct vg_context *ctx)
void paint_destroy(struct vg_paint *paint)
{
struct vg_context *ctx = paint->base.ctx;
- if (paint->pattern.texture)
- pipe_texture_reference(&paint->pattern.texture, NULL);
+ pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
+ if (paint->pattern.sampler_view)
+ pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
if (ctx)
vg_context_remove_object(ctx, VG_OBJECT_PAINT, paint);
@@ -329,8 +351,8 @@ static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
map[4] = 0.f;
map[5] = 1.f;
- map[6] = paint->pattern.texture->width0;
- map[7] = paint->pattern.texture->height0;
+ map[6] = paint->pattern.sampler_view->texture->width0;
+ map[7] = paint->pattern.sampler_view->texture->height0;
{
struct matrix mat;
memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
@@ -394,12 +416,12 @@ void paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops,
create_gradient_data(stops, num / 5, paint->gradient.color_data,
1024);
- if (paint->gradient.texture) {
- pipe_texture_reference(&paint->gradient.texture, NULL);
- paint->gradient.texture = 0;
+ if (paint->gradient.sampler_view) {
+ pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
+ paint->gradient.sampler_view = NULL;
}
- paint->gradient.texture = create_gradient_texture(paint);
+ paint->gradient.sampler_view = create_gradient_sampler_view(paint);
}
void paint_set_colori(struct vg_paint *p,
@@ -459,12 +481,12 @@ void paint_set_radial_gradient(struct vg_paint *paint,
void paint_set_pattern(struct vg_paint *paint,
struct vg_image *img)
{
- if (paint->pattern.texture)
- pipe_texture_reference(&paint->pattern.texture, NULL);
+ if (paint->pattern.sampler_view)
+ pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
- paint->pattern.texture = 0;
- pipe_texture_reference(&paint->pattern.texture,
- img->texture);
+ paint->pattern.sampler_view = NULL;
+ pipe_sampler_view_reference(&paint->pattern.sampler_view,
+ img->sampler_view);
}
void paint_set_pattern_tiling(struct vg_paint *paint,
@@ -611,18 +633,18 @@ VGTilingMode paint_pattern_tiling(struct vg_paint *paint)
}
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
struct vg_context *ctx = vg_current_context();
switch(paint->type) {
case VG_PAINT_TYPE_LINEAR_GRADIENT:
case VG_PAINT_TYPE_RADIAL_GRADIENT: {
- if (paint->gradient.texture) {
+ if (paint->gradient.sampler_view) {
paint->gradient.sampler.min_img_filter = image_sampler_filter(ctx);
paint->gradient.sampler.mag_img_filter = image_sampler_filter(ctx);
samplers[0] = &paint->gradient.sampler;
- textures[0] = paint->gradient.texture;
+ sampler_views[0] = paint->gradient.sampler_view;
return 1;
}
}
@@ -634,7 +656,7 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
paint->pattern.sampler.min_img_filter = image_sampler_filter(ctx);
paint->pattern.sampler.mag_img_filter = image_sampler_filter(ctx);
samplers[0] = &paint->pattern.sampler;
- textures[0] = paint->pattern.texture;
+ sampler_views[0] = paint->pattern.sampler_view;
return 1;
}
break;
@@ -647,7 +669,7 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
void paint_resolve_type(struct vg_paint *paint)
{
if (paint->type == VG_PAINT_TYPE_PATTERN &&
- !paint->pattern.texture) {
+ !paint->pattern.sampler_view) {
paint->type = VG_PAINT_TYPE_COLOR;
}
}
diff --git a/src/gallium/state_trackers/vega/paint.h b/src/gallium/state_trackers/vega/paint.h
index 999b5c167ca..9ea67c4b1e6 100644
--- a/src/gallium/state_trackers/vega/paint.h
+++ b/src/gallium/state_trackers/vega/paint.h
@@ -108,7 +108,7 @@ VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
VGint paint_constant_buffer_size(struct vg_paint *paint);
void paint_fill_constant_buffer(struct vg_paint *paint,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 47e8b470a11..2bb4c8bc756 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -39,6 +39,7 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
@@ -263,7 +264,7 @@ void renderer_draw_texture(struct renderer *r,
}
void renderer_copy_texture(struct renderer *ctx,
- struct pipe_texture *src,
+ struct pipe_sampler_view *src,
VGfloat sx1, VGfloat sy1,
VGfloat sx2, VGfloat sy2,
struct pipe_texture *dst,
@@ -272,6 +273,7 @@ void renderer_copy_texture(struct renderer *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
+ struct pipe_texture *tex = src->texture;
struct pipe_buffer *buf;
struct pipe_surface *dst_surf = screen->get_tex_surface(
screen, dst, 0, 0, 0,
@@ -279,8 +281,8 @@ void renderer_copy_texture(struct renderer *ctx,
struct pipe_framebuffer_state fb;
float s0, t0, s1, t1;
- assert(src->width0 != 0);
- assert(src->height0 != 0);
+ assert(tex->width0 != 0);
+ assert(tex->height0 != 0);
assert(dst->width0 != 0);
assert(dst->height0 != 0);
@@ -290,10 +292,10 @@ void renderer_copy_texture(struct renderer *ctx,
#endif
#if 1
- s0 = sx1 / src->width0;
- s1 = sx2 / src->width0;
- t0 = sy1 / src->height0;
- t1 = sy2 / src->height0;
+ s0 = sx1 / tex->width0;
+ s1 = sx2 / tex->width0;
+ t0 = sy1 / tex->height0;
+ t1 = sy2 / tex->height0;
#else
s0 = 0;
s1 = 1;
@@ -307,7 +309,7 @@ void renderer_copy_texture(struct renderer *ctx,
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(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);
@@ -345,7 +347,7 @@ void renderer_copy_texture(struct renderer *ctx,
vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &src);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &src);
/* shaders */
cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
@@ -385,7 +387,7 @@ void renderer_copy_texture(struct renderer *ctx,
/* restore state we changed */
cso_restore_blend(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(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);
@@ -406,6 +408,8 @@ void renderer_copy_surface(struct renderer *ctx,
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_buffer *buf;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
struct pipe_texture texTemp, *tex;
struct pipe_surface *texSurf;
struct pipe_framebuffer_state fb;
@@ -457,6 +461,12 @@ void renderer_copy_surface(struct renderer *ctx,
if (!tex)
return;
+ u_sampler_view_default_template(&view_templ, tex, tex->format);
+ view = pipe->create_sampler_view(pipe, tex, &view_templ);
+
+ if (!view)
+ return;
+
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -479,7 +489,7 @@ void renderer_copy_surface(struct renderer *ctx,
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(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);
@@ -515,7 +525,7 @@ void renderer_copy_surface(struct renderer *ctx,
}
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &view);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
@@ -552,13 +562,14 @@ void renderer_copy_surface(struct renderer *ctx,
/* restore state we changed */
cso_restore_blend(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(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_texture_reference(&tex, NULL);
+ pipe_sampler_view_reference(&view, NULL);
}
void renderer_texture_quad(struct renderer *r,
diff --git a/src/gallium/state_trackers/vega/renderer.h b/src/gallium/state_trackers/vega/renderer.h
index 990cd32c313..03366f13614 100644
--- a/src/gallium/state_trackers/vega/renderer.h
+++ b/src/gallium/state_trackers/vega/renderer.h
@@ -33,6 +33,7 @@ struct renderer;
struct vg_context;
struct pipe_texture;
+struct pipe_sampler_view;
struct pipe_surface;
struct renderer *renderer_create(struct vg_context *owner);
@@ -57,7 +58,7 @@ void renderer_texture_quad(struct renderer *,
VGfloat x3, VGfloat y3,
VGfloat x4, VGfloat y4);
void renderer_copy_texture(struct renderer *r,
- struct pipe_texture *src,
+ struct pipe_sampler_view *src,
VGfloat sx1, VGfloat sy1,
VGfloat sx2, VGfloat sy2,
struct pipe_texture *dst,
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 0e71a507bff..f2ec24c57ff 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -119,7 +119,7 @@ static void setup_constant_buffer(struct shader *shader)
static VGint blend_bind_samplers(struct vg_context *ctx,
struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
VGBlendMode bmode = ctx->state.vg.blend_mode;
@@ -132,15 +132,15 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
vg_prepare_blend_surface(ctx);
samplers[2] = &ctx->blend_sampler;
- textures[2] = stfb->blend_texture;
+ sampler_views[2] = stfb->blend_texture_view;
- if (!samplers[0] || !textures[0]) {
+ if (!samplers[0] || !sampler_views[0]) {
samplers[0] = samplers[2];
- textures[0] = textures[2];
+ sampler_views[0] = sampler_views[2];
}
- if (!samplers[1] || !textures[1]) {
+ if (!samplers[1] || !sampler_views[1]) {
samplers[1] = samplers[0];
- textures[1] = textures[0];
+ sampler_views[1] = sampler_views[0];
}
return 1;
@@ -151,7 +151,7 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
static void setup_samplers(struct shader *shader)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[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
@@ -167,20 +167,20 @@ static void setup_samplers(struct shader *shader)
samplers[1] = NULL;
samplers[2] = NULL;
samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[3] = NULL;
-
- num += paint_bind_samplers(shader->paint, samplers, textures);
- num += mask_bind_samplers(samplers, textures);
- num += blend_bind_samplers(ctx, samplers, textures);
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
+ sampler_views[2] = NULL;
+ sampler_views[3] = NULL;
+
+ num += paint_bind_samplers(shader->paint, samplers, sampler_views);
+ num += mask_bind_samplers(samplers, sampler_views);
+ num += blend_bind_samplers(ctx, samplers, sampler_views);
if (shader->drawing_image && shader->image)
- num += image_bind_samplers(shader->image, samplers, textures);
+ 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_sampler_textures(ctx->cso_context, 4, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, 4, sampler_views);
}
}
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 170391ec031..11ebbbe5444 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -32,6 +32,7 @@
#include "shader.h"
#include "asm_util.h"
#include "st_inlines.h"
+#include "vg_manager.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
@@ -42,6 +43,7 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_blit.h"
+#include "util/u_sampler.h"
struct vg_context *_vg_context = 0;
@@ -305,6 +307,8 @@ static void update_clip_state(struct vg_context *ctx)
void vg_validate_state(struct vg_context *ctx)
{
+ vg_manager_validate_framebuffer(ctx);
+
if ((ctx->state.dirty & BLEND_DIRTY)) {
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
memset(blend, 0, sizeof(struct pipe_blend_state));
@@ -433,19 +437,24 @@ void 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();
+ 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,
+ stfb->blend_texture_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* flip it, because we want to use it as a sampler */
util_blit_pixels_tex(ctx->blit,
- strb->texture,
+ view,
0, strb->height,
strb->width, 0,
dest_surface,
@@ -458,6 +467,8 @@ void vg_prepare_blend_surface(struct vg_context *ctx)
/* make sure it's complete */
vgFinish();
+
+ pipe_sampler_view_reference(&view, NULL);
}
@@ -474,13 +485,13 @@ void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
vgFinish();
dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture,
+ stfb->blend_texture_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* flip it, because we want to use it as a sampler */
util_blit_pixels_tex(ctx->blit,
- stfb->alpha_mask,
+ stfb->alpha_mask_view,
0, strb->height,
strb->width, 0,
dest_surface,
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index 804e9e76d77..c9e36d7d767 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -33,6 +33,7 @@
#include "pipe/p_state.h"
#include "util/u_pointer.h"
#include "util/u_math.h"
+#include "state_tracker/st_api.h"
#include "cso_cache/cso_hash.h"
#include "cso_cache/cso_context.h"
@@ -54,9 +55,13 @@ struct st_framebuffer {
struct st_renderbuffer *strb;
struct st_renderbuffer *dsrb;
- struct pipe_texture *alpha_mask;
+ struct pipe_sampler_view *alpha_mask_view;
- struct pipe_texture *blend_texture;
+ struct pipe_sampler_view *blend_texture_view;
+
+
+ struct st_framebuffer_iface *iface;
+ enum st_attachment_type strb_att;
void *privateData;
};
@@ -84,6 +89,8 @@ enum dirty_state {
struct vg_context
{
+ struct st_context_iface iface;
+
struct pipe_context *pipe;
struct {
@@ -101,6 +108,7 @@ struct vg_context
VGErrorCode _error;
struct st_framebuffer *draw_buffer;
+ int32_t draw_buffer_invalid;
struct cso_hash *owned_objects[VG_OBJECT_LAST];
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
new file mode 100644
index 00000000000..25c2e853f2a
--- /dev/null
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -0,0 +1,373 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "state_tracker/st_api.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "vg_manager.h"
+#include "vg_context.h"
+#include "vg_tracker.h" /* for st_resize_framebuffer */
+#include "image.h"
+
+/**
+ * Flush the front buffer if the current context renders to the front buffer.
+ */
+void
+vg_manager_flush_frontbuffer(struct vg_context *ctx)
+{
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+
+ if (!stfb)
+ return;
+
+ /* st_public.h is used */
+ if (!stfb->iface) {
+ struct pipe_screen *screen = ctx->pipe->screen;
+ if (screen->flush_frontbuffer) {
+ screen->flush_frontbuffer(screen,
+ stfb->strb->surface, ctx->pipe->priv);
+ }
+ return;
+ }
+
+ switch (stfb->strb_att) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ stfb->iface->flush_front(stfb->iface, stfb->strb_att);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Re-validate the framebuffer.
+ */
+void
+vg_manager_validate_framebuffer(struct vg_context *ctx)
+{
+ struct pipe_screen *screen = ctx->pipe->screen;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct st_renderbuffer *rb;
+ struct pipe_texture *pt;
+
+ /* no binding surface */
+ if (!stfb)
+ return;
+
+ /* st_public.h is used */
+ if (!stfb->iface) {
+ struct pipe_screen *screen = ctx->pipe->screen;
+ if (screen->update_buffer)
+ screen->update_buffer(screen, ctx->pipe->priv);
+ return;
+ }
+
+ if (!p_atomic_read(&ctx->draw_buffer_invalid))
+ return;
+
+ /* validate the fb */
+ if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
+ return;
+
+ rb = stfb->strb;
+ if (rb->texture == pt) {
+ pipe_texture_reference(&pt, NULL);
+ return;
+ }
+
+ /* unreference existing ones */
+ pipe_surface_reference(&rb->surface, NULL);
+ pipe_texture_reference(&rb->texture, NULL);
+
+ rb->texture = pt;
+ rb->surface = screen->get_tex_surface(screen, rb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ rb->width = rb->surface->width;
+ rb->height = rb->surface->height;
+
+ st_resize_framebuffer(stfb, rb->width, rb->height);
+
+ p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
+}
+
+
+static void
+vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stfbi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+}
+
+static void
+vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
+ struct pipe_fence_handle **fence)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ ctx->pipe->flush(ctx->pipe, flags, fence);
+ if (flags & PIPE_FLUSH_RENDER_CACHE)
+ vg_manager_flush_frontbuffer(ctx);
+}
+
+static void
+vg_context_destroy(struct st_context_iface *stctxi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ vg_destroy_context(ctx);
+}
+
+static struct st_context_iface *
+vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
+{
+ struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
+ struct vg_context *ctx;
+ struct pipe_context *pipe;
+
+ pipe = smapi->screen->context_create(smapi->screen, NULL);
+ if (!pipe)
+ return NULL;
+ ctx = vg_create_context(pipe, NULL, shared_ctx);
+ if (!ctx) {
+ pipe->destroy(pipe);
+ return NULL;
+ }
+
+ ctx->iface.destroy = vg_context_destroy;
+
+ ctx->iface.notify_invalid_framebuffer =
+ vg_context_notify_invalid_framebuffer;
+ ctx->iface.flush = vg_context_flush;
+
+ ctx->iface.teximage = NULL;
+ ctx->iface.copy = NULL;
+
+ ctx->iface.st_context_private = (void *) smapi;
+
+ return &ctx->iface;
+}
+
+static struct st_renderbuffer *
+create_renderbuffer(enum pipe_format format)
+{
+ struct st_renderbuffer *strb;
+
+ strb = CALLOC_STRUCT(st_renderbuffer);
+ if (strb)
+ strb->format = format;
+
+ return strb;
+}
+
+static void
+destroy_renderbuffer(struct st_renderbuffer *strb)
+{
+ pipe_surface_reference(&strb->surface, NULL);
+ pipe_texture_reference(&strb->texture, NULL);
+ free(strb);
+}
+
+/**
+ * Decide the buffer to render to.
+ */
+static enum st_attachment_type
+choose_attachment(struct st_framebuffer_iface *stfbi)
+{
+ enum st_attachment_type statt;
+
+ statt = stfbi->visual->render_buffer;
+ if (statt != ST_ATTACHMENT_INVALID) {
+ /* use the buffer given by the visual, unless it is unavailable */
+ if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) {
+ switch (statt) {
+ case ST_ATTACHMENT_BACK_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ statt = ST_ATTACHMENT_FRONT_RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ if (!st_visual_have_buffers(stfbi->visual, 1 << statt))
+ statt = ST_ATTACHMENT_INVALID;
+ }
+ }
+
+ return statt;
+}
+
+/**
+ * Bind the context to the given framebuffers.
+ */
+static boolean
+vg_context_bind_framebuffers(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ struct st_framebuffer *stfb;
+ enum st_attachment_type strb_att;
+
+ /* the draw and read framebuffers must be the same */
+ if (stdrawi != streadi)
+ return FALSE;
+
+ p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+
+ strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
+
+ if (ctx->draw_buffer) {
+ stfb = ctx->draw_buffer;
+
+ /* free the existing fb */
+ if (!stdrawi ||
+ stfb->strb_att != strb_att ||
+ stfb->strb->format != stdrawi->visual->color_format ||
+ stfb->dsrb->format != stdrawi->visual->depth_stencil_format) {
+ destroy_renderbuffer(stfb->strb);
+ destroy_renderbuffer(stfb->dsrb);
+ free(stfb);
+
+ ctx->draw_buffer = NULL;
+ }
+ }
+
+ if (!stdrawi)
+ return TRUE;
+
+ if (strb_att == ST_ATTACHMENT_INVALID)
+ return FALSE;
+
+ /* create a new fb */
+ if (!ctx->draw_buffer) {
+ stfb = CALLOC_STRUCT(st_framebuffer);
+ if (!stfb)
+ return FALSE;
+
+ stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
+ if (!stfb->strb) {
+ free(stfb);
+ return FALSE;
+ }
+
+ stfb->dsrb = create_renderbuffer(stdrawi->visual->depth_stencil_format);
+ if (!stfb->dsrb) {
+ free(stfb->strb);
+ free(stfb);
+ return FALSE;
+ }
+
+ stfb->width = 0;
+ stfb->height = 0;
+ stfb->strb_att = strb_att;
+
+ ctx->draw_buffer = stfb;
+ }
+
+ ctx->draw_buffer->iface = stdrawi;
+
+ return TRUE;
+}
+
+static boolean
+vg_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+
+ if (stctxi)
+ vg_context_bind_framebuffers(stctxi, stdrawi, streadi);
+ vg_set_current_context(ctx);
+
+ return TRUE;
+}
+
+static struct st_context_iface *
+vg_api_get_current(struct st_api *stapi)
+{
+ struct vg_context *ctx = vg_current_context();
+
+ return (ctx) ? &ctx->iface : NULL;
+}
+
+static boolean
+vg_api_is_visual_supported(struct st_api *stapi,
+ const struct st_visual *visual)
+{
+ /* the impl requires a depth/stencil buffer */
+ if (visual->depth_stencil_format == PIPE_FORMAT_NONE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static st_proc_t
+vg_api_get_proc_address(struct st_api *stapi, const char *procname)
+{
+ /* TODO */
+ return (st_proc_t) NULL;
+}
+
+static void
+vg_api_destroy(struct st_api *stapi)
+{
+ free(stapi);
+}
+
+static struct st_api *
+vg_module_create_api(void)
+{
+ struct st_api *stapi;
+
+ stapi = CALLOC_STRUCT(st_api);
+ if (stapi) {
+ stapi->destroy = vg_api_destroy;
+ stapi->get_proc_address = vg_api_get_proc_address;
+ stapi->is_visual_supported = vg_api_is_visual_supported;
+
+ stapi->create_context = vg_api_create_context;
+ stapi->make_current = vg_api_make_current;
+ stapi->get_current = vg_api_get_current;
+ }
+
+ return stapi;
+}
+
+PUBLIC const struct st_module st_module_OpenVG = {
+ .api = ST_API_OPENVG,
+ .create_api = vg_module_create_api,
+};
diff --git a/src/gallium/state_trackers/vega/vg_manager.h b/src/gallium/state_trackers/vega/vg_manager.h
new file mode 100644
index 00000000000..1a276c0f35e
--- /dev/null
+++ b/src/gallium/state_trackers/vega/vg_manager.h
@@ -0,0 +1,40 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef VG_MANAGER_H
+#define VG_MANAGER_H
+
+#include "state_tracker/st_api.h"
+#include "vg_context.h"
+
+void
+vg_manager_flush_frontbuffer(struct vg_context *ctx);
+
+void
+vg_manager_validate_framebuffer(struct vg_context *ctx);
+
+#endif /* VG_MANAGER_H */
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index ea5c2ce41f6..f438e34087e 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -32,6 +32,7 @@
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "util/u_format.h"
+#include "util/u_sampler.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_rect.h"
@@ -41,7 +42,7 @@ PUBLIC const int st_api_OpenVG = 1;
static struct pipe_texture *
create_texture(struct pipe_context *pipe, enum pipe_format format,
- VGint width, VGint height)
+ VGint width, VGint height)
{
struct pipe_texture templ;
@@ -71,6 +72,27 @@ create_texture(struct pipe_context *pipe, enum pipe_format format,
return pipe->screen->texture_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_texture *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_texture_reference(&texture, NULL);
+
+ return view;
+}
+
/**
* Allocate a renderbuffer for a an on-screen window (not a user-created
* renderbuffer). The window system code determines the format.
@@ -115,8 +137,8 @@ st_renderbuffer_alloc_storage(struct vg_context * ctx,
surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
- strb->texture = create_texture(pipe, strb->format,
- width, height);
+ strb->texture = create_texture(pipe, strb->format, width, height);
+
if (!strb->texture)
return FALSE;
@@ -191,7 +213,7 @@ struct st_framebuffer * st_create_framebuffer(const void *visual,
/*### currently we always allocate it but it's possible it's
not necessary if EGL_ALPHA_MASK_SIZE was 0
*/
- stfb->alpha_mask = 0;
+ stfb->alpha_mask_view = NULL;
stfb->width = width;
stfb->height = height;
@@ -206,19 +228,19 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
uint width, uint height)
{
struct pipe_context *pipe = ctx->pipe;
- struct pipe_texture *old_texture = stfb->alpha_mask;
+ 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 =
- create_texture(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+ stfb->alpha_mask_view =
+ create_tex_and_view(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
- if (!stfb->alpha_mask) {
- if (old_texture)
- pipe_texture_reference(&old_texture, NULL);
+ if (!stfb->alpha_mask_view) {
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
return;
}
@@ -228,15 +250,15 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
mask_fill(0, 0, width, height, 1.f);
/* if we had an old surface copy it over */
- if (old_texture) {
+ if (old_sampler_view) {
struct pipe_surface *surface = pipe->screen->get_tex_surface(
pipe->screen,
- stfb->alpha_mask,
+ stfb->alpha_mask_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
struct pipe_surface *old_surface = pipe->screen->get_tex_surface(
pipe->screen,
- old_texture,
+ old_sampler_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ);
if (pipe->surface_copy) {
@@ -264,8 +286,8 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
/* Free the old texture
*/
- if (old_texture)
- pipe_texture_reference(&old_texture, NULL);
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
}
void st_resize_framebuffer(struct st_framebuffer *stfb,
@@ -326,9 +348,9 @@ void st_resize_framebuffer(struct st_framebuffer *stfb,
setup_new_alpha_mask(ctx, stfb, width, height);
- pipe_texture_reference( &stfb->blend_texture, NULL );
- stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
- width, height);
+ pipe_sampler_view_reference( &stfb->blend_texture_view, NULL );
+ stfb->blend_texture_view = create_tex_and_view(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
+ width, height);
}
void st_set_framebuffer_surface(struct st_framebuffer *stfb,
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 715a5e7b943..4ff48026e50 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -4,6 +4,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
+#include "util/u_sampler.h"
/*XXX also in Xrender.h but the including it here breaks compilition */
@@ -356,6 +357,9 @@ bind_samplers(struct exa_context *exa, int op,
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state src_sampler, mask_sampler;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *src_view;
+ struct pipe_context *pipe = exa->pipe;
exa->num_bound_samplers = 0;
@@ -366,7 +370,7 @@ bind_samplers(struct exa_context *exa, int op,
if (exa->has_solid_color) {
debug_assert(!"solid color with textures");
samplers[0] = NULL;
- exa->bound_textures[0] = NULL;
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
} else {
unsigned src_wrap = render_repeat_to_gallium(
pSrcPicture->repeatType);
@@ -381,8 +385,13 @@ bind_samplers(struct exa_context *exa, int op,
src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.normalized_coords = 1;
samplers[0] = &src_sampler;
- exa->bound_textures[0] = pSrc->tex;
exa->num_bound_samplers = 1;
+ u_sampler_view_default_template(&view_templ,
+ pSrc->tex,
+ pSrc->tex->format);
+ src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+ exa->bound_sampler_views[0] = src_view;
}
}
@@ -400,14 +409,19 @@ bind_samplers(struct exa_context *exa, int op,
src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.normalized_coords = 1;
samplers[1] = &mask_sampler;
- exa->bound_textures[1] = pMask->tex;
exa->num_bound_samplers = 2;
+ u_sampler_view_default_template(&view_templ,
+ pMask->tex,
+ pMask->tex->format);
+ src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+ exa->bound_sampler_views[1] = src_view;
}
cso_set_samplers(exa->renderer->cso, exa->num_bound_samplers,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(exa->renderer->cso, exa->num_bound_samplers,
- exa->bound_textures);
+ cso_set_fragment_sampler_views(exa->renderer->cso, exa->num_bound_samplers,
+ exa->bound_sampler_views);
}
@@ -476,7 +490,6 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
renderer_begin_solid(exa->renderer);
} else {
renderer_begin_textures(exa->renderer,
- exa->bound_textures,
exa->num_bound_samplers);
}
@@ -506,7 +519,7 @@ void xorg_composite(struct exa_context *exa,
renderer_texture(exa->renderer,
pos, width, height,
- exa->bound_textures,
+ exa->bound_sampler_views,
exa->num_bound_samplers,
src_matrix, mask_matrix);
}
@@ -538,7 +551,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
pixmap->width, pixmap->height);
bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
cso_set_samplers(exa->renderer->cso, 0, NULL);
- cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
+ cso_set_fragment_sampler_views(exa->renderer->cso, 0, NULL);
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index bdec0e254fa..76e6411bb8c 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -975,6 +975,9 @@ xorg_exa_close(ScrnInfoPtr pScrn)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+
renderer_destroy(exa->renderer);
if (exa->pipe)
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index f2cefe23b99..41b19061599 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -18,7 +18,7 @@ struct exa_context
struct pipe_screen *scrn;
struct xorg_renderer *renderer;
- struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS];
+ struct pipe_sampler_view *bound_sampler_views[MAX_EXA_SAMPLERS];
int num_bound_samplers;
float solid_color[4];
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 1eb926360b9..81b0dcf656f 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -8,6 +8,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "util/u_inlines.h"
@@ -482,8 +483,17 @@ void renderer_copy_prepare(struct xorg_renderer *r,
dst_surface->width,
dst_surface->height);
- /* texture */
- cso_set_sampler_textures(r->cso, 1, &src_texture);
+ /* texture/sampler view */
+ {
+ struct pipe_sampler_view templ;
+ struct pipe_sampler_view *src_view;
+ u_sampler_view_default_template(&templ,
+ src_texture,
+ src_texture->format);
+ src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
+ cso_set_fragment_sampler_views(r->cso, 1, &src_view);
+ pipe_sampler_view_reference(&src_view, NULL);
+ }
/* shaders */
shader = xorg_shaders_get(r->shaders,
@@ -655,7 +665,6 @@ void renderer_draw_flush(struct xorg_renderer *r)
}
void renderer_begin_textures(struct xorg_renderer *r,
- struct pipe_texture **textures,
int num_textures)
{
r->attrs_per_vertex = 1 + num_textures;
@@ -665,7 +674,7 @@ void renderer_begin_textures(struct xorg_renderer *r,
void renderer_texture(struct xorg_renderer *r,
int *pos,
int width, int height,
- struct pipe_texture **textures,
+ struct pipe_sampler_view **sampler_view,
int num_textures,
float *src_matrix,
float *mask_matrix)
@@ -693,7 +702,7 @@ void renderer_texture(struct xorg_renderer *r,
pos[0], pos[1], /* src */
pos[4], pos[5], /* dst */
width, height,
- textures[0], src_matrix);
+ sampler_view[0]->texture, src_matrix);
break;
case 3:
renderer_draw_conditional(r, 4 * 12);
@@ -702,7 +711,7 @@ void renderer_texture(struct xorg_renderer *r,
pos[2], pos[3], /* mask */
pos[4], pos[5], /* dst */
width, height,
- textures[0], textures[1],
+ sampler_view[0]->texture, sampler_view[1]->texture,
src_matrix, mask_matrix);
break;
default:
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 3d006287199..cc5802e79b2 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -65,12 +65,12 @@ void renderer_solid(struct xorg_renderer *r,
float *color);
void renderer_begin_textures(struct xorg_renderer *r,
- struct pipe_texture **textures,
int num_textures);
+
void renderer_texture(struct xorg_renderer *r,
int *pos,
int width, int height,
- struct pipe_texture **textures,
+ struct pipe_sampler_view **textures,
int num_textures,
float *src_matrix,
float *mask_matrix);
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 5a195cb482d..5efda6837de 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -9,6 +9,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
+#include "util/u_sampler.h"
#include "pipe/p_screen.h"
@@ -91,6 +92,7 @@ struct xorg_xv_port_priv {
/* juggle two sets of seperate Y, U and V
* textures */
struct pipe_texture *yuv[2][3];
+ struct pipe_sampler_view *yuv_views[2][3];
};
@@ -180,32 +182,60 @@ static int
check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height)
{
struct pipe_texture **dst = priv->yuv[priv->current_set];
+ struct pipe_sampler_view **dst_view = priv->yuv_views[priv->current_set];
+ struct pipe_sampler_view view_templ;
+ struct pipe_context *pipe = priv->r->pipe;
+
if (!dst[0] ||
dst[0]->width0 != width ||
dst[0]->height0 != height) {
pipe_texture_reference(&dst[0], NULL);
+ pipe_sampler_view_reference(&dst_view[0], NULL);
}
if (!dst[1] ||
dst[1]->width0 != width ||
dst[1]->height0 != height) {
pipe_texture_reference(&dst[1], NULL);
+ pipe_sampler_view_reference(&dst_view[1], NULL);
}
if (!dst[2] ||
dst[2]->width0 != width ||
dst[2]->height0 != height) {
pipe_texture_reference(&dst[2], NULL);
+ pipe_sampler_view_reference(&dst_view[2], NULL);
}
- if (!dst[0])
+ if (!dst[0]) {
dst[0] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[0]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[0],
+ dst[0]->format);
+ dst_view[0] = pipe->create_sampler_view(pipe, dst[0], &view_templ);
+ }
+ }
- if (!dst[1])
+ if (!dst[1]) {
dst[1] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[1]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[1],
+ dst[1]->format);
+ dst_view[1] = pipe->create_sampler_view(pipe, dst[1], &view_templ);
+ }
+ }
- if (!dst[2])
+ if (!dst[2]) {
dst[2] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[2]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[2],
+ dst[2]->format);
+ dst_view[2] = pipe->create_sampler_view(pipe, dst[2], &view_templ);
+ }
+ }
- if (!dst[0] || !dst[1] || !dst[2])
+ if (!dst[0] || !dst[1] || !dst[2] || !dst_view[0] || !dst_view[1] || !dst_view[2] )
return BadAlloc;
return Success;
@@ -450,6 +480,7 @@ bind_samplers(struct xorg_xv_port_priv *port)
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state sampler;
struct pipe_texture **dst = port->yuv[port->current_set];
+ struct pipe_sampler_view **dst_views = port->yuv_views[port->current_set];
memset(&sampler, 0, sizeof(struct pipe_sampler_state));
@@ -469,8 +500,7 @@ bind_samplers(struct xorg_xv_port_priv *port)
cso_set_samplers(port->r->cso, 3,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(port->r->cso, 3,
- dst);
+ cso_set_fragment_sampler_views(port->r->cso, 3, dst_views);
}
static int
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/targets/Makefile.dri
index f4cc0def471..6d9b81aa249 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/targets/Makefile.dri
@@ -64,11 +64,14 @@ SHARED_INCLUDES = \
default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) Makefile \
- $(TOP)/src/mesa/drivers/dri/Makefile.template
- $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/src/mesa/drivers/dri/common/dri_test.o
+ $(MKLIB) -o [email protected] -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
$(OBJECTS) $(PIPE_DRIVERS) \
-Wl,--start-group $(MESA_MODULES) -Wl,--end-group \
$(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
+ $(CC) -o [email protected] $(TOP)/src/mesa/drivers/dri/common/dri_test.o [email protected] $(DRI_LIB_DEPS)
$(TOP)/$(LIB_DIR)/gallium:
mkdir -p $@
diff --git a/src/gallium/winsys/drm/Makefile.egl b/src/gallium/targets/Makefile.egl
index bc5dd3a53b8..9265e2eb7bc 100644
--- a/src/gallium/winsys/drm/Makefile.egl
+++ b/src/gallium/targets/Makefile.egl
@@ -13,8 +13,14 @@ EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o)
common_LIBS = -ldrm -lm -ldl
+# ximage backend calls gallium_wrap_screen, which requires libidentity.a and
+# libtrace.a
x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a \
- $(TOP)/src/gallium/winsys/xlib/libws_xlib.a
+ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a
+
x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes
kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a
diff --git a/src/gallium/targets/SConscript b/src/gallium/targets/SConscript
index df62fc65fb7..1292d4f6193 100644
--- a/src/gallium/targets/SConscript
+++ b/src/gallium/targets/SConscript
@@ -1,9 +1,4 @@
Import('*')
-
-#if env['dri']:
-# SConscript([
-# 'drm/SConscript',
-# ])
if 'xlib' in env['winsys']:
SConscript([
@@ -14,3 +9,19 @@ if 'gdi' in env['winsys']:
SConscript([
'libgl-gdi/SConscript',
])
+
+if 'graw-xlib' in env['winsys']:
+ SConscript([
+ 'graw-xlib/SConscript',
+ ])
+
+if env['dri']:
+ SConscript([
+ 'SConscript.dri'
+ ])
+
+if 'xorg' in env['statetrackers']:
+ if 'vmware' in env['winsys']:
+ SConscript([
+ 'xorg-vmwgfx/SConscript',
+ ])
diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri
new file mode 100644
index 00000000000..210af13720a
--- /dev/null
+++ b/src/gallium/targets/SConscript.dri
@@ -0,0 +1,96 @@
+###################################
+# SConcscript file for dri targets
+
+Import('*')
+
+drienv = env.Clone()
+
+drienv.Replace(CPPPATH = [
+ '#src/mesa/drivers/dri/common',
+ '#include',
+ '#include/GL/internal',
+ '#src/gallium/include',
+ '#src/gallium/auxiliary',
+ '#src/gallium/drivers',
+ '#src/mesa',
+ '#src/mesa/main',
+ '#src/mesa/glapi',
+ '#src/mesa/math',
+ '#src/mesa/transform',
+ '#src/mesa/shader',
+ '#src/mesa/swrast',
+ '#src/mesa/swrast_setup',
+ '#src/egl/main',
+ '#src/egl/drivers/dri',
+])
+
+drienv.ParseConfig('pkg-config --cflags --libs libdrm')
+
+dri_common_utils = drienv.SharedObject(
+ target = 'utils.o',
+ source = '#src/mesa/drivers/dri/common/utils.c'
+)
+
+dri_common_xmlconfig = drienv.SharedObject(
+ target = 'xmlconfig.o',
+ source = '#src/mesa/drivers/dri/common/xmlconfig.c'
+)
+
+dri_common_vblank = drienv.SharedObject(
+ target = 'vblank.o',
+ source = '#src/mesa/drivers/dri/common/vblank.c'
+)
+
+dri_common_dri_util = drienv.SharedObject(
+ target = 'dri_util.o',
+ source = '#src/mesa/drivers/dri/common/dri_util.c'
+)
+
+dri_common_drisw_util = drienv.SharedObject(
+ target = 'drisw_util.o',
+ source = '#src/mesa/drivers/dri/common/drisw_util.c'
+)
+
+
+COMMON_DRI_SW_OBJECTS = [
+ dri_common_utils,
+ dri_common_xmlconfig,
+ dri_common_drisw_util,
+]
+
+COMMON_DRI_DRM_OBJECTS = [
+ dri_common_utils,
+ dri_common_xmlconfig,
+ dri_common_vblank,
+ dri_common_dri_util,
+]
+
+Export([
+ 'drienv',
+ 'COMMON_DRI_SW_OBJECTS',
+ 'COMMON_DRI_DRM_OBJECTS',
+])
+
+SConscript([
+ 'dri-swrast/SConscript',
+])
+
+if 'vmware' in env['winsys']:
+ SConscript([
+ 'dri-vmwgfx/SConscript',
+ ])
+
+if 'i915' in env['winsys']:
+ SConscript([
+ 'dri-i915/SConscript',
+ ])
+
+if 'i965' in env['winsys']:
+ SConscript([
+ 'dri-i965/SConscript',
+ ])
+
+if 'radeon' in env['winsys']:
+ SConscript([
+ 'dri-radeong/SConscript',
+ ])
diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/targets/dri-i915/Makefile
index 26aae4122eb..50a8e11e17c 100644
--- a/src/gallium/winsys/drm/intel/dri/Makefile
+++ b/src/gallium/targets/dri-i915/Makefile
@@ -1,26 +1,22 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = i915_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/gallium/drivers/i915/libi915.a
-
-DRIVER_SOURCES =
-
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += -ldrm_intel
-symlinks: $(TOP)/$(LIB_DIR)/gallium
- @rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
+symlinks:
diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript
new file mode 100644
index 00000000000..2fcc8028f12
--- /dev/null
+++ b/src/gallium/targets/dri-i915/SConscript
@@ -0,0 +1,26 @@
+Import('*')
+
+if not 'i915' in env['drivers']:
+ print 'warning: i915 pipe driver not built skipping i915_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
+env.Prepend(LIBS = [
+ st_dri,
+ i915drm,
+ i915,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.LoadableModule(
+ target = 'i915_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-i915/dummy.c b/src/gallium/targets/dri-i915/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-i915/dummy.c
diff --git a/src/gallium/winsys/drm/i965/dri/Makefile b/src/gallium/targets/dri-i965/Makefile
index f7e81eed87b..e267ba3a023 100644
--- a/src/gallium/winsys/drm/i965/dri/Makefile
+++ b/src/gallium/targets/dri-i965/Makefile
@@ -1,26 +1,24 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = i965_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
+ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/gallium/drivers/i965/libi965.a
-
-DRIVER_SOURCES =
-
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += -ldrm_intel
-symlinks: $(TOP)/$(LIB_DIR)/gallium
- @rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
+symlinks:
diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript
new file mode 100644
index 00000000000..eb9e6cd172a
--- /dev/null
+++ b/src/gallium/targets/dri-i965/SConscript
@@ -0,0 +1,26 @@
+Import('*')
+
+if not 'i965' in env['drivers']:
+ print 'warning: i965 pipe driver not built skipping i965_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
+env.Prepend(LIBS = [
+ st_dri,
+ i965drm,
+ i965,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.LoadableModule(
+ target = 'i965_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-i965/dummy.c b/src/gallium/targets/dri-i965/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-i965/dummy.c
diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/targets/dri-nouveau/Makefile
index 50ac3f203e5..74d352c6a70 100644
--- a/src/gallium/winsys/drm/nouveau/dri/Makefile
+++ b/src/gallium/targets/dri-nouveau/Makefile
@@ -1,22 +1,20 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = nouveau_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
$(TOP)/src/gallium/drivers/nouveau/libnouveau.a
-DRIVER_SOURCES =
-
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
diff --git a/src/gallium/winsys/drm/radeon/dri/Makefile b/src/gallium/targets/dri-radeong/Makefile
index d75f7dd6da7..66dd392b68b 100644
--- a/src/gallium/winsys/drm/radeon/dri/Makefile
+++ b/src/gallium/targets/dri-radeong/Makefile
@@ -1,12 +1,11 @@
-
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = radeong_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
@@ -15,9 +14,7 @@ C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-ASM_SOURCES =
-
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += -ldrm_radeon
diff --git a/src/gallium/targets/dri-radeong/SConscript b/src/gallium/targets/dri-radeong/SConscript
new file mode 100644
index 00000000000..d926c272889
--- /dev/null
+++ b/src/gallium/targets/dri-radeong/SConscript
@@ -0,0 +1,26 @@
+Import('*')
+
+if not 'r300' in env['drivers']:
+ print 'warning: r300 pipe driver not built skipping radeong_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
+
+env.Prepend(LIBS = [
+ st_dri,
+ radeonwinsys,
+ r300,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.SharedLibrary(
+ target ='radeon_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-radeong/dummy.c b/src/gallium/targets/dri-radeong/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-radeong/dummy.c
diff --git a/src/gallium/targets/dri-swrast/Makefile b/src/gallium/targets/dri-swrast/Makefile
new file mode 100644
index 00000000000..fcfd690e438
--- /dev/null
+++ b/src/gallium/targets/dri-swrast/Makefile
@@ -0,0 +1,30 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swrastg_dri.so
+
+DRIVER_DEFINES = -D__NOT_HAVE_DRM_H -DGALLIUM_SOFTPIPE
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/dri/sw/libdrisw.a \
+ $(TOP)/src/gallium/winsys/sw/dri/libswdri.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+SWRAST_COMMON_GALLIUM_SOURCES = \
+ $(TOP)/src/mesa/drivers/dri/common/utils.c \
+ $(TOP)/src/mesa/drivers/dri/common/drisw_util.c \
+ $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c
+
+C_SOURCES = \
+ swrast_drm_api.c \
+ $(SWRAST_COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+include ../Makefile.dri
+
+INCLUDES += \
+ -I$(TOP)/src/gallium/winsys/sw/dri
+
+symlinks:
diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript
new file mode 100644
index 00000000000..94ff99a0a90
--- /dev/null
+++ b/src/gallium/targets/dri-swrast/SConscript
@@ -0,0 +1,42 @@
+Import('*')
+
+if not set(('softpipe', 'llvmpipe')).intersection(env['drivers']):
+ print 'warning: no supported pipe driver: skipping build of swrastg_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/winsys/sw/dri',
+])
+
+env.Prepend(LIBS = [
+ st_drisw,
+ ws_dri,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_SW_OBJECTS
+])
+
+if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+ env.Prepend(LIBS = [softpipe])
+
+if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ env.Prepend(LIBS = [llvmpipe])
+
+swrastg_sources = [
+ 'swrast_drm_api.c'
+]
+
+env.LoadableModule(
+ target ='swrastg_dri.so',
+ source = swrastg_sources,
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-swrast/swrast_drm_api.c b/src/gallium/targets/dri-swrast/swrast_drm_api.c
new file mode 100644
index 00000000000..99c25543a76
--- /dev/null
+++ b/src/gallium/targets/dri-swrast/swrast_drm_api.c
@@ -0,0 +1,147 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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 "pipe/p_compiler.h"
+#include "util/u_memory.h"
+#include "state_tracker/drm_api.h"
+#include "state_tracker/sw_winsys.h"
+#include "dri_sw_winsys.h"
+
+/* Copied from targets/libgl-xlib */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+static struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys)
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+ default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+ if (screen == NULL && strcmp(driver, "cell") == 0)
+ screen = cell_create_screen( winsys );
+#elif defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#elif defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ (void) driver;
+#else
+ (void) driver;
+#endif
+
+ return screen;
+}
+
+static struct pipe_screen *
+swrast_drm_create_screen(struct drm_api *api,
+ int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct sw_winsys *winsys = NULL;
+ struct pipe_screen *screen = NULL;
+ struct drisw_create_screen_arg *drisw;
+
+ (void) drmFD;
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_DRISW:
+ drisw = (struct drisw_create_screen_arg *)arg;
+ break;
+ default:
+ return NULL;
+ }
+ }
+ else {
+ return NULL;
+ }
+
+ winsys = dri_create_sw_winsys(drisw->lf);
+ if (winsys == NULL)
+ return NULL;
+
+ screen = swrast_create_screen(winsys);
+ if (!screen)
+ goto fail;
+
+ return screen;
+
+fail:
+ if (winsys)
+ winsys->destroy(winsys);
+
+ return NULL;
+}
+
+static void
+swrast_drm_api_destroy(struct drm_api *api)
+{
+ return;
+}
+
+static struct drm_api swrast_drm_api =
+{
+ .name = "swrast",
+ .driver_name = "swrast",
+ .create_screen = swrast_drm_create_screen,
+ .destroy = swrast_drm_api_destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ return &swrast_drm_api;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/winsys/drm/vmware/dri/Makefile b/src/gallium/targets/dri-vmwgfx/Makefile
index 8a39e23da6d..4b002e828fa 100644
--- a/src/gallium/winsys/drm/vmware/dri/Makefile
+++ b/src/gallium/targets/dri-vmwgfx/Makefile
@@ -1,18 +1,17 @@
-
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = vmwgfx_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
symlinks:
diff --git a/src/gallium/targets/dri-vmwgfx/SConscript b/src/gallium/targets/dri-vmwgfx/SConscript
new file mode 100644
index 00000000000..6a1f8827bc3
--- /dev/null
+++ b/src/gallium/targets/dri-vmwgfx/SConscript
@@ -0,0 +1,24 @@
+Import('*')
+
+if not 'svga' in env['drivers']:
+ print 'warning: svga pipe driver not built skipping vmwgfx_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.Prepend(LIBS = [
+ st_dri,
+ svgadrm,
+ svga,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.LoadableModule(
+ target = 'vmwgfx_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-vmwgfx/dummy.c b/src/gallium/targets/dri-vmwgfx/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-vmwgfx/dummy.c
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/targets/egl-i915/Makefile
index 60d675ca73d..02258fb69a4 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/targets/egl-i915/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = i915
@@ -6,9 +6,8 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS = -ldrm_intel
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915/libi915.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/i965/egl/dummy.c b/src/gallium/targets/egl-i915/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/i965/egl/dummy.c
+++ b/src/gallium/targets/egl-i915/dummy.c
diff --git a/src/gallium/targets/egl-i965/Makefile b/src/gallium/targets/egl-i965/Makefile
new file mode 100644
index 00000000000..fad56ef5554
--- /dev/null
+++ b/src/gallium/targets/egl-i965/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = i965
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_intel
+
+EGL_DRIVER_PIPES = \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
+ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/intel/egl/dummy.c b/src/gallium/targets/egl-i965/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/intel/egl/dummy.c
+++ b/src/gallium/targets/egl-i965/dummy.c
diff --git a/src/gallium/winsys/drm/nouveau/egl/Makefile b/src/gallium/targets/egl-nouveau/Makefile
index 47d11276155..e3fa8937e83 100644
--- a/src/gallium/winsys/drm/nouveau/egl/Makefile
+++ b/src/gallium/targets/egl-nouveau/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = nouveau
@@ -6,10 +6,9 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS = -ldrm_nouveau
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
- $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/nouveau/egl/dummy.c b/src/gallium/targets/egl-nouveau/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/nouveau/egl/dummy.c
+++ b/src/gallium/targets/egl-nouveau/dummy.c
diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/targets/egl-radeon/Makefile
index cd4f9b20f06..8daadb59791 100644
--- a/src/gallium/winsys/drm/radeon/egl/Makefile
+++ b/src/gallium/targets/egl-radeon/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = radeon
@@ -6,9 +6,8 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS = -ldrm_radeon
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/radeon/egl/dummy.c b/src/gallium/targets/egl-radeon/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/radeon/egl/dummy.c
+++ b/src/gallium/targets/egl-radeon/dummy.c
diff --git a/src/gallium/targets/egl-swrast/Makefile b/src/gallium/targets/egl-swrast/Makefile
new file mode 100644
index 00000000000..7d4f5054983
--- /dev/null
+++ b/src/gallium/targets/egl-swrast/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+# Do propperly
+CFLAGS+="-I$(TOP)/src/gallium/include"
+
+EGL_DRIVER_NAME = swrast
+EGL_DRIVER_SOURCES = swrast_glue.c
+EGL_DRIVER_LIBS =
+EGL_DRIVER_PIPES =
+
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c b/src/gallium/targets/egl-swrast/swrast_glue.c
index 8c9f80e2c15..9db8089a666 100644
--- a/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c
+++ b/src/gallium/targets/egl-swrast/swrast_glue.c
@@ -11,3 +11,7 @@ drm_api_create()
(void) swrast_drm_api;
return NULL;
}
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/targets/egl-vmwgfx/Makefile
index a3e73131c35..5f9385f42b0 100644
--- a/src/gallium/winsys/drm/vmware/egl/Makefile
+++ b/src/gallium/targets/egl-vmwgfx/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = vmwgfx
@@ -6,9 +6,8 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS =
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/swrast/egl/dummy.c b/src/gallium/targets/egl-vmwgfx/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/swrast/egl/dummy.c
+++ b/src/gallium/targets/egl-vmwgfx/dummy.c
diff --git a/src/gallium/targets/graw-xlib/SConscript b/src/gallium/targets/graw-xlib/SConscript
new file mode 100644
index 00000000000..24cea92f907
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/SConscript
@@ -0,0 +1,57 @@
+#######################################################################
+# SConscript for xlib winsys
+
+Import('*')
+
+if env['platform'] != 'linux':
+ Return()
+
+if not set(('softpipe', 'llvmpipe', 'cell')).intersection(env['drivers']):
+ print 'warning: no supported pipe driver: skipping build of xlib libGL.so'
+ Return()
+
+env = env.Clone()
+
+env.Prepend(LIBS = [
+ ws_xlib,
+ trace,
+ identity,
+# gallium,
+])
+
+env.Append(CPPPATH = [
+ '#src/gallium/drivers',
+])
+
+
+sources = [
+ 'graw_xlib.c',
+]
+
+if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+ env.Prepend(LIBS = [softpipe])
+
+if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ env.Prepend(LIBS = [llvmpipe])
+
+# Need this for trace, identity drivers referenced by
+# gallium_wrap_screen().
+#
+env.Prepend(LIBS = [gallium])
+
+# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+graw = env.SharedLibrary(
+ target ='graw',
+ source = sources,
+)
+
+env.InstallSharedLibrary(graw, version=(1, 0))
+
+graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+
+Export('graw')
diff --git a/src/gallium/targets/graw-xlib/graw.h b/src/gallium/targets/graw-xlib/graw.h
new file mode 100644
index 00000000000..a58e18e4739
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/graw.h
@@ -0,0 +1,36 @@
+#ifndef GALLIUM_RAW_H
+#define GALLIUM_RAW_H
+
+/* This is an API for exercising gallium functionality in a
+ * platform-neutral fashion. Whatever platform integration is
+ * necessary to implement this interface is orchestrated by the
+ * individual target building this entity.
+ *
+ * For instance, the graw-xlib target includes code to implent these
+ * interfaces on top of the X window system.
+ *
+ * Programs using this interface may additionally benefit from some of
+ * the utilities currently in the libgallium.a library, especially
+ * those for parsing text representations of TGSI shaders.
+ */
+
+#include "pipe/p_format.h"
+
+struct pipe_screen;
+
+struct pipe_screen *graw_init( void );
+
+/* Returns a handle to be used with flush_frontbuffer()/present().
+ *
+ * Query format support with screen::is_format_supported and usage
+ * XXX.
+ */
+void *graw_create_window( int x,
+ int y,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format );
+
+void graw_destroy_window( void *handle );
+
+#endif
diff --git a/src/gallium/targets/graw-xlib/graw_xlib.c b/src/gallium/targets/graw-xlib/graw_xlib.c
new file mode 100644
index 00000000000..fb8ef9d78b6
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/graw_xlib.c
@@ -0,0 +1,181 @@
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "target-helpers/wrap_screen.h"
+#include "state_tracker/xlib_sw_winsys.h"
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+/* Haven't figured out a decent way to build the helper code yet -
+ * #include it here temporarily.
+ */
+#include "sw/sw_public.h"
+#include "sw/sw.c"
+
+#include "graw.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <stdio.h>
+
+static struct {
+ Display *display;
+} graw;
+
+
+struct pipe_screen *
+graw_init( void )
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+ struct sw_winsys *winsys = NULL;
+
+ graw.display = XOpenDisplay(NULL);
+ if (graw.display == NULL)
+ return NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( graw.display );
+ if (winsys == NULL)
+ return NULL;
+
+#if defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+#endif
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+}
+
+
+
+
+
+void *
+graw_create_window( int x,
+ int y,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format )
+{
+ struct xlib_drawable *handle = NULL;
+ XSetWindowAttributes attr;
+ Window root;
+ Window win = 0;
+ XVisualInfo templat, *visinfo = NULL;
+ unsigned mask;
+ int n;
+ int scrnum;
+
+
+ scrnum = DefaultScreen( graw.display );
+ root = RootWindow( graw.display, scrnum );
+
+
+ if (format != PIPE_FORMAT_R8G8B8A8_UNORM)
+ goto fail;
+
+ if (graw.display == NULL)
+ goto fail;
+
+ handle = CALLOC_STRUCT(xlib_drawable);
+ if (handle == NULL)
+ goto fail;
+
+
+ mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
+ templat.screen = DefaultScreen(graw.display);
+ templat.depth = 32;
+ templat.class = TrueColor;
+
+ visinfo = XGetVisualInfo(graw.display, mask, &templat, &n);
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ /* XXX this is a bad way to get a borderless window! */
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( graw.display, root, x, y, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+
+ /* set hints and properties */
+ {
+ char *name = NULL;
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(graw.display, win, &sizehints);
+ XSetStandardProperties(graw.display, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ XFree(visinfo);
+ XMapWindow(graw.display, win);
+ while (1) {
+ XEvent e;
+ XNextEvent( graw.display, &e );
+ if (e.type == MapNotify && e.xmap.window == win) {
+ break;
+ }
+ }
+
+ handle->visual = visinfo->visual;
+ handle->drawable = (Drawable)win;
+ handle->depth = visinfo->depth;
+ return (void *)handle;
+
+fail:
+ FREE(handle);
+ XFree(visinfo);
+
+ if (win)
+ XDestroyWindow(graw.display, win);
+
+ return NULL;
+}
+
+
+void
+graw_destroy_window( void *xlib_drawable )
+{
+}
+
diff --git a/src/gallium/targets/libgl-gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript
index 57704440ce7..21b4eb2abee 100644
--- a/src/gallium/targets/libgl-gdi/SConscript
+++ b/src/gallium/targets/libgl-gdi/SConscript
@@ -9,6 +9,7 @@ if env['platform'] == 'windows':
env.Append(CPPPATH = [
'#src/gallium/state_trackers/wgl',
+ '#src/gallium/winsys/sw',
])
env.Append(LIBS = [
diff --git a/src/gallium/targets/libgl-xlib/Makefile b/src/gallium/targets/libgl-xlib/Makefile
index 5a4e035c2eb..6cd00cad458 100644
--- a/src/gallium/targets/libgl-xlib/Makefile
+++ b/src/gallium/targets/libgl-xlib/Makefile
@@ -38,7 +38,7 @@ XLIB_TARGET_OBJECTS = $(XLIB_TARGET_SOURCES:.c=.o)
LIBS = \
$(GALLIUM_DRIVERS) \
$(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
- $(TOP)/src/gallium/winsys/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/mesa/libglapi.a \
diff --git a/src/gallium/targets/libgl-xlib/xlib.c b/src/gallium/targets/libgl-xlib/xlib.c
index 05dc8db57d9..48e5bdff429 100644
--- a/src/gallium/targets/libgl-xlib/xlib.c
+++ b/src/gallium/targets/libgl-xlib/xlib.c
@@ -31,21 +31,23 @@
* Keith Whitwell
*/
#include "pipe/p_compiler.h"
-#include "state_tracker/xlib_sw_winsys.h"
#include "util/u_debug.h"
-#include "softpipe/sp_public.h"
-#include "llvmpipe/lp_public.h"
-#include "cell/ppu/cell_public.h"
#include "target-helpers/wrap_screen.h"
+#include "state_tracker/xlib_sw_winsys.h"
#include "xm_public.h"
+#include "state_tracker/st_manager.h"
+
/* advertise OpenGL support */
PUBLIC const int st_api_OpenGL = 1;
+PUBLIC const struct st_module st_module_OpenGL = {
+ .api = ST_API_OPENGL,
+ .create_api = st_manager_create_api
+};
-/* Helper function to build a subset of a driver stack consisting of
- * one of the software rasterizers (cell, llvmpipe, softpipe) and the
- * xlib winsys.
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * cell, llvmpipe, softpipe.
*
* This function could be shared, but currently causes headaches for
* the build systems, particularly scons if we try. Long term, want
@@ -53,37 +55,85 @@ PUBLIC const int st_api_OpenGL = 1;
* GALLIUM_CELL, etc. Scons already eliminates those #defines, so
* things that are painful for it now are likely to be painful for
* other build systems in the future.
+ *
+ * Copies (full or partial):
+ * targets/libgl-xlib
+ * targets/graw-xlib
+ * targets/dri-swrast
+ * winsys/sw/drm
+ * drivers/sw
+ *
*/
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
static struct pipe_screen *
-swrast_xlib_create_screen( Display *display )
+swrast_create_screen(struct sw_winsys *winsys)
{
- struct sw_winsys *winsys;
+ const char *default_driver;
+ const char *driver;
struct pipe_screen *screen = NULL;
- /* Create the underlying winsys, which performs presents to Xlib
- * drawables:
- */
- winsys = xlib_create_sw_winsys( display );
- if (winsys == NULL)
- return NULL;
+#if defined(GALLIUM_CELL)
+ default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
- /* Create a software rasterizer on top of that winsys:
- */
#if defined(GALLIUM_CELL)
- if (screen == NULL &&
- !debug_get_bool_option("GALLIUM_NO_CELL", FALSE))
+ if (screen == NULL && strcmp(driver, "cell") == 0)
screen = cell_create_screen( winsys );
#endif
#if defined(GALLIUM_LLVMPIPE)
- if (screen == NULL &&
- !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
screen = llvmpipe_create_screen( winsys );
#endif
+#if defined(GALLIUM_SOFTPIPE)
if (screen == NULL)
screen = softpipe_create_screen( winsys );
+#endif
+ return screen;
+}
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ */
+static struct pipe_screen *
+swrast_xlib_create_screen( Display *display )
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( display );
+ if (winsys == NULL)
+ return NULL;
+
+ /* Create a software rasterizer on top of that winsys:
+ */
+ screen = swrast_create_screen( winsys );
if (screen == NULL)
goto fail;
@@ -98,9 +148,10 @@ fail:
return NULL;
}
-struct xm_driver xlib_driver =
+static struct xm_driver xlib_driver =
{
.create_pipe_screen = swrast_xlib_create_screen,
+ .create_st_api = st_manager_create_api,
};
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/targets/xorg-i915/Makefile
index 14c2462524b..52a9e97b409 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/targets/xorg-i915/Makefile
@@ -1,13 +1,13 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
TARGET = modesetting_drv.so
CFILES = $(wildcard ./*.c)
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
-TOP = ../../../../../..
-
-include $(TOP)/configs/current
INCLUDES = \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
- -I../gem \
+ -I$(TOP)/src/gallium/winsys/drm/intel/gem \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary \
@@ -17,7 +17,7 @@ INCLUDES = \
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
$(TOP)/src/gallium/drivers/i915/libi915.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
diff --git a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c b/src/gallium/targets/xorg-i915/intel_xorg.c
index 369dc356cf8..08f3b088636 100644
--- a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
+++ b/src/gallium/targets/xorg-i915/intel_xorg.c
@@ -28,7 +28,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void intel_xorg_identify(int flags);
static Bool intel_xorg_pci_probe(DriverPtr driver,
diff --git a/src/gallium/winsys/drm/i965/xorg/Makefile b/src/gallium/targets/xorg-i965/Makefile
index c25726b0bb1..104a1434a84 100644
--- a/src/gallium/winsys/drm/i965/xorg/Makefile
+++ b/src/gallium/targets/xorg-i965/Makefile
@@ -1,29 +1,23 @@
-TOP = ../../../../../..
-
-
-GALLIUMDIR = $(TOP)/src/gallium
+TOP = ../../../..
+include $(TOP)/configs/current
TARGET = i965g_drv.so
-
CFILES = $(wildcard ./*.c)
-
-include ${TOP}/configs/current
-
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
CFLAGS = -DHAVE_CONFIG_H \
-g -Wall -Wimplicit-function-declaration -fPIC \
$(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \
- -I${GALLIUMDIR}/include \
- -I${GALLIUMDIR}/drivers \
- -I${GALLIUMDIR}/auxiliary \
- -I${TOP}/src/mesa \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
$(TOP)/src/gallium/drivers/i965/libi965.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
@@ -34,7 +28,7 @@ TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
all default: $(TARGET) $(TARGET_STAGING)
-$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
diff --git a/src/gallium/winsys/drm/i965/xorg/intel_xorg.c b/src/gallium/targets/xorg-i965/intel_xorg.c
index ac691cb76b3..f4608f0eb41 100644
--- a/src/gallium/winsys/drm/i965/xorg/intel_xorg.c
+++ b/src/gallium/targets/xorg-i965/intel_xorg.c
@@ -28,7 +28,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void intel_xorg_identify(int flags);
static Bool intel_xorg_pci_probe(DriverPtr driver,
diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/targets/xorg-nouveau/Makefile
index f7f6fe17dd6..b514b570007 100644
--- a/src/gallium/winsys/drm/nouveau/xorg/Makefile
+++ b/src/gallium/targets/xorg-nouveau/Makefile
@@ -1,13 +1,12 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
TARGET = modesetting_drv.so
CFILES = $(wildcard ./*.c)
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
-TOP = ../../../../../..
-
-include $(TOP)/configs/current
INCLUDES = \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
- -I../gem \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary \
@@ -17,7 +16,7 @@ INCLUDES = \
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
$(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
diff --git a/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
index a669b3080aa..699af09029f 100644
--- a/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c
+++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
@@ -28,7 +28,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void nouveau_xorg_identify(int flags);
static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
diff --git a/src/gallium/winsys/drm/radeon/xorg/Makefile b/src/gallium/targets/xorg-radeon/Makefile
index 0eb1b3988f3..cd32914c0d3 100644
--- a/src/gallium/winsys/drm/radeon/xorg/Makefile
+++ b/src/gallium/targets/xorg-radeon/Makefile
@@ -1,29 +1,23 @@
-TOP = ../../../../../..
-
-
-GALLIUMDIR = $(TOP)/src/gallium
+TOP = ../../../..
+include $(TOP)/configs/current
TARGET = radeong_drv.so
-
CFILES = $(wildcard ./*.c)
-
-include ${TOP}/configs/current
-
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
CFLAGS = -DHAVE_CONFIG_H \
-g -Wall -Wimplicit-function-declaration -fPIC \
$(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \
- -I${GALLIUMDIR}/include \
- -I${GALLIUMDIR}/drivers \
- -I${GALLIUMDIR}/auxiliary \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
-I${TOP}/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
LIBS = \
- $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \
- $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \
+ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/r300/libr300.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
@@ -34,7 +28,7 @@ TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
all default: $(TARGET) $(TARGET_STAGING)
-$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_radeon
diff --git a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c b/src/gallium/targets/xorg-radeon/radeon_xorg.c
index bb76cc03499..0d6aa567229 100644
--- a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
+++ b/src/gallium/targets/xorg-radeon/radeon_xorg.c
@@ -29,7 +29,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void radeon_xorg_identify(int flags);
static Bool radeon_xorg_pci_probe(DriverPtr driver,
diff --git a/src/gallium/winsys/drm/vmware/xorg/Makefile b/src/gallium/targets/xorg-vmwgfx/Makefile
index 49e28ae17f5..12bc307ef9b 100644
--- a/src/gallium/winsys/drm/vmware/xorg/Makefile
+++ b/src/gallium/targets/xorg-vmwgfx/Makefile
@@ -1,5 +1,4 @@
-TOP = ../../../../../..
-
+TOP = ../../../..
include $(TOP)/configs/current
TARGET = vmwgfx_drv.so
@@ -21,7 +20,7 @@ INCLUDES = \
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/drm/vmware/xorg/SConscript b/src/gallium/targets/xorg-vmwgfx/SConscript
index 1e5d8ff7fed..b63ab99e050 100644
--- a/src/gallium/winsys/drm/vmware/xorg/SConscript
+++ b/src/gallium/targets/xorg-vmwgfx/SConscript
@@ -2,6 +2,10 @@ import os.path
Import('*')
+if not 'svga' in env['drivers']:
+ print 'warning: svga pipe driver not built skipping vmwgfx_drv.so'
+ Return()
+
if env['platform'] == 'linux':
env = env.Clone()
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h b/src/gallium/targets/xorg-vmwgfx/vmw_driver.h
index ba754b51e47..ba754b51e47 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_driver.h
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h b/src/gallium/targets/xorg-vmwgfx/vmw_hook.h
index 224a2d92996..224a2d92996 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_hook.h
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c b/src/gallium/targets/xorg-vmwgfx/vmw_ioctl.c
index 521578ab35d..96ee4ff82b4 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_ioctl.c
@@ -42,7 +42,7 @@
#include <sys/mman.h>
#include "xf86drm.h"
-#include "../core/vmwgfx_drm.h"
+#include "../../winsys/svga/drm/vmwgfx_drm.h"
#include "vmw_driver.h"
#include "util/u_debug.h"
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
index f43f91e5c0d..f43f91e5c0d 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/targets/xorg-vmwgfx/vmw_video.c
index de28f06a475..eced60d0ec1 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_video.c
@@ -62,7 +62,7 @@ typedef uint8_t uint8;
#include <X11/extensions/Xv.h>
#include "xf86drm.h"
-#include "../core/vmwgfx_drm.h"
+#include "../../winsys/svga/drm/vmwgfx_drm.h"
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c b/src/gallium/targets/xorg-vmwgfx/vmw_xorg.c
index 87aad25b24f..87aad25b24f 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_xorg.c
diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript
index 30c3378dfff..2013ee97c1c 100644
--- a/src/gallium/winsys/SConscript
+++ b/src/gallium/winsys/SConscript
@@ -1,16 +1,36 @@
Import('*')
-if env['dri']:
- SConscript([
- 'drm/SConscript',
- ])
-
if 'xlib' in env['winsys']:
SConscript([
- 'xlib/SConscript',
+ 'sw/xlib/SConscript',
])
if 'gdi' in env['winsys']:
SConscript([
- 'gdi/SConscript',
+ 'sw/gdi/SConscript',
])
+
+if env['dri']:
+ SConscript([
+ 'sw/dri/SConscript',
+ ])
+
+ if 'vmware' in env['winsys']:
+ SConscript([
+ 'svga/drm/SConscript',
+ ])
+
+ if 'i915' in env['winsys']:
+ SConscript([
+ 'i915/drm/SConscript',
+ ])
+
+ if 'i965' in env['winsys']:
+ SConscript([
+ 'i965/drm/SConscript',
+ ])
+
+ if 'radeon' in env['winsys']:
+ SConscript([
+ 'radeon/drm/SConscript',
+ ])
diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript
deleted file mode 100644
index 66b73a8bf93..00000000000
--- a/src/gallium/winsys/drm/SConscript
+++ /dev/null
@@ -1,69 +0,0 @@
-Import('*')
-
-if env['dri']:
-
- drienv = env.Clone()
-
- drienv.Replace(CPPPATH = [
- '#src/mesa/drivers/dri/common',
- '#include',
- '#include/GL/internal',
- '#src/gallium/include',
- '#src/gallium/auxiliary',
- '#src/gallium/drivers',
- '#src/mesa',
- '#src/mesa/main',
- '#src/mesa/glapi',
- '#src/mesa/math',
- '#src/mesa/transform',
- '#src/mesa/shader',
- '#src/mesa/swrast',
- '#src/mesa/swrast_setup',
- '#src/egl/main',
- '#src/egl/drivers/dri',
- ])
-
- drienv.ParseConfig('pkg-config --cflags --libs libdrm')
-
- COMMON_GALLIUM_SOURCES = [
- '#src/mesa/drivers/dri/common/utils.c',
- '#src/mesa/drivers/dri/common/vblank.c',
- '#src/mesa/drivers/dri/common/dri_util.c',
- '#src/mesa/drivers/dri/common/xmlconfig.c',
- ]
-
- COMMON_BM_SOURCES = [
- '#src/mesa/drivers/dri/common/dri_bufmgr.c',
- '#src/mesa/drivers/dri/common/dri_drmpool.c',
- ]
-
- Export([
- 'drienv',
- 'COMMON_GALLIUM_SOURCES',
- 'COMMON_BM_SOURCES',
- ])
-
- # TODO: Installation
- #install: $(LIBNAME)
- # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
- # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
-
- if 'vmware' in env['winsys']:
- SConscript([
- 'vmware/SConscript',
- ])
-
- if 'intel' in env['winsys']:
- SConscript([
- 'intel/SConscript',
- ])
-
- if 'i965' in env['winsys']:
- SConscript([
- 'i965/SConscript',
- ])
-
- if 'radeon' in env['winsys']:
- SConscript([
- 'radeon/SConscript',
- ])
diff --git a/src/gallium/winsys/drm/i965/Makefile b/src/gallium/winsys/drm/i965/Makefile
deleted file mode 100644
index d8feef6824a..00000000000
--- a/src/gallium/winsys/drm/i965/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/intel/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = gem $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/i965/SConscript b/src/gallium/winsys/drm/i965/SConscript
deleted file mode 100644
index 50d7b75ed68..00000000000
--- a/src/gallium/winsys/drm/i965/SConscript
+++ /dev/null
@@ -1,7 +0,0 @@
-Import('*')
-
-SConscript(['gem/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/i965/dri/SConscript b/src/gallium/winsys/drm/i965/dri/SConscript
deleted file mode 100644
index a99533fd245..00000000000
--- a/src/gallium/winsys/drm/i965/dri/SConscript
+++ /dev/null
@@ -1,19 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
-
-drivers = [
- st_dri,
- i965drm,
- i965,
- trace,
-]
-
-env.LoadableModule(
- target ='i965_dri.so',
- source = COMMON_GALLIUM_SOURCES,
- LIBS = drivers + mesa + gallium + env['LIBS'],
- SHLIBPREFIX = '',
-)
diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile
deleted file mode 100644
index 1c132582005..00000000000
--- a/src/gallium/winsys/drm/i965/egl/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = i965
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_intel
-
-EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
- $(TOP)/src/gallium/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/i965/libi965.a
-
-include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/intel/Makefile b/src/gallium/winsys/drm/intel/Makefile
deleted file mode 100644
index d8feef6824a..00000000000
--- a/src/gallium/winsys/drm/intel/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/intel/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = gem $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/intel/SConscript b/src/gallium/winsys/drm/intel/SConscript
deleted file mode 100644
index 50d7b75ed68..00000000000
--- a/src/gallium/winsys/drm/intel/SConscript
+++ /dev/null
@@ -1,7 +0,0 @@
-Import('*')
-
-SConscript(['gem/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
deleted file mode 100644
index 0df841d8798..00000000000
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ /dev/null
@@ -1,21 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
-
-env.Prepend(LIBS = [
- st_dri,
- inteldrm,
- i915,
- trace,
- mesa,
- glsl,
- gallium
-])
-
-env.LoadableModule(
- target ='i915_dri.so',
- source = COMMON_GALLIUM_SOURCES,
- SHLIBPREFIX = '',
-)
diff --git a/src/gallium/winsys/drm/intel/gem/SConscript b/src/gallium/winsys/drm/intel/gem/SConscript
deleted file mode 100644
index 26717f391fa..00000000000
--- a/src/gallium/winsys/drm/intel/gem/SConscript
+++ /dev/null
@@ -1,17 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-inteldrm_sources = [
- 'intel_drm_api.c',
- 'intel_drm_batchbuffer.c',
- 'intel_drm_buffer.c',
- 'intel_drm_fence.c',
-]
-
-inteldrm = env.ConvenienceLibrary(
- target ='inteldrm',
- source = inteldrm_sources,
-)
-
-Export('inteldrm')
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
deleted file mode 100644
index 9786ee93650..00000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
+++ /dev/null
@@ -1,77 +0,0 @@
-
-#ifndef INTEL_DRM_WINSYS_H
-#define INTEL_DRM_WINSYS_H
-
-#include "i915/intel_batchbuffer.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-
-/*
- * Winsys
- */
-
-
-struct intel_drm_winsys
-{
- struct intel_winsys base;
-
- boolean dump_cmd;
-
- int fd; /**< Drm file discriptor */
-
- unsigned id;
-
- size_t max_batch_size;
-
- struct {
- drm_intel_bufmgr *gem;
- } pools;
-};
-
-static INLINE struct intel_drm_winsys *
-intel_drm_winsys(struct intel_winsys *iws)
-{
- return (struct intel_drm_winsys *)iws;
-}
-
-struct intel_drm_winsys * intel_drm_winsys_create(int fd, unsigned pci_id);
-struct pipe_fence_handle * intel_drm_fence_create(drm_intel_bo *bo);
-
-void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws);
-void intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws);
-void intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws);
-
-
-/*
- * Buffer
- */
-
-
-struct intel_drm_buffer {
- unsigned magic;
-
- drm_intel_bo *bo;
-
- void *ptr;
- unsigned map_count;
- boolean map_gtt;
-
- boolean flinked;
- unsigned flink;
-};
-
-static INLINE struct intel_drm_buffer *
-intel_drm_buffer(struct intel_buffer *buffer)
-{
- return (struct intel_drm_buffer *)buffer;
-}
-
-static INLINE drm_intel_bo *
-intel_bo(struct intel_buffer *buffer)
-{
- return intel_drm_buffer(buffer)->bo;
-}
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile
deleted file mode 100644
index 6c9cbef26df..00000000000
--- a/src/gallium/winsys/drm/nouveau/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/nouveau/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = drm $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/radeon/Makefile b/src/gallium/winsys/drm/radeon/Makefile
deleted file mode 100644
index bacdf3de28a..00000000000
--- a/src/gallium/winsys/drm/radeon/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/radeon/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript
deleted file mode 100644
index b2dfd504d42..00000000000
--- a/src/gallium/winsys/drm/radeon/SConscript
+++ /dev/null
@@ -1,7 +0,0 @@
-Import('*')
-
-SConscript(['core/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
deleted file mode 100644
index 25b58b2926c..00000000000
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright © 2008 Jérôme Glisse
- * 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:
- * Jérôme Glisse <[email protected]>
- * Corbin Simpson <[email protected]>
- */
-
-#include "radeon_buffer.h"
-#include "radeon_drm.h"
-
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "radeon_bo_gem.h"
-#include <X11/Xutil.h>
-
-struct radeon_vl_context
-{
- Display *display;
- int screen;
- Drawable drawable;
-};
-
-static const char *radeon_get_name(struct pipe_winsys *ws)
-{
- return "Radeon/GEM+KMS";
-}
-
-static uint32_t radeon_domain_from_usage(unsigned usage)
-{
- uint32_t domain = 0;
-
- if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BUFFER_USAGE_PIXEL) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BUFFER_USAGE_VERTEX) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
- if (usage & PIPE_BUFFER_USAGE_INDEX) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
-
- return domain;
-}
-
-static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct radeon_winsys *radeon_ws = (struct radeon_winsys *)ws;
- struct radeon_pipe_buffer *radeon_buffer;
- struct pb_desc desc;
- uint32_t domain;
-
- radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
- if (radeon_buffer == NULL) {
- return NULL;
- }
-
- pipe_reference_init(&radeon_buffer->base.reference, 1);
- radeon_buffer->base.alignment = alignment;
- radeon_buffer->base.usage = usage;
- radeon_buffer->base.size = size;
-
- if (usage & PIPE_BUFFER_USAGE_CONSTANT && is_r3xx(radeon_ws->pci_id)) {
- /* Don't bother allocating a BO, as it'll never get to the card. */
- desc.alignment = alignment;
- desc.usage = usage;
- radeon_buffer->pb = pb_malloc_buffer_create(size, &desc);
- return &radeon_buffer->base;
- }
-
- domain = radeon_domain_from_usage(usage);
-
- radeon_buffer->bo = radeon_bo_open(radeon_ws->priv->bom, 0, size,
- alignment, domain, 0);
- if (radeon_buffer->bo == NULL) {
- FREE(radeon_buffer);
- return NULL;
- }
- return &radeon_buffer->base;
-}
-
-static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
- void *ptr,
- unsigned bytes)
-{
- struct radeon_pipe_buffer *radeon_buffer;
-
- radeon_buffer =
- (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes);
- if (radeon_buffer == NULL) {
- return NULL;
- }
- radeon_bo_map(radeon_buffer->bo, 1);
- memcpy(radeon_buffer->bo->ptr, ptr, bytes);
- radeon_bo_unmap(radeon_buffer->bo);
- return &radeon_buffer->base;
-}
-
-static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
- unsigned width,
- unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- /* Radeons enjoy things in multiples of 32. */
- /* XXX this can be 32 when POT */
- const unsigned alignment = 64;
- unsigned nblocksy, size;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
- size = *stride * nblocksy;
-
- return radeon_buffer_create(ws, 64, usage, size);
-}
-
-static void radeon_buffer_del(struct pipe_buffer *buffer)
-{
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
-
- if (radeon_buffer->pb) {
- pipe_reference_init(&radeon_buffer->pb->base.reference, 0);
- pb_destroy(radeon_buffer->pb);
- }
-
- if (radeon_buffer->bo) {
- radeon_bo_unref(radeon_buffer->bo);
- }
-
- FREE(radeon_buffer);
-}
-
-static void *radeon_buffer_map(struct pipe_winsys *ws,
- struct pipe_buffer *buffer,
- unsigned flags)
-{
- struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv;
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- int write = 0;
-
- if (radeon_buffer->pb) {
- return pb_map(radeon_buffer->pb, flags);
- }
-
- if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
- uint32_t domain;
-
- if (radeon_bo_is_busy(radeon_buffer->bo, &domain))
- return NULL;
- }
-
- if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
- priv->flush_cb(priv->flush_data);
- }
-
- if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
- write = 1;
- }
-
- if (radeon_bo_map(radeon_buffer->bo, write)) {
- return NULL;
- }
-
- return radeon_buffer->bo->ptr;
-}
-
-static void radeon_buffer_unmap(struct pipe_winsys *ws,
- struct pipe_buffer *buffer)
-{
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
-
- if (radeon_buffer->pb) {
- pb_unmap(radeon_buffer->pb);
- } else {
- radeon_bo_unmap(radeon_buffer->bo);
- }
-}
-
-static boolean radeon_is_buffer_referenced(struct radeon_winsys *ws,
- struct pipe_buffer *buffer)
-{
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- uint32_t domain;
-
- /* Referenced by CS or HW. */
- return radeon_bo_is_referenced_by_cs(radeon_buffer->bo, ws->priv->cs) ||
- radeon_bo_is_busy(radeon_buffer->bo, &domain);
-}
-
-static void radeon_buffer_set_tiling(struct radeon_winsys *ws,
- struct pipe_buffer *buffer,
- uint32_t pitch,
- boolean microtiled,
- boolean macrotiled)
-{
- struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv;
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- uint32_t flags = 0, old_flags, old_pitch;
-
- if (microtiled) {
- flags |= RADEON_BO_FLAGS_MICRO_TILE;
- }
- if (macrotiled) {
- flags |= RADEON_BO_FLAGS_MACRO_TILE;
- }
-
- radeon_bo_get_tiling(radeon_buffer->bo, &old_flags, &old_pitch);
-
- if (flags != old_flags || pitch != old_pitch) {
- /* Tiling determines how DRM treats the buffer data.
- * We must flush CS when changing it if the buffer is referenced. */
- if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
- priv->flush_cb(priv->flush_data);
- }
-
- radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch);
- }
-}
-
-static void radeon_fence_reference(struct pipe_winsys *ws,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *pfence)
-{
-}
-
-static int radeon_fence_signalled(struct pipe_winsys *ws,
- struct pipe_fence_handle *pfence,
- unsigned flag)
-{
- return 1;
-}
-
-static int radeon_fence_finish(struct pipe_winsys *ws,
- struct pipe_fence_handle *pfence,
- unsigned flag)
-{
- return 0;
-}
-
-/* Create a buffer from a handle. */
-static struct pipe_buffer* radeon_buffer_from_handle(struct radeon_winsys *radeon_ws,
- struct pipe_screen *screen,
- struct winsys_handle *whandle,
- unsigned *stride)
-{
- struct radeon_bo_manager* bom = radeon_ws->priv->bom;
- struct radeon_pipe_buffer* radeon_buffer;
- struct radeon_bo* bo = NULL;
-
- bo = radeon_bo_open(bom, whandle->handle, 0, 0, 0, 0);
- if (bo == NULL) {
- return NULL;
- }
-
- radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
- if (radeon_buffer == NULL) {
- radeon_bo_unref(bo);
- return NULL;
- }
-
- pipe_reference_init(&radeon_buffer->base.reference, 1);
- radeon_buffer->base.screen = screen;
- radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
- radeon_buffer->bo = bo;
-
- *stride = whandle->stride;
-
- return &radeon_buffer->base;
-}
-
-static boolean radeon_buffer_get_handle(struct radeon_winsys *radeon_ws,
- struct pipe_buffer *buffer,
- unsigned stride,
- struct winsys_handle *whandle)
-{
- int retval, fd;
- struct drm_gem_flink flink;
- struct radeon_pipe_buffer* radeon_buffer;
-
- radeon_buffer = (struct radeon_pipe_buffer*)buffer;
-
-
- if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
- if (!radeon_buffer->flinked) {
- fd = radeon_ws->priv->fd;
-
- flink.handle = radeon_buffer->bo->handle;
-
- retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
- if (retval) {
- debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
- retval);
- return FALSE;
- }
-
- radeon_buffer->flink = flink.name;
- radeon_buffer->flinked = TRUE;
- }
-
- whandle->handle = radeon_buffer->flink;
- } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
- whandle->handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
- }
- whandle->stride = stride;
-
- return TRUE;
-}
-
-struct radeon_winsys* radeon_pipe_winsys(int fd)
-{
- struct radeon_winsys* radeon_ws;
-
- radeon_ws = CALLOC_STRUCT(radeon_winsys);
- if (radeon_ws == NULL) {
- return NULL;
- }
-
- radeon_ws->priv = CALLOC_STRUCT(radeon_winsys_priv);
- if (radeon_ws->priv == NULL) {
- FREE(radeon_ws);
- return NULL;
- }
-
- radeon_ws->priv->fd = fd;
- radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd);
-
- radeon_ws->base.flush_frontbuffer = NULL; /* overriden by co-state tracker */
-
- radeon_ws->base.buffer_create = radeon_buffer_create;
- radeon_ws->base.user_buffer_create = radeon_buffer_user_create;
- radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create;
- radeon_ws->base.buffer_map = radeon_buffer_map;
- radeon_ws->base.buffer_unmap = radeon_buffer_unmap;
- radeon_ws->base.buffer_destroy = radeon_buffer_del;
-
- radeon_ws->base.fence_reference = radeon_fence_reference;
- radeon_ws->base.fence_signalled = radeon_fence_signalled;
- radeon_ws->base.fence_finish = radeon_fence_finish;
-
- radeon_ws->base.get_name = radeon_get_name;
-
- radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling;
- radeon_ws->buffer_from_handle = radeon_buffer_from_handle;
- radeon_ws->buffer_get_handle = radeon_buffer_get_handle;
-
- radeon_ws->is_buffer_referenced = radeon_is_buffer_referenced;
-
- return radeon_ws;
-}
diff --git a/src/gallium/winsys/drm/radeon/dri/SConscript b/src/gallium/winsys/drm/radeon/dri/SConscript
deleted file mode 100644
index c4989d1b595..00000000000
--- a/src/gallium/winsys/drm/radeon/dri/SConscript
+++ /dev/null
@@ -1,17 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
-
-drivers = [
- trace,
- softpipe,
- r300
-]
-
-env.SharedLibrary(
- target ='radeon_dri.so',
- source = COMMON_GALLIUM_SOURCES,
- LIBS = st_dri + radeonwinsys + mesa + drivers + gallium + env['LIBS'],
-)
diff --git a/src/gallium/winsys/drm/swrast/Makefile b/src/gallium/winsys/drm/swrast/Makefile
deleted file mode 100644
index 363b89584f2..00000000000
--- a/src/gallium/winsys/drm/swrast/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/swrast/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/swrast/core/Makefile b/src/gallium/winsys/drm/swrast/core/Makefile
deleted file mode 100644
index 93931ae22b9..00000000000
--- a/src/gallium/winsys/drm/swrast/core/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# src/gallium/winsys/drm/swrast/core/Makefile
-
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = swrastdrm
-
-C_SOURCES = swrast_drm_api.c
-
-include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/swrast/egl/Makefile b/src/gallium/winsys/drm/swrast/egl/Makefile
deleted file mode 100644
index 26fe2d2805a..00000000000
--- a/src/gallium/winsys/drm/swrast/egl/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = swrast
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS =
-
-EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/swrast/core/libswrastdrm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
-
-include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/vmware/Makefile b/src/gallium/winsys/drm/vmware/Makefile
deleted file mode 100644
index 2ae6dead5c1..00000000000
--- a/src/gallium/winsys/drm/vmware/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/vmware/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/vmware/SConscript b/src/gallium/winsys/drm/vmware/SConscript
deleted file mode 100644
index 06e6d5be9ca..00000000000
--- a/src/gallium/winsys/drm/vmware/SConscript
+++ /dev/null
@@ -1,11 +0,0 @@
-Import('*')
-
-SConscript(['core/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
-
-if 'xorg' in env['statetrackers']:
-
- SConscript(['xorg/SConscript'])
diff --git a/src/gallium/winsys/drm/vmware/dri/SConscript b/src/gallium/winsys/drm/vmware/dri/SConscript
deleted file mode 100644
index d26d0cd7483..00000000000
--- a/src/gallium/winsys/drm/vmware/dri/SConscript
+++ /dev/null
@@ -1,63 +0,0 @@
-import os
-import os.path
-
-Import('*')
-
-if env['platform'] == 'linux':
-
- if env['dri']:
- env = env.Clone()
-
- sources = [
- '#/src/mesa/drivers/dri/common/utils.c',
- '#/src/mesa/drivers/dri/common/vblank.c',
- '#/src/mesa/drivers/dri/common/dri_util.c',
- '#/src/mesa/drivers/dri/common/xmlconfig.c',
- ]
-
-
- env.ParseConfig('pkg-config --cflags --libs libdrm')
-
- env.Prepend(CPPPATH = [
- '#/src/mesa/state_tracker',
- '#/src/mesa/drivers/dri/common',
- '#/src/mesa/main',
- '#/src/mesa/glapi',
- '#/src/mesa',
- '#/include',
- '#/src/gallium/drivers/svga',
- '#/src/gallium/drivers/svga/include',
- ])
-
- env.Append(CPPDEFINES = [
- 'HAVE_STDINT_H',
- 'HAVE_SYS_TYPES_H',
- ])
-
- env.Append(CFLAGS = [
- '-std=gnu99',
- '-D_FILE_OFFSET_BITS=64',
- ])
-
- env.Prepend(LIBPATH = [
- ])
-
- env.Prepend(LIBS = [
- trace,
- st_dri,
- svgadrm,
- svga,
- mesa,
- glsl,
- gallium,
- ])
-
- # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
- env.LoadableModule(
- target ='vmwgfx_dri.so',
- source = sources,
- LIBS = env['LIBS'],
- SHLIBPREFIX = '',
- )
-
-
diff --git a/src/gallium/winsys/drm/vmware/egl/dummy.c b/src/gallium/winsys/drm/vmware/egl/dummy.c
deleted file mode 100644
index 3181d0ba7e8..00000000000
--- a/src/gallium/winsys/drm/vmware/egl/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/i915/drm/Makefile
index 0d6d4e37dbd..a67b9e8a528 100644
--- a/src/gallium/winsys/drm/intel/gem/Makefile
+++ b/src/gallium/winsys/i915/drm/Makefile
@@ -1,16 +1,16 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
-LIBNAME = inteldrm
+LIBNAME = i915drm
C_SOURCES = \
- intel_drm_batchbuffer.c \
- intel_drm_buffer.c \
- intel_drm_fence.c \
- intel_drm_api.c
+ i915_drm_batchbuffer.c \
+ i915_drm_buffer.c \
+ i915_drm_fence.c \
+ i915_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/i915/drm/SConscript b/src/gallium/winsys/i915/drm/SConscript
new file mode 100644
index 00000000000..ba29ac72fe7
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/SConscript
@@ -0,0 +1,17 @@
+Import('*')
+
+env = env.Clone()
+
+i915drm_sources = [
+ 'i915_drm_api.c',
+ 'i915_drm_batchbuffer.c',
+ 'i915_drm_buffer.c',
+ 'i915_drm_fence.c',
+]
+
+i915drm = env.ConvenienceLibrary(
+ target ='i915drm',
+ source = i915drm_sources,
+)
+
+Export('i915drm')
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/i915/drm/i915_drm_api.c
index e3b980a832b..6bb0aec1a67 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_api.c
@@ -2,7 +2,7 @@
#include "state_tracker/drm_api.h"
-#include "intel_drm_winsys.h"
+#include "i915_drm_winsys.h"
#include "util/u_memory.h"
#include "i915/i915_context.h"
@@ -16,7 +16,7 @@
static void
-intel_drm_get_device_id(unsigned int *device_id)
+i915_drm_get_device_id(unsigned int *device_id)
{
char path[512];
FILE *file;
@@ -39,9 +39,9 @@ intel_drm_get_device_id(unsigned int *device_id)
}
static void
-intel_drm_winsys_destroy(struct intel_winsys *iws)
+i915_drm_winsys_destroy(struct i915_winsys *iws)
{
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
drm_intel_bufmgr_destroy(idws->pools.gem);
@@ -49,10 +49,10 @@ intel_drm_winsys_destroy(struct intel_winsys *iws)
}
static struct pipe_screen *
-intel_drm_create_screen(struct drm_api *api, int drmFD,
- struct drm_create_screen_arg *arg)
+i915_drm_create_screen(struct drm_api *api, int drmFD,
+ struct drm_create_screen_arg *arg)
{
- struct intel_drm_winsys *idws;
+ struct i915_drm_winsys *idws;
unsigned int deviceID;
if (arg != NULL) {
@@ -64,21 +64,21 @@ intel_drm_create_screen(struct drm_api *api, int drmFD,
}
}
- idws = CALLOC_STRUCT(intel_drm_winsys);
+ idws = CALLOC_STRUCT(i915_drm_winsys);
if (!idws)
return NULL;
- intel_drm_get_device_id(&deviceID);
+ i915_drm_get_device_id(&deviceID);
- intel_drm_winsys_init_batchbuffer_functions(idws);
- intel_drm_winsys_init_buffer_functions(idws);
- intel_drm_winsys_init_fence_functions(idws);
+ i915_drm_winsys_init_batchbuffer_functions(idws);
+ i915_drm_winsys_init_buffer_functions(idws);
+ i915_drm_winsys_init_fence_functions(idws);
idws->fd = drmFD;
idws->id = deviceID;
idws->max_batch_size = 16 * 4096;
- idws->base.destroy = intel_drm_winsys_destroy;
+ idws->base.destroy = i915_drm_winsys_destroy;
idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem);
@@ -98,7 +98,7 @@ struct drm_api intel_drm_api =
{
.name = "i915",
.driver_name = "i915",
- .create_screen = intel_drm_create_screen,
+ .create_screen = i915_drm_create_screen,
.destroy = destroy,
};
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
index 5b4dafc8e41..102f59dc541 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
@@ -1,5 +1,5 @@
-#include "intel_drm_winsys.h"
+#include "i915_drm_winsys.h"
#include "util/u_memory.h"
#include "i915_drm.h"
@@ -17,25 +17,25 @@
#undef INTEL_MAP_GTT
#define INTEL_ALWAYS_FLUSH
-struct intel_drm_batchbuffer
+struct i915_drm_batchbuffer
{
- struct intel_batchbuffer base;
+ struct i915_winsys_batchbuffer base;
size_t actual_size;
drm_intel_bo *bo;
};
-static INLINE struct intel_drm_batchbuffer *
-intel_drm_batchbuffer(struct intel_batchbuffer *batch)
+static INLINE struct i915_drm_batchbuffer *
+i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
{
- return (struct intel_drm_batchbuffer *)batch;
+ return (struct i915_drm_batchbuffer *)batch;
}
static void
-intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch)
+i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
{
- struct intel_drm_winsys *idws = intel_drm_winsys(batch->base.iws);
+ struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
int ret;
if (batch->bo)
@@ -63,11 +63,11 @@ intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch)
batch->base.relocs = 0;
}
-static struct intel_batchbuffer *
-intel_drm_batchbuffer_create(struct intel_winsys *iws)
+static struct i915_winsys_batchbuffer *
+i915_drm_batchbuffer_create(struct i915_winsys *iws)
{
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
- struct intel_drm_batchbuffer *batch = CALLOC_STRUCT(intel_drm_batchbuffer);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ struct i915_drm_batchbuffer *batch = CALLOC_STRUCT(i915_drm_batchbuffer);
batch->actual_size = idws->max_batch_size;
@@ -84,18 +84,18 @@ intel_drm_batchbuffer_create(struct intel_winsys *iws)
batch->base.iws = iws;
- intel_drm_batchbuffer_reset(batch);
+ i915_drm_batchbuffer_reset(batch);
return &batch->base;
}
static int
-intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
- struct intel_buffer *buffer,
- enum intel_buffer_usage usage,
+i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
+ struct i915_winsys_buffer *buffer,
+ enum i915_winsys_buffer_usage usage,
unsigned pre_add)
{
- struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
unsigned write_domain = 0;
unsigned read_domain = 0;
unsigned offset;
@@ -103,23 +103,23 @@ intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
assert(batch->base.relocs < batch->base.max_relocs);
- if (usage == INTEL_USAGE_SAMPLER) {
+ if (usage == I915_USAGE_SAMPLER) {
write_domain = 0;
read_domain = I915_GEM_DOMAIN_SAMPLER;
- } else if (usage == INTEL_USAGE_RENDER) {
+ } else if (usage == I915_USAGE_RENDER) {
write_domain = I915_GEM_DOMAIN_RENDER;
read_domain = I915_GEM_DOMAIN_RENDER;
- } else if (usage == INTEL_USAGE_2D_TARGET) {
+ } else if (usage == I915_USAGE_2D_TARGET) {
write_domain = I915_GEM_DOMAIN_RENDER;
read_domain = I915_GEM_DOMAIN_RENDER;
- } else if (usage == INTEL_USAGE_2D_SOURCE) {
+ } else if (usage == I915_USAGE_2D_SOURCE) {
write_domain = 0;
read_domain = I915_GEM_DOMAIN_RENDER;
- } else if (usage == INTEL_USAGE_VERTEX) {
+ } else if (usage == I915_USAGE_VERTEX) {
write_domain = 0;
read_domain = I915_GEM_DOMAIN_VERTEX;
@@ -145,15 +145,15 @@ intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
}
static void
-intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
+i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
struct pipe_fence_handle **fence)
{
- struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
unsigned used = 0;
int ret = 0;
int i;
- assert(intel_batchbuffer_space(ibatch) >= 0);
+ assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
used = batch->base.ptr - batch->base.map;
assert((used & 3) == 0);
@@ -161,16 +161,16 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
#ifdef INTEL_ALWAYS_FLUSH
/* MI_FLUSH | FLUSH_MAP_CACHE */
- intel_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
+ i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
used += 4;
#endif
if ((used & 4) == 0) {
/* MI_NOOP */
- intel_batchbuffer_dword(ibatch, 0);
+ i915_winsys_batchbuffer_dword(ibatch, 0);
}
/* MI_BATCH_BUFFER_END */
- intel_batchbuffer_dword(ibatch, (0xA<<23));
+ i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
used = batch->base.ptr - batch->base.map;
assert((used & 4) == 0);
@@ -189,7 +189,7 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
assert(ret == 0);
- if (intel_drm_winsys(ibatch->iws)->dump_cmd) {
+ if (i915_drm_winsys(ibatch->iws)->dump_cmd) {
unsigned *ptr;
drm_intel_bo_map(batch->bo, FALSE);
ptr = (unsigned*)batch->bo->virtual;
@@ -212,19 +212,19 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
#ifdef INTEL_RUN_SYNC
/* we run synced to GPU so just pass null */
- (*fence) = intel_drm_fence_create(NULL);
+ (*fence) = i915_drm_fence_create(NULL);
#else
- (*fence) = intel_drm_fence_create(batch->bo);
+ (*fence) = i915_drm_fence_create(batch->bo);
#endif
}
- intel_drm_batchbuffer_reset(batch);
+ i915_drm_batchbuffer_reset(batch);
}
static void
-intel_drm_batchbuffer_destroy(struct intel_batchbuffer *ibatch)
+i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
{
- struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
@@ -235,10 +235,10 @@ intel_drm_batchbuffer_destroy(struct intel_batchbuffer *ibatch)
FREE(batch);
}
-void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws)
+void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
{
- idws->base.batchbuffer_create = intel_drm_batchbuffer_create;
- idws->base.batchbuffer_reloc = intel_drm_batchbuffer_reloc;
- idws->base.batchbuffer_flush = intel_drm_batchbuffer_flush;
- idws->base.batchbuffer_destroy = intel_drm_batchbuffer_destroy;
+ idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
+ idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
+ idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
+ idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
index cb4f92a3b17..3bd85026b21 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
@@ -1,17 +1,17 @@
#include "state_tracker/drm_api.h"
-#include "intel_drm_winsys.h"
+#include "i915_drm_winsys.h"
#include "util/u_memory.h"
#include "i915_drm.h"
-static struct intel_buffer *
-intel_drm_buffer_create(struct intel_winsys *iws,
+static struct i915_winsys_buffer *
+i915_drm_buffer_create(struct i915_winsys *iws,
unsigned size, unsigned alignment,
- enum intel_buffer_type type)
+ enum i915_winsys_buffer_type type)
{
- struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+ struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
drm_intel_bufmgr *pool;
char *name;
@@ -23,14 +23,14 @@ intel_drm_buffer_create(struct intel_winsys *iws,
buf->flink = 0;
buf->map_gtt = FALSE;
- if (type == INTEL_NEW_TEXTURE) {
+ if (type == I915_NEW_TEXTURE) {
name = "gallium3d_texture";
pool = idws->pools.gem;
- } else if (type == INTEL_NEW_VERTEX) {
+ } else if (type == I915_NEW_VERTEX) {
name = "gallium3d_vertex";
pool = idws->pools.gem;
buf->map_gtt = TRUE;
- } else if (type == INTEL_NEW_SCANOUT) {
+ } else if (type == I915_NEW_SCANOUT) {
name = "gallium3d_scanout";
pool = idws->pools.gem;
buf->map_gtt = TRUE;
@@ -45,7 +45,7 @@ intel_drm_buffer_create(struct intel_winsys *iws,
if (!buf->bo)
goto err;
- return (struct intel_buffer *)buf;
+ return (struct i915_winsys_buffer *)buf;
err:
assert(0);
@@ -53,13 +53,13 @@ err:
return NULL;
}
-static struct intel_buffer *
-intel_drm_buffer_from_handle(struct intel_winsys *iws,
+static struct i915_winsys_buffer *
+i915_drm_buffer_from_handle(struct i915_winsys *iws,
struct winsys_handle *whandle,
unsigned *stride)
{
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
- struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
uint32_t tile = 0, swizzle = 0;
if (!buf)
@@ -74,12 +74,12 @@ intel_drm_buffer_from_handle(struct intel_winsys *iws,
goto err;
drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
- if (tile != INTEL_TILE_NONE)
+ if (tile != I915_TILE_NONE)
buf->map_gtt = TRUE;
*stride = whandle->stride;
- return (struct intel_buffer *)buf;
+ return (struct i915_winsys_buffer *)buf;
err:
FREE(buf);
@@ -87,12 +87,12 @@ err:
}
static boolean
-intel_drm_buffer_get_handle(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+i915_drm_buffer_get_handle(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
struct winsys_handle *whandle,
unsigned stride)
{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
if (!buf->flinked) {
@@ -114,17 +114,17 @@ intel_drm_buffer_get_handle(struct intel_winsys *iws,
}
static int
-intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+i915_drm_buffer_set_fence_reg(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
unsigned stride,
- enum intel_buffer_tile tile)
+ enum i915_winsys_buffer_tile tile)
{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
- assert(I915_TILING_NONE == INTEL_TILE_NONE);
- assert(I915_TILING_X == INTEL_TILE_X);
- assert(I915_TILING_Y == INTEL_TILE_Y);
+ 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 != INTEL_TILE_NONE) {
+ if (tile != I915_TILE_NONE) {
assert(buf->map_count == 0);
buf->map_gtt = TRUE;
}
@@ -133,11 +133,11 @@ intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
}
static void *
-intel_drm_buffer_map(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+i915_drm_buffer_map(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
boolean write)
{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
drm_intel_bo *bo = intel_bo(buffer);
int ret = 0;
@@ -163,10 +163,10 @@ out:
}
static void
-intel_drm_buffer_unmap(struct intel_winsys *iws,
- struct intel_buffer *buffer)
+i915_drm_buffer_unmap(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
if (--buf->map_count)
return;
@@ -178,40 +178,40 @@ intel_drm_buffer_unmap(struct intel_winsys *iws,
}
static int
-intel_drm_buffer_write(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+i915_drm_buffer_write(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
size_t offset,
size_t size,
const void *data)
{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
}
static void
-intel_drm_buffer_destroy(struct intel_winsys *iws,
- struct intel_buffer *buffer)
+i915_drm_buffer_destroy(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
{
drm_intel_bo_unreference(intel_bo(buffer));
#ifdef DEBUG
- intel_drm_buffer(buffer)->magic = 0;
- intel_drm_buffer(buffer)->bo = NULL;
+ i915_drm_buffer(buffer)->magic = 0;
+ i915_drm_buffer(buffer)->bo = NULL;
#endif
FREE(buffer);
}
void
-intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws)
+i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
{
- idws->base.buffer_create = intel_drm_buffer_create;
- idws->base.buffer_from_handle = intel_drm_buffer_from_handle;
- idws->base.buffer_get_handle = intel_drm_buffer_get_handle;
- idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg;
- idws->base.buffer_map = intel_drm_buffer_map;
- idws->base.buffer_unmap = intel_drm_buffer_unmap;
- idws->base.buffer_write = intel_drm_buffer_write;
- idws->base.buffer_destroy = intel_drm_buffer_destroy;
+ idws->base.buffer_create = i915_drm_buffer_create;
+ 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;
+ idws->base.buffer_destroy = i915_drm_buffer_destroy;
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/i915/drm/i915_drm_fence.c
index 102faedfeae..30ebf4835ea 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_fence.c
@@ -1,5 +1,5 @@
-#include "intel_drm_winsys.h"
+#include "i915_drm_winsys.h"
#include "util/u_memory.h"
#include "util/u_atomic.h"
#include "util/u_inlines.h"
@@ -10,7 +10,7 @@
* They work by keeping the batchbuffer around and checking if that has
* been idled. If bo is NULL fence has expired.
*/
-struct intel_drm_fence
+struct i915_drm_fence
{
struct pipe_reference reference;
drm_intel_bo *bo;
@@ -18,9 +18,9 @@ struct intel_drm_fence
struct pipe_fence_handle *
-intel_drm_fence_create(drm_intel_bo *bo)
+i915_drm_fence_create(drm_intel_bo *bo)
{
- struct intel_drm_fence *fence = CALLOC_STRUCT(intel_drm_fence);
+ struct i915_drm_fence *fence = CALLOC_STRUCT(i915_drm_fence);
pipe_reference_init(&fence->reference, 1);
/* bo is null if fence already expired */
@@ -33,14 +33,14 @@ intel_drm_fence_create(drm_intel_bo *bo)
}
static void
-intel_drm_fence_reference(struct intel_winsys *iws,
+i915_drm_fence_reference(struct i915_winsys *iws,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
- struct intel_drm_fence *old = (struct intel_drm_fence *)*ptr;
- struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+ struct i915_drm_fence *old = (struct i915_drm_fence *)*ptr;
+ struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
- if (pipe_reference(&((struct intel_drm_fence *)(*ptr))->reference, &f->reference)) {
+ if (pipe_reference(&((struct i915_drm_fence *)(*ptr))->reference, &f->reference)) {
if (old->bo)
drm_intel_bo_unreference(old->bo);
FREE(old);
@@ -49,7 +49,7 @@ intel_drm_fence_reference(struct intel_winsys *iws,
}
static int
-intel_drm_fence_signalled(struct intel_winsys *iws,
+i915_drm_fence_signalled(struct i915_winsys *iws,
struct pipe_fence_handle *fence)
{
assert(0);
@@ -58,10 +58,10 @@ intel_drm_fence_signalled(struct intel_winsys *iws,
}
static int
-intel_drm_fence_finish(struct intel_winsys *iws,
+i915_drm_fence_finish(struct i915_winsys *iws,
struct pipe_fence_handle *fence)
{
- struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+ struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
/* fence already expired */
if (!f->bo)
@@ -75,9 +75,9 @@ intel_drm_fence_finish(struct intel_winsys *iws,
}
void
-intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws)
+i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws)
{
- idws->base.fence_reference = intel_drm_fence_reference;
- idws->base.fence_signalled = intel_drm_fence_signalled;
- idws->base.fence_finish = intel_drm_fence_finish;
+ idws->base.fence_reference = i915_drm_fence_reference;
+ idws->base.fence_signalled = i915_drm_fence_signalled;
+ idws->base.fence_finish = i915_drm_fence_finish;
}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
new file mode 100644
index 00000000000..217c4a7eafb
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
@@ -0,0 +1,77 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i915/i915_batchbuffer.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct i915_drm_winsys
+{
+ struct i915_winsys base;
+
+ boolean dump_cmd;
+
+ int fd; /**< Drm file discriptor */
+
+ unsigned id;
+
+ size_t max_batch_size;
+
+ struct {
+ drm_intel_bufmgr *gem;
+ } pools;
+};
+
+static INLINE struct i915_drm_winsys *
+i915_drm_winsys(struct i915_winsys *iws)
+{
+ return (struct i915_drm_winsys *)iws;
+}
+
+struct i915_drm_winsys * i915_drm_winsys_create(int fd, unsigned pci_id);
+struct pipe_fence_handle * i915_drm_fence_create(drm_intel_bo *bo);
+
+void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws);
+void i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws);
+void i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct i915_drm_buffer {
+ unsigned magic;
+
+ drm_intel_bo *bo;
+
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
+ boolean flinked;
+ unsigned flink;
+};
+
+static INLINE struct i915_drm_buffer *
+i915_drm_buffer(struct i915_winsys_buffer *buffer)
+{
+ return (struct i915_drm_buffer *)buffer;
+}
+
+static INLINE drm_intel_bo *
+intel_bo(struct i915_winsys_buffer *buffer)
+{
+ return i915_drm_buffer(buffer)->bo;
+}
+
+#endif
diff --git a/src/gallium/winsys/drm/i965/gem/Makefile b/src/gallium/winsys/i965/drm/Makefile
index 6a7497b6be3..bbb71e25d84 100644
--- a/src/gallium/winsys/drm/i965/gem/Makefile
+++ b/src/gallium/winsys/i965/drm/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = i965drm
@@ -11,4 +11,4 @@ LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/i965/gem/SConscript b/src/gallium/winsys/i965/drm/SConscript
index 6256ec6eaf0..150ab19a33e 100644
--- a/src/gallium/winsys/drm/i965/gem/SConscript
+++ b/src/gallium/winsys/i965/drm/SConscript
@@ -1,6 +1,6 @@
Import('*')
-env = drienv.Clone()
+env = env.Clone()
i965drm_sources = [
'i965_drm_api.c',
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/i965/drm/i965_drm_api.c
index 21e82303f72..9072a186384 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
+++ b/src/gallium/winsys/i965/drm/i965_drm_api.c
@@ -10,6 +10,8 @@
#include "trace/tr_drm.h"
+#include "../../sw/drm/sw_drm_api.h"
+
/*
* Helper functions
*/
@@ -108,5 +110,13 @@ struct drm_api i965_libdrm_api =
struct drm_api *
drm_api_create()
{
- return trace_drm_create(&i965_libdrm_api);
+ struct drm_api *api = NULL;
+
+ if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+ api = sw_drm_api_create(&i965_libdrm_api);
+
+ if (api == NULL)
+ api = &i965_libdrm_api;
+
+ return trace_drm_create(api);
}
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
index 33a17496b2b..33a17496b2b 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
+++ b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
index c6a7d4a8c51..c6a7d4a8c51 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h
+++ b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
diff --git a/src/gallium/winsys/drm/i965/xlib/Makefile b/src/gallium/winsys/i965/xlib/Makefile
index 0efa0ca6f9a..3730db6997e 100644
--- a/src/gallium/winsys/drm/i965/xlib/Makefile
+++ b/src/gallium/winsys/i965/xlib/Makefile
@@ -1,10 +1,10 @@
-# src/gallium/winsys/xlib/Makefile
+# src/gallium/winsys/i965/xlib/Makefile
# This makefile produces a "stand-alone" libGL.so which is based on
# Xlib (no DRI HW acceleration)
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/i965/xlib/xlib_i965.c
index 063e9f600b9..063e9f600b9 100644
--- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
+++ b/src/gallium/winsys/i965/xlib/xlib_i965.c
diff --git a/src/gallium/winsys/drm/nouveau/drm/Makefile b/src/gallium/winsys/nouveau/drm/Makefile
index 54c3b26c755..71029858f75 100644
--- a/src/gallium/winsys/drm/nouveau/drm/Makefile
+++ b/src/gallium/winsys/nouveau/drm/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = nouveaudrm
@@ -8,4 +8,4 @@ C_SOURCES = nouveau_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h b/src/gallium/winsys/nouveau/drm/nouveau_dri.h
index 1207c2d609c..1207c2d609c 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h
+++ b/src/gallium/winsys/nouveau/drm/nouveau_dri.h
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
index 716d4bacd3b..716d4bacd3b 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
index a91aad7df8e..a91aad7df8e 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/radeon/drm/Makefile
index 13bbbf730d6..7f69e392735 100644
--- a/src/gallium/winsys/drm/radeon/core/Makefile
+++ b/src/gallium/winsys/radeon/drm/Makefile
@@ -1,5 +1,5 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = radeonwinsys
@@ -12,6 +12,6 @@ C_SOURCES = \
LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \
$(shell pkg-config libdrm --cflags-only-I)
-include ../../../../Makefile.template
+include ../../../Makefile.template
symlinks:
diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/radeon/drm/SConscript
index f4e9c397bdf..fab42929514 100644
--- a/src/gallium/winsys/drm/radeon/core/SConscript
+++ b/src/gallium/winsys/radeon/drm/SConscript
@@ -1,9 +1,9 @@
Import('*')
-env = drienv.Clone()
+env = env.Clone()
radeon_sources = [
- 'radeon_buffer.c',
+ 'radeon_drm_buffer.c',
'radeon_drm.c',
'radeon_r300.c',
]
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
index e1fcfcfccaa..218a3763018 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -69,12 +69,13 @@ void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
uint32_t rd, uint32_t wd,
uint32_t flags);
-struct radeon_libdrm_winsys* radeon_pipe_winsys(int fd);
-
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
uint32_t handle);
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch);
+void radeon_drm_bufmgr_set_tiling(struct pb_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);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c
index d70173e805d..3dfcc5aef07 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.c
@@ -93,6 +93,13 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
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
+
info.request = RADEON_INFO_DEVICE_ID;
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/radeon/drm/radeon_drm.h
index 2dc077c0521..2dc077c0521 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.h
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index cc56a2bb8fd..66f61322457 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -23,7 +23,6 @@ struct radeon_drm_buffer {
boolean flinked;
uint32_t flink;
- boolean mapped;
struct radeon_drm_buffer *next, *prev;
};
@@ -56,10 +55,10 @@ radeon_drm_buffer_destroy(struct pb_buffer *_buf)
{
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
- if (buf->mapped) {
+ if (buf->bo->ptr != NULL) {
remove_from_list(buf);
radeon_bo_unmap(buf->bo);
- buf->mapped = false;
+ buf->bo->ptr = NULL;
}
radeon_bo_unref(buf->bo);
@@ -71,19 +70,24 @@ radeon_drm_buffer_map(struct pb_buffer *_buf,
unsigned flags)
{
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
- int write;
+ int write = 0;
- if (buf->mapped)
+ if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
+ if ((_buf->base.usage & PIPE_BUFFER_USAGE_VERTEX) ||
+ (_buf->base.usage & PIPE_BUFFER_USAGE_INDEX))
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs))
+ return NULL;
+ }
+
+ if (buf->bo->ptr != NULL)
return buf->bo->ptr;
-
+
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
uint32_t domain;
-
if (radeon_bo_is_busy(buf->bo, &domain))
return NULL;
}
-
if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
}
@@ -95,7 +99,6 @@ radeon_drm_buffer_map(struct pb_buffer *_buf,
if (radeon_bo_map(buf->bo, write)) {
return NULL;
}
- buf->mapped = true;
insert_at_tail(&buf->mgr->buffer_map_list, buf);
return buf->bo->ptr;
}
@@ -289,7 +292,7 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
if (retval) {
- return false;
+ return FALSE;
}
buf->flinked = TRUE;
@@ -303,16 +306,32 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
}
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch)
+void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled,
+ uint32_t pitch)
{
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
- uint32_t flags = 0;
-
- if (microtiled)
- flags |= RADEON_BO_FLAGS_MICRO_TILE;
- if (macrotiled)
- flags |= RADEON_BO_FLAGS_MACRO_TILE;
-
+ uint32_t flags = 0, old_flags, old_pitch;
+ if (microtiled == R300_BUFFER_TILED)
+ flags |= RADEON_BO_FLAGS_MICRO_TILE;
+/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
+#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
+ else if (microtiled == R300_BUFFER_SQUARETILED)
+ flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE;
+#endif
+ if (macrotiled == R300_BUFFER_TILED)
+ flags |= RADEON_BO_FLAGS_MACRO_TILE;
+
+ radeon_bo_get_tiling(buf->bo, &old_flags, &old_pitch);
+
+ if (flags != old_flags || pitch != old_pitch) {
+ /* Tiling determines how DRM treats the buffer data.
+ * We must flush CS when changing it if the buffer is referenced. */
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ }
+ }
radeon_bo_set_tiling(buf->bo, flags, pitch);
}
@@ -323,7 +342,7 @@ boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
rd, wd);
- return true;
+ return TRUE;
}
void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
@@ -349,7 +368,7 @@ boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf)
return (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs) ||
radeon_bo_is_busy(buf->bo, &domain));
}
-
+
void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
{
@@ -357,12 +376,10 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
struct radeon_drm_buffer *rpb, *t_rpb;
foreach_s(rpb, t_rpb, &mgr->buffer_map_list) {
- rpb->mapped = 0;
radeon_bo_unmap(rpb->bo);
+ rpb->bo->ptr = NULL;
remove_from_list(rpb);
}
make_empty_list(&mgr->buffer_map_list);
-
-
}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index 5b82a776a81..38fcf889c8b 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -44,6 +44,9 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
if (usage & PIPE_BUFFER_USAGE_CONSTANT)
provider = ws->mman;
+ else if ((usage & PIPE_BUFFER_USAGE_VERTEX) ||
+ (usage & PIPE_BUFFER_USAGE_INDEX))
+ provider = ws->cman;
else
provider = ws->kman;
buffer = provider->create_buffer(provider, size, &desc);
@@ -62,8 +65,8 @@ static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf)
static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws,
struct r300_winsys_buffer *buf,
uint32_t pitch,
- boolean microtiled,
- boolean macrotiled)
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled)
{
struct pb_buffer *_buf = radeon_pb_buffer(buf);
radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
@@ -250,6 +253,8 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
return ws->gb_pipes;
case R300_VID_Z_PIPES:
return ws->z_pipes;
+ case R300_VID_SQUARE_TILING_SUPPORT:
+ return ws->squaretiling;
}
return 0;
}
@@ -260,6 +265,7 @@ radeon_winsys_destroy(struct r300_winsys_screen *rws)
struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
radeon_cs_destroy(ws->cs);
+ ws->cman->destroy(ws->cman);
ws->kman->destroy(ws->kman);
ws->mman->destroy(ws->mman);
@@ -281,6 +287,10 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
if (!ws->kman)
goto fail;
+ ws->cman = pb_cache_manager_create(ws->kman, 100000);
+ if (!ws->cman)
+ goto fail;
+
ws->mman = pb_malloc_bufmgr_create();
if (!ws->mman)
goto fail;
@@ -325,7 +335,8 @@ fail:
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);
if (ws->mman)
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/radeon/drm/radeon_r300.h
index 2703464ad8f..2703464ad8f 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.h
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 16cc701ad6f..4260dbaad72 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -38,6 +38,8 @@ struct radeon_libdrm_winsys {
struct pb_manager *kman;
+ struct pb_manager *cman;
+
struct pb_manager *mman;
/* PCI ID */
@@ -55,6 +57,9 @@ struct radeon_libdrm_winsys {
/* VRAM size. */
uint32_t vram_size;
+ /* Square tiling support. */
+ boolean squaretiling;
+
/* DRM FD */
int fd;
diff --git a/src/gallium/winsys/drm/vmware/core/Makefile b/src/gallium/winsys/svga/drm/Makefile
index a52957c1a5b..c2f59e01b0d 100644
--- a/src/gallium/winsys/drm/vmware/core/Makefile
+++ b/src/gallium/winsys/svga/drm/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = svgadrm
@@ -17,14 +17,6 @@ C_SOURCES = \
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/svga \
-I$(TOP)/src/gallium/drivers/svga/include \
- -I$(GALLIUM)/src/mesa/drivers/dri/common \
- -I$(GALLIUM)/include \
- -I$(GALLIUM)/include/GL/internal \
- -I$(GALLIUM)/src/mesa \
- -I$(GALLIUM)/src/mesa/main \
- -I$(GALLIUM)/src/mesa/glapi \
- -I$(GALLIUM)/src/egl/main \
- -I$(GALLIUM)/src/egl/drivers/dri \
$(shell pkg-config libdrm --cflags-only-I)
LIBRARY_DEFINES = \
@@ -32,4 +24,4 @@ LIBRARY_DEFINES = \
-DHAVE_STDINT_H -D_FILE_OFFSET_BITS=64 \
$(shell pkg-config libdrm --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/vmware/core/SConscript b/src/gallium/winsys/svga/drm/SConscript
index edaf9458bee..edaf9458bee 100644
--- a/src/gallium/winsys/drm/vmware/core/SConscript
+++ b/src/gallium/winsys/svga/drm/SConscript
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c b/src/gallium/winsys/svga/drm/vmw_buffer.c
index eca174a6c56..eca174a6c56 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h b/src/gallium/winsys/svga/drm/vmw_buffer.h
index 41fb4476da5..41fb4476da5 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c
index 90ffc4868f7..90ffc4868f7 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.h b/src/gallium/winsys/svga/drm/vmw_context.h
index d4884d24e99..d4884d24e99 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_context.h
+++ b/src/gallium/winsys/svga/drm/vmw_context.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.c b/src/gallium/winsys/svga/drm/vmw_fence.c
index 873dd51166c..873dd51166c 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_fence.c
+++ b/src/gallium/winsys/svga/drm/vmw_fence.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.h b/src/gallium/winsys/svga/drm/vmw_fence.h
index 5357b4f61de..5357b4f61de 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_fence.h
+++ b/src/gallium/winsys/svga/drm/vmw_fence.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 6cc9b382932..6cc9b382932 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index d3f2c2c7f56..d3f2c2c7f56 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
index 657544dcb21..e8ebe9ac893 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
@@ -39,7 +39,7 @@
#include <state_tracker/dri1_api.h>
#include <state_tracker/drm_api.h>
-#include <vmwgfx_drm.h>
+#include "vmwgfx_drm.h"
#include <xf86drm.h>
#include <stdio.h>
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 5d81fa8c4a6..5d81fa8c4a6 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
index b9823d78575..b9823d78575 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
index 2b4e80f0039..2b4e80f0039 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c
index 5f1b9ad5770..5f1b9ad5770 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_surface.c
+++ b/src/gallium/winsys/svga/drm/vmw_surface.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.h b/src/gallium/winsys/svga/drm/vmw_surface.h
index 3d61595c288..3d61595c288 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_surface.h
+++ b/src/gallium/winsys/svga/drm/vmw_surface.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
index 47914bdb711..47914bdb711 100644
--- a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
+++ b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/winsys/sw/Makefile
index fee01916432..e9182ea5b1b 100644
--- a/src/gallium/winsys/drm/Makefile
+++ b/src/gallium/winsys/sw/Makefile
@@ -1,8 +1,8 @@
-# src/gallium/winsys/Makefile
+# src/gallium/winsys/sw/Makefile
TOP = ../../../..
include $(TOP)/configs/current
-SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS)
+SUBDIRS = null wrapper
default install clean:
@for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/sw/dri/Makefile b/src/gallium/winsys/sw/dri/Makefile
new file mode 100644
index 00000000000..a3fca6be885
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/Makefile
@@ -0,0 +1,13 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdri
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+C_SOURCES = \
+ dri_sw_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/dri/SConscript b/src/gallium/winsys/sw/dri/SConscript
new file mode 100644
index 00000000000..b255d725f95
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_dri = env.ConvenienceLibrary(
+ target = 'ws_dri',
+ source = [
+ 'dri_sw_winsys.c',
+ ]
+ )
+ Export('ws_dri')
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
new file mode 100644
index 00000000000..870c6afc124
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -0,0 +1,225 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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 "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/sw_winsys.h"
+#include "dri_sw_winsys.h"
+
+
+struct dri_sw_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+};
+
+struct dri_sw_winsys
+{
+ struct sw_winsys base;
+
+ struct drisw_loader_funcs *lf;
+};
+
+static INLINE struct dri_sw_displaytarget *
+dri_sw_displaytarget( struct sw_displaytarget *dt )
+{
+ return (struct dri_sw_displaytarget *)dt;
+}
+
+static INLINE struct dri_sw_winsys *
+dri_sw_winsys( struct sw_winsys *ws )
+{
+ return (struct dri_sw_winsys *)ws;
+}
+
+
+static boolean
+dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ /* TODO: check visuals or other sensible thing here */
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+dri_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct dri_sw_displaytarget *dri_sw_dt;
+ unsigned nblocksy, size, format_stride;
+
+ dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
+ if(!dri_sw_dt)
+ goto no_dt;
+
+ dri_sw_dt->format = format;
+ dri_sw_dt->width = width;
+ dri_sw_dt->height = height;
+
+ format_stride = util_format_get_stride(format, width);
+ dri_sw_dt->stride = align(format_stride, alignment);
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ size = dri_sw_dt->stride * nblocksy;
+
+ dri_sw_dt->data = align_malloc(size, alignment);
+ if(!dri_sw_dt->data)
+ goto no_data;
+
+ *stride = dri_sw_dt->stride;
+ return (struct sw_displaytarget *)dri_sw_dt;
+
+no_data:
+ FREE(dri_sw_dt);
+no_dt:
+ return NULL;
+}
+
+static void
+dri_sw_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+
+ if (dri_sw_dt->data) {
+ FREE(dri_sw_dt->data);
+ }
+
+ FREE(dri_sw_dt);
+}
+
+static void *
+dri_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ dri_sw_dt->mapped = dri_sw_dt->data;
+ return dri_sw_dt->mapped;
+}
+
+static void
+dri_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ dri_sw_dt->mapped = NULL;
+}
+
+static struct sw_displaytarget *
+dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+static boolean
+dri_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+static void
+dri_sw_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
+ unsigned width, height;
+
+ /* Set the width to 'stride / cpp'.
+ *
+ * PutImage correctly clips to the width of the dst drawable.
+ */
+ width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
+
+ height = dri_sw_dt->height;
+
+ dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
+}
+
+
+static void
+dri_destroy_sw_winsys(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+struct sw_winsys *
+dri_create_sw_winsys(struct drisw_loader_funcs *lf)
+{
+ struct dri_sw_winsys *ws;
+
+ ws = CALLOC_STRUCT(dri_sw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->lf = lf;
+ ws->base.destroy = dri_destroy_sw_winsys;
+
+ ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
+
+ /* screen texture functions */
+ ws->base.displaytarget_create = dri_sw_displaytarget_create;
+ ws->base.displaytarget_destroy = dri_sw_displaytarget_destroy;
+ ws->base.displaytarget_from_handle = dri_sw_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = dri_sw_displaytarget_get_handle;
+
+ /* texture functions */
+ ws->base.displaytarget_map = dri_sw_displaytarget_map;
+ ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap;
+
+ ws->base.displaytarget_display = dri_sw_displaytarget_display;
+
+ return &ws->base;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.h b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
new file mode 100644
index 00000000000..329ac06a05b
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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 DRI_SW_WINSYS
+#define DRI_SW_WINSYS
+
+#include "state_tracker/drisw_api.h"
+
+struct sw_winsys;
+
+struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf);
+
+#endif
diff --git a/src/gallium/winsys/sw/drm/Makefile b/src/gallium/winsys/sw/drm/Makefile
new file mode 100644
index 00000000000..79664536aa0
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdrm
+
+C_SOURCES = sw_drm_api.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.c b/src/gallium/winsys/sw/drm/sw_drm_api.c
new file mode 100644
index 00000000000..eb81d26a593
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/sw_drm_api.c
@@ -0,0 +1,97 @@
+/**********************************************************
+ * 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "util/u_memory.h"
+#include "softpipe/sp_public.h"
+#include "state_tracker/drm_api.h"
+#include "../../sw/wrapper/wrapper_sw_winsys.h"
+#include "sw_drm_api.h"
+
+
+/*
+ * Defines
+ */
+
+
+struct sw_drm_api
+{
+ struct drm_api base;
+ struct drm_api *api;
+ struct sw_winsys *sw;
+};
+
+static INLINE struct sw_drm_api *
+sw_drm_api(struct drm_api *api)
+{
+ return (struct sw_drm_api *)api;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_screen *
+sw_drm_create_screen(struct drm_api *_api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct sw_drm_api *swapi = sw_drm_api(_api);
+ struct drm_api *api = swapi->api;
+ struct sw_winsys *sww;
+ struct pipe_screen *screen;
+
+ screen = api->create_screen(api, drmFD, arg);
+
+ sww = wrapper_sw_winsys_warp_pipe_screen(screen);
+
+ return softpipe_create_screen(sww);
+}
+
+static void
+sw_drm_destroy(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = sw_drm_api(api);
+ if (swapi->api->destroy)
+ swapi->api->destroy(swapi->api);
+
+ FREE(swapi);
+}
+
+struct drm_api *
+sw_drm_api_create(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);
+
+ swapi->base.name = "sw";
+ swapi->base.driver_name = api->driver_name;
+ swapi->base.create_screen = sw_drm_create_screen;
+ swapi->base.destroy = sw_drm_destroy;
+
+ swapi->api = api;
+
+ return &swapi->base;
+}
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.h b/src/gallium/winsys/sw/drm/sw_drm_api.h
new file mode 100644
index 00000000000..ce90a04ae0c
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/sw_drm_api.h
@@ -0,0 +1,34 @@
+/**********************************************************
+ * 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef SW_DRM_API_H
+#define SW_DRM_API_H
+
+struct drm_api;
+
+struct drm_api * sw_drm_api_create(struct drm_api *api);
+
+#endif
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/sw/gdi/SConscript
index 1267fc6eea4..1267fc6eea4 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/winsys/sw/gdi/SConscript
diff --git a/src/gallium/winsys/gdi/gdi_sw_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
index f5c0b7d56ec..4dba4b577b8 100644
--- a/src/gallium/winsys/gdi/gdi_sw_winsys.c
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
@@ -71,6 +71,7 @@ gdi_sw_displaytarget( struct sw_displaytarget *buf )
static boolean
gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
switch(format) {
@@ -119,6 +120,7 @@ gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,
static struct sw_displaytarget *
gdi_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -168,6 +170,27 @@ no_gdt:
}
+static struct sw_displaytarget *
+gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
void
gdi_sw_display( struct sw_winsys *winsys,
struct sw_displaytarget *dt,
@@ -212,6 +235,8 @@ gdi_create_sw_winsys(void)
winsys->destroy = gdi_sw_destroy;
winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported;
winsys->displaytarget_create = gdi_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle;
winsys->displaytarget_map = gdi_sw_displaytarget_map;
winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap;
winsys->displaytarget_display = gdi_sw_displaytarget_display;
diff --git a/src/gallium/winsys/gdi/gdi_sw_winsys.h b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h
index 4bbcb47848b..4bbcb47848b 100644
--- a/src/gallium/winsys/gdi/gdi_sw_winsys.h
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h
diff --git a/src/gallium/winsys/null/Makefile b/src/gallium/winsys/sw/null/Makefile
index 3a3fb75ab36..b1882b582e9 100644
--- a/src/gallium/winsys/null/Makefile
+++ b/src/gallium/winsys/sw/null/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = ws_null
@@ -11,6 +11,6 @@ LIBRARY_INCLUDES = \
C_SOURCES = \
null_sw_winsys.c
-include ../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/null/SConscript b/src/gallium/winsys/sw/null/SConscript
index 21837dc60c2..21837dc60c2 100644
--- a/src/gallium/winsys/null/SConscript
+++ b/src/gallium/winsys/sw/null/SConscript
diff --git a/src/gallium/winsys/null/null_sw_winsys.c b/src/gallium/winsys/sw/null/null_sw_winsys.c
index d961d34860e..5027e57b303 100644
--- a/src/gallium/winsys/null/null_sw_winsys.c
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.c
@@ -44,6 +44,7 @@
static boolean
null_sw_is_displaytarget_format_supported(struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
return FALSE;
@@ -78,6 +79,7 @@ null_sw_displaytarget_destroy(struct sw_winsys *winsys,
static struct sw_displaytarget *
null_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -87,6 +89,26 @@ null_sw_displaytarget_create(struct sw_winsys *winsys,
}
+static struct sw_displaytarget *
+null_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static boolean
+null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
static void
null_sw_displaytarget_display(struct sw_winsys *winsys,
struct sw_displaytarget *dt,
@@ -115,6 +137,8 @@ null_sw_create(void)
winsys->destroy = null_sw_destroy;
winsys->is_displaytarget_format_supported = null_sw_is_displaytarget_format_supported;
winsys->displaytarget_create = null_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = null_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = null_sw_displaytarget_get_handle;
winsys->displaytarget_map = null_sw_displaytarget_map;
winsys->displaytarget_unmap = null_sw_displaytarget_unmap;
winsys->displaytarget_display = null_sw_displaytarget_display;
diff --git a/src/gallium/winsys/null/null_sw_winsys.h b/src/gallium/winsys/sw/null/null_sw_winsys.h
index 1986186febe..1986186febe 100644
--- a/src/gallium/winsys/null/null_sw_winsys.h
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.h
diff --git a/src/gallium/winsys/sw/wrapper/Makefile b/src/gallium/winsys/sw/wrapper/Makefile
new file mode 100644
index 00000000000..4771fbcf700
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = wsw
+
+C_SOURCES = wrapper_sw_winsys.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
new file mode 100644
index 00000000000..459b1c1e2a3
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
@@ -0,0 +1,282 @@
+/**********************************************************
+ * 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "wrapper_sw_winsys.h"
+
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+
+#include "state_tracker/sw_winsys.h"
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+/*
+ * This code wraps a pipe_screen and exposes a sw_winsys interface for use
+ * with software resterizers. This code is used by the DRM based winsys to
+ * allow access to the drm driver.
+ *
+ * We must borrow the whole stack because only the pipe screen knows how
+ * to decode the content of a buffer. Or how to create a buffer that
+ * can still be used by drivers using real hardware (as the case is
+ * with software st/xorg but hw st/dri).
+ *
+ * We also need a pipe context for the transfers.
+ */
+
+struct wrapper_sw_winsys
+{
+ struct sw_winsys base;
+ struct pipe_screen *screen;
+ struct pipe_context *pipe;
+};
+
+struct wrapper_sw_displaytarget
+{
+ struct wrapper_sw_winsys *winsys;
+ struct pipe_texture *tex;
+ struct pipe_transfer *transfer;
+
+ unsigned width;
+ unsigned height;
+ unsigned map_count;
+ unsigned stride; /**< because we give stride at create */
+ void *ptr;
+};
+
+static INLINE struct wrapper_sw_winsys *
+wrapper_sw_winsys(struct sw_winsys *ws)
+{
+ return (struct wrapper_sw_winsys *)ws;
+}
+
+static INLINE struct wrapper_sw_displaytarget *
+wrapper_sw_displaytarget(struct sw_displaytarget *dt)
+{
+ return (struct wrapper_sw_displaytarget *)dt;
+}
+
+
+/*
+ * Functions
+ */
+
+
+static boolean
+wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)
+{
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_texture *tex = wdt->tex;
+ struct pipe_transfer *tr;
+
+ tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return FALSE;
+
+ *stride = tr->stride;
+ wdt->stride = tr->stride;
+
+ pipe->tex_transfer_destroy(pipe, tr);
+
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw,
+ struct pipe_texture *tex, unsigned *stride)
+{
+ struct wrapper_sw_displaytarget *wdt = CALLOC_STRUCT(wrapper_sw_displaytarget);
+ if (!wdt)
+ goto err_unref;
+
+ wdt->tex = tex;
+ wdt->winsys = wsw;
+
+ if (!wsw_dt_get_stride(wdt, stride))
+ goto err_free;
+
+ return (struct sw_displaytarget *)wdt;
+
+err_free:
+ FREE(wdt);
+err_unref:
+ pipe_texture_reference(&tex, NULL);
+ return NULL;
+}
+
+static struct sw_displaytarget *
+wsw_dt_create(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_texture templ;
+ struct pipe_texture *tex;
+
+ /*
+ * XXX Why don't we just get the template.
+ */
+ memset(&templ, 0, sizeof(templ));
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ /* XXX alignment: we can't do anything about this */
+
+ tex = wsw->screen->texture_create(wsw->screen, &templ);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static struct sw_displaytarget *
+wsw_dt_from_handle(struct sw_winsys *ws,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_texture *tex;
+
+ tex = wsw->screen->texture_from_handle(wsw->screen, templ, whandle);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static void *
+wsw_dt_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_texture *tex = wdt->tex;
+ struct pipe_transfer *tr;
+ void *ptr;
+
+ if (!wdt->map_count) {
+
+ assert(!wdt->transfer);
+
+ tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return NULL;
+
+ ptr = pipe->transfer_map(pipe, tr);
+ if (!ptr)
+ goto err;
+
+ wdt->transfer = tr;
+ wdt->ptr = ptr;
+
+ /* XXX Handle this case */
+ assert(tr->stride == wdt->stride);
+ }
+
+ wdt->map_count++;
+
+ return wdt->ptr;
+
+err:
+ pipe->tex_transfer_destroy(pipe, tr);
+ return NULL;
+}
+
+static void
+wsw_dt_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+
+ assert(wdt->transfer);
+
+ wdt->map_count--;
+
+ if (wdt->map_count)
+ return;
+
+ pipe->transfer_unmap(pipe, wdt->transfer);
+ pipe->tex_transfer_destroy(pipe, wdt->transfer);
+ wdt->transfer = NULL;
+}
+
+static void
+wsw_dt_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+
+ pipe_texture_reference(&wdt->tex, NULL);
+
+ FREE(wdt);
+}
+
+static void
+wsw_destroy(struct sw_winsys *ws)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+
+ wsw->pipe->destroy(wsw->pipe);
+ wsw->screen->destroy(wsw->screen);
+
+ FREE(wsw);
+}
+
+struct sw_winsys *
+wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen)
+{
+ struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys);
+
+ wsw->base.displaytarget_create = wsw_dt_create;
+ wsw->base.displaytarget_from_handle = wsw_dt_from_handle;
+ wsw->base.displaytarget_map = wsw_dt_map;
+ wsw->base.displaytarget_unmap = wsw_dt_unmap;
+ wsw->base.displaytarget_destroy = wsw_dt_destroy;
+ wsw->base.destroy = wsw_destroy;
+
+ wsw->screen = screen;
+ wsw->pipe = screen->context_create(screen, NULL);
+ if (!wsw->pipe)
+ goto err;
+
+ return &wsw->base;
+
+err:
+ FREE(wsw);
+ return NULL;
+}
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h
new file mode 100644
index 00000000000..b5c25a3c50f
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h
@@ -0,0 +1,35 @@
+/**********************************************************
+ * 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef WRAPPER_SW_WINSYS
+#define WRAPPER_SW_WINSYS
+
+struct sw_winsys;
+struct pipe_screen;
+
+struct sw_winsys *wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/sw/xlib/Makefile
index 18357a41127..c6693899281 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/sw/xlib/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = ws_xlib
@@ -7,11 +7,11 @@ LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary \
- $(X_CFLAGS)
+ $(X11_CFLAGS)
C_SOURCES = \
xlib_sw_winsys.c
-include ../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript
index 2af6153b4c7..2af6153b4c7 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/sw/xlib/SConscript
diff --git a/src/gallium/winsys/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
index cecfa4a53d4..ad843b7def6 100644
--- a/src/gallium/winsys/xlib/xlib_sw_winsys.c
+++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
@@ -208,6 +208,7 @@ alloc_ximage(struct xm_displaytarget *xm_dt,
static boolean
xm_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
/* TODO: check visuals or other sensible thing here */
@@ -340,6 +341,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable,
XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
}
+
+ XFlush(xm_dt->display);
}
/**
@@ -358,6 +361,7 @@ xm_displaytarget_display(struct sw_winsys *ws,
static struct sw_displaytarget *
xm_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -406,6 +410,27 @@ no_xm_dt:
}
+static struct sw_displaytarget *
+xm_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+xm_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
static void
xm_destroy( struct sw_winsys *ws )
{
@@ -428,6 +453,8 @@ xlib_create_sw_winsys( Display *display )
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
ws->base.displaytarget_create = xm_displaytarget_create;
+ ws->base.displaytarget_from_handle = xm_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = xm_displaytarget_get_handle;
ws->base.displaytarget_map = xm_displaytarget_map;
ws->base.displaytarget_unmap = xm_displaytarget_unmap;
ws->base.displaytarget_destroy = xm_displaytarget_destroy;